Add support for API client to receive L2 MAC events
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 static void
1287 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1288 {
1289   u32 n_macs = ntohl (mp->n_macs);
1290   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1291           ntohl (mp->pid), mp->client_index, n_macs);
1292   int i;
1293   for (i = 0; i < n_macs; i++)
1294     {
1295       vl_api_mac_entry_t *mac = &mp->mac[i];
1296       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1297               i + 1, ntohl (mac->sw_if_index),
1298               format_ethernet_address, mac->mac_addr, mac->is_del);
1299       if (i == 1000)
1300         break;
1301     }
1302 }
1303
1304 static void
1305 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1311 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1312
1313 /*
1314  * Special-case: build the bridge domain table, maintain
1315  * the next bd id vbl.
1316  */
1317 static void vl_api_bridge_domain_details_t_handler
1318   (vl_api_bridge_domain_details_t * mp)
1319 {
1320   vat_main_t *vam = &vat_main;
1321   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1322   int i;
1323
1324   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1325          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1326
1327   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1328          ntohl (mp->bd_id), mp->learn, mp->forward,
1329          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1330
1331   if (n_sw_ifs)
1332     {
1333       vl_api_bridge_domain_sw_if_t *sw_ifs;
1334       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1335              "Interface Name");
1336
1337       sw_ifs = mp->sw_if_details;
1338       for (i = 0; i < n_sw_ifs; i++)
1339         {
1340           u8 *sw_if_name = 0;
1341           u32 sw_if_index;
1342           hash_pair_t *p;
1343
1344           sw_if_index = ntohl (sw_ifs->sw_if_index);
1345
1346           /* *INDENT-OFF* */
1347           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1348                              ({
1349                                if ((u32) p->value[0] == sw_if_index)
1350                                  {
1351                                    sw_if_name = (u8 *)(p->key);
1352                                    break;
1353                                  }
1354                              }));
1355           /* *INDENT-ON* */
1356           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1357                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1358                  "sw_if_index not found!");
1359
1360           sw_ifs++;
1361         }
1362     }
1363 }
1364
1365 static void vl_api_bridge_domain_details_t_handler_json
1366   (vl_api_bridge_domain_details_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t *node, *array = NULL;
1370   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1371
1372   if (VAT_JSON_ARRAY != vam->json_tree.type)
1373     {
1374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1375       vat_json_init_array (&vam->json_tree);
1376     }
1377   node = vat_json_array_add (&vam->json_tree);
1378
1379   vat_json_init_object (node);
1380   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1381   vat_json_object_add_uint (node, "flood", mp->flood);
1382   vat_json_object_add_uint (node, "forward", mp->forward);
1383   vat_json_object_add_uint (node, "learn", mp->learn);
1384   vat_json_object_add_uint (node, "bvi_sw_if_index",
1385                             ntohl (mp->bvi_sw_if_index));
1386   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1387   array = vat_json_object_add (node, "sw_if");
1388   vat_json_init_array (array);
1389
1390
1391
1392   if (n_sw_ifs)
1393     {
1394       vl_api_bridge_domain_sw_if_t *sw_ifs;
1395       int i;
1396
1397       sw_ifs = mp->sw_if_details;
1398       for (i = 0; i < n_sw_ifs; i++)
1399         {
1400           node = vat_json_array_add (array);
1401           vat_json_init_object (node);
1402           vat_json_object_add_uint (node, "sw_if_index",
1403                                     ntohl (sw_ifs->sw_if_index));
1404           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1405           sw_ifs++;
1406         }
1407     }
1408 }
1409
1410 static void vl_api_control_ping_reply_t_handler
1411   (vl_api_control_ping_reply_t * mp)
1412 {
1413   vat_main_t *vam = &vat_main;
1414   i32 retval = ntohl (mp->retval);
1415   if (vam->async_mode)
1416     {
1417       vam->async_errors += (retval < 0);
1418     }
1419   else
1420     {
1421       vam->retval = retval;
1422       vam->result_ready = 1;
1423     }
1424 }
1425
1426 static void vl_api_control_ping_reply_t_handler_json
1427   (vl_api_control_ping_reply_t * mp)
1428 {
1429   vat_main_t *vam = &vat_main;
1430   i32 retval = ntohl (mp->retval);
1431
1432   if (VAT_JSON_NONE != vam->json_tree.type)
1433     {
1434       vat_json_print (vam->ofp, &vam->json_tree);
1435       vat_json_free (&vam->json_tree);
1436       vam->json_tree.type = VAT_JSON_NONE;
1437     }
1438   else
1439     {
1440       /* just print [] */
1441       vat_json_init_array (&vam->json_tree);
1442       vat_json_print (vam->ofp, &vam->json_tree);
1443       vam->json_tree.type = VAT_JSON_NONE;
1444     }
1445
1446   vam->retval = retval;
1447   vam->result_ready = 1;
1448 }
1449
1450 static void
1451   vl_api_bridge_domain_set_mac_age_reply_t_handler
1452   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   i32 retval = ntohl (mp->retval);
1456   if (vam->async_mode)
1457     {
1458       vam->async_errors += (retval < 0);
1459     }
1460   else
1461     {
1462       vam->retval = retval;
1463       vam->result_ready = 1;
1464     }
1465 }
1466
1467 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1468   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   vat_json_node_t node;
1472
1473   vat_json_init_object (&node);
1474   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1475
1476   vat_json_print (vam->ofp, &node);
1477   vat_json_free (&node);
1478
1479   vam->retval = ntohl (mp->retval);
1480   vam->result_ready = 1;
1481 }
1482
1483 static void
1484 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488   if (vam->async_mode)
1489     {
1490       vam->async_errors += (retval < 0);
1491     }
1492   else
1493     {
1494       vam->retval = retval;
1495       vam->result_ready = 1;
1496     }
1497 }
1498
1499 static void vl_api_l2_flags_reply_t_handler_json
1500   (vl_api_l2_flags_reply_t * mp)
1501 {
1502   vat_main_t *vam = &vat_main;
1503   vat_json_node_t node;
1504
1505   vat_json_init_object (&node);
1506   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1507   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1508                             ntohl (mp->resulting_feature_bitmap));
1509
1510   vat_json_print (vam->ofp, &node);
1511   vat_json_free (&node);
1512
1513   vam->retval = ntohl (mp->retval);
1514   vam->result_ready = 1;
1515 }
1516
1517 static void vl_api_bridge_flags_reply_t_handler
1518   (vl_api_bridge_flags_reply_t * mp)
1519 {
1520   vat_main_t *vam = &vat_main;
1521   i32 retval = ntohl (mp->retval);
1522   if (vam->async_mode)
1523     {
1524       vam->async_errors += (retval < 0);
1525     }
1526   else
1527     {
1528       vam->retval = retval;
1529       vam->result_ready = 1;
1530     }
1531 }
1532
1533 static void vl_api_bridge_flags_reply_t_handler_json
1534   (vl_api_bridge_flags_reply_t * mp)
1535 {
1536   vat_main_t *vam = &vat_main;
1537   vat_json_node_t node;
1538
1539   vat_json_init_object (&node);
1540   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1541   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1542                             ntohl (mp->resulting_feature_bitmap));
1543
1544   vat_json_print (vam->ofp, &node);
1545   vat_json_free (&node);
1546
1547   vam->retval = ntohl (mp->retval);
1548   vam->result_ready = 1;
1549 }
1550
1551 static void vl_api_tap_connect_reply_t_handler
1552   (vl_api_tap_connect_reply_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   i32 retval = ntohl (mp->retval);
1556   if (vam->async_mode)
1557     {
1558       vam->async_errors += (retval < 0);
1559     }
1560   else
1561     {
1562       vam->retval = retval;
1563       vam->sw_if_index = ntohl (mp->sw_if_index);
1564       vam->result_ready = 1;
1565     }
1566
1567 }
1568
1569 static void vl_api_tap_connect_reply_t_handler_json
1570   (vl_api_tap_connect_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1578
1579   vat_json_print (vam->ofp, &node);
1580   vat_json_free (&node);
1581
1582   vam->retval = ntohl (mp->retval);
1583   vam->result_ready = 1;
1584
1585 }
1586
1587 static void
1588 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->sw_if_index = ntohl (mp->sw_if_index);
1600       vam->result_ready = 1;
1601     }
1602 }
1603
1604 static void vl_api_tap_modify_reply_t_handler_json
1605   (vl_api_tap_modify_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   vat_json_node_t node;
1609
1610   vat_json_init_object (&node);
1611   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1612   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void
1622 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->result_ready = 1;
1634     }
1635 }
1636
1637 static void vl_api_tap_delete_reply_t_handler_json
1638   (vl_api_tap_delete_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   vat_json_node_t node;
1642
1643   vat_json_init_object (&node);
1644   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1645
1646   vat_json_print (vam->ofp, &node);
1647   vat_json_free (&node);
1648
1649   vam->retval = ntohl (mp->retval);
1650   vam->result_ready = 1;
1651 }
1652
1653 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1654   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   i32 retval = ntohl (mp->retval);
1658   if (vam->async_mode)
1659     {
1660       vam->async_errors += (retval < 0);
1661     }
1662   else
1663     {
1664       vam->retval = retval;
1665       vam->result_ready = 1;
1666     }
1667 }
1668
1669 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1670   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   vat_json_node_t node;
1674
1675   vat_json_init_object (&node);
1676   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1677   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1678                             ntohl (mp->sw_if_index));
1679
1680   vat_json_print (vam->ofp, &node);
1681   vat_json_free (&node);
1682
1683   vam->retval = ntohl (mp->retval);
1684   vam->result_ready = 1;
1685 }
1686
1687 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1688   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   i32 retval = ntohl (mp->retval);
1692   if (vam->async_mode)
1693     {
1694       vam->async_errors += (retval < 0);
1695     }
1696   else
1697     {
1698       vam->retval = retval;
1699       vam->sw_if_index = ntohl (mp->sw_if_index);
1700       vam->result_ready = 1;
1701     }
1702 }
1703
1704 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1705   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1706 {
1707   vat_main_t *vam = &vat_main;
1708   vat_json_node_t node;
1709
1710   vat_json_init_object (&node);
1711   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1712   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1713
1714   vat_json_print (vam->ofp, &node);
1715   vat_json_free (&node);
1716
1717   vam->retval = ntohl (mp->retval);
1718   vam->result_ready = 1;
1719 }
1720
1721 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1722   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1723 {
1724   vat_main_t *vam = &vat_main;
1725   i32 retval = ntohl (mp->retval);
1726   if (vam->async_mode)
1727     {
1728       vam->async_errors += (retval < 0);
1729     }
1730   else
1731     {
1732       vam->retval = retval;
1733       vam->result_ready = 1;
1734     }
1735 }
1736
1737 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1738   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1739 {
1740   vat_main_t *vam = &vat_main;
1741   vat_json_node_t node;
1742
1743   vat_json_init_object (&node);
1744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1745   vat_json_object_add_uint (&node, "fwd_entry_index",
1746                             clib_net_to_host_u32 (mp->fwd_entry_index));
1747
1748   vat_json_print (vam->ofp, &node);
1749   vat_json_free (&node);
1750
1751   vam->retval = ntohl (mp->retval);
1752   vam->result_ready = 1;
1753 }
1754
1755 static void vl_api_one_add_del_locator_set_reply_t_handler
1756   (vl_api_one_add_del_locator_set_reply_t * mp)
1757 {
1758   vat_main_t *vam = &vat_main;
1759   i32 retval = ntohl (mp->retval);
1760   if (vam->async_mode)
1761     {
1762       vam->async_errors += (retval < 0);
1763     }
1764   else
1765     {
1766       vam->retval = retval;
1767       vam->result_ready = 1;
1768     }
1769 }
1770
1771 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1772   (vl_api_one_add_del_locator_set_reply_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   vat_json_node_t node;
1776
1777   vat_json_init_object (&node);
1778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1779   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1780
1781   vat_json_print (vam->ofp, &node);
1782   vat_json_free (&node);
1783
1784   vam->retval = ntohl (mp->retval);
1785   vam->result_ready = 1;
1786 }
1787
1788 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1789   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1790 {
1791   vat_main_t *vam = &vat_main;
1792   i32 retval = ntohl (mp->retval);
1793   if (vam->async_mode)
1794     {
1795       vam->async_errors += (retval < 0);
1796     }
1797   else
1798     {
1799       vam->retval = retval;
1800       vam->sw_if_index = ntohl (mp->sw_if_index);
1801       vam->result_ready = 1;
1802     }
1803 }
1804
1805 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1806   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1807 {
1808   vat_main_t *vam = &vat_main;
1809   vat_json_node_t node;
1810
1811   vat_json_init_object (&node);
1812   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1813   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1814
1815   vat_json_print (vam->ofp, &node);
1816   vat_json_free (&node);
1817
1818   vam->retval = ntohl (mp->retval);
1819   vam->result_ready = 1;
1820 }
1821
1822 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1823   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1824 {
1825   vat_main_t *vam = &vat_main;
1826   i32 retval = ntohl (mp->retval);
1827   if (vam->async_mode)
1828     {
1829       vam->async_errors += (retval < 0);
1830     }
1831   else
1832     {
1833       vam->retval = retval;
1834       vam->sw_if_index = ntohl (mp->sw_if_index);
1835       vam->result_ready = 1;
1836     }
1837 }
1838
1839 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1840   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   vat_json_node_t node;
1844
1845   vat_json_init_object (&node);
1846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1847   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1848
1849   vat_json_print (vam->ofp, &node);
1850   vat_json_free (&node);
1851
1852   vam->retval = ntohl (mp->retval);
1853   vam->result_ready = 1;
1854 }
1855
1856 static void vl_api_gre_add_del_tunnel_reply_t_handler
1857   (vl_api_gre_add_del_tunnel_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   i32 retval = ntohl (mp->retval);
1861   if (vam->async_mode)
1862     {
1863       vam->async_errors += (retval < 0);
1864     }
1865   else
1866     {
1867       vam->retval = retval;
1868       vam->sw_if_index = ntohl (mp->sw_if_index);
1869       vam->result_ready = 1;
1870     }
1871 }
1872
1873 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1874   (vl_api_gre_add_del_tunnel_reply_t * mp)
1875 {
1876   vat_main_t *vam = &vat_main;
1877   vat_json_node_t node;
1878
1879   vat_json_init_object (&node);
1880   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1881   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1882
1883   vat_json_print (vam->ofp, &node);
1884   vat_json_free (&node);
1885
1886   vam->retval = ntohl (mp->retval);
1887   vam->result_ready = 1;
1888 }
1889
1890 static void vl_api_create_vhost_user_if_reply_t_handler
1891   (vl_api_create_vhost_user_if_reply_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   i32 retval = ntohl (mp->retval);
1895   if (vam->async_mode)
1896     {
1897       vam->async_errors += (retval < 0);
1898     }
1899   else
1900     {
1901       vam->retval = retval;
1902       vam->sw_if_index = ntohl (mp->sw_if_index);
1903       vam->result_ready = 1;
1904     }
1905 }
1906
1907 static void vl_api_create_vhost_user_if_reply_t_handler_json
1908   (vl_api_create_vhost_user_if_reply_t * mp)
1909 {
1910   vat_main_t *vam = &vat_main;
1911   vat_json_node_t node;
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1916
1917   vat_json_print (vam->ofp, &node);
1918   vat_json_free (&node);
1919
1920   vam->retval = ntohl (mp->retval);
1921   vam->result_ready = 1;
1922 }
1923
1924 static void vl_api_ip_address_details_t_handler
1925   (vl_api_ip_address_details_t * mp)
1926 {
1927   vat_main_t *vam = &vat_main;
1928   static ip_address_details_t empty_ip_address_details = { {0} };
1929   ip_address_details_t *address = NULL;
1930   ip_details_t *current_ip_details = NULL;
1931   ip_details_t *details = NULL;
1932
1933   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1934
1935   if (!details || vam->current_sw_if_index >= vec_len (details)
1936       || !details[vam->current_sw_if_index].present)
1937     {
1938       errmsg ("ip address details arrived but not stored");
1939       errmsg ("ip_dump should be called first");
1940       return;
1941     }
1942
1943   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1944
1945 #define addresses (current_ip_details->addr)
1946
1947   vec_validate_init_empty (addresses, vec_len (addresses),
1948                            empty_ip_address_details);
1949
1950   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1951
1952   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1953   address->prefix_length = mp->prefix_length;
1954 #undef addresses
1955 }
1956
1957 static void vl_api_ip_address_details_t_handler_json
1958   (vl_api_ip_address_details_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   vat_json_node_t *node = NULL;
1962   struct in6_addr ip6;
1963   struct in_addr ip4;
1964
1965   if (VAT_JSON_ARRAY != vam->json_tree.type)
1966     {
1967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1968       vat_json_init_array (&vam->json_tree);
1969     }
1970   node = vat_json_array_add (&vam->json_tree);
1971
1972   vat_json_init_object (node);
1973   if (vam->is_ipv6)
1974     {
1975       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1976       vat_json_object_add_ip6 (node, "ip", ip6);
1977     }
1978   else
1979     {
1980       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1981       vat_json_object_add_ip4 (node, "ip", ip4);
1982     }
1983   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1984 }
1985
1986 static void
1987 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990   static ip_details_t empty_ip_details = { 0 };
1991   ip_details_t *ip = NULL;
1992   u32 sw_if_index = ~0;
1993
1994   sw_if_index = ntohl (mp->sw_if_index);
1995
1996   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1997                            sw_if_index, empty_ip_details);
1998
1999   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2000                          sw_if_index);
2001
2002   ip->present = 1;
2003 }
2004
2005 static void
2006 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2007 {
2008   vat_main_t *vam = &vat_main;
2009
2010   if (VAT_JSON_ARRAY != vam->json_tree.type)
2011     {
2012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2013       vat_json_init_array (&vam->json_tree);
2014     }
2015   vat_json_array_add_uint (&vam->json_tree,
2016                            clib_net_to_host_u32 (mp->sw_if_index));
2017 }
2018
2019 static void vl_api_map_domain_details_t_handler_json
2020   (vl_api_map_domain_details_t * mp)
2021 {
2022   vat_json_node_t *node = NULL;
2023   vat_main_t *vam = &vat_main;
2024   struct in6_addr ip6;
2025   struct in_addr ip4;
2026
2027   if (VAT_JSON_ARRAY != vam->json_tree.type)
2028     {
2029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2030       vat_json_init_array (&vam->json_tree);
2031     }
2032
2033   node = vat_json_array_add (&vam->json_tree);
2034   vat_json_init_object (node);
2035
2036   vat_json_object_add_uint (node, "domain_index",
2037                             clib_net_to_host_u32 (mp->domain_index));
2038   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2039   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2040   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2041   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2042   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2043   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2044   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2045   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2046   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2047   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2048   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2049   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2050   vat_json_object_add_uint (node, "flags", mp->flags);
2051   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2052   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2053 }
2054
2055 static void vl_api_map_domain_details_t_handler
2056   (vl_api_map_domain_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059
2060   if (mp->is_translation)
2061     {
2062       print (vam->ofp,
2063              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2064              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2065              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2066              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2067              clib_net_to_host_u32 (mp->domain_index));
2068     }
2069   else
2070     {
2071       print (vam->ofp,
2072              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2073              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2074              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2075              format_ip6_address, mp->ip6_src,
2076              clib_net_to_host_u32 (mp->domain_index));
2077     }
2078   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2079          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2080          mp->is_translation ? "map-t" : "");
2081 }
2082
2083 static void vl_api_map_rule_details_t_handler_json
2084   (vl_api_map_rule_details_t * mp)
2085 {
2086   struct in6_addr ip6;
2087   vat_json_node_t *node = NULL;
2088   vat_main_t *vam = &vat_main;
2089
2090   if (VAT_JSON_ARRAY != vam->json_tree.type)
2091     {
2092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2093       vat_json_init_array (&vam->json_tree);
2094     }
2095
2096   node = vat_json_array_add (&vam->json_tree);
2097   vat_json_init_object (node);
2098
2099   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2100   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2101   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2102 }
2103
2104 static void
2105 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2109          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2110 }
2111
2112 static void
2113 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2114 {
2115   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2116           "router_addr %U host_mac %U",
2117           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2118           format_ip4_address, &mp->host_address,
2119           format_ip4_address, &mp->router_address,
2120           format_ethernet_address, mp->host_mac);
2121 }
2122
2123 static void vl_api_dhcp_compl_event_t_handler_json
2124   (vl_api_dhcp_compl_event_t * mp)
2125 {
2126   /* JSON output not supported */
2127 }
2128
2129 static void
2130 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2131                               u32 counter)
2132 {
2133   vat_main_t *vam = &vat_main;
2134   static u64 default_counter = 0;
2135
2136   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2137                            NULL);
2138   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2139                            sw_if_index, default_counter);
2140   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2141 }
2142
2143 static void
2144 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2145                                 interface_counter_t counter)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   static interface_counter_t default_counter = { 0, };
2149
2150   vec_validate_init_empty (vam->combined_interface_counters,
2151                            vnet_counter_type, NULL);
2152   vec_validate_init_empty (vam->combined_interface_counters
2153                            [vnet_counter_type], sw_if_index, default_counter);
2154   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2155 }
2156
2157 static void vl_api_vnet_interface_simple_counters_t_handler
2158   (vl_api_vnet_interface_simple_counters_t * mp)
2159 {
2160   /* not supported */
2161 }
2162
2163 static void vl_api_vnet_interface_combined_counters_t_handler
2164   (vl_api_vnet_interface_combined_counters_t * mp)
2165 {
2166   /* not supported */
2167 }
2168
2169 static void vl_api_vnet_interface_simple_counters_t_handler_json
2170   (vl_api_vnet_interface_simple_counters_t * mp)
2171 {
2172   u64 *v_packets;
2173   u64 packets;
2174   u32 count;
2175   u32 first_sw_if_index;
2176   int i;
2177
2178   count = ntohl (mp->count);
2179   first_sw_if_index = ntohl (mp->first_sw_if_index);
2180
2181   v_packets = (u64 *) & mp->data;
2182   for (i = 0; i < count; i++)
2183     {
2184       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2185       set_simple_interface_counter (mp->vnet_counter_type,
2186                                     first_sw_if_index + i, packets);
2187       v_packets++;
2188     }
2189 }
2190
2191 static void vl_api_vnet_interface_combined_counters_t_handler_json
2192   (vl_api_vnet_interface_combined_counters_t * mp)
2193 {
2194   interface_counter_t counter;
2195   vlib_counter_t *v;
2196   u32 first_sw_if_index;
2197   int i;
2198   u32 count;
2199
2200   count = ntohl (mp->count);
2201   first_sw_if_index = ntohl (mp->first_sw_if_index);
2202
2203   v = (vlib_counter_t *) & mp->data;
2204   for (i = 0; i < count; i++)
2205     {
2206       counter.packets =
2207         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2208       counter.bytes =
2209         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2210       set_combined_interface_counter (mp->vnet_counter_type,
2211                                       first_sw_if_index + i, counter);
2212       v++;
2213     }
2214 }
2215
2216 static u32
2217 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   u32 i;
2221
2222   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2223     {
2224       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2225         {
2226           return i;
2227         }
2228     }
2229   return ~0;
2230 }
2231
2232 static u32
2233 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   u32 i;
2237
2238   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2239     {
2240       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2241         {
2242           return i;
2243         }
2244     }
2245   return ~0;
2246 }
2247
2248 static void vl_api_vnet_ip4_fib_counters_t_handler
2249   (vl_api_vnet_ip4_fib_counters_t * mp)
2250 {
2251   /* not supported */
2252 }
2253
2254 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2255   (vl_api_vnet_ip4_fib_counters_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   vl_api_ip4_fib_counter_t *v;
2259   ip4_fib_counter_t *counter;
2260   struct in_addr ip4;
2261   u32 vrf_id;
2262   u32 vrf_index;
2263   u32 count;
2264   int i;
2265
2266   vrf_id = ntohl (mp->vrf_id);
2267   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2268   if (~0 == vrf_index)
2269     {
2270       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2271       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2272       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2273       vec_validate (vam->ip4_fib_counters, vrf_index);
2274       vam->ip4_fib_counters[vrf_index] = NULL;
2275     }
2276
2277   vec_free (vam->ip4_fib_counters[vrf_index]);
2278   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2279   count = ntohl (mp->count);
2280   for (i = 0; i < count; i++)
2281     {
2282       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2283       counter = &vam->ip4_fib_counters[vrf_index][i];
2284       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2285       counter->address = ip4;
2286       counter->address_length = v->address_length;
2287       counter->packets = clib_net_to_host_u64 (v->packets);
2288       counter->bytes = clib_net_to_host_u64 (v->bytes);
2289       v++;
2290     }
2291 }
2292
2293 static void vl_api_vnet_ip4_nbr_counters_t_handler
2294   (vl_api_vnet_ip4_nbr_counters_t * mp)
2295 {
2296   /* not supported */
2297 }
2298
2299 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2300   (vl_api_vnet_ip4_nbr_counters_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   vl_api_ip4_nbr_counter_t *v;
2304   ip4_nbr_counter_t *counter;
2305   u32 sw_if_index;
2306   u32 count;
2307   int i;
2308
2309   sw_if_index = ntohl (mp->sw_if_index);
2310   count = ntohl (mp->count);
2311   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2312
2313   if (mp->begin)
2314     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2315
2316   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2317   for (i = 0; i < count; i++)
2318     {
2319       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2320       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2321       counter->address.s_addr = v->address;
2322       counter->packets = clib_net_to_host_u64 (v->packets);
2323       counter->bytes = clib_net_to_host_u64 (v->bytes);
2324       counter->linkt = v->link_type;
2325       v++;
2326     }
2327 }
2328
2329 static void vl_api_vnet_ip6_fib_counters_t_handler
2330   (vl_api_vnet_ip6_fib_counters_t * mp)
2331 {
2332   /* not supported */
2333 }
2334
2335 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2336   (vl_api_vnet_ip6_fib_counters_t * mp)
2337 {
2338   vat_main_t *vam = &vat_main;
2339   vl_api_ip6_fib_counter_t *v;
2340   ip6_fib_counter_t *counter;
2341   struct in6_addr ip6;
2342   u32 vrf_id;
2343   u32 vrf_index;
2344   u32 count;
2345   int i;
2346
2347   vrf_id = ntohl (mp->vrf_id);
2348   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2349   if (~0 == vrf_index)
2350     {
2351       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2352       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2353       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2354       vec_validate (vam->ip6_fib_counters, vrf_index);
2355       vam->ip6_fib_counters[vrf_index] = NULL;
2356     }
2357
2358   vec_free (vam->ip6_fib_counters[vrf_index]);
2359   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2360   count = ntohl (mp->count);
2361   for (i = 0; i < count; i++)
2362     {
2363       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2364       counter = &vam->ip6_fib_counters[vrf_index][i];
2365       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2366       counter->address = ip6;
2367       counter->address_length = v->address_length;
2368       counter->packets = clib_net_to_host_u64 (v->packets);
2369       counter->bytes = clib_net_to_host_u64 (v->bytes);
2370       v++;
2371     }
2372 }
2373
2374 static void vl_api_vnet_ip6_nbr_counters_t_handler
2375   (vl_api_vnet_ip6_nbr_counters_t * mp)
2376 {
2377   /* not supported */
2378 }
2379
2380 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2381   (vl_api_vnet_ip6_nbr_counters_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vl_api_ip6_nbr_counter_t *v;
2385   ip6_nbr_counter_t *counter;
2386   struct in6_addr ip6;
2387   u32 sw_if_index;
2388   u32 count;
2389   int i;
2390
2391   sw_if_index = ntohl (mp->sw_if_index);
2392   count = ntohl (mp->count);
2393   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2394
2395   if (mp->begin)
2396     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2397
2398   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2399   for (i = 0; i < count; i++)
2400     {
2401       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2402       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2403       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2404       counter->address = ip6;
2405       counter->packets = clib_net_to_host_u64 (v->packets);
2406       counter->bytes = clib_net_to_host_u64 (v->bytes);
2407       v++;
2408     }
2409 }
2410
2411 static void vl_api_get_first_msg_id_reply_t_handler
2412   (vl_api_get_first_msg_id_reply_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   i32 retval = ntohl (mp->retval);
2416
2417   if (vam->async_mode)
2418     {
2419       vam->async_errors += (retval < 0);
2420     }
2421   else
2422     {
2423       vam->retval = retval;
2424       vam->result_ready = 1;
2425     }
2426   if (retval >= 0)
2427     {
2428       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2429     }
2430 }
2431
2432 static void vl_api_get_first_msg_id_reply_t_handler_json
2433   (vl_api_get_first_msg_id_reply_t * mp)
2434 {
2435   vat_main_t *vam = &vat_main;
2436   vat_json_node_t node;
2437
2438   vat_json_init_object (&node);
2439   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2440   vat_json_object_add_uint (&node, "first_msg_id",
2441                             (uint) ntohs (mp->first_msg_id));
2442
2443   vat_json_print (vam->ofp, &node);
2444   vat_json_free (&node);
2445
2446   vam->retval = ntohl (mp->retval);
2447   vam->result_ready = 1;
2448 }
2449
2450 static void vl_api_get_node_graph_reply_t_handler
2451   (vl_api_get_node_graph_reply_t * mp)
2452 {
2453   vat_main_t *vam = &vat_main;
2454   api_main_t *am = &api_main;
2455   i32 retval = ntohl (mp->retval);
2456   u8 *pvt_copy, *reply;
2457   void *oldheap;
2458   vlib_node_t *node;
2459   int i;
2460
2461   if (vam->async_mode)
2462     {
2463       vam->async_errors += (retval < 0);
2464     }
2465   else
2466     {
2467       vam->retval = retval;
2468       vam->result_ready = 1;
2469     }
2470
2471   /* "Should never happen..." */
2472   if (retval != 0)
2473     return;
2474
2475   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2476   pvt_copy = vec_dup (reply);
2477
2478   /* Toss the shared-memory original... */
2479   pthread_mutex_lock (&am->vlib_rp->mutex);
2480   oldheap = svm_push_data_heap (am->vlib_rp);
2481
2482   vec_free (reply);
2483
2484   svm_pop_heap (oldheap);
2485   pthread_mutex_unlock (&am->vlib_rp->mutex);
2486
2487   if (vam->graph_nodes)
2488     {
2489       hash_free (vam->graph_node_index_by_name);
2490
2491       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2492         {
2493           node = vam->graph_nodes[i];
2494           vec_free (node->name);
2495           vec_free (node->next_nodes);
2496           vec_free (node);
2497         }
2498       vec_free (vam->graph_nodes);
2499     }
2500
2501   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2502   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2503   vec_free (pvt_copy);
2504
2505   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2506     {
2507       node = vam->graph_nodes[i];
2508       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2509     }
2510 }
2511
2512 static void vl_api_get_node_graph_reply_t_handler_json
2513   (vl_api_get_node_graph_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   api_main_t *am = &api_main;
2517   void *oldheap;
2518   vat_json_node_t node;
2519   u8 *reply;
2520
2521   /* $$$$ make this real? */
2522   vat_json_init_object (&node);
2523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2524   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2525
2526   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2527
2528   /* Toss the shared-memory original... */
2529   pthread_mutex_lock (&am->vlib_rp->mutex);
2530   oldheap = svm_push_data_heap (am->vlib_rp);
2531
2532   vec_free (reply);
2533
2534   svm_pop_heap (oldheap);
2535   pthread_mutex_unlock (&am->vlib_rp->mutex);
2536
2537   vat_json_print (vam->ofp, &node);
2538   vat_json_free (&node);
2539
2540   vam->retval = ntohl (mp->retval);
2541   vam->result_ready = 1;
2542 }
2543
2544 static void
2545 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2546 {
2547   vat_main_t *vam = &vat_main;
2548   u8 *s = 0;
2549
2550   if (mp->local)
2551     {
2552       s = format (s, "%=16d%=16d%=16d",
2553                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2554     }
2555   else
2556     {
2557       s = format (s, "%=16U%=16d%=16d",
2558                   mp->is_ipv6 ? format_ip6_address :
2559                   format_ip4_address,
2560                   mp->ip_address, mp->priority, mp->weight);
2561     }
2562
2563   print (vam->ofp, "%v", s);
2564   vec_free (s);
2565 }
2566
2567 static void
2568 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   vat_json_node_t *node = NULL;
2572   struct in6_addr ip6;
2573   struct in_addr ip4;
2574
2575   if (VAT_JSON_ARRAY != vam->json_tree.type)
2576     {
2577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578       vat_json_init_array (&vam->json_tree);
2579     }
2580   node = vat_json_array_add (&vam->json_tree);
2581   vat_json_init_object (node);
2582
2583   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2584   vat_json_object_add_uint (node, "priority", mp->priority);
2585   vat_json_object_add_uint (node, "weight", mp->weight);
2586
2587   if (mp->local)
2588     vat_json_object_add_uint (node, "sw_if_index",
2589                               clib_net_to_host_u32 (mp->sw_if_index));
2590   else
2591     {
2592       if (mp->is_ipv6)
2593         {
2594           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2595           vat_json_object_add_ip6 (node, "address", ip6);
2596         }
2597       else
2598         {
2599           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2600           vat_json_object_add_ip4 (node, "address", ip4);
2601         }
2602     }
2603 }
2604
2605 static void
2606 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2607                                           mp)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u8 *ls_name = 0;
2611
2612   ls_name = format (0, "%s", mp->ls_name);
2613
2614   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2615          ls_name);
2616   vec_free (ls_name);
2617 }
2618
2619 static void
2620   vl_api_one_locator_set_details_t_handler_json
2621   (vl_api_one_locator_set_details_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = 0;
2625   u8 *ls_name = 0;
2626
2627   ls_name = format (0, "%s", mp->ls_name);
2628   vec_add1 (ls_name, 0);
2629
2630   if (VAT_JSON_ARRAY != vam->json_tree.type)
2631     {
2632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2633       vat_json_init_array (&vam->json_tree);
2634     }
2635   node = vat_json_array_add (&vam->json_tree);
2636
2637   vat_json_init_object (node);
2638   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2639   vat_json_object_add_uint (node, "ls_index",
2640                             clib_net_to_host_u32 (mp->ls_index));
2641   vec_free (ls_name);
2642 }
2643
2644 typedef struct
2645 {
2646   u32 spi;
2647   u8 si;
2648 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2649
2650 uword
2651 unformat_nsh_address (unformat_input_t * input, va_list * args)
2652 {
2653   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2654   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2655 }
2656
2657 u8 *
2658 format_nsh_address_vat (u8 * s, va_list * args)
2659 {
2660   nsh_t *a = va_arg (*args, nsh_t *);
2661   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2662 }
2663
2664 static u8 *
2665 format_lisp_flat_eid (u8 * s, va_list * args)
2666 {
2667   u32 type = va_arg (*args, u32);
2668   u8 *eid = va_arg (*args, u8 *);
2669   u32 eid_len = va_arg (*args, u32);
2670
2671   switch (type)
2672     {
2673     case 0:
2674       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2675     case 1:
2676       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2677     case 2:
2678       return format (s, "%U", format_ethernet_address, eid);
2679     case 3:
2680       return format (s, "%U", format_nsh_address_vat, eid);
2681     }
2682   return 0;
2683 }
2684
2685 static u8 *
2686 format_lisp_eid_vat (u8 * s, va_list * args)
2687 {
2688   u32 type = va_arg (*args, u32);
2689   u8 *eid = va_arg (*args, u8 *);
2690   u32 eid_len = va_arg (*args, u32);
2691   u8 *seid = va_arg (*args, u8 *);
2692   u32 seid_len = va_arg (*args, u32);
2693   u32 is_src_dst = va_arg (*args, u32);
2694
2695   if (is_src_dst)
2696     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2697
2698   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2699
2700   return s;
2701 }
2702
2703 static void
2704 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   u8 *s = 0, *eid = 0;
2708
2709   if (~0 == mp->locator_set_index)
2710     s = format (0, "action: %d", mp->action);
2711   else
2712     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2713
2714   eid = format (0, "%U", format_lisp_eid_vat,
2715                 mp->eid_type,
2716                 mp->eid,
2717                 mp->eid_prefix_len,
2718                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2719   vec_add1 (eid, 0);
2720
2721   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2722          clib_net_to_host_u32 (mp->vni),
2723          eid,
2724          mp->is_local ? "local" : "remote",
2725          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2726          clib_net_to_host_u16 (mp->key_id), mp->key);
2727
2728   vec_free (s);
2729   vec_free (eid);
2730 }
2731
2732 static void
2733 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2734                                              * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   vat_json_node_t *node = 0;
2738   u8 *eid = 0;
2739
2740   if (VAT_JSON_ARRAY != vam->json_tree.type)
2741     {
2742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2743       vat_json_init_array (&vam->json_tree);
2744     }
2745   node = vat_json_array_add (&vam->json_tree);
2746
2747   vat_json_init_object (node);
2748   if (~0 == mp->locator_set_index)
2749     vat_json_object_add_uint (node, "action", mp->action);
2750   else
2751     vat_json_object_add_uint (node, "locator_set_index",
2752                               clib_net_to_host_u32 (mp->locator_set_index));
2753
2754   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2755   if (mp->eid_type == 3)
2756     {
2757       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2758       vat_json_init_object (nsh_json);
2759       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2760       vat_json_object_add_uint (nsh_json, "spi",
2761                                 clib_net_to_host_u32 (nsh->spi));
2762       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2763     }
2764   else
2765     {
2766       eid = format (0, "%U", format_lisp_eid_vat,
2767                     mp->eid_type,
2768                     mp->eid,
2769                     mp->eid_prefix_len,
2770                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2771       vec_add1 (eid, 0);
2772       vat_json_object_add_string_copy (node, "eid", eid);
2773       vec_free (eid);
2774     }
2775   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2776   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2777   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2778
2779   if (mp->key_id)
2780     {
2781       vat_json_object_add_uint (node, "key_id",
2782                                 clib_net_to_host_u16 (mp->key_id));
2783       vat_json_object_add_string_copy (node, "key", mp->key);
2784     }
2785 }
2786
2787 static void
2788 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   u8 *seid = 0, *deid = 0;
2792   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2793
2794   deid = format (0, "%U", format_lisp_eid_vat,
2795                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2796
2797   seid = format (0, "%U", format_lisp_eid_vat,
2798                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2799
2800   vec_add1 (deid, 0);
2801   vec_add1 (seid, 0);
2802
2803   if (mp->is_ip4)
2804     format_ip_address_fcn = format_ip4_address;
2805   else
2806     format_ip_address_fcn = format_ip6_address;
2807
2808
2809   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2810          clib_net_to_host_u32 (mp->vni),
2811          seid, deid,
2812          format_ip_address_fcn, mp->lloc,
2813          format_ip_address_fcn, mp->rloc,
2814          clib_net_to_host_u32 (mp->pkt_count),
2815          clib_net_to_host_u32 (mp->bytes));
2816
2817   vec_free (deid);
2818   vec_free (seid);
2819 }
2820
2821 static void
2822 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2823 {
2824   struct in6_addr ip6;
2825   struct in_addr ip4;
2826   vat_main_t *vam = &vat_main;
2827   vat_json_node_t *node = 0;
2828   u8 *deid = 0, *seid = 0;
2829
2830   if (VAT_JSON_ARRAY != vam->json_tree.type)
2831     {
2832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2833       vat_json_init_array (&vam->json_tree);
2834     }
2835   node = vat_json_array_add (&vam->json_tree);
2836
2837   vat_json_init_object (node);
2838   deid = format (0, "%U", format_lisp_eid_vat,
2839                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2840
2841   seid = format (0, "%U", format_lisp_eid_vat,
2842                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2843
2844   vec_add1 (deid, 0);
2845   vec_add1 (seid, 0);
2846
2847   vat_json_object_add_string_copy (node, "seid", seid);
2848   vat_json_object_add_string_copy (node, "deid", deid);
2849   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2850
2851   if (mp->is_ip4)
2852     {
2853       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2854       vat_json_object_add_ip4 (node, "lloc", ip4);
2855       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2856       vat_json_object_add_ip4 (node, "rloc", ip4);
2857     }
2858   else
2859     {
2860       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2861       vat_json_object_add_ip6 (node, "lloc", ip6);
2862       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2863       vat_json_object_add_ip6 (node, "rloc", ip6);
2864     }
2865   vat_json_object_add_uint (node, "pkt_count",
2866                             clib_net_to_host_u32 (mp->pkt_count));
2867   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2868
2869   vec_free (deid);
2870   vec_free (seid);
2871 }
2872
2873 static void
2874   vl_api_one_eid_table_map_details_t_handler
2875   (vl_api_one_eid_table_map_details_t * mp)
2876 {
2877   vat_main_t *vam = &vat_main;
2878
2879   u8 *line = format (0, "%=10d%=10d",
2880                      clib_net_to_host_u32 (mp->vni),
2881                      clib_net_to_host_u32 (mp->dp_table));
2882   print (vam->ofp, "%v", line);
2883   vec_free (line);
2884 }
2885
2886 static void
2887   vl_api_one_eid_table_map_details_t_handler_json
2888   (vl_api_one_eid_table_map_details_t * mp)
2889 {
2890   vat_main_t *vam = &vat_main;
2891   vat_json_node_t *node = NULL;
2892
2893   if (VAT_JSON_ARRAY != vam->json_tree.type)
2894     {
2895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2896       vat_json_init_array (&vam->json_tree);
2897     }
2898   node = vat_json_array_add (&vam->json_tree);
2899   vat_json_init_object (node);
2900   vat_json_object_add_uint (node, "dp_table",
2901                             clib_net_to_host_u32 (mp->dp_table));
2902   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2903 }
2904
2905 static void
2906   vl_api_one_eid_table_vni_details_t_handler
2907   (vl_api_one_eid_table_vni_details_t * mp)
2908 {
2909   vat_main_t *vam = &vat_main;
2910
2911   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2912   print (vam->ofp, "%v", line);
2913   vec_free (line);
2914 }
2915
2916 static void
2917   vl_api_one_eid_table_vni_details_t_handler_json
2918   (vl_api_one_eid_table_vni_details_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   vat_json_node_t *node = NULL;
2922
2923   if (VAT_JSON_ARRAY != vam->json_tree.type)
2924     {
2925       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2926       vat_json_init_array (&vam->json_tree);
2927     }
2928   node = vat_json_array_add (&vam->json_tree);
2929   vat_json_init_object (node);
2930   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2931 }
2932
2933 static void
2934   vl_api_show_one_map_register_state_reply_t_handler
2935   (vl_api_show_one_map_register_state_reply_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   int retval = clib_net_to_host_u32 (mp->retval);
2939
2940   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2941
2942   vam->retval = retval;
2943   vam->result_ready = 1;
2944 }
2945
2946 static void
2947   vl_api_show_one_map_register_state_reply_t_handler_json
2948   (vl_api_show_one_map_register_state_reply_t * mp)
2949 {
2950   vat_main_t *vam = &vat_main;
2951   vat_json_node_t _node, *node = &_node;
2952   int retval = clib_net_to_host_u32 (mp->retval);
2953
2954   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2955
2956   vat_json_init_object (node);
2957   vat_json_object_add_string_copy (node, "state", s);
2958
2959   vat_json_print (vam->ofp, node);
2960   vat_json_free (node);
2961
2962   vam->retval = retval;
2963   vam->result_ready = 1;
2964   vec_free (s);
2965 }
2966
2967 static void
2968   vl_api_show_one_rloc_probe_state_reply_t_handler
2969   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2970 {
2971   vat_main_t *vam = &vat_main;
2972   int retval = clib_net_to_host_u32 (mp->retval);
2973
2974   if (retval)
2975     goto end;
2976
2977   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2978 end:
2979   vam->retval = retval;
2980   vam->result_ready = 1;
2981 }
2982
2983 static void
2984   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2985   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2986 {
2987   vat_main_t *vam = &vat_main;
2988   vat_json_node_t _node, *node = &_node;
2989   int retval = clib_net_to_host_u32 (mp->retval);
2990
2991   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2992   vat_json_init_object (node);
2993   vat_json_object_add_string_copy (node, "state", s);
2994
2995   vat_json_print (vam->ofp, node);
2996   vat_json_free (node);
2997
2998   vam->retval = retval;
2999   vam->result_ready = 1;
3000   vec_free (s);
3001 }
3002
3003 static void
3004   vl_api_show_one_stats_enable_disable_reply_t_handler
3005   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3006 {
3007   vat_main_t *vam = &vat_main;
3008   int retval = clib_net_to_host_u32 (mp->retval);
3009
3010   if (retval)
3011     goto end;
3012
3013   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3014 end:
3015   vam->retval = retval;
3016   vam->result_ready = 1;
3017 }
3018
3019 static void
3020   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3021   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3022 {
3023   vat_main_t *vam = &vat_main;
3024   vat_json_node_t _node, *node = &_node;
3025   int retval = clib_net_to_host_u32 (mp->retval);
3026
3027   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3028   vat_json_init_object (node);
3029   vat_json_object_add_string_copy (node, "state", s);
3030
3031   vat_json_print (vam->ofp, node);
3032   vat_json_free (node);
3033
3034   vam->retval = retval;
3035   vam->result_ready = 1;
3036   vec_free (s);
3037 }
3038
3039 static void
3040 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3041 {
3042   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3043   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3044   e->vni = clib_net_to_host_u32 (e->vni);
3045 }
3046
3047 static void
3048   gpe_fwd_entries_get_reply_t_net_to_host
3049   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3050 {
3051   u32 i;
3052
3053   mp->count = clib_net_to_host_u32 (mp->count);
3054   for (i = 0; i < mp->count; i++)
3055     {
3056       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3057     }
3058 }
3059
3060 static u8 *
3061 format_gpe_encap_mode (u8 * s, va_list * args)
3062 {
3063   u32 mode = va_arg (*args, u32);
3064
3065   switch (mode)
3066     {
3067     case 0:
3068       return format (s, "lisp");
3069     case 1:
3070       return format (s, "vxlan");
3071     }
3072   return 0;
3073 }
3074
3075 static void
3076   vl_api_gpe_get_encap_mode_reply_t_handler
3077   (vl_api_gpe_get_encap_mode_reply_t * mp)
3078 {
3079   vat_main_t *vam = &vat_main;
3080
3081   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3082   vam->retval = ntohl (mp->retval);
3083   vam->result_ready = 1;
3084 }
3085
3086 static void
3087   vl_api_gpe_get_encap_mode_reply_t_handler_json
3088   (vl_api_gpe_get_encap_mode_reply_t * mp)
3089 {
3090   vat_main_t *vam = &vat_main;
3091   vat_json_node_t node;
3092
3093   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3094   vec_add1 (encap_mode, 0);
3095
3096   vat_json_init_object (&node);
3097   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3098
3099   vec_free (encap_mode);
3100   vat_json_print (vam->ofp, &node);
3101   vat_json_free (&node);
3102
3103   vam->retval = ntohl (mp->retval);
3104   vam->result_ready = 1;
3105 }
3106
3107 static void
3108   vl_api_gpe_fwd_entry_path_details_t_handler
3109   (vl_api_gpe_fwd_entry_path_details_t * mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3113
3114   if (mp->lcl_loc.is_ip4)
3115     format_ip_address_fcn = format_ip4_address;
3116   else
3117     format_ip_address_fcn = format_ip6_address;
3118
3119   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3120          format_ip_address_fcn, &mp->lcl_loc,
3121          format_ip_address_fcn, &mp->rmt_loc);
3122 }
3123
3124 static void
3125 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3126 {
3127   struct in6_addr ip6;
3128   struct in_addr ip4;
3129
3130   if (loc->is_ip4)
3131     {
3132       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3133       vat_json_object_add_ip4 (n, "address", ip4);
3134     }
3135   else
3136     {
3137       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3138       vat_json_object_add_ip6 (n, "address", ip6);
3139     }
3140   vat_json_object_add_uint (n, "weight", loc->weight);
3141 }
3142
3143 static void
3144   vl_api_gpe_fwd_entry_path_details_t_handler_json
3145   (vl_api_gpe_fwd_entry_path_details_t * mp)
3146 {
3147   vat_main_t *vam = &vat_main;
3148   vat_json_node_t *node = NULL;
3149   vat_json_node_t *loc_node;
3150
3151   if (VAT_JSON_ARRAY != vam->json_tree.type)
3152     {
3153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3154       vat_json_init_array (&vam->json_tree);
3155     }
3156   node = vat_json_array_add (&vam->json_tree);
3157   vat_json_init_object (node);
3158
3159   loc_node = vat_json_object_add (node, "local_locator");
3160   vat_json_init_object (loc_node);
3161   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3162
3163   loc_node = vat_json_object_add (node, "remote_locator");
3164   vat_json_init_object (loc_node);
3165   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3166 }
3167
3168 static void
3169   vl_api_gpe_fwd_entries_get_reply_t_handler
3170   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3171 {
3172   vat_main_t *vam = &vat_main;
3173   u32 i;
3174   int retval = clib_net_to_host_u32 (mp->retval);
3175   vl_api_gpe_fwd_entry_t *e;
3176
3177   if (retval)
3178     goto end;
3179
3180   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3181
3182   for (i = 0; i < mp->count; i++)
3183     {
3184       e = &mp->entries[i];
3185       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3186              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3187              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3188     }
3189
3190 end:
3191   vam->retval = retval;
3192   vam->result_ready = 1;
3193 }
3194
3195 static void
3196   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3197   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3198 {
3199   u8 *s = 0;
3200   vat_main_t *vam = &vat_main;
3201   vat_json_node_t *e = 0, root;
3202   u32 i;
3203   int retval = clib_net_to_host_u32 (mp->retval);
3204   vl_api_gpe_fwd_entry_t *fwd;
3205
3206   if (retval)
3207     goto end;
3208
3209   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3210   vat_json_init_array (&root);
3211
3212   for (i = 0; i < mp->count; i++)
3213     {
3214       e = vat_json_array_add (&root);
3215       fwd = &mp->entries[i];
3216
3217       vat_json_init_object (e);
3218       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3219       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3220       vat_json_object_add_int (e, "vni", fwd->vni);
3221       vat_json_object_add_int (e, "action", fwd->action);
3222
3223       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3224                   fwd->leid_prefix_len);
3225       vec_add1 (s, 0);
3226       vat_json_object_add_string_copy (e, "leid", s);
3227       vec_free (s);
3228
3229       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3230                   fwd->reid_prefix_len);
3231       vec_add1 (s, 0);
3232       vat_json_object_add_string_copy (e, "reid", s);
3233       vec_free (s);
3234     }
3235
3236   vat_json_print (vam->ofp, &root);
3237   vat_json_free (&root);
3238
3239 end:
3240   vam->retval = retval;
3241   vam->result_ready = 1;
3242 }
3243
3244 static void
3245   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3246   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3247 {
3248   vat_main_t *vam = &vat_main;
3249   u32 i, n;
3250   int retval = clib_net_to_host_u32 (mp->retval);
3251   vl_api_gpe_native_fwd_rpath_t *r;
3252
3253   if (retval)
3254     goto end;
3255
3256   n = clib_net_to_host_u32 (mp->count);
3257
3258   for (i = 0; i < n; i++)
3259     {
3260       r = &mp->entries[i];
3261       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3262              clib_net_to_host_u32 (r->fib_index),
3263              clib_net_to_host_u32 (r->nh_sw_if_index),
3264              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3265     }
3266
3267 end:
3268   vam->retval = retval;
3269   vam->result_ready = 1;
3270 }
3271
3272 static void
3273   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3274   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3275 {
3276   vat_main_t *vam = &vat_main;
3277   vat_json_node_t root, *e;
3278   u32 i, n;
3279   int retval = clib_net_to_host_u32 (mp->retval);
3280   vl_api_gpe_native_fwd_rpath_t *r;
3281   u8 *s;
3282
3283   if (retval)
3284     goto end;
3285
3286   n = clib_net_to_host_u32 (mp->count);
3287   vat_json_init_array (&root);
3288
3289   for (i = 0; i < n; i++)
3290     {
3291       e = vat_json_array_add (&root);
3292       vat_json_init_object (e);
3293       r = &mp->entries[i];
3294       s =
3295         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3296                 r->nh_addr);
3297       vec_add1 (s, 0);
3298       vat_json_object_add_string_copy (e, "ip4", s);
3299       vec_free (s);
3300
3301       vat_json_object_add_uint (e, "fib_index",
3302                                 clib_net_to_host_u32 (r->fib_index));
3303       vat_json_object_add_uint (e, "nh_sw_if_index",
3304                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3305     }
3306
3307   vat_json_print (vam->ofp, &root);
3308   vat_json_free (&root);
3309
3310 end:
3311   vam->retval = retval;
3312   vam->result_ready = 1;
3313 }
3314
3315 static void
3316   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3317   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3318 {
3319   vat_main_t *vam = &vat_main;
3320   u32 i, n;
3321   int retval = clib_net_to_host_u32 (mp->retval);
3322
3323   if (retval)
3324     goto end;
3325
3326   n = clib_net_to_host_u32 (mp->count);
3327
3328   for (i = 0; i < n; i++)
3329     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3330
3331 end:
3332   vam->retval = retval;
3333   vam->result_ready = 1;
3334 }
3335
3336 static void
3337   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3338   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341   vat_json_node_t root;
3342   u32 i, n;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   if (retval)
3346     goto end;
3347
3348   n = clib_net_to_host_u32 (mp->count);
3349   vat_json_init_array (&root);
3350
3351   for (i = 0; i < n; i++)
3352     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3353
3354   vat_json_print (vam->ofp, &root);
3355   vat_json_free (&root);
3356
3357 end:
3358   vam->retval = retval;
3359   vam->result_ready = 1;
3360 }
3361
3362 static void
3363   vl_api_one_l2_arp_entries_get_reply_t_handler
3364   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3365 {
3366   vat_main_t *vam = &vat_main;
3367   u32 i, n;
3368   int retval = clib_net_to_host_u32 (mp->retval);
3369
3370   if (retval)
3371     goto end;
3372
3373   n = clib_net_to_host_u32 (mp->count);
3374
3375   for (i = 0; i < n; i++)
3376     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3377            format_ethernet_address, mp->entries[i].mac);
3378
3379 end:
3380   vam->retval = retval;
3381   vam->result_ready = 1;
3382 }
3383
3384 static void
3385   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3386   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3387 {
3388   u8 *s = 0;
3389   vat_main_t *vam = &vat_main;
3390   vat_json_node_t *e = 0, root;
3391   u32 i, n;
3392   int retval = clib_net_to_host_u32 (mp->retval);
3393   vl_api_one_l2_arp_entry_t *arp_entry;
3394
3395   if (retval)
3396     goto end;
3397
3398   n = clib_net_to_host_u32 (mp->count);
3399   vat_json_init_array (&root);
3400
3401   for (i = 0; i < n; i++)
3402     {
3403       e = vat_json_array_add (&root);
3404       arp_entry = &mp->entries[i];
3405
3406       vat_json_init_object (e);
3407       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3408       vec_add1 (s, 0);
3409
3410       vat_json_object_add_string_copy (e, "mac", s);
3411       vec_free (s);
3412
3413       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3414       vec_add1 (s, 0);
3415       vat_json_object_add_string_copy (e, "ip4", s);
3416       vec_free (s);
3417     }
3418
3419   vat_json_print (vam->ofp, &root);
3420   vat_json_free (&root);
3421
3422 end:
3423   vam->retval = retval;
3424   vam->result_ready = 1;
3425 }
3426
3427 static void
3428   vl_api_one_l2_arp_bd_get_reply_t_handler
3429   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3430 {
3431   vat_main_t *vam = &vat_main;
3432   u32 i, n;
3433   int retval = clib_net_to_host_u32 (mp->retval);
3434
3435   if (retval)
3436     goto end;
3437
3438   n = clib_net_to_host_u32 (mp->count);
3439
3440   for (i = 0; i < n; i++)
3441     {
3442       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3443     }
3444
3445 end:
3446   vam->retval = retval;
3447   vam->result_ready = 1;
3448 }
3449
3450 static void
3451   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3452   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3453 {
3454   vat_main_t *vam = &vat_main;
3455   vat_json_node_t root;
3456   u32 i, n;
3457   int retval = clib_net_to_host_u32 (mp->retval);
3458
3459   if (retval)
3460     goto end;
3461
3462   n = clib_net_to_host_u32 (mp->count);
3463   vat_json_init_array (&root);
3464
3465   for (i = 0; i < n; i++)
3466     {
3467       vat_json_array_add_uint (&root,
3468                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3469     }
3470
3471   vat_json_print (vam->ofp, &root);
3472   vat_json_free (&root);
3473
3474 end:
3475   vam->retval = retval;
3476   vam->result_ready = 1;
3477 }
3478
3479 static void
3480   vl_api_one_adjacencies_get_reply_t_handler
3481   (vl_api_one_adjacencies_get_reply_t * mp)
3482 {
3483   vat_main_t *vam = &vat_main;
3484   u32 i, n;
3485   int retval = clib_net_to_host_u32 (mp->retval);
3486   vl_api_one_adjacency_t *a;
3487
3488   if (retval)
3489     goto end;
3490
3491   n = clib_net_to_host_u32 (mp->count);
3492
3493   for (i = 0; i < n; i++)
3494     {
3495       a = &mp->adjacencies[i];
3496       print (vam->ofp, "%U %40U",
3497              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3498              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3499     }
3500
3501 end:
3502   vam->retval = retval;
3503   vam->result_ready = 1;
3504 }
3505
3506 static void
3507   vl_api_one_adjacencies_get_reply_t_handler_json
3508   (vl_api_one_adjacencies_get_reply_t * mp)
3509 {
3510   u8 *s = 0;
3511   vat_main_t *vam = &vat_main;
3512   vat_json_node_t *e = 0, root;
3513   u32 i, n;
3514   int retval = clib_net_to_host_u32 (mp->retval);
3515   vl_api_one_adjacency_t *a;
3516
3517   if (retval)
3518     goto end;
3519
3520   n = clib_net_to_host_u32 (mp->count);
3521   vat_json_init_array (&root);
3522
3523   for (i = 0; i < n; i++)
3524     {
3525       e = vat_json_array_add (&root);
3526       a = &mp->adjacencies[i];
3527
3528       vat_json_init_object (e);
3529       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3530                   a->leid_prefix_len);
3531       vec_add1 (s, 0);
3532       vat_json_object_add_string_copy (e, "leid", s);
3533       vec_free (s);
3534
3535       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3536                   a->reid_prefix_len);
3537       vec_add1 (s, 0);
3538       vat_json_object_add_string_copy (e, "reid", s);
3539       vec_free (s);
3540     }
3541
3542   vat_json_print (vam->ofp, &root);
3543   vat_json_free (&root);
3544
3545 end:
3546   vam->retval = retval;
3547   vam->result_ready = 1;
3548 }
3549
3550 static void
3551 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3552 {
3553   vat_main_t *vam = &vat_main;
3554
3555   print (vam->ofp, "%=20U",
3556          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3557          mp->ip_address);
3558 }
3559
3560 static void
3561   vl_api_one_map_server_details_t_handler_json
3562   (vl_api_one_map_server_details_t * mp)
3563 {
3564   vat_main_t *vam = &vat_main;
3565   vat_json_node_t *node = NULL;
3566   struct in6_addr ip6;
3567   struct in_addr ip4;
3568
3569   if (VAT_JSON_ARRAY != vam->json_tree.type)
3570     {
3571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3572       vat_json_init_array (&vam->json_tree);
3573     }
3574   node = vat_json_array_add (&vam->json_tree);
3575
3576   vat_json_init_object (node);
3577   if (mp->is_ipv6)
3578     {
3579       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3580       vat_json_object_add_ip6 (node, "map-server", ip6);
3581     }
3582   else
3583     {
3584       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3585       vat_json_object_add_ip4 (node, "map-server", ip4);
3586     }
3587 }
3588
3589 static void
3590 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3591                                            * mp)
3592 {
3593   vat_main_t *vam = &vat_main;
3594
3595   print (vam->ofp, "%=20U",
3596          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3597          mp->ip_address);
3598 }
3599
3600 static void
3601   vl_api_one_map_resolver_details_t_handler_json
3602   (vl_api_one_map_resolver_details_t * mp)
3603 {
3604   vat_main_t *vam = &vat_main;
3605   vat_json_node_t *node = NULL;
3606   struct in6_addr ip6;
3607   struct in_addr ip4;
3608
3609   if (VAT_JSON_ARRAY != vam->json_tree.type)
3610     {
3611       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3612       vat_json_init_array (&vam->json_tree);
3613     }
3614   node = vat_json_array_add (&vam->json_tree);
3615
3616   vat_json_init_object (node);
3617   if (mp->is_ipv6)
3618     {
3619       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3620       vat_json_object_add_ip6 (node, "map resolver", ip6);
3621     }
3622   else
3623     {
3624       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3625       vat_json_object_add_ip4 (node, "map resolver", ip4);
3626     }
3627 }
3628
3629 static void
3630 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3631 {
3632   vat_main_t *vam = &vat_main;
3633   i32 retval = ntohl (mp->retval);
3634
3635   if (0 <= retval)
3636     {
3637       print (vam->ofp, "feature: %s\ngpe: %s",
3638              mp->feature_status ? "enabled" : "disabled",
3639              mp->gpe_status ? "enabled" : "disabled");
3640     }
3641
3642   vam->retval = retval;
3643   vam->result_ready = 1;
3644 }
3645
3646 static void
3647   vl_api_show_one_status_reply_t_handler_json
3648   (vl_api_show_one_status_reply_t * mp)
3649 {
3650   vat_main_t *vam = &vat_main;
3651   vat_json_node_t node;
3652   u8 *gpe_status = NULL;
3653   u8 *feature_status = NULL;
3654
3655   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3656   feature_status = format (0, "%s",
3657                            mp->feature_status ? "enabled" : "disabled");
3658   vec_add1 (gpe_status, 0);
3659   vec_add1 (feature_status, 0);
3660
3661   vat_json_init_object (&node);
3662   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3663   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3664
3665   vec_free (gpe_status);
3666   vec_free (feature_status);
3667
3668   vat_json_print (vam->ofp, &node);
3669   vat_json_free (&node);
3670
3671   vam->retval = ntohl (mp->retval);
3672   vam->result_ready = 1;
3673 }
3674
3675 static void
3676   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3677   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680   i32 retval = ntohl (mp->retval);
3681
3682   if (retval >= 0)
3683     {
3684       print (vam->ofp, "%=20s", mp->locator_set_name);
3685     }
3686
3687   vam->retval = retval;
3688   vam->result_ready = 1;
3689 }
3690
3691 static void
3692   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3693   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3694 {
3695   vat_main_t *vam = &vat_main;
3696   vat_json_node_t *node = NULL;
3697
3698   if (VAT_JSON_ARRAY != vam->json_tree.type)
3699     {
3700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3701       vat_json_init_array (&vam->json_tree);
3702     }
3703   node = vat_json_array_add (&vam->json_tree);
3704
3705   vat_json_init_object (node);
3706   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3707
3708   vat_json_print (vam->ofp, node);
3709   vat_json_free (node);
3710
3711   vam->retval = ntohl (mp->retval);
3712   vam->result_ready = 1;
3713 }
3714
3715 static u8 *
3716 format_lisp_map_request_mode (u8 * s, va_list * args)
3717 {
3718   u32 mode = va_arg (*args, u32);
3719
3720   switch (mode)
3721     {
3722     case 0:
3723       return format (0, "dst-only");
3724     case 1:
3725       return format (0, "src-dst");
3726     }
3727   return 0;
3728 }
3729
3730 static void
3731   vl_api_show_one_map_request_mode_reply_t_handler
3732   (vl_api_show_one_map_request_mode_reply_t * mp)
3733 {
3734   vat_main_t *vam = &vat_main;
3735   i32 retval = ntohl (mp->retval);
3736
3737   if (0 <= retval)
3738     {
3739       u32 mode = mp->mode;
3740       print (vam->ofp, "map_request_mode: %U",
3741              format_lisp_map_request_mode, mode);
3742     }
3743
3744   vam->retval = retval;
3745   vam->result_ready = 1;
3746 }
3747
3748 static void
3749   vl_api_show_one_map_request_mode_reply_t_handler_json
3750   (vl_api_show_one_map_request_mode_reply_t * mp)
3751 {
3752   vat_main_t *vam = &vat_main;
3753   vat_json_node_t node;
3754   u8 *s = 0;
3755   u32 mode;
3756
3757   mode = mp->mode;
3758   s = format (0, "%U", format_lisp_map_request_mode, mode);
3759   vec_add1 (s, 0);
3760
3761   vat_json_init_object (&node);
3762   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3763   vat_json_print (vam->ofp, &node);
3764   vat_json_free (&node);
3765
3766   vec_free (s);
3767   vam->retval = ntohl (mp->retval);
3768   vam->result_ready = 1;
3769 }
3770
3771 static void
3772   vl_api_show_one_use_petr_reply_t_handler
3773   (vl_api_show_one_use_petr_reply_t * mp)
3774 {
3775   vat_main_t *vam = &vat_main;
3776   i32 retval = ntohl (mp->retval);
3777
3778   if (0 <= retval)
3779     {
3780       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3781       if (mp->status)
3782         {
3783           print (vam->ofp, "Proxy-ETR address; %U",
3784                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3785                  mp->address);
3786         }
3787     }
3788
3789   vam->retval = retval;
3790   vam->result_ready = 1;
3791 }
3792
3793 static void
3794   vl_api_show_one_use_petr_reply_t_handler_json
3795   (vl_api_show_one_use_petr_reply_t * mp)
3796 {
3797   vat_main_t *vam = &vat_main;
3798   vat_json_node_t node;
3799   u8 *status = 0;
3800   struct in_addr ip4;
3801   struct in6_addr ip6;
3802
3803   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3804   vec_add1 (status, 0);
3805
3806   vat_json_init_object (&node);
3807   vat_json_object_add_string_copy (&node, "status", status);
3808   if (mp->status)
3809     {
3810       if (mp->is_ip4)
3811         {
3812           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3813           vat_json_object_add_ip6 (&node, "address", ip6);
3814         }
3815       else
3816         {
3817           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3818           vat_json_object_add_ip4 (&node, "address", ip4);
3819         }
3820     }
3821
3822   vec_free (status);
3823
3824   vat_json_print (vam->ofp, &node);
3825   vat_json_free (&node);
3826
3827   vam->retval = ntohl (mp->retval);
3828   vam->result_ready = 1;
3829 }
3830
3831 static void
3832   vl_api_show_one_nsh_mapping_reply_t_handler
3833   (vl_api_show_one_nsh_mapping_reply_t * mp)
3834 {
3835   vat_main_t *vam = &vat_main;
3836   i32 retval = ntohl (mp->retval);
3837
3838   if (0 <= retval)
3839     {
3840       print (vam->ofp, "%-20s%-16s",
3841              mp->is_set ? "set" : "not-set",
3842              mp->is_set ? (char *) mp->locator_set_name : "");
3843     }
3844
3845   vam->retval = retval;
3846   vam->result_ready = 1;
3847 }
3848
3849 static void
3850   vl_api_show_one_nsh_mapping_reply_t_handler_json
3851   (vl_api_show_one_nsh_mapping_reply_t * mp)
3852 {
3853   vat_main_t *vam = &vat_main;
3854   vat_json_node_t node;
3855   u8 *status = 0;
3856
3857   status = format (0, "%s", mp->is_set ? "yes" : "no");
3858   vec_add1 (status, 0);
3859
3860   vat_json_init_object (&node);
3861   vat_json_object_add_string_copy (&node, "is_set", status);
3862   if (mp->is_set)
3863     {
3864       vat_json_object_add_string_copy (&node, "locator_set",
3865                                        mp->locator_set_name);
3866     }
3867
3868   vec_free (status);
3869
3870   vat_json_print (vam->ofp, &node);
3871   vat_json_free (&node);
3872
3873   vam->retval = ntohl (mp->retval);
3874   vam->result_ready = 1;
3875 }
3876
3877 static void
3878   vl_api_show_one_map_register_ttl_reply_t_handler
3879   (vl_api_show_one_map_register_ttl_reply_t * mp)
3880 {
3881   vat_main_t *vam = &vat_main;
3882   i32 retval = ntohl (mp->retval);
3883
3884   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3885
3886   if (0 <= retval)
3887     {
3888       print (vam->ofp, "ttl: %u", mp->ttl);
3889     }
3890
3891   vam->retval = retval;
3892   vam->result_ready = 1;
3893 }
3894
3895 static void
3896   vl_api_show_one_map_register_ttl_reply_t_handler_json
3897   (vl_api_show_one_map_register_ttl_reply_t * mp)
3898 {
3899   vat_main_t *vam = &vat_main;
3900   vat_json_node_t node;
3901
3902   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3903   vat_json_init_object (&node);
3904   vat_json_object_add_uint (&node, "ttl", mp->ttl);
3905
3906   vat_json_print (vam->ofp, &node);
3907   vat_json_free (&node);
3908
3909   vam->retval = ntohl (mp->retval);
3910   vam->result_ready = 1;
3911 }
3912
3913 static void
3914 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3915 {
3916   vat_main_t *vam = &vat_main;
3917   i32 retval = ntohl (mp->retval);
3918
3919   if (0 <= retval)
3920     {
3921       print (vam->ofp, "%-20s%-16s",
3922              mp->status ? "enabled" : "disabled",
3923              mp->status ? (char *) mp->locator_set_name : "");
3924     }
3925
3926   vam->retval = retval;
3927   vam->result_ready = 1;
3928 }
3929
3930 static void
3931 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3932 {
3933   vat_main_t *vam = &vat_main;
3934   vat_json_node_t node;
3935   u8 *status = 0;
3936
3937   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3938   vec_add1 (status, 0);
3939
3940   vat_json_init_object (&node);
3941   vat_json_object_add_string_copy (&node, "status", status);
3942   if (mp->status)
3943     {
3944       vat_json_object_add_string_copy (&node, "locator_set",
3945                                        mp->locator_set_name);
3946     }
3947
3948   vec_free (status);
3949
3950   vat_json_print (vam->ofp, &node);
3951   vat_json_free (&node);
3952
3953   vam->retval = ntohl (mp->retval);
3954   vam->result_ready = 1;
3955 }
3956
3957 static u8 *
3958 format_policer_type (u8 * s, va_list * va)
3959 {
3960   u32 i = va_arg (*va, u32);
3961
3962   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3963     s = format (s, "1r2c");
3964   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3965     s = format (s, "1r3c");
3966   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3967     s = format (s, "2r3c-2698");
3968   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3969     s = format (s, "2r3c-4115");
3970   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3971     s = format (s, "2r3c-mef5cf1");
3972   else
3973     s = format (s, "ILLEGAL");
3974   return s;
3975 }
3976
3977 static u8 *
3978 format_policer_rate_type (u8 * s, va_list * va)
3979 {
3980   u32 i = va_arg (*va, u32);
3981
3982   if (i == SSE2_QOS_RATE_KBPS)
3983     s = format (s, "kbps");
3984   else if (i == SSE2_QOS_RATE_PPS)
3985     s = format (s, "pps");
3986   else
3987     s = format (s, "ILLEGAL");
3988   return s;
3989 }
3990
3991 static u8 *
3992 format_policer_round_type (u8 * s, va_list * va)
3993 {
3994   u32 i = va_arg (*va, u32);
3995
3996   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3997     s = format (s, "closest");
3998   else if (i == SSE2_QOS_ROUND_TO_UP)
3999     s = format (s, "up");
4000   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4001     s = format (s, "down");
4002   else
4003     s = format (s, "ILLEGAL");
4004   return s;
4005 }
4006
4007 static u8 *
4008 format_policer_action_type (u8 * s, va_list * va)
4009 {
4010   u32 i = va_arg (*va, u32);
4011
4012   if (i == SSE2_QOS_ACTION_DROP)
4013     s = format (s, "drop");
4014   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4015     s = format (s, "transmit");
4016   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4017     s = format (s, "mark-and-transmit");
4018   else
4019     s = format (s, "ILLEGAL");
4020   return s;
4021 }
4022
4023 static u8 *
4024 format_dscp (u8 * s, va_list * va)
4025 {
4026   u32 i = va_arg (*va, u32);
4027   char *t = 0;
4028
4029   switch (i)
4030     {
4031 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4032       foreach_vnet_dscp
4033 #undef _
4034     default:
4035       return format (s, "ILLEGAL");
4036     }
4037   s = format (s, "%s", t);
4038   return s;
4039 }
4040
4041 static void
4042 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4043 {
4044   vat_main_t *vam = &vat_main;
4045   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4046
4047   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4048     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4049   else
4050     conform_dscp_str = format (0, "");
4051
4052   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4053     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4054   else
4055     exceed_dscp_str = format (0, "");
4056
4057   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4058     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4059   else
4060     violate_dscp_str = format (0, "");
4061
4062   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4063          "rate type %U, round type %U, %s rate, %s color-aware, "
4064          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4065          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4066          "conform action %U%s, exceed action %U%s, violate action %U%s",
4067          mp->name,
4068          format_policer_type, mp->type,
4069          ntohl (mp->cir),
4070          ntohl (mp->eir),
4071          clib_net_to_host_u64 (mp->cb),
4072          clib_net_to_host_u64 (mp->eb),
4073          format_policer_rate_type, mp->rate_type,
4074          format_policer_round_type, mp->round_type,
4075          mp->single_rate ? "single" : "dual",
4076          mp->color_aware ? "is" : "not",
4077          ntohl (mp->cir_tokens_per_period),
4078          ntohl (mp->pir_tokens_per_period),
4079          ntohl (mp->scale),
4080          ntohl (mp->current_limit),
4081          ntohl (mp->current_bucket),
4082          ntohl (mp->extended_limit),
4083          ntohl (mp->extended_bucket),
4084          clib_net_to_host_u64 (mp->last_update_time),
4085          format_policer_action_type, mp->conform_action_type,
4086          conform_dscp_str,
4087          format_policer_action_type, mp->exceed_action_type,
4088          exceed_dscp_str,
4089          format_policer_action_type, mp->violate_action_type,
4090          violate_dscp_str);
4091
4092   vec_free (conform_dscp_str);
4093   vec_free (exceed_dscp_str);
4094   vec_free (violate_dscp_str);
4095 }
4096
4097 static void vl_api_policer_details_t_handler_json
4098   (vl_api_policer_details_t * mp)
4099 {
4100   vat_main_t *vam = &vat_main;
4101   vat_json_node_t *node;
4102   u8 *rate_type_str, *round_type_str, *type_str;
4103   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4104
4105   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4106   round_type_str =
4107     format (0, "%U", format_policer_round_type, mp->round_type);
4108   type_str = format (0, "%U", format_policer_type, mp->type);
4109   conform_action_str = format (0, "%U", format_policer_action_type,
4110                                mp->conform_action_type);
4111   exceed_action_str = format (0, "%U", format_policer_action_type,
4112                               mp->exceed_action_type);
4113   violate_action_str = format (0, "%U", format_policer_action_type,
4114                                mp->violate_action_type);
4115
4116   if (VAT_JSON_ARRAY != vam->json_tree.type)
4117     {
4118       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4119       vat_json_init_array (&vam->json_tree);
4120     }
4121   node = vat_json_array_add (&vam->json_tree);
4122
4123   vat_json_init_object (node);
4124   vat_json_object_add_string_copy (node, "name", mp->name);
4125   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4126   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4127   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4128   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4129   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4130   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4131   vat_json_object_add_string_copy (node, "type", type_str);
4132   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4133   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4134   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4135   vat_json_object_add_uint (node, "cir_tokens_per_period",
4136                             ntohl (mp->cir_tokens_per_period));
4137   vat_json_object_add_uint (node, "eir_tokens_per_period",
4138                             ntohl (mp->pir_tokens_per_period));
4139   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4140   vat_json_object_add_uint (node, "current_bucket",
4141                             ntohl (mp->current_bucket));
4142   vat_json_object_add_uint (node, "extended_limit",
4143                             ntohl (mp->extended_limit));
4144   vat_json_object_add_uint (node, "extended_bucket",
4145                             ntohl (mp->extended_bucket));
4146   vat_json_object_add_uint (node, "last_update_time",
4147                             ntohl (mp->last_update_time));
4148   vat_json_object_add_string_copy (node, "conform_action",
4149                                    conform_action_str);
4150   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4151     {
4152       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4153       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4154       vec_free (dscp_str);
4155     }
4156   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4157   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4158     {
4159       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4160       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4161       vec_free (dscp_str);
4162     }
4163   vat_json_object_add_string_copy (node, "violate_action",
4164                                    violate_action_str);
4165   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4166     {
4167       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4168       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4169       vec_free (dscp_str);
4170     }
4171
4172   vec_free (rate_type_str);
4173   vec_free (round_type_str);
4174   vec_free (type_str);
4175   vec_free (conform_action_str);
4176   vec_free (exceed_action_str);
4177   vec_free (violate_action_str);
4178 }
4179
4180 static void
4181 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4182                                            mp)
4183 {
4184   vat_main_t *vam = &vat_main;
4185   int i, count = ntohl (mp->count);
4186
4187   if (count > 0)
4188     print (vam->ofp, "classify table ids (%d) : ", count);
4189   for (i = 0; i < count; i++)
4190     {
4191       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4192       print (vam->ofp, (i < count - 1) ? "," : "");
4193     }
4194   vam->retval = ntohl (mp->retval);
4195   vam->result_ready = 1;
4196 }
4197
4198 static void
4199   vl_api_classify_table_ids_reply_t_handler_json
4200   (vl_api_classify_table_ids_reply_t * mp)
4201 {
4202   vat_main_t *vam = &vat_main;
4203   int i, count = ntohl (mp->count);
4204
4205   if (count > 0)
4206     {
4207       vat_json_node_t node;
4208
4209       vat_json_init_object (&node);
4210       for (i = 0; i < count; i++)
4211         {
4212           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4213         }
4214       vat_json_print (vam->ofp, &node);
4215       vat_json_free (&node);
4216     }
4217   vam->retval = ntohl (mp->retval);
4218   vam->result_ready = 1;
4219 }
4220
4221 static void
4222   vl_api_classify_table_by_interface_reply_t_handler
4223   (vl_api_classify_table_by_interface_reply_t * mp)
4224 {
4225   vat_main_t *vam = &vat_main;
4226   u32 table_id;
4227
4228   table_id = ntohl (mp->l2_table_id);
4229   if (table_id != ~0)
4230     print (vam->ofp, "l2 table id : %d", table_id);
4231   else
4232     print (vam->ofp, "l2 table id : No input ACL tables configured");
4233   table_id = ntohl (mp->ip4_table_id);
4234   if (table_id != ~0)
4235     print (vam->ofp, "ip4 table id : %d", table_id);
4236   else
4237     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4238   table_id = ntohl (mp->ip6_table_id);
4239   if (table_id != ~0)
4240     print (vam->ofp, "ip6 table id : %d", table_id);
4241   else
4242     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4243   vam->retval = ntohl (mp->retval);
4244   vam->result_ready = 1;
4245 }
4246
4247 static void
4248   vl_api_classify_table_by_interface_reply_t_handler_json
4249   (vl_api_classify_table_by_interface_reply_t * mp)
4250 {
4251   vat_main_t *vam = &vat_main;
4252   vat_json_node_t node;
4253
4254   vat_json_init_object (&node);
4255
4256   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4257   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4258   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4259
4260   vat_json_print (vam->ofp, &node);
4261   vat_json_free (&node);
4262
4263   vam->retval = ntohl (mp->retval);
4264   vam->result_ready = 1;
4265 }
4266
4267 static void vl_api_policer_add_del_reply_t_handler
4268   (vl_api_policer_add_del_reply_t * mp)
4269 {
4270   vat_main_t *vam = &vat_main;
4271   i32 retval = ntohl (mp->retval);
4272   if (vam->async_mode)
4273     {
4274       vam->async_errors += (retval < 0);
4275     }
4276   else
4277     {
4278       vam->retval = retval;
4279       vam->result_ready = 1;
4280       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4281         /*
4282          * Note: this is just barely thread-safe, depends on
4283          * the main thread spinning waiting for an answer...
4284          */
4285         errmsg ("policer index %d", ntohl (mp->policer_index));
4286     }
4287 }
4288
4289 static void vl_api_policer_add_del_reply_t_handler_json
4290   (vl_api_policer_add_del_reply_t * mp)
4291 {
4292   vat_main_t *vam = &vat_main;
4293   vat_json_node_t node;
4294
4295   vat_json_init_object (&node);
4296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4297   vat_json_object_add_uint (&node, "policer_index",
4298                             ntohl (mp->policer_index));
4299
4300   vat_json_print (vam->ofp, &node);
4301   vat_json_free (&node);
4302
4303   vam->retval = ntohl (mp->retval);
4304   vam->result_ready = 1;
4305 }
4306
4307 /* Format hex dump. */
4308 u8 *
4309 format_hex_bytes (u8 * s, va_list * va)
4310 {
4311   u8 *bytes = va_arg (*va, u8 *);
4312   int n_bytes = va_arg (*va, int);
4313   uword i;
4314
4315   /* Print short or long form depending on byte count. */
4316   uword short_form = n_bytes <= 32;
4317   uword indent = format_get_indent (s);
4318
4319   if (n_bytes == 0)
4320     return s;
4321
4322   for (i = 0; i < n_bytes; i++)
4323     {
4324       if (!short_form && (i % 32) == 0)
4325         s = format (s, "%08x: ", i);
4326       s = format (s, "%02x", bytes[i]);
4327       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4328         s = format (s, "\n%U", format_white_space, indent);
4329     }
4330
4331   return s;
4332 }
4333
4334 static void
4335 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4336                                             * mp)
4337 {
4338   vat_main_t *vam = &vat_main;
4339   i32 retval = ntohl (mp->retval);
4340   if (retval == 0)
4341     {
4342       print (vam->ofp, "classify table info :");
4343       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4344              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4345              ntohl (mp->miss_next_index));
4346       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4347              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4348              ntohl (mp->match_n_vectors));
4349       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4350              ntohl (mp->mask_length));
4351     }
4352   vam->retval = retval;
4353   vam->result_ready = 1;
4354 }
4355
4356 static void
4357   vl_api_classify_table_info_reply_t_handler_json
4358   (vl_api_classify_table_info_reply_t * mp)
4359 {
4360   vat_main_t *vam = &vat_main;
4361   vat_json_node_t node;
4362
4363   i32 retval = ntohl (mp->retval);
4364   if (retval == 0)
4365     {
4366       vat_json_init_object (&node);
4367
4368       vat_json_object_add_int (&node, "sessions",
4369                                ntohl (mp->active_sessions));
4370       vat_json_object_add_int (&node, "nexttbl",
4371                                ntohl (mp->next_table_index));
4372       vat_json_object_add_int (&node, "nextnode",
4373                                ntohl (mp->miss_next_index));
4374       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4375       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4376       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4377       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4378                       ntohl (mp->mask_length), 0);
4379       vat_json_object_add_string_copy (&node, "mask", s);
4380
4381       vat_json_print (vam->ofp, &node);
4382       vat_json_free (&node);
4383     }
4384   vam->retval = ntohl (mp->retval);
4385   vam->result_ready = 1;
4386 }
4387
4388 static void
4389 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4390                                            mp)
4391 {
4392   vat_main_t *vam = &vat_main;
4393
4394   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4395          ntohl (mp->hit_next_index), ntohl (mp->advance),
4396          ntohl (mp->opaque_index));
4397   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4398          ntohl (mp->match_length));
4399 }
4400
4401 static void
4402   vl_api_classify_session_details_t_handler_json
4403   (vl_api_classify_session_details_t * mp)
4404 {
4405   vat_main_t *vam = &vat_main;
4406   vat_json_node_t *node = NULL;
4407
4408   if (VAT_JSON_ARRAY != vam->json_tree.type)
4409     {
4410       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4411       vat_json_init_array (&vam->json_tree);
4412     }
4413   node = vat_json_array_add (&vam->json_tree);
4414
4415   vat_json_init_object (node);
4416   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4417   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4418   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4419   u8 *s =
4420     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4421             0);
4422   vat_json_object_add_string_copy (node, "match", s);
4423 }
4424
4425 static void vl_api_pg_create_interface_reply_t_handler
4426   (vl_api_pg_create_interface_reply_t * mp)
4427 {
4428   vat_main_t *vam = &vat_main;
4429
4430   vam->retval = ntohl (mp->retval);
4431   vam->result_ready = 1;
4432 }
4433
4434 static void vl_api_pg_create_interface_reply_t_handler_json
4435   (vl_api_pg_create_interface_reply_t * mp)
4436 {
4437   vat_main_t *vam = &vat_main;
4438   vat_json_node_t node;
4439
4440   i32 retval = ntohl (mp->retval);
4441   if (retval == 0)
4442     {
4443       vat_json_init_object (&node);
4444
4445       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4446
4447       vat_json_print (vam->ofp, &node);
4448       vat_json_free (&node);
4449     }
4450   vam->retval = ntohl (mp->retval);
4451   vam->result_ready = 1;
4452 }
4453
4454 static void vl_api_policer_classify_details_t_handler
4455   (vl_api_policer_classify_details_t * mp)
4456 {
4457   vat_main_t *vam = &vat_main;
4458
4459   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4460          ntohl (mp->table_index));
4461 }
4462
4463 static void vl_api_policer_classify_details_t_handler_json
4464   (vl_api_policer_classify_details_t * mp)
4465 {
4466   vat_main_t *vam = &vat_main;
4467   vat_json_node_t *node;
4468
4469   if (VAT_JSON_ARRAY != vam->json_tree.type)
4470     {
4471       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4472       vat_json_init_array (&vam->json_tree);
4473     }
4474   node = vat_json_array_add (&vam->json_tree);
4475
4476   vat_json_init_object (node);
4477   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4478   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4479 }
4480
4481 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4482   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4483 {
4484   vat_main_t *vam = &vat_main;
4485   i32 retval = ntohl (mp->retval);
4486   if (vam->async_mode)
4487     {
4488       vam->async_errors += (retval < 0);
4489     }
4490   else
4491     {
4492       vam->retval = retval;
4493       vam->sw_if_index = ntohl (mp->sw_if_index);
4494       vam->result_ready = 1;
4495     }
4496 }
4497
4498 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4499   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4500 {
4501   vat_main_t *vam = &vat_main;
4502   vat_json_node_t node;
4503
4504   vat_json_init_object (&node);
4505   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4506   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4507
4508   vat_json_print (vam->ofp, &node);
4509   vat_json_free (&node);
4510
4511   vam->retval = ntohl (mp->retval);
4512   vam->result_ready = 1;
4513 }
4514
4515 static void vl_api_flow_classify_details_t_handler
4516   (vl_api_flow_classify_details_t * mp)
4517 {
4518   vat_main_t *vam = &vat_main;
4519
4520   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4521          ntohl (mp->table_index));
4522 }
4523
4524 static void vl_api_flow_classify_details_t_handler_json
4525   (vl_api_flow_classify_details_t * mp)
4526 {
4527   vat_main_t *vam = &vat_main;
4528   vat_json_node_t *node;
4529
4530   if (VAT_JSON_ARRAY != vam->json_tree.type)
4531     {
4532       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4533       vat_json_init_array (&vam->json_tree);
4534     }
4535   node = vat_json_array_add (&vam->json_tree);
4536
4537   vat_json_init_object (node);
4538   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4539   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4540 }
4541
4542 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4543 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4544 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4545 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4546 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4547 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4548 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4549 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4550 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4551 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4552 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4553 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4554 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4555 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4556 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4557 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4558 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4559 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4560
4561 /*
4562  * Generate boilerplate reply handlers, which
4563  * dig the return value out of the xxx_reply_t API message,
4564  * stick it into vam->retval, and set vam->result_ready
4565  *
4566  * Could also do this by pointing N message decode slots at
4567  * a single function, but that could break in subtle ways.
4568  */
4569
4570 #define foreach_standard_reply_retval_handler           \
4571 _(sw_interface_set_flags_reply)                         \
4572 _(sw_interface_add_del_address_reply)                   \
4573 _(sw_interface_set_table_reply)                         \
4574 _(sw_interface_set_mpls_enable_reply)                   \
4575 _(sw_interface_set_vpath_reply)                         \
4576 _(sw_interface_set_vxlan_bypass_reply)                  \
4577 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4578 _(sw_interface_set_l2_bridge_reply)                     \
4579 _(bridge_domain_add_del_reply)                          \
4580 _(sw_interface_set_l2_xconnect_reply)                   \
4581 _(l2fib_add_del_reply)                                  \
4582 _(l2fib_flush_int_reply)                                \
4583 _(l2fib_flush_bd_reply)                                 \
4584 _(ip_add_del_route_reply)                               \
4585 _(ip_mroute_add_del_reply)                              \
4586 _(mpls_route_add_del_reply)                             \
4587 _(mpls_ip_bind_unbind_reply)                            \
4588 _(proxy_arp_add_del_reply)                              \
4589 _(proxy_arp_intfc_enable_disable_reply)                 \
4590 _(sw_interface_set_unnumbered_reply)                    \
4591 _(ip_neighbor_add_del_reply)                            \
4592 _(reset_vrf_reply)                                      \
4593 _(oam_add_del_reply)                                    \
4594 _(reset_fib_reply)                                      \
4595 _(dhcp_proxy_config_reply)                              \
4596 _(dhcp_proxy_set_vss_reply)                             \
4597 _(dhcp_client_config_reply)                             \
4598 _(set_ip_flow_hash_reply)                               \
4599 _(sw_interface_ip6_enable_disable_reply)                \
4600 _(sw_interface_ip6_set_link_local_address_reply)        \
4601 _(ip6nd_proxy_add_del_reply)                            \
4602 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4603 _(sw_interface_ip6nd_ra_config_reply)                   \
4604 _(set_arp_neighbor_limit_reply)                         \
4605 _(l2_patch_add_del_reply)                               \
4606 _(sr_policy_add_reply)                                  \
4607 _(sr_policy_mod_reply)                                  \
4608 _(sr_policy_del_reply)                                  \
4609 _(sr_localsid_add_del_reply)                            \
4610 _(sr_steering_add_del_reply)                            \
4611 _(classify_add_del_session_reply)                       \
4612 _(classify_set_interface_ip_table_reply)                \
4613 _(classify_set_interface_l2_tables_reply)               \
4614 _(l2tpv3_set_tunnel_cookies_reply)                      \
4615 _(l2tpv3_interface_enable_disable_reply)                \
4616 _(l2tpv3_set_lookup_key_reply)                          \
4617 _(l2_fib_clear_table_reply)                             \
4618 _(l2_interface_efp_filter_reply)                        \
4619 _(l2_interface_vlan_tag_rewrite_reply)                  \
4620 _(modify_vhost_user_if_reply)                           \
4621 _(delete_vhost_user_if_reply)                           \
4622 _(want_ip4_arp_events_reply)                            \
4623 _(want_ip6_nd_events_reply)                             \
4624 _(want_l2_macs_events_reply)                            \
4625 _(input_acl_set_interface_reply)                        \
4626 _(ipsec_spd_add_del_reply)                              \
4627 _(ipsec_interface_add_del_spd_reply)                    \
4628 _(ipsec_spd_add_del_entry_reply)                        \
4629 _(ipsec_sad_add_del_entry_reply)                        \
4630 _(ipsec_sa_set_key_reply)                               \
4631 _(ipsec_tunnel_if_add_del_reply)                        \
4632 _(ikev2_profile_add_del_reply)                          \
4633 _(ikev2_profile_set_auth_reply)                         \
4634 _(ikev2_profile_set_id_reply)                           \
4635 _(ikev2_profile_set_ts_reply)                           \
4636 _(ikev2_set_local_key_reply)                            \
4637 _(ikev2_set_responder_reply)                            \
4638 _(ikev2_set_ike_transforms_reply)                       \
4639 _(ikev2_set_esp_transforms_reply)                       \
4640 _(ikev2_set_sa_lifetime_reply)                          \
4641 _(ikev2_initiate_sa_init_reply)                         \
4642 _(ikev2_initiate_del_ike_sa_reply)                      \
4643 _(ikev2_initiate_del_child_sa_reply)                    \
4644 _(ikev2_initiate_rekey_child_sa_reply)                  \
4645 _(delete_loopback_reply)                                \
4646 _(bd_ip_mac_add_del_reply)                              \
4647 _(map_del_domain_reply)                                 \
4648 _(map_add_del_rule_reply)                               \
4649 _(want_interface_events_reply)                          \
4650 _(want_stats_reply)                                     \
4651 _(cop_interface_enable_disable_reply)                   \
4652 _(cop_whitelist_enable_disable_reply)                   \
4653 _(sw_interface_clear_stats_reply)                       \
4654 _(ioam_enable_reply)                              \
4655 _(ioam_disable_reply)                              \
4656 _(one_add_del_locator_reply)                            \
4657 _(one_add_del_local_eid_reply)                          \
4658 _(one_add_del_remote_mapping_reply)                     \
4659 _(one_add_del_adjacency_reply)                          \
4660 _(one_add_del_map_resolver_reply)                       \
4661 _(one_add_del_map_server_reply)                         \
4662 _(one_enable_disable_reply)                             \
4663 _(one_rloc_probe_enable_disable_reply)                  \
4664 _(one_map_register_enable_disable_reply)                \
4665 _(one_map_register_set_ttl_reply)                       \
4666 _(one_pitr_set_locator_set_reply)                       \
4667 _(one_map_request_mode_reply)                           \
4668 _(one_add_del_map_request_itr_rlocs_reply)              \
4669 _(one_eid_table_add_del_map_reply)                      \
4670 _(one_use_petr_reply)                                   \
4671 _(one_stats_enable_disable_reply)                       \
4672 _(one_add_del_l2_arp_entry_reply)                       \
4673 _(one_stats_flush_reply)                                \
4674 _(gpe_enable_disable_reply)                             \
4675 _(gpe_set_encap_mode_reply)                             \
4676 _(gpe_add_del_iface_reply)                              \
4677 _(gpe_add_del_native_fwd_rpath_reply)                   \
4678 _(af_packet_delete_reply)                               \
4679 _(policer_classify_set_interface_reply)                 \
4680 _(netmap_create_reply)                                  \
4681 _(netmap_delete_reply)                                  \
4682 _(set_ipfix_exporter_reply)                             \
4683 _(set_ipfix_classify_stream_reply)                      \
4684 _(ipfix_classify_table_add_del_reply)                   \
4685 _(flow_classify_set_interface_reply)                    \
4686 _(sw_interface_span_enable_disable_reply)               \
4687 _(pg_capture_reply)                                     \
4688 _(pg_enable_disable_reply)                              \
4689 _(ip_source_and_port_range_check_add_del_reply)         \
4690 _(ip_source_and_port_range_check_interface_add_del_reply)\
4691 _(delete_subif_reply)                                   \
4692 _(l2_interface_pbb_tag_rewrite_reply)                   \
4693 _(punt_reply)                                           \
4694 _(feature_enable_disable_reply)                         \
4695 _(sw_interface_tag_add_del_reply)                       \
4696 _(sw_interface_set_mtu_reply)                           \
4697 _(p2p_ethernet_add_reply)                               \
4698 _(p2p_ethernet_del_reply)                               \
4699 _(lldp_config_reply)                                    \
4700 _(sw_interface_set_lldp_reply)
4701
4702 #define _(n)                                    \
4703     static void vl_api_##n##_t_handler          \
4704     (vl_api_##n##_t * mp)                       \
4705     {                                           \
4706         vat_main_t * vam = &vat_main;           \
4707         i32 retval = ntohl(mp->retval);         \
4708         if (vam->async_mode) {                  \
4709             vam->async_errors += (retval < 0);  \
4710         } else {                                \
4711             vam->retval = retval;               \
4712             vam->result_ready = 1;              \
4713         }                                       \
4714     }
4715 foreach_standard_reply_retval_handler;
4716 #undef _
4717
4718 #define _(n)                                    \
4719     static void vl_api_##n##_t_handler_json     \
4720     (vl_api_##n##_t * mp)                       \
4721     {                                           \
4722         vat_main_t * vam = &vat_main;           \
4723         vat_json_node_t node;                   \
4724         vat_json_init_object(&node);            \
4725         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4726         vat_json_print(vam->ofp, &node);        \
4727         vam->retval = ntohl(mp->retval);        \
4728         vam->result_ready = 1;                  \
4729     }
4730 foreach_standard_reply_retval_handler;
4731 #undef _
4732
4733 /*
4734  * Table of message reply handlers, must include boilerplate handlers
4735  * we just generated
4736  */
4737
4738 #define foreach_vpe_api_reply_msg                                       \
4739 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4740 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4741 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4742 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4743 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4744 _(CLI_REPLY, cli_reply)                                                 \
4745 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4746 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4747   sw_interface_add_del_address_reply)                                   \
4748 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4749 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4750 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4751 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4752 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4753 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4754   sw_interface_set_l2_xconnect_reply)                                   \
4755 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4756   sw_interface_set_l2_bridge_reply)                                     \
4757 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4758 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4759 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4760 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4761 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4762 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4763 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4764 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4765 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4766 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4767 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4768 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4769 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4770 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4771 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4772 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4773 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4774 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4775   proxy_arp_intfc_enable_disable_reply)                                 \
4776 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4777 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4778   sw_interface_set_unnumbered_reply)                                    \
4779 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4780 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4781 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4782 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4783 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4784 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4785 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4786 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4787 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4788 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4789 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4790 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4791   sw_interface_ip6_enable_disable_reply)                                \
4792 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4793   sw_interface_ip6_set_link_local_address_reply)                        \
4794 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4795 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4796 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4797   sw_interface_ip6nd_ra_prefix_reply)                                   \
4798 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4799   sw_interface_ip6nd_ra_config_reply)                                   \
4800 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4801 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4802 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4803 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4804 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4805 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4806 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4807 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4808 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4809 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4810 classify_set_interface_ip_table_reply)                                  \
4811 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4812   classify_set_interface_l2_tables_reply)                               \
4813 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4814 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4815 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4816 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4817 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4818   l2tpv3_interface_enable_disable_reply)                                \
4819 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4820 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4821 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4822 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4823 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4824 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4825 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4826 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4827 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4828 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4829 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4830 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4831 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4832 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4833 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4834 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4835 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4836 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4837 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4838 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4839 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4840 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4841 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
4842 _(L2_MACS_EVENT, l2_macs_event)                                         \
4843 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4844 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4845 _(IP_DETAILS, ip_details)                                               \
4846 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4847 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4848 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4849 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4850 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4851 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4852 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4853 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4854 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4855 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4856 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4857 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4858 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4859 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4860 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4861 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4862 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4863 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4864 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4865 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4866 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4867 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4868 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4869 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4870 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4871 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4872 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4873 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4874 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4875 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4876 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4877 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4878 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4879 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4880 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4881 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4882 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4883 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4884 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4885 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4886 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4887 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4888 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4889 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4890 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4891   one_map_register_enable_disable_reply)                                \
4892 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
4893 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4894   one_rloc_probe_enable_disable_reply)                                  \
4895 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4896 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4897 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4898 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4899 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4900 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4901 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4902 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4903 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4904 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4905 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4906 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4907 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4908 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4909 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4910 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4911   show_one_stats_enable_disable_reply)                                  \
4912 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4913 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4914 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4915 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4916 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4917 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4918 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4919 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4920 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4921 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4922 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
4923 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
4924   gpe_add_del_native_fwd_rpath_reply)                                   \
4925 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4926   gpe_fwd_entry_path_details)                                           \
4927 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4928 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4929   one_add_del_map_request_itr_rlocs_reply)                              \
4930 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4931   one_get_map_request_itr_rlocs_reply)                                  \
4932 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4933 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4934 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4935 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4936 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4937 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4938   show_one_map_register_state_reply)                                    \
4939 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
4940 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4941 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4942 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4943 _(POLICER_DETAILS, policer_details)                                     \
4944 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4945 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4946 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4947 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4948 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4949 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4950 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4951 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4952 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4953 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4954 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4955 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4956 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4957 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4958 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4959 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4960 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4961 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4962 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4963 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4964 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4965 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4966 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4967 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4968 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4969  ip_source_and_port_range_check_add_del_reply)                          \
4970 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4971  ip_source_and_port_range_check_interface_add_del_reply)                \
4972 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4973 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4974 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4975 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4976 _(PUNT_REPLY, punt_reply)                                               \
4977 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4978 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4979 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4980 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4981 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4982 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4983 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4984 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
4985 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
4986 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
4987 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
4988 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)
4989
4990 #define foreach_standalone_reply_msg                                    \
4991 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4992 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4993 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4994 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4995 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4996 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4997 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4998
4999 typedef struct
5000 {
5001   u8 *name;
5002   u32 value;
5003 } name_sort_t;
5004
5005
5006 #define STR_VTR_OP_CASE(op)     \
5007     case L2_VTR_ ## op:         \
5008         return "" # op;
5009
5010 static const char *
5011 str_vtr_op (u32 vtr_op)
5012 {
5013   switch (vtr_op)
5014     {
5015       STR_VTR_OP_CASE (DISABLED);
5016       STR_VTR_OP_CASE (PUSH_1);
5017       STR_VTR_OP_CASE (PUSH_2);
5018       STR_VTR_OP_CASE (POP_1);
5019       STR_VTR_OP_CASE (POP_2);
5020       STR_VTR_OP_CASE (TRANSLATE_1_1);
5021       STR_VTR_OP_CASE (TRANSLATE_1_2);
5022       STR_VTR_OP_CASE (TRANSLATE_2_1);
5023       STR_VTR_OP_CASE (TRANSLATE_2_2);
5024     }
5025
5026   return "UNKNOWN";
5027 }
5028
5029 static int
5030 dump_sub_interface_table (vat_main_t * vam)
5031 {
5032   const sw_interface_subif_t *sub = NULL;
5033
5034   if (vam->json_output)
5035     {
5036       clib_warning
5037         ("JSON output supported only for VPE API calls and dump_stats_table");
5038       return -99;
5039     }
5040
5041   print (vam->ofp,
5042          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5043          "Interface", "sw_if_index",
5044          "sub id", "dot1ad", "tags", "outer id",
5045          "inner id", "exact", "default", "outer any", "inner any");
5046
5047   vec_foreach (sub, vam->sw_if_subif_table)
5048   {
5049     print (vam->ofp,
5050            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5051            sub->interface_name,
5052            sub->sw_if_index,
5053            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5054            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5055            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5056            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5057     if (sub->vtr_op != L2_VTR_DISABLED)
5058       {
5059         print (vam->ofp,
5060                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5061                "tag1: %d tag2: %d ]",
5062                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5063                sub->vtr_tag1, sub->vtr_tag2);
5064       }
5065   }
5066
5067   return 0;
5068 }
5069
5070 static int
5071 name_sort_cmp (void *a1, void *a2)
5072 {
5073   name_sort_t *n1 = a1;
5074   name_sort_t *n2 = a2;
5075
5076   return strcmp ((char *) n1->name, (char *) n2->name);
5077 }
5078
5079 static int
5080 dump_interface_table (vat_main_t * vam)
5081 {
5082   hash_pair_t *p;
5083   name_sort_t *nses = 0, *ns;
5084
5085   if (vam->json_output)
5086     {
5087       clib_warning
5088         ("JSON output supported only for VPE API calls and dump_stats_table");
5089       return -99;
5090     }
5091
5092   /* *INDENT-OFF* */
5093   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5094   ({
5095     vec_add2 (nses, ns, 1);
5096     ns->name = (u8 *)(p->key);
5097     ns->value = (u32) p->value[0];
5098   }));
5099   /* *INDENT-ON* */
5100
5101   vec_sort_with_function (nses, name_sort_cmp);
5102
5103   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5104   vec_foreach (ns, nses)
5105   {
5106     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5107   }
5108   vec_free (nses);
5109   return 0;
5110 }
5111
5112 static int
5113 dump_ip_table (vat_main_t * vam, int is_ipv6)
5114 {
5115   const ip_details_t *det = NULL;
5116   const ip_address_details_t *address = NULL;
5117   u32 i = ~0;
5118
5119   print (vam->ofp, "%-12s", "sw_if_index");
5120
5121   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5122   {
5123     i++;
5124     if (!det->present)
5125       {
5126         continue;
5127       }
5128     print (vam->ofp, "%-12d", i);
5129     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5130     if (!det->addr)
5131       {
5132         continue;
5133       }
5134     vec_foreach (address, det->addr)
5135     {
5136       print (vam->ofp,
5137              "            %-30U%-13d",
5138              is_ipv6 ? format_ip6_address : format_ip4_address,
5139              address->ip, address->prefix_length);
5140     }
5141   }
5142
5143   return 0;
5144 }
5145
5146 static int
5147 dump_ipv4_table (vat_main_t * vam)
5148 {
5149   if (vam->json_output)
5150     {
5151       clib_warning
5152         ("JSON output supported only for VPE API calls and dump_stats_table");
5153       return -99;
5154     }
5155
5156   return dump_ip_table (vam, 0);
5157 }
5158
5159 static int
5160 dump_ipv6_table (vat_main_t * vam)
5161 {
5162   if (vam->json_output)
5163     {
5164       clib_warning
5165         ("JSON output supported only for VPE API calls and dump_stats_table");
5166       return -99;
5167     }
5168
5169   return dump_ip_table (vam, 1);
5170 }
5171
5172 static char *
5173 counter_type_to_str (u8 counter_type, u8 is_combined)
5174 {
5175   if (!is_combined)
5176     {
5177       switch (counter_type)
5178         {
5179         case VNET_INTERFACE_COUNTER_DROP:
5180           return "drop";
5181         case VNET_INTERFACE_COUNTER_PUNT:
5182           return "punt";
5183         case VNET_INTERFACE_COUNTER_IP4:
5184           return "ip4";
5185         case VNET_INTERFACE_COUNTER_IP6:
5186           return "ip6";
5187         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5188           return "rx-no-buf";
5189         case VNET_INTERFACE_COUNTER_RX_MISS:
5190           return "rx-miss";
5191         case VNET_INTERFACE_COUNTER_RX_ERROR:
5192           return "rx-error";
5193         case VNET_INTERFACE_COUNTER_TX_ERROR:
5194           return "tx-error";
5195         default:
5196           return "INVALID-COUNTER-TYPE";
5197         }
5198     }
5199   else
5200     {
5201       switch (counter_type)
5202         {
5203         case VNET_INTERFACE_COUNTER_RX:
5204           return "rx";
5205         case VNET_INTERFACE_COUNTER_TX:
5206           return "tx";
5207         default:
5208           return "INVALID-COUNTER-TYPE";
5209         }
5210     }
5211 }
5212
5213 static int
5214 dump_stats_table (vat_main_t * vam)
5215 {
5216   vat_json_node_t node;
5217   vat_json_node_t *msg_array;
5218   vat_json_node_t *msg;
5219   vat_json_node_t *counter_array;
5220   vat_json_node_t *counter;
5221   interface_counter_t c;
5222   u64 packets;
5223   ip4_fib_counter_t *c4;
5224   ip6_fib_counter_t *c6;
5225   ip4_nbr_counter_t *n4;
5226   ip6_nbr_counter_t *n6;
5227   int i, j;
5228
5229   if (!vam->json_output)
5230     {
5231       clib_warning ("dump_stats_table supported only in JSON format");
5232       return -99;
5233     }
5234
5235   vat_json_init_object (&node);
5236
5237   /* interface counters */
5238   msg_array = vat_json_object_add (&node, "interface_counters");
5239   vat_json_init_array (msg_array);
5240   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5241     {
5242       msg = vat_json_array_add (msg_array);
5243       vat_json_init_object (msg);
5244       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5245                                        (u8 *) counter_type_to_str (i, 0));
5246       vat_json_object_add_int (msg, "is_combined", 0);
5247       counter_array = vat_json_object_add (msg, "data");
5248       vat_json_init_array (counter_array);
5249       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5250         {
5251           packets = vam->simple_interface_counters[i][j];
5252           vat_json_array_add_uint (counter_array, packets);
5253         }
5254     }
5255   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5256     {
5257       msg = vat_json_array_add (msg_array);
5258       vat_json_init_object (msg);
5259       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5260                                        (u8 *) counter_type_to_str (i, 1));
5261       vat_json_object_add_int (msg, "is_combined", 1);
5262       counter_array = vat_json_object_add (msg, "data");
5263       vat_json_init_array (counter_array);
5264       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5265         {
5266           c = vam->combined_interface_counters[i][j];
5267           counter = vat_json_array_add (counter_array);
5268           vat_json_init_object (counter);
5269           vat_json_object_add_uint (counter, "packets", c.packets);
5270           vat_json_object_add_uint (counter, "bytes", c.bytes);
5271         }
5272     }
5273
5274   /* ip4 fib counters */
5275   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5276   vat_json_init_array (msg_array);
5277   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5278     {
5279       msg = vat_json_array_add (msg_array);
5280       vat_json_init_object (msg);
5281       vat_json_object_add_uint (msg, "vrf_id",
5282                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5283       counter_array = vat_json_object_add (msg, "c");
5284       vat_json_init_array (counter_array);
5285       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5286         {
5287           counter = vat_json_array_add (counter_array);
5288           vat_json_init_object (counter);
5289           c4 = &vam->ip4_fib_counters[i][j];
5290           vat_json_object_add_ip4 (counter, "address", c4->address);
5291           vat_json_object_add_uint (counter, "address_length",
5292                                     c4->address_length);
5293           vat_json_object_add_uint (counter, "packets", c4->packets);
5294           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5295         }
5296     }
5297
5298   /* ip6 fib counters */
5299   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5300   vat_json_init_array (msg_array);
5301   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5302     {
5303       msg = vat_json_array_add (msg_array);
5304       vat_json_init_object (msg);
5305       vat_json_object_add_uint (msg, "vrf_id",
5306                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5307       counter_array = vat_json_object_add (msg, "c");
5308       vat_json_init_array (counter_array);
5309       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5310         {
5311           counter = vat_json_array_add (counter_array);
5312           vat_json_init_object (counter);
5313           c6 = &vam->ip6_fib_counters[i][j];
5314           vat_json_object_add_ip6 (counter, "address", c6->address);
5315           vat_json_object_add_uint (counter, "address_length",
5316                                     c6->address_length);
5317           vat_json_object_add_uint (counter, "packets", c6->packets);
5318           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5319         }
5320     }
5321
5322   /* ip4 nbr counters */
5323   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5324   vat_json_init_array (msg_array);
5325   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5326     {
5327       msg = vat_json_array_add (msg_array);
5328       vat_json_init_object (msg);
5329       vat_json_object_add_uint (msg, "sw_if_index", i);
5330       counter_array = vat_json_object_add (msg, "c");
5331       vat_json_init_array (counter_array);
5332       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5333         {
5334           counter = vat_json_array_add (counter_array);
5335           vat_json_init_object (counter);
5336           n4 = &vam->ip4_nbr_counters[i][j];
5337           vat_json_object_add_ip4 (counter, "address", n4->address);
5338           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5339           vat_json_object_add_uint (counter, "packets", n4->packets);
5340           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5341         }
5342     }
5343
5344   /* ip6 nbr counters */
5345   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5346   vat_json_init_array (msg_array);
5347   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5348     {
5349       msg = vat_json_array_add (msg_array);
5350       vat_json_init_object (msg);
5351       vat_json_object_add_uint (msg, "sw_if_index", i);
5352       counter_array = vat_json_object_add (msg, "c");
5353       vat_json_init_array (counter_array);
5354       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5355         {
5356           counter = vat_json_array_add (counter_array);
5357           vat_json_init_object (counter);
5358           n6 = &vam->ip6_nbr_counters[i][j];
5359           vat_json_object_add_ip6 (counter, "address", n6->address);
5360           vat_json_object_add_uint (counter, "packets", n6->packets);
5361           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5362         }
5363     }
5364
5365   vat_json_print (vam->ofp, &node);
5366   vat_json_free (&node);
5367
5368   return 0;
5369 }
5370
5371 int
5372 exec (vat_main_t * vam)
5373 {
5374   api_main_t *am = &api_main;
5375   vl_api_cli_t *mp;
5376   f64 timeout;
5377   void *oldheap;
5378   u8 *cmd = 0;
5379   unformat_input_t *i = vam->input;
5380
5381   if (vec_len (i->buffer) == 0)
5382     return -1;
5383
5384   if (vam->exec_mode == 0 && unformat (i, "mode"))
5385     {
5386       vam->exec_mode = 1;
5387       return 0;
5388     }
5389   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5390     {
5391       vam->exec_mode = 0;
5392       return 0;
5393     }
5394
5395
5396   M (CLI, mp);
5397
5398   /*
5399    * Copy cmd into shared memory.
5400    * In order for the CLI command to work, it
5401    * must be a vector ending in \n, not a C-string ending
5402    * in \n\0.
5403    */
5404   pthread_mutex_lock (&am->vlib_rp->mutex);
5405   oldheap = svm_push_data_heap (am->vlib_rp);
5406
5407   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5408   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5409
5410   svm_pop_heap (oldheap);
5411   pthread_mutex_unlock (&am->vlib_rp->mutex);
5412
5413   mp->cmd_in_shmem = pointer_to_uword (cmd);
5414   S (mp);
5415   timeout = vat_time_now (vam) + 10.0;
5416
5417   while (vat_time_now (vam) < timeout)
5418     {
5419       if (vam->result_ready == 1)
5420         {
5421           u8 *free_me;
5422           if (vam->shmem_result != NULL)
5423             print (vam->ofp, "%s", vam->shmem_result);
5424           pthread_mutex_lock (&am->vlib_rp->mutex);
5425           oldheap = svm_push_data_heap (am->vlib_rp);
5426
5427           free_me = (u8 *) vam->shmem_result;
5428           vec_free (free_me);
5429
5430           svm_pop_heap (oldheap);
5431           pthread_mutex_unlock (&am->vlib_rp->mutex);
5432           return 0;
5433         }
5434     }
5435   return -99;
5436 }
5437
5438 /*
5439  * Future replacement of exec() that passes CLI buffers directly in
5440  * the API messages instead of an additional shared memory area.
5441  */
5442 static int
5443 exec_inband (vat_main_t * vam)
5444 {
5445   vl_api_cli_inband_t *mp;
5446   unformat_input_t *i = vam->input;
5447   int ret;
5448
5449   if (vec_len (i->buffer) == 0)
5450     return -1;
5451
5452   if (vam->exec_mode == 0 && unformat (i, "mode"))
5453     {
5454       vam->exec_mode = 1;
5455       return 0;
5456     }
5457   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5458     {
5459       vam->exec_mode = 0;
5460       return 0;
5461     }
5462
5463   /*
5464    * In order for the CLI command to work, it
5465    * must be a vector ending in \n, not a C-string ending
5466    * in \n\0.
5467    */
5468   u32 len = vec_len (vam->input->buffer);
5469   M2 (CLI_INBAND, mp, len);
5470   clib_memcpy (mp->cmd, vam->input->buffer, len);
5471   mp->length = htonl (len);
5472
5473   S (mp);
5474   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5475   return ret;
5476 }
5477
5478 static int
5479 api_create_loopback (vat_main_t * vam)
5480 {
5481   unformat_input_t *i = vam->input;
5482   vl_api_create_loopback_t *mp;
5483   vl_api_create_loopback_instance_t *mp_lbi;
5484   u8 mac_address[6];
5485   u8 mac_set = 0;
5486   u8 is_specified = 0;
5487   u32 user_instance = 0;
5488   int ret;
5489
5490   memset (mac_address, 0, sizeof (mac_address));
5491
5492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5493     {
5494       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5495         mac_set = 1;
5496       if (unformat (i, "instance %d", &user_instance))
5497         is_specified = 1;
5498       else
5499         break;
5500     }
5501
5502   if (is_specified)
5503     {
5504       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5505       mp_lbi->is_specified = is_specified;
5506       if (is_specified)
5507         mp_lbi->user_instance = htonl (user_instance);
5508       if (mac_set)
5509         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5510       S (mp_lbi);
5511     }
5512   else
5513     {
5514       /* Construct the API message */
5515       M (CREATE_LOOPBACK, mp);
5516       if (mac_set)
5517         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5518       S (mp);
5519     }
5520
5521   W (ret);
5522   return ret;
5523 }
5524
5525 static int
5526 api_delete_loopback (vat_main_t * vam)
5527 {
5528   unformat_input_t *i = vam->input;
5529   vl_api_delete_loopback_t *mp;
5530   u32 sw_if_index = ~0;
5531   int ret;
5532
5533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5534     {
5535       if (unformat (i, "sw_if_index %d", &sw_if_index))
5536         ;
5537       else
5538         break;
5539     }
5540
5541   if (sw_if_index == ~0)
5542     {
5543       errmsg ("missing sw_if_index");
5544       return -99;
5545     }
5546
5547   /* Construct the API message */
5548   M (DELETE_LOOPBACK, mp);
5549   mp->sw_if_index = ntohl (sw_if_index);
5550
5551   S (mp);
5552   W (ret);
5553   return ret;
5554 }
5555
5556 static int
5557 api_want_stats (vat_main_t * vam)
5558 {
5559   unformat_input_t *i = vam->input;
5560   vl_api_want_stats_t *mp;
5561   int enable = -1;
5562   int ret;
5563
5564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5565     {
5566       if (unformat (i, "enable"))
5567         enable = 1;
5568       else if (unformat (i, "disable"))
5569         enable = 0;
5570       else
5571         break;
5572     }
5573
5574   if (enable == -1)
5575     {
5576       errmsg ("missing enable|disable");
5577       return -99;
5578     }
5579
5580   M (WANT_STATS, mp);
5581   mp->enable_disable = enable;
5582
5583   S (mp);
5584   W (ret);
5585   return ret;
5586 }
5587
5588 static int
5589 api_want_interface_events (vat_main_t * vam)
5590 {
5591   unformat_input_t *i = vam->input;
5592   vl_api_want_interface_events_t *mp;
5593   int enable = -1;
5594   int ret;
5595
5596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5597     {
5598       if (unformat (i, "enable"))
5599         enable = 1;
5600       else if (unformat (i, "disable"))
5601         enable = 0;
5602       else
5603         break;
5604     }
5605
5606   if (enable == -1)
5607     {
5608       errmsg ("missing enable|disable");
5609       return -99;
5610     }
5611
5612   M (WANT_INTERFACE_EVENTS, mp);
5613   mp->enable_disable = enable;
5614
5615   vam->interface_event_display = enable;
5616
5617   S (mp);
5618   W (ret);
5619   return ret;
5620 }
5621
5622
5623 /* Note: non-static, called once to set up the initial intfc table */
5624 int
5625 api_sw_interface_dump (vat_main_t * vam)
5626 {
5627   vl_api_sw_interface_dump_t *mp;
5628   vl_api_control_ping_t *mp_ping;
5629   hash_pair_t *p;
5630   name_sort_t *nses = 0, *ns;
5631   sw_interface_subif_t *sub = NULL;
5632   int ret;
5633
5634   /* Toss the old name table */
5635   /* *INDENT-OFF* */
5636   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5637   ({
5638     vec_add2 (nses, ns, 1);
5639     ns->name = (u8 *)(p->key);
5640     ns->value = (u32) p->value[0];
5641   }));
5642   /* *INDENT-ON* */
5643
5644   hash_free (vam->sw_if_index_by_interface_name);
5645
5646   vec_foreach (ns, nses) vec_free (ns->name);
5647
5648   vec_free (nses);
5649
5650   vec_foreach (sub, vam->sw_if_subif_table)
5651   {
5652     vec_free (sub->interface_name);
5653   }
5654   vec_free (vam->sw_if_subif_table);
5655
5656   /* recreate the interface name hash table */
5657   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5658
5659   /* Get list of ethernets */
5660   M (SW_INTERFACE_DUMP, mp);
5661   mp->name_filter_valid = 1;
5662   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5663   S (mp);
5664
5665   /* and local / loopback interfaces */
5666   M (SW_INTERFACE_DUMP, mp);
5667   mp->name_filter_valid = 1;
5668   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5669   S (mp);
5670
5671   /* and packet-generator interfaces */
5672   M (SW_INTERFACE_DUMP, mp);
5673   mp->name_filter_valid = 1;
5674   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5675   S (mp);
5676
5677   /* and vxlan-gpe tunnel interfaces */
5678   M (SW_INTERFACE_DUMP, mp);
5679   mp->name_filter_valid = 1;
5680   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5681            sizeof (mp->name_filter) - 1);
5682   S (mp);
5683
5684   /* and vxlan tunnel interfaces */
5685   M (SW_INTERFACE_DUMP, mp);
5686   mp->name_filter_valid = 1;
5687   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5688   S (mp);
5689
5690   /* and host (af_packet) interfaces */
5691   M (SW_INTERFACE_DUMP, mp);
5692   mp->name_filter_valid = 1;
5693   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5694   S (mp);
5695
5696   /* and l2tpv3 tunnel interfaces */
5697   M (SW_INTERFACE_DUMP, mp);
5698   mp->name_filter_valid = 1;
5699   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5700            sizeof (mp->name_filter) - 1);
5701   S (mp);
5702
5703   /* and GRE tunnel interfaces */
5704   M (SW_INTERFACE_DUMP, mp);
5705   mp->name_filter_valid = 1;
5706   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5707   S (mp);
5708
5709   /* and LISP-GPE interfaces */
5710   M (SW_INTERFACE_DUMP, mp);
5711   mp->name_filter_valid = 1;
5712   strncpy ((char *) mp->name_filter, "lisp_gpe",
5713            sizeof (mp->name_filter) - 1);
5714   S (mp);
5715
5716   /* and IPSEC tunnel interfaces */
5717   M (SW_INTERFACE_DUMP, mp);
5718   mp->name_filter_valid = 1;
5719   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5720   S (mp);
5721
5722   /* Use a control ping for synchronization */
5723   M (CONTROL_PING, mp_ping);
5724   S (mp_ping);
5725
5726   W (ret);
5727   return ret;
5728 }
5729
5730 static int
5731 api_sw_interface_set_flags (vat_main_t * vam)
5732 {
5733   unformat_input_t *i = vam->input;
5734   vl_api_sw_interface_set_flags_t *mp;
5735   u32 sw_if_index;
5736   u8 sw_if_index_set = 0;
5737   u8 admin_up = 0, link_up = 0;
5738   int ret;
5739
5740   /* Parse args required to build the message */
5741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5742     {
5743       if (unformat (i, "admin-up"))
5744         admin_up = 1;
5745       else if (unformat (i, "admin-down"))
5746         admin_up = 0;
5747       else if (unformat (i, "link-up"))
5748         link_up = 1;
5749       else if (unformat (i, "link-down"))
5750         link_up = 0;
5751       else
5752         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5753         sw_if_index_set = 1;
5754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5755         sw_if_index_set = 1;
5756       else
5757         break;
5758     }
5759
5760   if (sw_if_index_set == 0)
5761     {
5762       errmsg ("missing interface name or sw_if_index");
5763       return -99;
5764     }
5765
5766   /* Construct the API message */
5767   M (SW_INTERFACE_SET_FLAGS, mp);
5768   mp->sw_if_index = ntohl (sw_if_index);
5769   mp->admin_up_down = admin_up;
5770   mp->link_up_down = link_up;
5771
5772   /* send it... */
5773   S (mp);
5774
5775   /* Wait for a reply, return the good/bad news... */
5776   W (ret);
5777   return ret;
5778 }
5779
5780 static int
5781 api_sw_interface_clear_stats (vat_main_t * vam)
5782 {
5783   unformat_input_t *i = vam->input;
5784   vl_api_sw_interface_clear_stats_t *mp;
5785   u32 sw_if_index;
5786   u8 sw_if_index_set = 0;
5787   int ret;
5788
5789   /* Parse args required to build the message */
5790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5791     {
5792       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5793         sw_if_index_set = 1;
5794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5795         sw_if_index_set = 1;
5796       else
5797         break;
5798     }
5799
5800   /* Construct the API message */
5801   M (SW_INTERFACE_CLEAR_STATS, mp);
5802
5803   if (sw_if_index_set == 1)
5804     mp->sw_if_index = ntohl (sw_if_index);
5805   else
5806     mp->sw_if_index = ~0;
5807
5808   /* send it... */
5809   S (mp);
5810
5811   /* Wait for a reply, return the good/bad news... */
5812   W (ret);
5813   return ret;
5814 }
5815
5816 static int
5817 api_sw_interface_add_del_address (vat_main_t * vam)
5818 {
5819   unformat_input_t *i = vam->input;
5820   vl_api_sw_interface_add_del_address_t *mp;
5821   u32 sw_if_index;
5822   u8 sw_if_index_set = 0;
5823   u8 is_add = 1, del_all = 0;
5824   u32 address_length = 0;
5825   u8 v4_address_set = 0;
5826   u8 v6_address_set = 0;
5827   ip4_address_t v4address;
5828   ip6_address_t v6address;
5829   int ret;
5830
5831   /* Parse args required to build the message */
5832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5833     {
5834       if (unformat (i, "del-all"))
5835         del_all = 1;
5836       else if (unformat (i, "del"))
5837         is_add = 0;
5838       else
5839         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5840         sw_if_index_set = 1;
5841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5842         sw_if_index_set = 1;
5843       else if (unformat (i, "%U/%d",
5844                          unformat_ip4_address, &v4address, &address_length))
5845         v4_address_set = 1;
5846       else if (unformat (i, "%U/%d",
5847                          unformat_ip6_address, &v6address, &address_length))
5848         v6_address_set = 1;
5849       else
5850         break;
5851     }
5852
5853   if (sw_if_index_set == 0)
5854     {
5855       errmsg ("missing interface name or sw_if_index");
5856       return -99;
5857     }
5858   if (v4_address_set && v6_address_set)
5859     {
5860       errmsg ("both v4 and v6 addresses set");
5861       return -99;
5862     }
5863   if (!v4_address_set && !v6_address_set && !del_all)
5864     {
5865       errmsg ("no addresses set");
5866       return -99;
5867     }
5868
5869   /* Construct the API message */
5870   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5871
5872   mp->sw_if_index = ntohl (sw_if_index);
5873   mp->is_add = is_add;
5874   mp->del_all = del_all;
5875   if (v6_address_set)
5876     {
5877       mp->is_ipv6 = 1;
5878       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5879     }
5880   else
5881     {
5882       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5883     }
5884   mp->address_length = address_length;
5885
5886   /* send it... */
5887   S (mp);
5888
5889   /* Wait for a reply, return good/bad news  */
5890   W (ret);
5891   return ret;
5892 }
5893
5894 static int
5895 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5896 {
5897   unformat_input_t *i = vam->input;
5898   vl_api_sw_interface_set_mpls_enable_t *mp;
5899   u32 sw_if_index;
5900   u8 sw_if_index_set = 0;
5901   u8 enable = 1;
5902   int ret;
5903
5904   /* Parse args required to build the message */
5905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5906     {
5907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5908         sw_if_index_set = 1;
5909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5910         sw_if_index_set = 1;
5911       else if (unformat (i, "disable"))
5912         enable = 0;
5913       else if (unformat (i, "dis"))
5914         enable = 0;
5915       else
5916         break;
5917     }
5918
5919   if (sw_if_index_set == 0)
5920     {
5921       errmsg ("missing interface name or sw_if_index");
5922       return -99;
5923     }
5924
5925   /* Construct the API message */
5926   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5927
5928   mp->sw_if_index = ntohl (sw_if_index);
5929   mp->enable = enable;
5930
5931   /* send it... */
5932   S (mp);
5933
5934   /* Wait for a reply... */
5935   W (ret);
5936   return ret;
5937 }
5938
5939 static int
5940 api_sw_interface_set_table (vat_main_t * vam)
5941 {
5942   unformat_input_t *i = vam->input;
5943   vl_api_sw_interface_set_table_t *mp;
5944   u32 sw_if_index, vrf_id = 0;
5945   u8 sw_if_index_set = 0;
5946   u8 is_ipv6 = 0;
5947   int ret;
5948
5949   /* Parse args required to build the message */
5950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5951     {
5952       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5953         sw_if_index_set = 1;
5954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5955         sw_if_index_set = 1;
5956       else if (unformat (i, "vrf %d", &vrf_id))
5957         ;
5958       else if (unformat (i, "ipv6"))
5959         is_ipv6 = 1;
5960       else
5961         break;
5962     }
5963
5964   if (sw_if_index_set == 0)
5965     {
5966       errmsg ("missing interface name or sw_if_index");
5967       return -99;
5968     }
5969
5970   /* Construct the API message */
5971   M (SW_INTERFACE_SET_TABLE, mp);
5972
5973   mp->sw_if_index = ntohl (sw_if_index);
5974   mp->is_ipv6 = is_ipv6;
5975   mp->vrf_id = ntohl (vrf_id);
5976
5977   /* send it... */
5978   S (mp);
5979
5980   /* Wait for a reply... */
5981   W (ret);
5982   return ret;
5983 }
5984
5985 static void vl_api_sw_interface_get_table_reply_t_handler
5986   (vl_api_sw_interface_get_table_reply_t * mp)
5987 {
5988   vat_main_t *vam = &vat_main;
5989
5990   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5991
5992   vam->retval = ntohl (mp->retval);
5993   vam->result_ready = 1;
5994
5995 }
5996
5997 static void vl_api_sw_interface_get_table_reply_t_handler_json
5998   (vl_api_sw_interface_get_table_reply_t * mp)
5999 {
6000   vat_main_t *vam = &vat_main;
6001   vat_json_node_t node;
6002
6003   vat_json_init_object (&node);
6004   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6005   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6006
6007   vat_json_print (vam->ofp, &node);
6008   vat_json_free (&node);
6009
6010   vam->retval = ntohl (mp->retval);
6011   vam->result_ready = 1;
6012 }
6013
6014 static int
6015 api_sw_interface_get_table (vat_main_t * vam)
6016 {
6017   unformat_input_t *i = vam->input;
6018   vl_api_sw_interface_get_table_t *mp;
6019   u32 sw_if_index;
6020   u8 sw_if_index_set = 0;
6021   u8 is_ipv6 = 0;
6022   int ret;
6023
6024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6025     {
6026       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6027         sw_if_index_set = 1;
6028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6029         sw_if_index_set = 1;
6030       else if (unformat (i, "ipv6"))
6031         is_ipv6 = 1;
6032       else
6033         break;
6034     }
6035
6036   if (sw_if_index_set == 0)
6037     {
6038       errmsg ("missing interface name or sw_if_index");
6039       return -99;
6040     }
6041
6042   M (SW_INTERFACE_GET_TABLE, mp);
6043   mp->sw_if_index = htonl (sw_if_index);
6044   mp->is_ipv6 = is_ipv6;
6045
6046   S (mp);
6047   W (ret);
6048   return ret;
6049 }
6050
6051 static int
6052 api_sw_interface_set_vpath (vat_main_t * vam)
6053 {
6054   unformat_input_t *i = vam->input;
6055   vl_api_sw_interface_set_vpath_t *mp;
6056   u32 sw_if_index = 0;
6057   u8 sw_if_index_set = 0;
6058   u8 is_enable = 0;
6059   int ret;
6060
6061   /* Parse args required to build the message */
6062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6063     {
6064       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6065         sw_if_index_set = 1;
6066       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6067         sw_if_index_set = 1;
6068       else if (unformat (i, "enable"))
6069         is_enable = 1;
6070       else if (unformat (i, "disable"))
6071         is_enable = 0;
6072       else
6073         break;
6074     }
6075
6076   if (sw_if_index_set == 0)
6077     {
6078       errmsg ("missing interface name or sw_if_index");
6079       return -99;
6080     }
6081
6082   /* Construct the API message */
6083   M (SW_INTERFACE_SET_VPATH, mp);
6084
6085   mp->sw_if_index = ntohl (sw_if_index);
6086   mp->enable = is_enable;
6087
6088   /* send it... */
6089   S (mp);
6090
6091   /* Wait for a reply... */
6092   W (ret);
6093   return ret;
6094 }
6095
6096 static int
6097 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6098 {
6099   unformat_input_t *i = vam->input;
6100   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6101   u32 sw_if_index = 0;
6102   u8 sw_if_index_set = 0;
6103   u8 is_enable = 1;
6104   u8 is_ipv6 = 0;
6105   int ret;
6106
6107   /* Parse args required to build the message */
6108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6109     {
6110       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6111         sw_if_index_set = 1;
6112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6113         sw_if_index_set = 1;
6114       else if (unformat (i, "enable"))
6115         is_enable = 1;
6116       else if (unformat (i, "disable"))
6117         is_enable = 0;
6118       else if (unformat (i, "ip4"))
6119         is_ipv6 = 0;
6120       else if (unformat (i, "ip6"))
6121         is_ipv6 = 1;
6122       else
6123         break;
6124     }
6125
6126   if (sw_if_index_set == 0)
6127     {
6128       errmsg ("missing interface name or sw_if_index");
6129       return -99;
6130     }
6131
6132   /* Construct the API message */
6133   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6134
6135   mp->sw_if_index = ntohl (sw_if_index);
6136   mp->enable = is_enable;
6137   mp->is_ipv6 = is_ipv6;
6138
6139   /* send it... */
6140   S (mp);
6141
6142   /* Wait for a reply... */
6143   W (ret);
6144   return ret;
6145 }
6146
6147
6148 static int
6149 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6150 {
6151   unformat_input_t *i = vam->input;
6152   vl_api_sw_interface_set_l2_xconnect_t *mp;
6153   u32 rx_sw_if_index;
6154   u8 rx_sw_if_index_set = 0;
6155   u32 tx_sw_if_index;
6156   u8 tx_sw_if_index_set = 0;
6157   u8 enable = 1;
6158   int ret;
6159
6160   /* Parse args required to build the message */
6161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6162     {
6163       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6164         rx_sw_if_index_set = 1;
6165       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6166         tx_sw_if_index_set = 1;
6167       else if (unformat (i, "rx"))
6168         {
6169           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6170             {
6171               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6172                             &rx_sw_if_index))
6173                 rx_sw_if_index_set = 1;
6174             }
6175           else
6176             break;
6177         }
6178       else if (unformat (i, "tx"))
6179         {
6180           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6181             {
6182               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6183                             &tx_sw_if_index))
6184                 tx_sw_if_index_set = 1;
6185             }
6186           else
6187             break;
6188         }
6189       else if (unformat (i, "enable"))
6190         enable = 1;
6191       else if (unformat (i, "disable"))
6192         enable = 0;
6193       else
6194         break;
6195     }
6196
6197   if (rx_sw_if_index_set == 0)
6198     {
6199       errmsg ("missing rx interface name or rx_sw_if_index");
6200       return -99;
6201     }
6202
6203   if (enable && (tx_sw_if_index_set == 0))
6204     {
6205       errmsg ("missing tx interface name or tx_sw_if_index");
6206       return -99;
6207     }
6208
6209   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6210
6211   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6212   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6213   mp->enable = enable;
6214
6215   S (mp);
6216   W (ret);
6217   return ret;
6218 }
6219
6220 static int
6221 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6222 {
6223   unformat_input_t *i = vam->input;
6224   vl_api_sw_interface_set_l2_bridge_t *mp;
6225   u32 rx_sw_if_index;
6226   u8 rx_sw_if_index_set = 0;
6227   u32 bd_id;
6228   u8 bd_id_set = 0;
6229   u8 bvi = 0;
6230   u32 shg = 0;
6231   u8 enable = 1;
6232   int ret;
6233
6234   /* Parse args required to build the message */
6235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6236     {
6237       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6238         rx_sw_if_index_set = 1;
6239       else if (unformat (i, "bd_id %d", &bd_id))
6240         bd_id_set = 1;
6241       else
6242         if (unformat
6243             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6244         rx_sw_if_index_set = 1;
6245       else if (unformat (i, "shg %d", &shg))
6246         ;
6247       else if (unformat (i, "bvi"))
6248         bvi = 1;
6249       else if (unformat (i, "enable"))
6250         enable = 1;
6251       else if (unformat (i, "disable"))
6252         enable = 0;
6253       else
6254         break;
6255     }
6256
6257   if (rx_sw_if_index_set == 0)
6258     {
6259       errmsg ("missing rx interface name or sw_if_index");
6260       return -99;
6261     }
6262
6263   if (enable && (bd_id_set == 0))
6264     {
6265       errmsg ("missing bridge domain");
6266       return -99;
6267     }
6268
6269   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6270
6271   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6272   mp->bd_id = ntohl (bd_id);
6273   mp->shg = (u8) shg;
6274   mp->bvi = bvi;
6275   mp->enable = enable;
6276
6277   S (mp);
6278   W (ret);
6279   return ret;
6280 }
6281
6282 static int
6283 api_bridge_domain_dump (vat_main_t * vam)
6284 {
6285   unformat_input_t *i = vam->input;
6286   vl_api_bridge_domain_dump_t *mp;
6287   vl_api_control_ping_t *mp_ping;
6288   u32 bd_id = ~0;
6289   int ret;
6290
6291   /* Parse args required to build the message */
6292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6293     {
6294       if (unformat (i, "bd_id %d", &bd_id))
6295         ;
6296       else
6297         break;
6298     }
6299
6300   M (BRIDGE_DOMAIN_DUMP, mp);
6301   mp->bd_id = ntohl (bd_id);
6302   S (mp);
6303
6304   /* Use a control ping for synchronization */
6305   M (CONTROL_PING, mp_ping);
6306   S (mp_ping);
6307
6308   W (ret);
6309   return ret;
6310 }
6311
6312 static int
6313 api_bridge_domain_add_del (vat_main_t * vam)
6314 {
6315   unformat_input_t *i = vam->input;
6316   vl_api_bridge_domain_add_del_t *mp;
6317   u32 bd_id = ~0;
6318   u8 is_add = 1;
6319   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6320   u32 mac_age = 0;
6321   int ret;
6322
6323   /* Parse args required to build the message */
6324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6325     {
6326       if (unformat (i, "bd_id %d", &bd_id))
6327         ;
6328       else if (unformat (i, "flood %d", &flood))
6329         ;
6330       else if (unformat (i, "uu-flood %d", &uu_flood))
6331         ;
6332       else if (unformat (i, "forward %d", &forward))
6333         ;
6334       else if (unformat (i, "learn %d", &learn))
6335         ;
6336       else if (unformat (i, "arp-term %d", &arp_term))
6337         ;
6338       else if (unformat (i, "mac-age %d", &mac_age))
6339         ;
6340       else if (unformat (i, "del"))
6341         {
6342           is_add = 0;
6343           flood = uu_flood = forward = learn = 0;
6344         }
6345       else
6346         break;
6347     }
6348
6349   if (bd_id == ~0)
6350     {
6351       errmsg ("missing bridge domain");
6352       return -99;
6353     }
6354
6355   if (mac_age > 255)
6356     {
6357       errmsg ("mac age must be less than 256 ");
6358       return -99;
6359     }
6360
6361   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6362
6363   mp->bd_id = ntohl (bd_id);
6364   mp->flood = flood;
6365   mp->uu_flood = uu_flood;
6366   mp->forward = forward;
6367   mp->learn = learn;
6368   mp->arp_term = arp_term;
6369   mp->is_add = is_add;
6370   mp->mac_age = (u8) mac_age;
6371
6372   S (mp);
6373   W (ret);
6374   return ret;
6375 }
6376
6377 static int
6378 api_l2fib_flush_bd (vat_main_t * vam)
6379 {
6380   unformat_input_t *i = vam->input;
6381   vl_api_l2fib_flush_bd_t *mp;
6382   u32 bd_id = ~0;
6383   int ret;
6384
6385   /* Parse args required to build the message */
6386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6387     {
6388       if (unformat (i, "bd_id %d", &bd_id));
6389       else
6390         break;
6391     }
6392
6393   if (bd_id == ~0)
6394     {
6395       errmsg ("missing bridge domain");
6396       return -99;
6397     }
6398
6399   M (L2FIB_FLUSH_BD, mp);
6400
6401   mp->bd_id = htonl (bd_id);
6402
6403   S (mp);
6404   W (ret);
6405   return ret;
6406 }
6407
6408 static int
6409 api_l2fib_flush_int (vat_main_t * vam)
6410 {
6411   unformat_input_t *i = vam->input;
6412   vl_api_l2fib_flush_int_t *mp;
6413   u32 sw_if_index = ~0;
6414   int ret;
6415
6416   /* Parse args required to build the message */
6417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6418     {
6419       if (unformat (i, "sw_if_index %d", &sw_if_index));
6420       else
6421         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6422       else
6423         break;
6424     }
6425
6426   if (sw_if_index == ~0)
6427     {
6428       errmsg ("missing interface name or sw_if_index");
6429       return -99;
6430     }
6431
6432   M (L2FIB_FLUSH_INT, mp);
6433
6434   mp->sw_if_index = ntohl (sw_if_index);
6435
6436   S (mp);
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_l2fib_add_del (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_l2fib_add_del_t *mp;
6446   f64 timeout;
6447   u64 mac = 0;
6448   u8 mac_set = 0;
6449   u32 bd_id;
6450   u8 bd_id_set = 0;
6451   u32 sw_if_index = ~0;
6452   u8 sw_if_index_set = 0;
6453   u8 is_add = 1;
6454   u8 static_mac = 0;
6455   u8 filter_mac = 0;
6456   u8 bvi_mac = 0;
6457   int count = 1;
6458   f64 before = 0;
6459   int j;
6460
6461   /* Parse args required to build the message */
6462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6463     {
6464       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6465         mac_set = 1;
6466       else if (unformat (i, "bd_id %d", &bd_id))
6467         bd_id_set = 1;
6468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6469         sw_if_index_set = 1;
6470       else if (unformat (i, "sw_if"))
6471         {
6472           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6473             {
6474               if (unformat
6475                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6476                 sw_if_index_set = 1;
6477             }
6478           else
6479             break;
6480         }
6481       else if (unformat (i, "static"))
6482         static_mac = 1;
6483       else if (unformat (i, "filter"))
6484         {
6485           filter_mac = 1;
6486           static_mac = 1;
6487         }
6488       else if (unformat (i, "bvi"))
6489         {
6490           bvi_mac = 1;
6491           static_mac = 1;
6492         }
6493       else if (unformat (i, "del"))
6494         is_add = 0;
6495       else if (unformat (i, "count %d", &count))
6496         ;
6497       else
6498         break;
6499     }
6500
6501   if (mac_set == 0)
6502     {
6503       errmsg ("missing mac address");
6504       return -99;
6505     }
6506
6507   if (bd_id_set == 0)
6508     {
6509       errmsg ("missing bridge domain");
6510       return -99;
6511     }
6512
6513   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6514     {
6515       errmsg ("missing interface name or sw_if_index");
6516       return -99;
6517     }
6518
6519   if (count > 1)
6520     {
6521       /* Turn on async mode */
6522       vam->async_mode = 1;
6523       vam->async_errors = 0;
6524       before = vat_time_now (vam);
6525     }
6526
6527   for (j = 0; j < count; j++)
6528     {
6529       M (L2FIB_ADD_DEL, mp);
6530
6531       mp->mac = mac;
6532       mp->bd_id = ntohl (bd_id);
6533       mp->is_add = is_add;
6534
6535       if (is_add)
6536         {
6537           mp->sw_if_index = ntohl (sw_if_index);
6538           mp->static_mac = static_mac;
6539           mp->filter_mac = filter_mac;
6540           mp->bvi_mac = bvi_mac;
6541         }
6542       increment_mac_address (&mac);
6543       /* send it... */
6544       S (mp);
6545     }
6546
6547   if (count > 1)
6548     {
6549       vl_api_control_ping_t *mp_ping;
6550       f64 after;
6551
6552       /* Shut off async mode */
6553       vam->async_mode = 0;
6554
6555       M (CONTROL_PING, mp_ping);
6556       S (mp_ping);
6557
6558       timeout = vat_time_now (vam) + 1.0;
6559       while (vat_time_now (vam) < timeout)
6560         if (vam->result_ready == 1)
6561           goto out;
6562       vam->retval = -99;
6563
6564     out:
6565       if (vam->retval == -99)
6566         errmsg ("timeout");
6567
6568       if (vam->async_errors > 0)
6569         {
6570           errmsg ("%d asynchronous errors", vam->async_errors);
6571           vam->retval = -98;
6572         }
6573       vam->async_errors = 0;
6574       after = vat_time_now (vam);
6575
6576       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6577              count, after - before, count / (after - before));
6578     }
6579   else
6580     {
6581       int ret;
6582
6583       /* Wait for a reply... */
6584       W (ret);
6585       return ret;
6586     }
6587   /* Return the good/bad news */
6588   return (vam->retval);
6589 }
6590
6591 static int
6592 api_bridge_domain_set_mac_age (vat_main_t * vam)
6593 {
6594   unformat_input_t *i = vam->input;
6595   vl_api_bridge_domain_set_mac_age_t *mp;
6596   u32 bd_id = ~0;
6597   u32 mac_age = 0;
6598   int ret;
6599
6600   /* Parse args required to build the message */
6601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6602     {
6603       if (unformat (i, "bd_id %d", &bd_id));
6604       else if (unformat (i, "mac-age %d", &mac_age));
6605       else
6606         break;
6607     }
6608
6609   if (bd_id == ~0)
6610     {
6611       errmsg ("missing bridge domain");
6612       return -99;
6613     }
6614
6615   if (mac_age > 255)
6616     {
6617       errmsg ("mac age must be less than 256 ");
6618       return -99;
6619     }
6620
6621   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6622
6623   mp->bd_id = htonl (bd_id);
6624   mp->mac_age = (u8) mac_age;
6625
6626   S (mp);
6627   W (ret);
6628   return ret;
6629 }
6630
6631 static int
6632 api_l2_flags (vat_main_t * vam)
6633 {
6634   unformat_input_t *i = vam->input;
6635   vl_api_l2_flags_t *mp;
6636   u32 sw_if_index;
6637   u32 flags = 0;
6638   u8 sw_if_index_set = 0;
6639   u8 is_set = 0;
6640   int ret;
6641
6642   /* Parse args required to build the message */
6643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6644     {
6645       if (unformat (i, "sw_if_index %d", &sw_if_index))
6646         sw_if_index_set = 1;
6647       else if (unformat (i, "sw_if"))
6648         {
6649           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6650             {
6651               if (unformat
6652                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6653                 sw_if_index_set = 1;
6654             }
6655           else
6656             break;
6657         }
6658       else if (unformat (i, "learn"))
6659         flags |= L2_LEARN;
6660       else if (unformat (i, "forward"))
6661         flags |= L2_FWD;
6662       else if (unformat (i, "flood"))
6663         flags |= L2_FLOOD;
6664       else if (unformat (i, "uu-flood"))
6665         flags |= L2_UU_FLOOD;
6666       else if (unformat (i, "arp-term"))
6667         flags |= L2_ARP_TERM;
6668       else if (unformat (i, "off"))
6669         is_set = 0;
6670       else if (unformat (i, "disable"))
6671         is_set = 0;
6672       else
6673         break;
6674     }
6675
6676   if (sw_if_index_set == 0)
6677     {
6678       errmsg ("missing interface name or sw_if_index");
6679       return -99;
6680     }
6681
6682   M (L2_FLAGS, mp);
6683
6684   mp->sw_if_index = ntohl (sw_if_index);
6685   mp->feature_bitmap = ntohl (flags);
6686   mp->is_set = is_set;
6687
6688   S (mp);
6689   W (ret);
6690   return ret;
6691 }
6692
6693 static int
6694 api_bridge_flags (vat_main_t * vam)
6695 {
6696   unformat_input_t *i = vam->input;
6697   vl_api_bridge_flags_t *mp;
6698   u32 bd_id;
6699   u8 bd_id_set = 0;
6700   u8 is_set = 1;
6701   u32 flags = 0;
6702   int ret;
6703
6704   /* Parse args required to build the message */
6705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6706     {
6707       if (unformat (i, "bd_id %d", &bd_id))
6708         bd_id_set = 1;
6709       else if (unformat (i, "learn"))
6710         flags |= L2_LEARN;
6711       else if (unformat (i, "forward"))
6712         flags |= L2_FWD;
6713       else if (unformat (i, "flood"))
6714         flags |= L2_FLOOD;
6715       else if (unformat (i, "uu-flood"))
6716         flags |= L2_UU_FLOOD;
6717       else if (unformat (i, "arp-term"))
6718         flags |= L2_ARP_TERM;
6719       else if (unformat (i, "off"))
6720         is_set = 0;
6721       else if (unformat (i, "disable"))
6722         is_set = 0;
6723       else
6724         break;
6725     }
6726
6727   if (bd_id_set == 0)
6728     {
6729       errmsg ("missing bridge domain");
6730       return -99;
6731     }
6732
6733   M (BRIDGE_FLAGS, mp);
6734
6735   mp->bd_id = ntohl (bd_id);
6736   mp->feature_bitmap = ntohl (flags);
6737   mp->is_set = is_set;
6738
6739   S (mp);
6740   W (ret);
6741   return ret;
6742 }
6743
6744 static int
6745 api_bd_ip_mac_add_del (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_bd_ip_mac_add_del_t *mp;
6749   u32 bd_id;
6750   u8 is_ipv6 = 0;
6751   u8 is_add = 1;
6752   u8 bd_id_set = 0;
6753   u8 ip_set = 0;
6754   u8 mac_set = 0;
6755   ip4_address_t v4addr;
6756   ip6_address_t v6addr;
6757   u8 macaddr[6];
6758   int ret;
6759
6760
6761   /* Parse args required to build the message */
6762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6763     {
6764       if (unformat (i, "bd_id %d", &bd_id))
6765         {
6766           bd_id_set++;
6767         }
6768       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6769         {
6770           ip_set++;
6771         }
6772       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6773         {
6774           ip_set++;
6775           is_ipv6++;
6776         }
6777       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6778         {
6779           mac_set++;
6780         }
6781       else if (unformat (i, "del"))
6782         is_add = 0;
6783       else
6784         break;
6785     }
6786
6787   if (bd_id_set == 0)
6788     {
6789       errmsg ("missing bridge domain");
6790       return -99;
6791     }
6792   else if (ip_set == 0)
6793     {
6794       errmsg ("missing IP address");
6795       return -99;
6796     }
6797   else if (mac_set == 0)
6798     {
6799       errmsg ("missing MAC address");
6800       return -99;
6801     }
6802
6803   M (BD_IP_MAC_ADD_DEL, mp);
6804
6805   mp->bd_id = ntohl (bd_id);
6806   mp->is_ipv6 = is_ipv6;
6807   mp->is_add = is_add;
6808   if (is_ipv6)
6809     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6810   else
6811     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6812   clib_memcpy (mp->mac_address, macaddr, 6);
6813   S (mp);
6814   W (ret);
6815   return ret;
6816 }
6817
6818 static int
6819 api_tap_connect (vat_main_t * vam)
6820 {
6821   unformat_input_t *i = vam->input;
6822   vl_api_tap_connect_t *mp;
6823   u8 mac_address[6];
6824   u8 random_mac = 1;
6825   u8 name_set = 0;
6826   u8 *tap_name;
6827   u8 *tag = 0;
6828   ip4_address_t ip4_address;
6829   u32 ip4_mask_width;
6830   int ip4_address_set = 0;
6831   ip6_address_t ip6_address;
6832   u32 ip6_mask_width;
6833   int ip6_address_set = 0;
6834   int ret;
6835
6836   memset (mac_address, 0, sizeof (mac_address));
6837
6838   /* Parse args required to build the message */
6839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6840     {
6841       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6842         {
6843           random_mac = 0;
6844         }
6845       else if (unformat (i, "random-mac"))
6846         random_mac = 1;
6847       else if (unformat (i, "tapname %s", &tap_name))
6848         name_set = 1;
6849       else if (unformat (i, "tag %s", &tag))
6850         ;
6851       else if (unformat (i, "address %U/%d",
6852                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6853         ip4_address_set = 1;
6854       else if (unformat (i, "address %U/%d",
6855                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6856         ip6_address_set = 1;
6857       else
6858         break;
6859     }
6860
6861   if (name_set == 0)
6862     {
6863       errmsg ("missing tap name");
6864       return -99;
6865     }
6866   if (vec_len (tap_name) > 63)
6867     {
6868       errmsg ("tap name too long");
6869       return -99;
6870     }
6871   vec_add1 (tap_name, 0);
6872
6873   if (vec_len (tag) > 63)
6874     {
6875       errmsg ("tag too long");
6876       return -99;
6877     }
6878
6879   /* Construct the API message */
6880   M (TAP_CONNECT, mp);
6881
6882   mp->use_random_mac = random_mac;
6883   clib_memcpy (mp->mac_address, mac_address, 6);
6884   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6885   if (tag)
6886     clib_memcpy (mp->tag, tag, vec_len (tag));
6887
6888   if (ip4_address_set)
6889     {
6890       mp->ip4_address_set = 1;
6891       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6892       mp->ip4_mask_width = ip4_mask_width;
6893     }
6894   if (ip6_address_set)
6895     {
6896       mp->ip6_address_set = 1;
6897       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6898       mp->ip6_mask_width = ip6_mask_width;
6899     }
6900
6901   vec_free (tap_name);
6902   vec_free (tag);
6903
6904   /* send it... */
6905   S (mp);
6906
6907   /* Wait for a reply... */
6908   W (ret);
6909   return ret;
6910 }
6911
6912 static int
6913 api_tap_modify (vat_main_t * vam)
6914 {
6915   unformat_input_t *i = vam->input;
6916   vl_api_tap_modify_t *mp;
6917   u8 mac_address[6];
6918   u8 random_mac = 1;
6919   u8 name_set = 0;
6920   u8 *tap_name;
6921   u32 sw_if_index = ~0;
6922   u8 sw_if_index_set = 0;
6923   int ret;
6924
6925   memset (mac_address, 0, sizeof (mac_address));
6926
6927   /* Parse args required to build the message */
6928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6929     {
6930       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6931         sw_if_index_set = 1;
6932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6933         sw_if_index_set = 1;
6934       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6935         {
6936           random_mac = 0;
6937         }
6938       else if (unformat (i, "random-mac"))
6939         random_mac = 1;
6940       else if (unformat (i, "tapname %s", &tap_name))
6941         name_set = 1;
6942       else
6943         break;
6944     }
6945
6946   if (sw_if_index_set == 0)
6947     {
6948       errmsg ("missing vpp interface name");
6949       return -99;
6950     }
6951   if (name_set == 0)
6952     {
6953       errmsg ("missing tap name");
6954       return -99;
6955     }
6956   if (vec_len (tap_name) > 63)
6957     {
6958       errmsg ("tap name too long");
6959     }
6960   vec_add1 (tap_name, 0);
6961
6962   /* Construct the API message */
6963   M (TAP_MODIFY, mp);
6964
6965   mp->use_random_mac = random_mac;
6966   mp->sw_if_index = ntohl (sw_if_index);
6967   clib_memcpy (mp->mac_address, mac_address, 6);
6968   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6969   vec_free (tap_name);
6970
6971   /* send it... */
6972   S (mp);
6973
6974   /* Wait for a reply... */
6975   W (ret);
6976   return ret;
6977 }
6978
6979 static int
6980 api_tap_delete (vat_main_t * vam)
6981 {
6982   unformat_input_t *i = vam->input;
6983   vl_api_tap_delete_t *mp;
6984   u32 sw_if_index = ~0;
6985   u8 sw_if_index_set = 0;
6986   int ret;
6987
6988   /* Parse args required to build the message */
6989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6990     {
6991       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6992         sw_if_index_set = 1;
6993       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6994         sw_if_index_set = 1;
6995       else
6996         break;
6997     }
6998
6999   if (sw_if_index_set == 0)
7000     {
7001       errmsg ("missing vpp interface name");
7002       return -99;
7003     }
7004
7005   /* Construct the API message */
7006   M (TAP_DELETE, mp);
7007
7008   mp->sw_if_index = ntohl (sw_if_index);
7009
7010   /* send it... */
7011   S (mp);
7012
7013   /* Wait for a reply... */
7014   W (ret);
7015   return ret;
7016 }
7017
7018 static int
7019 api_ip_add_del_route (vat_main_t * vam)
7020 {
7021   unformat_input_t *i = vam->input;
7022   vl_api_ip_add_del_route_t *mp;
7023   u32 sw_if_index = ~0, vrf_id = 0;
7024   u8 is_ipv6 = 0;
7025   u8 is_local = 0, is_drop = 0;
7026   u8 is_unreach = 0, is_prohibit = 0;
7027   u8 create_vrf_if_needed = 0;
7028   u8 is_add = 1;
7029   u32 next_hop_weight = 1;
7030   u8 not_last = 0;
7031   u8 is_multipath = 0;
7032   u8 address_set = 0;
7033   u8 address_length_set = 0;
7034   u32 next_hop_table_id = 0;
7035   u32 resolve_attempts = 0;
7036   u32 dst_address_length = 0;
7037   u8 next_hop_set = 0;
7038   ip4_address_t v4_dst_address, v4_next_hop_address;
7039   ip6_address_t v6_dst_address, v6_next_hop_address;
7040   int count = 1;
7041   int j;
7042   f64 before = 0;
7043   u32 random_add_del = 0;
7044   u32 *random_vector = 0;
7045   uword *random_hash;
7046   u32 random_seed = 0xdeaddabe;
7047   u32 classify_table_index = ~0;
7048   u8 is_classify = 0;
7049   u8 resolve_host = 0, resolve_attached = 0;
7050   mpls_label_t *next_hop_out_label_stack = NULL;
7051   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7052   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7053
7054   /* Parse args required to build the message */
7055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7056     {
7057       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7058         ;
7059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7060         ;
7061       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7062         {
7063           address_set = 1;
7064           is_ipv6 = 0;
7065         }
7066       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7067         {
7068           address_set = 1;
7069           is_ipv6 = 1;
7070         }
7071       else if (unformat (i, "/%d", &dst_address_length))
7072         {
7073           address_length_set = 1;
7074         }
7075
7076       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7077                                          &v4_next_hop_address))
7078         {
7079           next_hop_set = 1;
7080         }
7081       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7082                                          &v6_next_hop_address))
7083         {
7084           next_hop_set = 1;
7085         }
7086       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7087         ;
7088       else if (unformat (i, "weight %d", &next_hop_weight))
7089         ;
7090       else if (unformat (i, "drop"))
7091         {
7092           is_drop = 1;
7093         }
7094       else if (unformat (i, "null-send-unreach"))
7095         {
7096           is_unreach = 1;
7097         }
7098       else if (unformat (i, "null-send-prohibit"))
7099         {
7100           is_prohibit = 1;
7101         }
7102       else if (unformat (i, "local"))
7103         {
7104           is_local = 1;
7105         }
7106       else if (unformat (i, "classify %d", &classify_table_index))
7107         {
7108           is_classify = 1;
7109         }
7110       else if (unformat (i, "del"))
7111         is_add = 0;
7112       else if (unformat (i, "add"))
7113         is_add = 1;
7114       else if (unformat (i, "not-last"))
7115         not_last = 1;
7116       else if (unformat (i, "resolve-via-host"))
7117         resolve_host = 1;
7118       else if (unformat (i, "resolve-via-attached"))
7119         resolve_attached = 1;
7120       else if (unformat (i, "multipath"))
7121         is_multipath = 1;
7122       else if (unformat (i, "vrf %d", &vrf_id))
7123         ;
7124       else if (unformat (i, "create-vrf"))
7125         create_vrf_if_needed = 1;
7126       else if (unformat (i, "count %d", &count))
7127         ;
7128       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7129         ;
7130       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7131         ;
7132       else if (unformat (i, "out-label %d", &next_hop_out_label))
7133         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7134       else if (unformat (i, "via-label %d", &next_hop_via_label))
7135         ;
7136       else if (unformat (i, "random"))
7137         random_add_del = 1;
7138       else if (unformat (i, "seed %d", &random_seed))
7139         ;
7140       else
7141         {
7142           clib_warning ("parse error '%U'", format_unformat_error, i);
7143           return -99;
7144         }
7145     }
7146
7147   if (!next_hop_set && !is_drop && !is_local &&
7148       !is_classify && !is_unreach && !is_prohibit &&
7149       MPLS_LABEL_INVALID == next_hop_via_label)
7150     {
7151       errmsg
7152         ("next hop / local / drop / unreach / prohibit / classify not set");
7153       return -99;
7154     }
7155
7156   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7157     {
7158       errmsg ("next hop and next-hop via label set");
7159       return -99;
7160     }
7161   if (address_set == 0)
7162     {
7163       errmsg ("missing addresses");
7164       return -99;
7165     }
7166
7167   if (address_length_set == 0)
7168     {
7169       errmsg ("missing address length");
7170       return -99;
7171     }
7172
7173   /* Generate a pile of unique, random routes */
7174   if (random_add_del)
7175     {
7176       u32 this_random_address;
7177       random_hash = hash_create (count, sizeof (uword));
7178
7179       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7180       for (j = 0; j <= count; j++)
7181         {
7182           do
7183             {
7184               this_random_address = random_u32 (&random_seed);
7185               this_random_address =
7186                 clib_host_to_net_u32 (this_random_address);
7187             }
7188           while (hash_get (random_hash, this_random_address));
7189           vec_add1 (random_vector, this_random_address);
7190           hash_set (random_hash, this_random_address, 1);
7191         }
7192       hash_free (random_hash);
7193       v4_dst_address.as_u32 = random_vector[0];
7194     }
7195
7196   if (count > 1)
7197     {
7198       /* Turn on async mode */
7199       vam->async_mode = 1;
7200       vam->async_errors = 0;
7201       before = vat_time_now (vam);
7202     }
7203
7204   for (j = 0; j < count; j++)
7205     {
7206       /* Construct the API message */
7207       M2 (IP_ADD_DEL_ROUTE, mp,
7208           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7209
7210       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7211       mp->table_id = ntohl (vrf_id);
7212       mp->create_vrf_if_needed = create_vrf_if_needed;
7213
7214       mp->is_add = is_add;
7215       mp->is_drop = is_drop;
7216       mp->is_unreach = is_unreach;
7217       mp->is_prohibit = is_prohibit;
7218       mp->is_ipv6 = is_ipv6;
7219       mp->is_local = is_local;
7220       mp->is_classify = is_classify;
7221       mp->is_multipath = is_multipath;
7222       mp->is_resolve_host = resolve_host;
7223       mp->is_resolve_attached = resolve_attached;
7224       mp->not_last = not_last;
7225       mp->next_hop_weight = next_hop_weight;
7226       mp->dst_address_length = dst_address_length;
7227       mp->next_hop_table_id = ntohl (next_hop_table_id);
7228       mp->classify_table_index = ntohl (classify_table_index);
7229       mp->next_hop_via_label = ntohl (next_hop_via_label);
7230       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7231       if (0 != mp->next_hop_n_out_labels)
7232         {
7233           memcpy (mp->next_hop_out_label_stack,
7234                   next_hop_out_label_stack,
7235                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7236           vec_free (next_hop_out_label_stack);
7237         }
7238
7239       if (is_ipv6)
7240         {
7241           clib_memcpy (mp->dst_address, &v6_dst_address,
7242                        sizeof (v6_dst_address));
7243           if (next_hop_set)
7244             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7245                          sizeof (v6_next_hop_address));
7246           increment_v6_address (&v6_dst_address);
7247         }
7248       else
7249         {
7250           clib_memcpy (mp->dst_address, &v4_dst_address,
7251                        sizeof (v4_dst_address));
7252           if (next_hop_set)
7253             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7254                          sizeof (v4_next_hop_address));
7255           if (random_add_del)
7256             v4_dst_address.as_u32 = random_vector[j + 1];
7257           else
7258             increment_v4_address (&v4_dst_address);
7259         }
7260       /* send it... */
7261       S (mp);
7262       /* If we receive SIGTERM, stop now... */
7263       if (vam->do_exit)
7264         break;
7265     }
7266
7267   /* When testing multiple add/del ops, use a control-ping to sync */
7268   if (count > 1)
7269     {
7270       vl_api_control_ping_t *mp_ping;
7271       f64 after;
7272       f64 timeout;
7273
7274       /* Shut off async mode */
7275       vam->async_mode = 0;
7276
7277       M (CONTROL_PING, mp_ping);
7278       S (mp_ping);
7279
7280       timeout = vat_time_now (vam) + 1.0;
7281       while (vat_time_now (vam) < timeout)
7282         if (vam->result_ready == 1)
7283           goto out;
7284       vam->retval = -99;
7285
7286     out:
7287       if (vam->retval == -99)
7288         errmsg ("timeout");
7289
7290       if (vam->async_errors > 0)
7291         {
7292           errmsg ("%d asynchronous errors", vam->async_errors);
7293           vam->retval = -98;
7294         }
7295       vam->async_errors = 0;
7296       after = vat_time_now (vam);
7297
7298       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7299       if (j > 0)
7300         count = j;
7301
7302       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7303              count, after - before, count / (after - before));
7304     }
7305   else
7306     {
7307       int ret;
7308
7309       /* Wait for a reply... */
7310       W (ret);
7311       return ret;
7312     }
7313
7314   /* Return the good/bad news */
7315   return (vam->retval);
7316 }
7317
7318 static int
7319 api_ip_mroute_add_del (vat_main_t * vam)
7320 {
7321   unformat_input_t *i = vam->input;
7322   vl_api_ip_mroute_add_del_t *mp;
7323   u32 sw_if_index = ~0, vrf_id = 0;
7324   u8 is_ipv6 = 0;
7325   u8 is_local = 0;
7326   u8 create_vrf_if_needed = 0;
7327   u8 is_add = 1;
7328   u8 address_set = 0;
7329   u32 grp_address_length = 0;
7330   ip4_address_t v4_grp_address, v4_src_address;
7331   ip6_address_t v6_grp_address, v6_src_address;
7332   mfib_itf_flags_t iflags = 0;
7333   mfib_entry_flags_t eflags = 0;
7334   int ret;
7335
7336   /* Parse args required to build the message */
7337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7338     {
7339       if (unformat (i, "sw_if_index %d", &sw_if_index))
7340         ;
7341       else if (unformat (i, "%U %U",
7342                          unformat_ip4_address, &v4_src_address,
7343                          unformat_ip4_address, &v4_grp_address))
7344         {
7345           grp_address_length = 64;
7346           address_set = 1;
7347           is_ipv6 = 0;
7348         }
7349       else if (unformat (i, "%U %U",
7350                          unformat_ip6_address, &v6_src_address,
7351                          unformat_ip6_address, &v6_grp_address))
7352         {
7353           grp_address_length = 256;
7354           address_set = 1;
7355           is_ipv6 = 1;
7356         }
7357       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7358         {
7359           memset (&v4_src_address, 0, sizeof (v4_src_address));
7360           grp_address_length = 32;
7361           address_set = 1;
7362           is_ipv6 = 0;
7363         }
7364       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7365         {
7366           memset (&v6_src_address, 0, sizeof (v6_src_address));
7367           grp_address_length = 128;
7368           address_set = 1;
7369           is_ipv6 = 1;
7370         }
7371       else if (unformat (i, "/%d", &grp_address_length))
7372         ;
7373       else if (unformat (i, "local"))
7374         {
7375           is_local = 1;
7376         }
7377       else if (unformat (i, "del"))
7378         is_add = 0;
7379       else if (unformat (i, "add"))
7380         is_add = 1;
7381       else if (unformat (i, "vrf %d", &vrf_id))
7382         ;
7383       else if (unformat (i, "create-vrf"))
7384         create_vrf_if_needed = 1;
7385       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7386         ;
7387       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7388         ;
7389       else
7390         {
7391           clib_warning ("parse error '%U'", format_unformat_error, i);
7392           return -99;
7393         }
7394     }
7395
7396   if (address_set == 0)
7397     {
7398       errmsg ("missing addresses\n");
7399       return -99;
7400     }
7401
7402   /* Construct the API message */
7403   M (IP_MROUTE_ADD_DEL, mp);
7404
7405   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7406   mp->table_id = ntohl (vrf_id);
7407   mp->create_vrf_if_needed = create_vrf_if_needed;
7408
7409   mp->is_add = is_add;
7410   mp->is_ipv6 = is_ipv6;
7411   mp->is_local = is_local;
7412   mp->itf_flags = ntohl (iflags);
7413   mp->entry_flags = ntohl (eflags);
7414   mp->grp_address_length = grp_address_length;
7415   mp->grp_address_length = ntohs (mp->grp_address_length);
7416
7417   if (is_ipv6)
7418     {
7419       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7420       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7421     }
7422   else
7423     {
7424       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7425       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7426
7427     }
7428
7429   /* send it... */
7430   S (mp);
7431   /* Wait for a reply... */
7432   W (ret);
7433   return ret;
7434 }
7435
7436 static int
7437 api_mpls_route_add_del (vat_main_t * vam)
7438 {
7439   unformat_input_t *i = vam->input;
7440   vl_api_mpls_route_add_del_t *mp;
7441   u32 sw_if_index = ~0, table_id = 0;
7442   u8 create_table_if_needed = 0;
7443   u8 is_add = 1;
7444   u32 next_hop_weight = 1;
7445   u8 is_multipath = 0;
7446   u32 next_hop_table_id = 0;
7447   u8 next_hop_set = 0;
7448   ip4_address_t v4_next_hop_address = {
7449     .as_u32 = 0,
7450   };
7451   ip6_address_t v6_next_hop_address = { {0} };
7452   int count = 1;
7453   int j;
7454   f64 before = 0;
7455   u32 classify_table_index = ~0;
7456   u8 is_classify = 0;
7457   u8 resolve_host = 0, resolve_attached = 0;
7458   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7459   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7460   mpls_label_t *next_hop_out_label_stack = NULL;
7461   mpls_label_t local_label = MPLS_LABEL_INVALID;
7462   u8 is_eos = 0;
7463   u8 next_hop_proto_is_ip4 = 1;
7464
7465   /* Parse args required to build the message */
7466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7467     {
7468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7469         ;
7470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7471         ;
7472       else if (unformat (i, "%d", &local_label))
7473         ;
7474       else if (unformat (i, "eos"))
7475         is_eos = 1;
7476       else if (unformat (i, "non-eos"))
7477         is_eos = 0;
7478       else if (unformat (i, "via %U", unformat_ip4_address,
7479                          &v4_next_hop_address))
7480         {
7481           next_hop_set = 1;
7482           next_hop_proto_is_ip4 = 1;
7483         }
7484       else if (unformat (i, "via %U", unformat_ip6_address,
7485                          &v6_next_hop_address))
7486         {
7487           next_hop_set = 1;
7488           next_hop_proto_is_ip4 = 0;
7489         }
7490       else if (unformat (i, "weight %d", &next_hop_weight))
7491         ;
7492       else if (unformat (i, "create-table"))
7493         create_table_if_needed = 1;
7494       else if (unformat (i, "classify %d", &classify_table_index))
7495         {
7496           is_classify = 1;
7497         }
7498       else if (unformat (i, "del"))
7499         is_add = 0;
7500       else if (unformat (i, "add"))
7501         is_add = 1;
7502       else if (unformat (i, "resolve-via-host"))
7503         resolve_host = 1;
7504       else if (unformat (i, "resolve-via-attached"))
7505         resolve_attached = 1;
7506       else if (unformat (i, "multipath"))
7507         is_multipath = 1;
7508       else if (unformat (i, "count %d", &count))
7509         ;
7510       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7511         {
7512           next_hop_set = 1;
7513           next_hop_proto_is_ip4 = 1;
7514         }
7515       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7516         {
7517           next_hop_set = 1;
7518           next_hop_proto_is_ip4 = 0;
7519         }
7520       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7521         ;
7522       else if (unformat (i, "via-label %d", &next_hop_via_label))
7523         ;
7524       else if (unformat (i, "out-label %d", &next_hop_out_label))
7525         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7526       else
7527         {
7528           clib_warning ("parse error '%U'", format_unformat_error, i);
7529           return -99;
7530         }
7531     }
7532
7533   if (!next_hop_set && !is_classify)
7534     {
7535       errmsg ("next hop / classify not set");
7536       return -99;
7537     }
7538
7539   if (MPLS_LABEL_INVALID == local_label)
7540     {
7541       errmsg ("missing label");
7542       return -99;
7543     }
7544
7545   if (count > 1)
7546     {
7547       /* Turn on async mode */
7548       vam->async_mode = 1;
7549       vam->async_errors = 0;
7550       before = vat_time_now (vam);
7551     }
7552
7553   for (j = 0; j < count; j++)
7554     {
7555       /* Construct the API message */
7556       M2 (MPLS_ROUTE_ADD_DEL, mp,
7557           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7558
7559       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7560       mp->mr_table_id = ntohl (table_id);
7561       mp->mr_create_table_if_needed = create_table_if_needed;
7562
7563       mp->mr_is_add = is_add;
7564       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7565       mp->mr_is_classify = is_classify;
7566       mp->mr_is_multipath = is_multipath;
7567       mp->mr_is_resolve_host = resolve_host;
7568       mp->mr_is_resolve_attached = resolve_attached;
7569       mp->mr_next_hop_weight = next_hop_weight;
7570       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7571       mp->mr_classify_table_index = ntohl (classify_table_index);
7572       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7573       mp->mr_label = ntohl (local_label);
7574       mp->mr_eos = is_eos;
7575
7576       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7577       if (0 != mp->mr_next_hop_n_out_labels)
7578         {
7579           memcpy (mp->mr_next_hop_out_label_stack,
7580                   next_hop_out_label_stack,
7581                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7582           vec_free (next_hop_out_label_stack);
7583         }
7584
7585       if (next_hop_set)
7586         {
7587           if (next_hop_proto_is_ip4)
7588             {
7589               clib_memcpy (mp->mr_next_hop,
7590                            &v4_next_hop_address,
7591                            sizeof (v4_next_hop_address));
7592             }
7593           else
7594             {
7595               clib_memcpy (mp->mr_next_hop,
7596                            &v6_next_hop_address,
7597                            sizeof (v6_next_hop_address));
7598             }
7599         }
7600       local_label++;
7601
7602       /* send it... */
7603       S (mp);
7604       /* If we receive SIGTERM, stop now... */
7605       if (vam->do_exit)
7606         break;
7607     }
7608
7609   /* When testing multiple add/del ops, use a control-ping to sync */
7610   if (count > 1)
7611     {
7612       vl_api_control_ping_t *mp_ping;
7613       f64 after;
7614       f64 timeout;
7615
7616       /* Shut off async mode */
7617       vam->async_mode = 0;
7618
7619       M (CONTROL_PING, mp_ping);
7620       S (mp_ping);
7621
7622       timeout = vat_time_now (vam) + 1.0;
7623       while (vat_time_now (vam) < timeout)
7624         if (vam->result_ready == 1)
7625           goto out;
7626       vam->retval = -99;
7627
7628     out:
7629       if (vam->retval == -99)
7630         errmsg ("timeout");
7631
7632       if (vam->async_errors > 0)
7633         {
7634           errmsg ("%d asynchronous errors", vam->async_errors);
7635           vam->retval = -98;
7636         }
7637       vam->async_errors = 0;
7638       after = vat_time_now (vam);
7639
7640       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7641       if (j > 0)
7642         count = j;
7643
7644       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7645              count, after - before, count / (after - before));
7646     }
7647   else
7648     {
7649       int ret;
7650
7651       /* Wait for a reply... */
7652       W (ret);
7653       return ret;
7654     }
7655
7656   /* Return the good/bad news */
7657   return (vam->retval);
7658 }
7659
7660 static int
7661 api_mpls_ip_bind_unbind (vat_main_t * vam)
7662 {
7663   unformat_input_t *i = vam->input;
7664   vl_api_mpls_ip_bind_unbind_t *mp;
7665   u32 ip_table_id = 0;
7666   u8 create_table_if_needed = 0;
7667   u8 is_bind = 1;
7668   u8 is_ip4 = 1;
7669   ip4_address_t v4_address;
7670   ip6_address_t v6_address;
7671   u32 address_length;
7672   u8 address_set = 0;
7673   mpls_label_t local_label = MPLS_LABEL_INVALID;
7674   int ret;
7675
7676   /* Parse args required to build the message */
7677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7678     {
7679       if (unformat (i, "%U/%d", unformat_ip4_address,
7680                     &v4_address, &address_length))
7681         {
7682           is_ip4 = 1;
7683           address_set = 1;
7684         }
7685       else if (unformat (i, "%U/%d", unformat_ip6_address,
7686                          &v6_address, &address_length))
7687         {
7688           is_ip4 = 0;
7689           address_set = 1;
7690         }
7691       else if (unformat (i, "%d", &local_label))
7692         ;
7693       else if (unformat (i, "create-table"))
7694         create_table_if_needed = 1;
7695       else if (unformat (i, "table-id %d", &ip_table_id))
7696         ;
7697       else if (unformat (i, "unbind"))
7698         is_bind = 0;
7699       else if (unformat (i, "bind"))
7700         is_bind = 1;
7701       else
7702         {
7703           clib_warning ("parse error '%U'", format_unformat_error, i);
7704           return -99;
7705         }
7706     }
7707
7708   if (!address_set)
7709     {
7710       errmsg ("IP addres not set");
7711       return -99;
7712     }
7713
7714   if (MPLS_LABEL_INVALID == local_label)
7715     {
7716       errmsg ("missing label");
7717       return -99;
7718     }
7719
7720   /* Construct the API message */
7721   M (MPLS_IP_BIND_UNBIND, mp);
7722
7723   mp->mb_create_table_if_needed = create_table_if_needed;
7724   mp->mb_is_bind = is_bind;
7725   mp->mb_is_ip4 = is_ip4;
7726   mp->mb_ip_table_id = ntohl (ip_table_id);
7727   mp->mb_mpls_table_id = 0;
7728   mp->mb_label = ntohl (local_label);
7729   mp->mb_address_length = address_length;
7730
7731   if (is_ip4)
7732     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7733   else
7734     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7735
7736   /* send it... */
7737   S (mp);
7738
7739   /* Wait for a reply... */
7740   W (ret);
7741   return ret;
7742 }
7743
7744 static int
7745 api_proxy_arp_add_del (vat_main_t * vam)
7746 {
7747   unformat_input_t *i = vam->input;
7748   vl_api_proxy_arp_add_del_t *mp;
7749   u32 vrf_id = 0;
7750   u8 is_add = 1;
7751   ip4_address_t lo, hi;
7752   u8 range_set = 0;
7753   int ret;
7754
7755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7756     {
7757       if (unformat (i, "vrf %d", &vrf_id))
7758         ;
7759       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7760                          unformat_ip4_address, &hi))
7761         range_set = 1;
7762       else if (unformat (i, "del"))
7763         is_add = 0;
7764       else
7765         {
7766           clib_warning ("parse error '%U'", format_unformat_error, i);
7767           return -99;
7768         }
7769     }
7770
7771   if (range_set == 0)
7772     {
7773       errmsg ("address range not set");
7774       return -99;
7775     }
7776
7777   M (PROXY_ARP_ADD_DEL, mp);
7778
7779   mp->vrf_id = ntohl (vrf_id);
7780   mp->is_add = is_add;
7781   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7782   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7783
7784   S (mp);
7785   W (ret);
7786   return ret;
7787 }
7788
7789 static int
7790 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7791 {
7792   unformat_input_t *i = vam->input;
7793   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7794   u32 sw_if_index;
7795   u8 enable = 1;
7796   u8 sw_if_index_set = 0;
7797   int ret;
7798
7799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7800     {
7801       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7802         sw_if_index_set = 1;
7803       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7804         sw_if_index_set = 1;
7805       else if (unformat (i, "enable"))
7806         enable = 1;
7807       else if (unformat (i, "disable"))
7808         enable = 0;
7809       else
7810         {
7811           clib_warning ("parse error '%U'", format_unformat_error, i);
7812           return -99;
7813         }
7814     }
7815
7816   if (sw_if_index_set == 0)
7817     {
7818       errmsg ("missing interface name or sw_if_index");
7819       return -99;
7820     }
7821
7822   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7823
7824   mp->sw_if_index = ntohl (sw_if_index);
7825   mp->enable_disable = enable;
7826
7827   S (mp);
7828   W (ret);
7829   return ret;
7830 }
7831
7832 static int
7833 api_mpls_tunnel_add_del (vat_main_t * vam)
7834 {
7835   unformat_input_t *i = vam->input;
7836   vl_api_mpls_tunnel_add_del_t *mp;
7837
7838   u8 is_add = 1;
7839   u8 l2_only = 0;
7840   u32 sw_if_index = ~0;
7841   u32 next_hop_sw_if_index = ~0;
7842   u32 next_hop_proto_is_ip4 = 1;
7843
7844   u32 next_hop_table_id = 0;
7845   ip4_address_t v4_next_hop_address = {
7846     .as_u32 = 0,
7847   };
7848   ip6_address_t v6_next_hop_address = { {0} };
7849   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7850   int ret;
7851
7852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7853     {
7854       if (unformat (i, "add"))
7855         is_add = 1;
7856       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7857         is_add = 0;
7858       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7859         ;
7860       else if (unformat (i, "via %U",
7861                          unformat_ip4_address, &v4_next_hop_address))
7862         {
7863           next_hop_proto_is_ip4 = 1;
7864         }
7865       else if (unformat (i, "via %U",
7866                          unformat_ip6_address, &v6_next_hop_address))
7867         {
7868           next_hop_proto_is_ip4 = 0;
7869         }
7870       else if (unformat (i, "l2-only"))
7871         l2_only = 1;
7872       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7873         ;
7874       else if (unformat (i, "out-label %d", &next_hop_out_label))
7875         vec_add1 (labels, ntohl (next_hop_out_label));
7876       else
7877         {
7878           clib_warning ("parse error '%U'", format_unformat_error, i);
7879           return -99;
7880         }
7881     }
7882
7883   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7884
7885   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7886   mp->mt_sw_if_index = ntohl (sw_if_index);
7887   mp->mt_is_add = is_add;
7888   mp->mt_l2_only = l2_only;
7889   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7890   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7891
7892   mp->mt_next_hop_n_out_labels = vec_len (labels);
7893
7894   if (0 != mp->mt_next_hop_n_out_labels)
7895     {
7896       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7897                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7898       vec_free (labels);
7899     }
7900
7901   if (next_hop_proto_is_ip4)
7902     {
7903       clib_memcpy (mp->mt_next_hop,
7904                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7905     }
7906   else
7907     {
7908       clib_memcpy (mp->mt_next_hop,
7909                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7910     }
7911
7912   S (mp);
7913   W (ret);
7914   return ret;
7915 }
7916
7917 static int
7918 api_sw_interface_set_unnumbered (vat_main_t * vam)
7919 {
7920   unformat_input_t *i = vam->input;
7921   vl_api_sw_interface_set_unnumbered_t *mp;
7922   u32 sw_if_index;
7923   u32 unnum_sw_index = ~0;
7924   u8 is_add = 1;
7925   u8 sw_if_index_set = 0;
7926   int ret;
7927
7928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7929     {
7930       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7931         sw_if_index_set = 1;
7932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7933         sw_if_index_set = 1;
7934       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7935         ;
7936       else if (unformat (i, "del"))
7937         is_add = 0;
7938       else
7939         {
7940           clib_warning ("parse error '%U'", format_unformat_error, i);
7941           return -99;
7942         }
7943     }
7944
7945   if (sw_if_index_set == 0)
7946     {
7947       errmsg ("missing interface name or sw_if_index");
7948       return -99;
7949     }
7950
7951   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7952
7953   mp->sw_if_index = ntohl (sw_if_index);
7954   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7955   mp->is_add = is_add;
7956
7957   S (mp);
7958   W (ret);
7959   return ret;
7960 }
7961
7962 static int
7963 api_ip_neighbor_add_del (vat_main_t * vam)
7964 {
7965   unformat_input_t *i = vam->input;
7966   vl_api_ip_neighbor_add_del_t *mp;
7967   u32 sw_if_index;
7968   u8 sw_if_index_set = 0;
7969   u8 is_add = 1;
7970   u8 is_static = 0;
7971   u8 is_no_fib_entry = 0;
7972   u8 mac_address[6];
7973   u8 mac_set = 0;
7974   u8 v4_address_set = 0;
7975   u8 v6_address_set = 0;
7976   ip4_address_t v4address;
7977   ip6_address_t v6address;
7978   int ret;
7979
7980   memset (mac_address, 0, sizeof (mac_address));
7981
7982   /* Parse args required to build the message */
7983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7984     {
7985       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7986         {
7987           mac_set = 1;
7988         }
7989       else if (unformat (i, "del"))
7990         is_add = 0;
7991       else
7992         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7993         sw_if_index_set = 1;
7994       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7995         sw_if_index_set = 1;
7996       else if (unformat (i, "is_static"))
7997         is_static = 1;
7998       else if (unformat (i, "no-fib-entry"))
7999         is_no_fib_entry = 1;
8000       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8001         v4_address_set = 1;
8002       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8003         v6_address_set = 1;
8004       else
8005         {
8006           clib_warning ("parse error '%U'", format_unformat_error, i);
8007           return -99;
8008         }
8009     }
8010
8011   if (sw_if_index_set == 0)
8012     {
8013       errmsg ("missing interface name or sw_if_index");
8014       return -99;
8015     }
8016   if (v4_address_set && v6_address_set)
8017     {
8018       errmsg ("both v4 and v6 addresses set");
8019       return -99;
8020     }
8021   if (!v4_address_set && !v6_address_set)
8022     {
8023       errmsg ("no address set");
8024       return -99;
8025     }
8026
8027   /* Construct the API message */
8028   M (IP_NEIGHBOR_ADD_DEL, mp);
8029
8030   mp->sw_if_index = ntohl (sw_if_index);
8031   mp->is_add = is_add;
8032   mp->is_static = is_static;
8033   mp->is_no_adj_fib = is_no_fib_entry;
8034   if (mac_set)
8035     clib_memcpy (mp->mac_address, mac_address, 6);
8036   if (v6_address_set)
8037     {
8038       mp->is_ipv6 = 1;
8039       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8040     }
8041   else
8042     {
8043       /* mp->is_ipv6 = 0; via memset in M macro above */
8044       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8045     }
8046
8047   /* send it... */
8048   S (mp);
8049
8050   /* Wait for a reply, return good/bad news  */
8051   W (ret);
8052   return ret;
8053 }
8054
8055 static int
8056 api_reset_vrf (vat_main_t * vam)
8057 {
8058   unformat_input_t *i = vam->input;
8059   vl_api_reset_vrf_t *mp;
8060   u32 vrf_id = 0;
8061   u8 is_ipv6 = 0;
8062   u8 vrf_id_set = 0;
8063   int ret;
8064
8065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8066     {
8067       if (unformat (i, "vrf %d", &vrf_id))
8068         vrf_id_set = 1;
8069       else if (unformat (i, "ipv6"))
8070         is_ipv6 = 1;
8071       else
8072         {
8073           clib_warning ("parse error '%U'", format_unformat_error, i);
8074           return -99;
8075         }
8076     }
8077
8078   if (vrf_id_set == 0)
8079     {
8080       errmsg ("missing vrf id");
8081       return -99;
8082     }
8083
8084   M (RESET_VRF, mp);
8085
8086   mp->vrf_id = ntohl (vrf_id);
8087   mp->is_ipv6 = is_ipv6;
8088
8089   S (mp);
8090   W (ret);
8091   return ret;
8092 }
8093
8094 static int
8095 api_create_vlan_subif (vat_main_t * vam)
8096 {
8097   unformat_input_t *i = vam->input;
8098   vl_api_create_vlan_subif_t *mp;
8099   u32 sw_if_index;
8100   u8 sw_if_index_set = 0;
8101   u32 vlan_id;
8102   u8 vlan_id_set = 0;
8103   int ret;
8104
8105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8106     {
8107       if (unformat (i, "sw_if_index %d", &sw_if_index))
8108         sw_if_index_set = 1;
8109       else
8110         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8111         sw_if_index_set = 1;
8112       else if (unformat (i, "vlan %d", &vlan_id))
8113         vlan_id_set = 1;
8114       else
8115         {
8116           clib_warning ("parse error '%U'", format_unformat_error, i);
8117           return -99;
8118         }
8119     }
8120
8121   if (sw_if_index_set == 0)
8122     {
8123       errmsg ("missing interface name or sw_if_index");
8124       return -99;
8125     }
8126
8127   if (vlan_id_set == 0)
8128     {
8129       errmsg ("missing vlan_id");
8130       return -99;
8131     }
8132   M (CREATE_VLAN_SUBIF, mp);
8133
8134   mp->sw_if_index = ntohl (sw_if_index);
8135   mp->vlan_id = ntohl (vlan_id);
8136
8137   S (mp);
8138   W (ret);
8139   return ret;
8140 }
8141
8142 #define foreach_create_subif_bit                \
8143 _(no_tags)                                      \
8144 _(one_tag)                                      \
8145 _(two_tags)                                     \
8146 _(dot1ad)                                       \
8147 _(exact_match)                                  \
8148 _(default_sub)                                  \
8149 _(outer_vlan_id_any)                            \
8150 _(inner_vlan_id_any)
8151
8152 static int
8153 api_create_subif (vat_main_t * vam)
8154 {
8155   unformat_input_t *i = vam->input;
8156   vl_api_create_subif_t *mp;
8157   u32 sw_if_index;
8158   u8 sw_if_index_set = 0;
8159   u32 sub_id;
8160   u8 sub_id_set = 0;
8161   u32 no_tags = 0;
8162   u32 one_tag = 0;
8163   u32 two_tags = 0;
8164   u32 dot1ad = 0;
8165   u32 exact_match = 0;
8166   u32 default_sub = 0;
8167   u32 outer_vlan_id_any = 0;
8168   u32 inner_vlan_id_any = 0;
8169   u32 tmp;
8170   u16 outer_vlan_id = 0;
8171   u16 inner_vlan_id = 0;
8172   int ret;
8173
8174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8175     {
8176       if (unformat (i, "sw_if_index %d", &sw_if_index))
8177         sw_if_index_set = 1;
8178       else
8179         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8180         sw_if_index_set = 1;
8181       else if (unformat (i, "sub_id %d", &sub_id))
8182         sub_id_set = 1;
8183       else if (unformat (i, "outer_vlan_id %d", &tmp))
8184         outer_vlan_id = tmp;
8185       else if (unformat (i, "inner_vlan_id %d", &tmp))
8186         inner_vlan_id = tmp;
8187
8188 #define _(a) else if (unformat (i, #a)) a = 1 ;
8189       foreach_create_subif_bit
8190 #undef _
8191         else
8192         {
8193           clib_warning ("parse error '%U'", format_unformat_error, i);
8194           return -99;
8195         }
8196     }
8197
8198   if (sw_if_index_set == 0)
8199     {
8200       errmsg ("missing interface name or sw_if_index");
8201       return -99;
8202     }
8203
8204   if (sub_id_set == 0)
8205     {
8206       errmsg ("missing sub_id");
8207       return -99;
8208     }
8209   M (CREATE_SUBIF, mp);
8210
8211   mp->sw_if_index = ntohl (sw_if_index);
8212   mp->sub_id = ntohl (sub_id);
8213
8214 #define _(a) mp->a = a;
8215   foreach_create_subif_bit;
8216 #undef _
8217
8218   mp->outer_vlan_id = ntohs (outer_vlan_id);
8219   mp->inner_vlan_id = ntohs (inner_vlan_id);
8220
8221   S (mp);
8222   W (ret);
8223   return ret;
8224 }
8225
8226 static int
8227 api_oam_add_del (vat_main_t * vam)
8228 {
8229   unformat_input_t *i = vam->input;
8230   vl_api_oam_add_del_t *mp;
8231   u32 vrf_id = 0;
8232   u8 is_add = 1;
8233   ip4_address_t src, dst;
8234   u8 src_set = 0;
8235   u8 dst_set = 0;
8236   int ret;
8237
8238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8239     {
8240       if (unformat (i, "vrf %d", &vrf_id))
8241         ;
8242       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8243         src_set = 1;
8244       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8245         dst_set = 1;
8246       else if (unformat (i, "del"))
8247         is_add = 0;
8248       else
8249         {
8250           clib_warning ("parse error '%U'", format_unformat_error, i);
8251           return -99;
8252         }
8253     }
8254
8255   if (src_set == 0)
8256     {
8257       errmsg ("missing src addr");
8258       return -99;
8259     }
8260
8261   if (dst_set == 0)
8262     {
8263       errmsg ("missing dst addr");
8264       return -99;
8265     }
8266
8267   M (OAM_ADD_DEL, mp);
8268
8269   mp->vrf_id = ntohl (vrf_id);
8270   mp->is_add = is_add;
8271   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8272   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8273
8274   S (mp);
8275   W (ret);
8276   return ret;
8277 }
8278
8279 static int
8280 api_reset_fib (vat_main_t * vam)
8281 {
8282   unformat_input_t *i = vam->input;
8283   vl_api_reset_fib_t *mp;
8284   u32 vrf_id = 0;
8285   u8 is_ipv6 = 0;
8286   u8 vrf_id_set = 0;
8287
8288   int ret;
8289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8290     {
8291       if (unformat (i, "vrf %d", &vrf_id))
8292         vrf_id_set = 1;
8293       else if (unformat (i, "ipv6"))
8294         is_ipv6 = 1;
8295       else
8296         {
8297           clib_warning ("parse error '%U'", format_unformat_error, i);
8298           return -99;
8299         }
8300     }
8301
8302   if (vrf_id_set == 0)
8303     {
8304       errmsg ("missing vrf id");
8305       return -99;
8306     }
8307
8308   M (RESET_FIB, mp);
8309
8310   mp->vrf_id = ntohl (vrf_id);
8311   mp->is_ipv6 = is_ipv6;
8312
8313   S (mp);
8314   W (ret);
8315   return ret;
8316 }
8317
8318 static int
8319 api_dhcp_proxy_config (vat_main_t * vam)
8320 {
8321   unformat_input_t *i = vam->input;
8322   vl_api_dhcp_proxy_config_t *mp;
8323   u32 rx_vrf_id = 0;
8324   u32 server_vrf_id = 0;
8325   u8 is_add = 1;
8326   u8 v4_address_set = 0;
8327   u8 v6_address_set = 0;
8328   ip4_address_t v4address;
8329   ip6_address_t v6address;
8330   u8 v4_src_address_set = 0;
8331   u8 v6_src_address_set = 0;
8332   ip4_address_t v4srcaddress;
8333   ip6_address_t v6srcaddress;
8334   int ret;
8335
8336   /* Parse args required to build the message */
8337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8338     {
8339       if (unformat (i, "del"))
8340         is_add = 0;
8341       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8342         ;
8343       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8344         ;
8345       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8346         v4_address_set = 1;
8347       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8348         v6_address_set = 1;
8349       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8350         v4_src_address_set = 1;
8351       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8352         v6_src_address_set = 1;
8353       else
8354         break;
8355     }
8356
8357   if (v4_address_set && v6_address_set)
8358     {
8359       errmsg ("both v4 and v6 server addresses set");
8360       return -99;
8361     }
8362   if (!v4_address_set && !v6_address_set)
8363     {
8364       errmsg ("no server addresses set");
8365       return -99;
8366     }
8367
8368   if (v4_src_address_set && v6_src_address_set)
8369     {
8370       errmsg ("both v4 and v6  src addresses set");
8371       return -99;
8372     }
8373   if (!v4_src_address_set && !v6_src_address_set)
8374     {
8375       errmsg ("no src addresses set");
8376       return -99;
8377     }
8378
8379   if (!(v4_src_address_set && v4_address_set) &&
8380       !(v6_src_address_set && v6_address_set))
8381     {
8382       errmsg ("no matching server and src addresses set");
8383       return -99;
8384     }
8385
8386   /* Construct the API message */
8387   M (DHCP_PROXY_CONFIG, mp);
8388
8389   mp->is_add = is_add;
8390   mp->rx_vrf_id = ntohl (rx_vrf_id);
8391   mp->server_vrf_id = ntohl (server_vrf_id);
8392   if (v6_address_set)
8393     {
8394       mp->is_ipv6 = 1;
8395       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8396       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8397     }
8398   else
8399     {
8400       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8401       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8402     }
8403
8404   /* send it... */
8405   S (mp);
8406
8407   /* Wait for a reply, return good/bad news  */
8408   W (ret);
8409   return ret;
8410 }
8411
8412 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8413 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8414
8415 static void
8416 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8417 {
8418   vat_main_t *vam = &vat_main;
8419   u32 i, count = mp->count;
8420   vl_api_dhcp_server_t *s;
8421
8422   if (mp->is_ipv6)
8423     print (vam->ofp,
8424            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8425            ntohl (mp->rx_vrf_id),
8426            format_ip6_address, mp->dhcp_src_address,
8427            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8428   else
8429     print (vam->ofp,
8430            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8431            ntohl (mp->rx_vrf_id),
8432            format_ip4_address, mp->dhcp_src_address,
8433            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8434
8435   for (i = 0; i < count; i++)
8436     {
8437       s = &mp->servers[i];
8438
8439       if (mp->is_ipv6)
8440         print (vam->ofp,
8441                " Server Table-ID %d, Server Address %U",
8442                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8443       else
8444         print (vam->ofp,
8445                " Server Table-ID %d, Server Address %U",
8446                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8447     }
8448 }
8449
8450 static void vl_api_dhcp_proxy_details_t_handler_json
8451   (vl_api_dhcp_proxy_details_t * mp)
8452 {
8453   vat_main_t *vam = &vat_main;
8454   vat_json_node_t *node = NULL;
8455   u32 i, count = mp->count;
8456   struct in_addr ip4;
8457   struct in6_addr ip6;
8458   vl_api_dhcp_server_t *s;
8459
8460   if (VAT_JSON_ARRAY != vam->json_tree.type)
8461     {
8462       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8463       vat_json_init_array (&vam->json_tree);
8464     }
8465   node = vat_json_array_add (&vam->json_tree);
8466
8467   vat_json_init_object (node);
8468   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8469   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8470   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8471
8472   if (mp->is_ipv6)
8473     {
8474       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8475       vat_json_object_add_ip6 (node, "src_address", ip6);
8476     }
8477   else
8478     {
8479       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8480       vat_json_object_add_ip4 (node, "src_address", ip4);
8481     }
8482
8483   for (i = 0; i < count; i++)
8484     {
8485       s = &mp->servers[i];
8486
8487       vat_json_object_add_uint (node, "server-table-id",
8488                                 ntohl (s->server_vrf_id));
8489
8490       if (mp->is_ipv6)
8491         {
8492           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8493           vat_json_object_add_ip4 (node, "src_address", ip4);
8494         }
8495       else
8496         {
8497           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8498           vat_json_object_add_ip6 (node, "server_address", ip6);
8499         }
8500     }
8501 }
8502
8503 static int
8504 api_dhcp_proxy_dump (vat_main_t * vam)
8505 {
8506   unformat_input_t *i = vam->input;
8507   vl_api_control_ping_t *mp_ping;
8508   vl_api_dhcp_proxy_dump_t *mp;
8509   u8 is_ipv6 = 0;
8510   int ret;
8511
8512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8513     {
8514       if (unformat (i, "ipv6"))
8515         is_ipv6 = 1;
8516       else
8517         {
8518           clib_warning ("parse error '%U'", format_unformat_error, i);
8519           return -99;
8520         }
8521     }
8522
8523   M (DHCP_PROXY_DUMP, mp);
8524
8525   mp->is_ip6 = is_ipv6;
8526   S (mp);
8527
8528   /* Use a control ping for synchronization */
8529   M (CONTROL_PING, mp_ping);
8530   S (mp_ping);
8531
8532   W (ret);
8533   return ret;
8534 }
8535
8536 static int
8537 api_dhcp_proxy_set_vss (vat_main_t * vam)
8538 {
8539   unformat_input_t *i = vam->input;
8540   vl_api_dhcp_proxy_set_vss_t *mp;
8541   u8 is_ipv6 = 0;
8542   u8 is_add = 1;
8543   u32 tbl_id;
8544   u8 tbl_id_set = 0;
8545   u32 oui;
8546   u8 oui_set = 0;
8547   u32 fib_id;
8548   u8 fib_id_set = 0;
8549   int ret;
8550
8551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8552     {
8553       if (unformat (i, "tbl_id %d", &tbl_id))
8554         tbl_id_set = 1;
8555       if (unformat (i, "fib_id %d", &fib_id))
8556         fib_id_set = 1;
8557       if (unformat (i, "oui %d", &oui))
8558         oui_set = 1;
8559       else if (unformat (i, "ipv6"))
8560         is_ipv6 = 1;
8561       else if (unformat (i, "del"))
8562         is_add = 0;
8563       else
8564         {
8565           clib_warning ("parse error '%U'", format_unformat_error, i);
8566           return -99;
8567         }
8568     }
8569
8570   if (tbl_id_set == 0)
8571     {
8572       errmsg ("missing tbl id");
8573       return -99;
8574     }
8575
8576   if (fib_id_set == 0)
8577     {
8578       errmsg ("missing fib id");
8579       return -99;
8580     }
8581   if (oui_set == 0)
8582     {
8583       errmsg ("missing oui");
8584       return -99;
8585     }
8586
8587   M (DHCP_PROXY_SET_VSS, mp);
8588   mp->tbl_id = ntohl (tbl_id);
8589   mp->fib_id = ntohl (fib_id);
8590   mp->oui = ntohl (oui);
8591   mp->is_ipv6 = is_ipv6;
8592   mp->is_add = is_add;
8593
8594   S (mp);
8595   W (ret);
8596   return ret;
8597 }
8598
8599 static int
8600 api_dhcp_client_config (vat_main_t * vam)
8601 {
8602   unformat_input_t *i = vam->input;
8603   vl_api_dhcp_client_config_t *mp;
8604   u32 sw_if_index;
8605   u8 sw_if_index_set = 0;
8606   u8 is_add = 1;
8607   u8 *hostname = 0;
8608   u8 disable_event = 0;
8609   int ret;
8610
8611   /* Parse args required to build the message */
8612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8613     {
8614       if (unformat (i, "del"))
8615         is_add = 0;
8616       else
8617         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8618         sw_if_index_set = 1;
8619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8620         sw_if_index_set = 1;
8621       else if (unformat (i, "hostname %s", &hostname))
8622         ;
8623       else if (unformat (i, "disable_event"))
8624         disable_event = 1;
8625       else
8626         break;
8627     }
8628
8629   if (sw_if_index_set == 0)
8630     {
8631       errmsg ("missing interface name or sw_if_index");
8632       return -99;
8633     }
8634
8635   if (vec_len (hostname) > 63)
8636     {
8637       errmsg ("hostname too long");
8638     }
8639   vec_add1 (hostname, 0);
8640
8641   /* Construct the API message */
8642   M (DHCP_CLIENT_CONFIG, mp);
8643
8644   mp->sw_if_index = htonl (sw_if_index);
8645   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8646   vec_free (hostname);
8647   mp->is_add = is_add;
8648   mp->want_dhcp_event = disable_event ? 0 : 1;
8649   mp->pid = htonl (getpid ());
8650
8651   /* send it... */
8652   S (mp);
8653
8654   /* Wait for a reply, return good/bad news  */
8655   W (ret);
8656   return ret;
8657 }
8658
8659 static int
8660 api_set_ip_flow_hash (vat_main_t * vam)
8661 {
8662   unformat_input_t *i = vam->input;
8663   vl_api_set_ip_flow_hash_t *mp;
8664   u32 vrf_id = 0;
8665   u8 is_ipv6 = 0;
8666   u8 vrf_id_set = 0;
8667   u8 src = 0;
8668   u8 dst = 0;
8669   u8 sport = 0;
8670   u8 dport = 0;
8671   u8 proto = 0;
8672   u8 reverse = 0;
8673   int ret;
8674
8675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8676     {
8677       if (unformat (i, "vrf %d", &vrf_id))
8678         vrf_id_set = 1;
8679       else if (unformat (i, "ipv6"))
8680         is_ipv6 = 1;
8681       else if (unformat (i, "src"))
8682         src = 1;
8683       else if (unformat (i, "dst"))
8684         dst = 1;
8685       else if (unformat (i, "sport"))
8686         sport = 1;
8687       else if (unformat (i, "dport"))
8688         dport = 1;
8689       else if (unformat (i, "proto"))
8690         proto = 1;
8691       else if (unformat (i, "reverse"))
8692         reverse = 1;
8693
8694       else
8695         {
8696           clib_warning ("parse error '%U'", format_unformat_error, i);
8697           return -99;
8698         }
8699     }
8700
8701   if (vrf_id_set == 0)
8702     {
8703       errmsg ("missing vrf id");
8704       return -99;
8705     }
8706
8707   M (SET_IP_FLOW_HASH, mp);
8708   mp->src = src;
8709   mp->dst = dst;
8710   mp->sport = sport;
8711   mp->dport = dport;
8712   mp->proto = proto;
8713   mp->reverse = reverse;
8714   mp->vrf_id = ntohl (vrf_id);
8715   mp->is_ipv6 = is_ipv6;
8716
8717   S (mp);
8718   W (ret);
8719   return ret;
8720 }
8721
8722 static int
8723 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8724 {
8725   unformat_input_t *i = vam->input;
8726   vl_api_sw_interface_ip6_enable_disable_t *mp;
8727   u32 sw_if_index;
8728   u8 sw_if_index_set = 0;
8729   u8 enable = 0;
8730   int ret;
8731
8732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8733     {
8734       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8735         sw_if_index_set = 1;
8736       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8737         sw_if_index_set = 1;
8738       else if (unformat (i, "enable"))
8739         enable = 1;
8740       else if (unformat (i, "disable"))
8741         enable = 0;
8742       else
8743         {
8744           clib_warning ("parse error '%U'", format_unformat_error, i);
8745           return -99;
8746         }
8747     }
8748
8749   if (sw_if_index_set == 0)
8750     {
8751       errmsg ("missing interface name or sw_if_index");
8752       return -99;
8753     }
8754
8755   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8756
8757   mp->sw_if_index = ntohl (sw_if_index);
8758   mp->enable = enable;
8759
8760   S (mp);
8761   W (ret);
8762   return ret;
8763 }
8764
8765 static int
8766 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8767 {
8768   unformat_input_t *i = vam->input;
8769   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8770   u32 sw_if_index;
8771   u8 sw_if_index_set = 0;
8772   u8 v6_address_set = 0;
8773   ip6_address_t v6address;
8774   int ret;
8775
8776   /* Parse args required to build the message */
8777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8778     {
8779       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8780         sw_if_index_set = 1;
8781       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8782         sw_if_index_set = 1;
8783       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8784         v6_address_set = 1;
8785       else
8786         break;
8787     }
8788
8789   if (sw_if_index_set == 0)
8790     {
8791       errmsg ("missing interface name or sw_if_index");
8792       return -99;
8793     }
8794   if (!v6_address_set)
8795     {
8796       errmsg ("no address set");
8797       return -99;
8798     }
8799
8800   /* Construct the API message */
8801   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8802
8803   mp->sw_if_index = ntohl (sw_if_index);
8804   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8805
8806   /* send it... */
8807   S (mp);
8808
8809   /* Wait for a reply, return good/bad news  */
8810   W (ret);
8811   return ret;
8812 }
8813
8814 static int
8815 api_ip6nd_proxy_add_del (vat_main_t * vam)
8816 {
8817   unformat_input_t *i = vam->input;
8818   vl_api_ip6nd_proxy_add_del_t *mp;
8819   u32 sw_if_index = ~0;
8820   u8 v6_address_set = 0;
8821   ip6_address_t v6address;
8822   u8 is_del = 0;
8823   int ret;
8824
8825   /* Parse args required to build the message */
8826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8827     {
8828       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8829         ;
8830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8831         ;
8832       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8833         v6_address_set = 1;
8834       if (unformat (i, "del"))
8835         is_del = 1;
8836       else
8837         {
8838           clib_warning ("parse error '%U'", format_unformat_error, i);
8839           return -99;
8840         }
8841     }
8842
8843   if (sw_if_index == ~0)
8844     {
8845       errmsg ("missing interface name or sw_if_index");
8846       return -99;
8847     }
8848   if (!v6_address_set)
8849     {
8850       errmsg ("no address set");
8851       return -99;
8852     }
8853
8854   /* Construct the API message */
8855   M (IP6ND_PROXY_ADD_DEL, mp);
8856
8857   mp->is_del = is_del;
8858   mp->sw_if_index = ntohl (sw_if_index);
8859   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8860
8861   /* send it... */
8862   S (mp);
8863
8864   /* Wait for a reply, return good/bad news  */
8865   W (ret);
8866   return ret;
8867 }
8868
8869 static int
8870 api_ip6nd_proxy_dump (vat_main_t * vam)
8871 {
8872   vl_api_ip6nd_proxy_dump_t *mp;
8873   vl_api_control_ping_t *mp_ping;
8874   int ret;
8875
8876   M (IP6ND_PROXY_DUMP, mp);
8877
8878   S (mp);
8879
8880   /* Use a control ping for synchronization */
8881   M (CONTROL_PING, mp_ping);
8882   S (mp_ping);
8883
8884   W (ret);
8885   return ret;
8886 }
8887
8888 static void vl_api_ip6nd_proxy_details_t_handler
8889   (vl_api_ip6nd_proxy_details_t * mp)
8890 {
8891   vat_main_t *vam = &vat_main;
8892
8893   print (vam->ofp, "host %U sw_if_index %d",
8894          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8895 }
8896
8897 static void vl_api_ip6nd_proxy_details_t_handler_json
8898   (vl_api_ip6nd_proxy_details_t * mp)
8899 {
8900   vat_main_t *vam = &vat_main;
8901   struct in6_addr ip6;
8902   vat_json_node_t *node = NULL;
8903
8904   if (VAT_JSON_ARRAY != vam->json_tree.type)
8905     {
8906       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8907       vat_json_init_array (&vam->json_tree);
8908     }
8909   node = vat_json_array_add (&vam->json_tree);
8910
8911   vat_json_init_object (node);
8912   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8913
8914   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8915   vat_json_object_add_ip6 (node, "host", ip6);
8916 }
8917
8918 static int
8919 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8920 {
8921   unformat_input_t *i = vam->input;
8922   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8923   u32 sw_if_index;
8924   u8 sw_if_index_set = 0;
8925   u32 address_length = 0;
8926   u8 v6_address_set = 0;
8927   ip6_address_t v6address;
8928   u8 use_default = 0;
8929   u8 no_advertise = 0;
8930   u8 off_link = 0;
8931   u8 no_autoconfig = 0;
8932   u8 no_onlink = 0;
8933   u8 is_no = 0;
8934   u32 val_lifetime = 0;
8935   u32 pref_lifetime = 0;
8936   int ret;
8937
8938   /* Parse args required to build the message */
8939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8940     {
8941       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8942         sw_if_index_set = 1;
8943       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8944         sw_if_index_set = 1;
8945       else if (unformat (i, "%U/%d",
8946                          unformat_ip6_address, &v6address, &address_length))
8947         v6_address_set = 1;
8948       else if (unformat (i, "val_life %d", &val_lifetime))
8949         ;
8950       else if (unformat (i, "pref_life %d", &pref_lifetime))
8951         ;
8952       else if (unformat (i, "def"))
8953         use_default = 1;
8954       else if (unformat (i, "noadv"))
8955         no_advertise = 1;
8956       else if (unformat (i, "offl"))
8957         off_link = 1;
8958       else if (unformat (i, "noauto"))
8959         no_autoconfig = 1;
8960       else if (unformat (i, "nolink"))
8961         no_onlink = 1;
8962       else if (unformat (i, "isno"))
8963         is_no = 1;
8964       else
8965         {
8966           clib_warning ("parse error '%U'", format_unformat_error, i);
8967           return -99;
8968         }
8969     }
8970
8971   if (sw_if_index_set == 0)
8972     {
8973       errmsg ("missing interface name or sw_if_index");
8974       return -99;
8975     }
8976   if (!v6_address_set)
8977     {
8978       errmsg ("no address set");
8979       return -99;
8980     }
8981
8982   /* Construct the API message */
8983   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8984
8985   mp->sw_if_index = ntohl (sw_if_index);
8986   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8987   mp->address_length = address_length;
8988   mp->use_default = use_default;
8989   mp->no_advertise = no_advertise;
8990   mp->off_link = off_link;
8991   mp->no_autoconfig = no_autoconfig;
8992   mp->no_onlink = no_onlink;
8993   mp->is_no = is_no;
8994   mp->val_lifetime = ntohl (val_lifetime);
8995   mp->pref_lifetime = ntohl (pref_lifetime);
8996
8997   /* send it... */
8998   S (mp);
8999
9000   /* Wait for a reply, return good/bad news  */
9001   W (ret);
9002   return ret;
9003 }
9004
9005 static int
9006 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9007 {
9008   unformat_input_t *i = vam->input;
9009   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9010   u32 sw_if_index;
9011   u8 sw_if_index_set = 0;
9012   u8 suppress = 0;
9013   u8 managed = 0;
9014   u8 other = 0;
9015   u8 ll_option = 0;
9016   u8 send_unicast = 0;
9017   u8 cease = 0;
9018   u8 is_no = 0;
9019   u8 default_router = 0;
9020   u32 max_interval = 0;
9021   u32 min_interval = 0;
9022   u32 lifetime = 0;
9023   u32 initial_count = 0;
9024   u32 initial_interval = 0;
9025   int ret;
9026
9027
9028   /* Parse args required to build the message */
9029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9030     {
9031       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9032         sw_if_index_set = 1;
9033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9034         sw_if_index_set = 1;
9035       else if (unformat (i, "maxint %d", &max_interval))
9036         ;
9037       else if (unformat (i, "minint %d", &min_interval))
9038         ;
9039       else if (unformat (i, "life %d", &lifetime))
9040         ;
9041       else if (unformat (i, "count %d", &initial_count))
9042         ;
9043       else if (unformat (i, "interval %d", &initial_interval))
9044         ;
9045       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9046         suppress = 1;
9047       else if (unformat (i, "managed"))
9048         managed = 1;
9049       else if (unformat (i, "other"))
9050         other = 1;
9051       else if (unformat (i, "ll"))
9052         ll_option = 1;
9053       else if (unformat (i, "send"))
9054         send_unicast = 1;
9055       else if (unformat (i, "cease"))
9056         cease = 1;
9057       else if (unformat (i, "isno"))
9058         is_no = 1;
9059       else if (unformat (i, "def"))
9060         default_router = 1;
9061       else
9062         {
9063           clib_warning ("parse error '%U'", format_unformat_error, i);
9064           return -99;
9065         }
9066     }
9067
9068   if (sw_if_index_set == 0)
9069     {
9070       errmsg ("missing interface name or sw_if_index");
9071       return -99;
9072     }
9073
9074   /* Construct the API message */
9075   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9076
9077   mp->sw_if_index = ntohl (sw_if_index);
9078   mp->max_interval = ntohl (max_interval);
9079   mp->min_interval = ntohl (min_interval);
9080   mp->lifetime = ntohl (lifetime);
9081   mp->initial_count = ntohl (initial_count);
9082   mp->initial_interval = ntohl (initial_interval);
9083   mp->suppress = suppress;
9084   mp->managed = managed;
9085   mp->other = other;
9086   mp->ll_option = ll_option;
9087   mp->send_unicast = send_unicast;
9088   mp->cease = cease;
9089   mp->is_no = is_no;
9090   mp->default_router = default_router;
9091
9092   /* send it... */
9093   S (mp);
9094
9095   /* Wait for a reply, return good/bad news  */
9096   W (ret);
9097   return ret;
9098 }
9099
9100 static int
9101 api_set_arp_neighbor_limit (vat_main_t * vam)
9102 {
9103   unformat_input_t *i = vam->input;
9104   vl_api_set_arp_neighbor_limit_t *mp;
9105   u32 arp_nbr_limit;
9106   u8 limit_set = 0;
9107   u8 is_ipv6 = 0;
9108   int ret;
9109
9110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9111     {
9112       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9113         limit_set = 1;
9114       else if (unformat (i, "ipv6"))
9115         is_ipv6 = 1;
9116       else
9117         {
9118           clib_warning ("parse error '%U'", format_unformat_error, i);
9119           return -99;
9120         }
9121     }
9122
9123   if (limit_set == 0)
9124     {
9125       errmsg ("missing limit value");
9126       return -99;
9127     }
9128
9129   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9130
9131   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9132   mp->is_ipv6 = is_ipv6;
9133
9134   S (mp);
9135   W (ret);
9136   return ret;
9137 }
9138
9139 static int
9140 api_l2_patch_add_del (vat_main_t * vam)
9141 {
9142   unformat_input_t *i = vam->input;
9143   vl_api_l2_patch_add_del_t *mp;
9144   u32 rx_sw_if_index;
9145   u8 rx_sw_if_index_set = 0;
9146   u32 tx_sw_if_index;
9147   u8 tx_sw_if_index_set = 0;
9148   u8 is_add = 1;
9149   int ret;
9150
9151   /* Parse args required to build the message */
9152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9153     {
9154       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9155         rx_sw_if_index_set = 1;
9156       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9157         tx_sw_if_index_set = 1;
9158       else if (unformat (i, "rx"))
9159         {
9160           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9161             {
9162               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9163                             &rx_sw_if_index))
9164                 rx_sw_if_index_set = 1;
9165             }
9166           else
9167             break;
9168         }
9169       else if (unformat (i, "tx"))
9170         {
9171           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9172             {
9173               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9174                             &tx_sw_if_index))
9175                 tx_sw_if_index_set = 1;
9176             }
9177           else
9178             break;
9179         }
9180       else if (unformat (i, "del"))
9181         is_add = 0;
9182       else
9183         break;
9184     }
9185
9186   if (rx_sw_if_index_set == 0)
9187     {
9188       errmsg ("missing rx interface name or rx_sw_if_index");
9189       return -99;
9190     }
9191
9192   if (tx_sw_if_index_set == 0)
9193     {
9194       errmsg ("missing tx interface name or tx_sw_if_index");
9195       return -99;
9196     }
9197
9198   M (L2_PATCH_ADD_DEL, mp);
9199
9200   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9201   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9202   mp->is_add = is_add;
9203
9204   S (mp);
9205   W (ret);
9206   return ret;
9207 }
9208
9209 u8 is_del;
9210 u8 localsid_addr[16];
9211 u8 end_psp;
9212 u8 behavior;
9213 u32 sw_if_index;
9214 u32 vlan_index;
9215 u32 fib_table;
9216 u8 nh_addr[16];
9217
9218 static int
9219 api_sr_localsid_add_del (vat_main_t * vam)
9220 {
9221   unformat_input_t *i = vam->input;
9222   vl_api_sr_localsid_add_del_t *mp;
9223
9224   u8 is_del;
9225   ip6_address_t localsid;
9226   u8 end_psp = 0;
9227   u8 behavior = ~0;
9228   u32 sw_if_index;
9229   u32 fib_table = ~(u32) 0;
9230   ip6_address_t next_hop;
9231
9232   bool nexthop_set = 0;
9233
9234   int ret;
9235
9236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9237     {
9238       if (unformat (i, "del"))
9239         is_del = 1;
9240       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9241       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9242         nexthop_set = 1;
9243       else if (unformat (i, "behavior %u", &behavior));
9244       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9245       else if (unformat (i, "fib-table %u", &fib_table));
9246       else if (unformat (i, "end.psp %u", &behavior));
9247       else
9248         break;
9249     }
9250
9251   M (SR_LOCALSID_ADD_DEL, mp);
9252
9253   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9254   if (nexthop_set)
9255     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9256   mp->behavior = behavior;
9257   mp->sw_if_index = ntohl (sw_if_index);
9258   mp->fib_table = ntohl (fib_table);
9259   mp->end_psp = end_psp;
9260   mp->is_del = is_del;
9261
9262   S (mp);
9263   W (ret);
9264   return ret;
9265 }
9266
9267 static int
9268 api_ioam_enable (vat_main_t * vam)
9269 {
9270   unformat_input_t *input = vam->input;
9271   vl_api_ioam_enable_t *mp;
9272   u32 id = 0;
9273   int has_trace_option = 0;
9274   int has_pot_option = 0;
9275   int has_seqno_option = 0;
9276   int has_analyse_option = 0;
9277   int ret;
9278
9279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9280     {
9281       if (unformat (input, "trace"))
9282         has_trace_option = 1;
9283       else if (unformat (input, "pot"))
9284         has_pot_option = 1;
9285       else if (unformat (input, "seqno"))
9286         has_seqno_option = 1;
9287       else if (unformat (input, "analyse"))
9288         has_analyse_option = 1;
9289       else
9290         break;
9291     }
9292   M (IOAM_ENABLE, mp);
9293   mp->id = htons (id);
9294   mp->seqno = has_seqno_option;
9295   mp->analyse = has_analyse_option;
9296   mp->pot_enable = has_pot_option;
9297   mp->trace_enable = has_trace_option;
9298
9299   S (mp);
9300   W (ret);
9301   return ret;
9302 }
9303
9304
9305 static int
9306 api_ioam_disable (vat_main_t * vam)
9307 {
9308   vl_api_ioam_disable_t *mp;
9309   int ret;
9310
9311   M (IOAM_DISABLE, mp);
9312   S (mp);
9313   W (ret);
9314   return ret;
9315 }
9316
9317 #define foreach_tcp_proto_field                 \
9318 _(src_port)                                     \
9319 _(dst_port)
9320
9321 #define foreach_udp_proto_field                 \
9322 _(src_port)                                     \
9323 _(dst_port)
9324
9325 #define foreach_ip4_proto_field                 \
9326 _(src_address)                                  \
9327 _(dst_address)                                  \
9328 _(tos)                                          \
9329 _(length)                                       \
9330 _(fragment_id)                                  \
9331 _(ttl)                                          \
9332 _(protocol)                                     \
9333 _(checksum)
9334
9335 typedef struct
9336 {
9337   u16 src_port, dst_port;
9338 } tcpudp_header_t;
9339
9340 #if VPP_API_TEST_BUILTIN == 0
9341 uword
9342 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9343 {
9344   u8 **maskp = va_arg (*args, u8 **);
9345   u8 *mask = 0;
9346   u8 found_something = 0;
9347   tcp_header_t *tcp;
9348
9349 #define _(a) u8 a=0;
9350   foreach_tcp_proto_field;
9351 #undef _
9352
9353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9354     {
9355       if (0);
9356 #define _(a) else if (unformat (input, #a)) a=1;
9357       foreach_tcp_proto_field
9358 #undef _
9359         else
9360         break;
9361     }
9362
9363 #define _(a) found_something += a;
9364   foreach_tcp_proto_field;
9365 #undef _
9366
9367   if (found_something == 0)
9368     return 0;
9369
9370   vec_validate (mask, sizeof (*tcp) - 1);
9371
9372   tcp = (tcp_header_t *) mask;
9373
9374 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9375   foreach_tcp_proto_field;
9376 #undef _
9377
9378   *maskp = mask;
9379   return 1;
9380 }
9381
9382 uword
9383 unformat_udp_mask (unformat_input_t * input, va_list * args)
9384 {
9385   u8 **maskp = va_arg (*args, u8 **);
9386   u8 *mask = 0;
9387   u8 found_something = 0;
9388   udp_header_t *udp;
9389
9390 #define _(a) u8 a=0;
9391   foreach_udp_proto_field;
9392 #undef _
9393
9394   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9395     {
9396       if (0);
9397 #define _(a) else if (unformat (input, #a)) a=1;
9398       foreach_udp_proto_field
9399 #undef _
9400         else
9401         break;
9402     }
9403
9404 #define _(a) found_something += a;
9405   foreach_udp_proto_field;
9406 #undef _
9407
9408   if (found_something == 0)
9409     return 0;
9410
9411   vec_validate (mask, sizeof (*udp) - 1);
9412
9413   udp = (udp_header_t *) mask;
9414
9415 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9416   foreach_udp_proto_field;
9417 #undef _
9418
9419   *maskp = mask;
9420   return 1;
9421 }
9422
9423 uword
9424 unformat_l4_mask (unformat_input_t * input, va_list * args)
9425 {
9426   u8 **maskp = va_arg (*args, u8 **);
9427   u16 src_port = 0, dst_port = 0;
9428   tcpudp_header_t *tcpudp;
9429
9430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9431     {
9432       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9433         return 1;
9434       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9435         return 1;
9436       else if (unformat (input, "src_port"))
9437         src_port = 0xFFFF;
9438       else if (unformat (input, "dst_port"))
9439         dst_port = 0xFFFF;
9440       else
9441         return 0;
9442     }
9443
9444   if (!src_port && !dst_port)
9445     return 0;
9446
9447   u8 *mask = 0;
9448   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9449
9450   tcpudp = (tcpudp_header_t *) mask;
9451   tcpudp->src_port = src_port;
9452   tcpudp->dst_port = dst_port;
9453
9454   *maskp = mask;
9455
9456   return 1;
9457 }
9458
9459 uword
9460 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9461 {
9462   u8 **maskp = va_arg (*args, u8 **);
9463   u8 *mask = 0;
9464   u8 found_something = 0;
9465   ip4_header_t *ip;
9466
9467 #define _(a) u8 a=0;
9468   foreach_ip4_proto_field;
9469 #undef _
9470   u8 version = 0;
9471   u8 hdr_length = 0;
9472
9473
9474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9475     {
9476       if (unformat (input, "version"))
9477         version = 1;
9478       else if (unformat (input, "hdr_length"))
9479         hdr_length = 1;
9480       else if (unformat (input, "src"))
9481         src_address = 1;
9482       else if (unformat (input, "dst"))
9483         dst_address = 1;
9484       else if (unformat (input, "proto"))
9485         protocol = 1;
9486
9487 #define _(a) else if (unformat (input, #a)) a=1;
9488       foreach_ip4_proto_field
9489 #undef _
9490         else
9491         break;
9492     }
9493
9494 #define _(a) found_something += a;
9495   foreach_ip4_proto_field;
9496 #undef _
9497
9498   if (found_something == 0)
9499     return 0;
9500
9501   vec_validate (mask, sizeof (*ip) - 1);
9502
9503   ip = (ip4_header_t *) mask;
9504
9505 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9506   foreach_ip4_proto_field;
9507 #undef _
9508
9509   ip->ip_version_and_header_length = 0;
9510
9511   if (version)
9512     ip->ip_version_and_header_length |= 0xF0;
9513
9514   if (hdr_length)
9515     ip->ip_version_and_header_length |= 0x0F;
9516
9517   *maskp = mask;
9518   return 1;
9519 }
9520
9521 #define foreach_ip6_proto_field                 \
9522 _(src_address)                                  \
9523 _(dst_address)                                  \
9524 _(payload_length)                               \
9525 _(hop_limit)                                    \
9526 _(protocol)
9527
9528 uword
9529 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9530 {
9531   u8 **maskp = va_arg (*args, u8 **);
9532   u8 *mask = 0;
9533   u8 found_something = 0;
9534   ip6_header_t *ip;
9535   u32 ip_version_traffic_class_and_flow_label;
9536
9537 #define _(a) u8 a=0;
9538   foreach_ip6_proto_field;
9539 #undef _
9540   u8 version = 0;
9541   u8 traffic_class = 0;
9542   u8 flow_label = 0;
9543
9544   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9545     {
9546       if (unformat (input, "version"))
9547         version = 1;
9548       else if (unformat (input, "traffic-class"))
9549         traffic_class = 1;
9550       else if (unformat (input, "flow-label"))
9551         flow_label = 1;
9552       else if (unformat (input, "src"))
9553         src_address = 1;
9554       else if (unformat (input, "dst"))
9555         dst_address = 1;
9556       else if (unformat (input, "proto"))
9557         protocol = 1;
9558
9559 #define _(a) else if (unformat (input, #a)) a=1;
9560       foreach_ip6_proto_field
9561 #undef _
9562         else
9563         break;
9564     }
9565
9566 #define _(a) found_something += a;
9567   foreach_ip6_proto_field;
9568 #undef _
9569
9570   if (found_something == 0)
9571     return 0;
9572
9573   vec_validate (mask, sizeof (*ip) - 1);
9574
9575   ip = (ip6_header_t *) mask;
9576
9577 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9578   foreach_ip6_proto_field;
9579 #undef _
9580
9581   ip_version_traffic_class_and_flow_label = 0;
9582
9583   if (version)
9584     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9585
9586   if (traffic_class)
9587     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9588
9589   if (flow_label)
9590     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9591
9592   ip->ip_version_traffic_class_and_flow_label =
9593     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9594
9595   *maskp = mask;
9596   return 1;
9597 }
9598
9599 uword
9600 unformat_l3_mask (unformat_input_t * input, va_list * args)
9601 {
9602   u8 **maskp = va_arg (*args, u8 **);
9603
9604   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9605     {
9606       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9607         return 1;
9608       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9609         return 1;
9610       else
9611         break;
9612     }
9613   return 0;
9614 }
9615
9616 uword
9617 unformat_l2_mask (unformat_input_t * input, va_list * args)
9618 {
9619   u8 **maskp = va_arg (*args, u8 **);
9620   u8 *mask = 0;
9621   u8 src = 0;
9622   u8 dst = 0;
9623   u8 proto = 0;
9624   u8 tag1 = 0;
9625   u8 tag2 = 0;
9626   u8 ignore_tag1 = 0;
9627   u8 ignore_tag2 = 0;
9628   u8 cos1 = 0;
9629   u8 cos2 = 0;
9630   u8 dot1q = 0;
9631   u8 dot1ad = 0;
9632   int len = 14;
9633
9634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9635     {
9636       if (unformat (input, "src"))
9637         src = 1;
9638       else if (unformat (input, "dst"))
9639         dst = 1;
9640       else if (unformat (input, "proto"))
9641         proto = 1;
9642       else if (unformat (input, "tag1"))
9643         tag1 = 1;
9644       else if (unformat (input, "tag2"))
9645         tag2 = 1;
9646       else if (unformat (input, "ignore-tag1"))
9647         ignore_tag1 = 1;
9648       else if (unformat (input, "ignore-tag2"))
9649         ignore_tag2 = 1;
9650       else if (unformat (input, "cos1"))
9651         cos1 = 1;
9652       else if (unformat (input, "cos2"))
9653         cos2 = 1;
9654       else if (unformat (input, "dot1q"))
9655         dot1q = 1;
9656       else if (unformat (input, "dot1ad"))
9657         dot1ad = 1;
9658       else
9659         break;
9660     }
9661   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9662        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9663     return 0;
9664
9665   if (tag1 || ignore_tag1 || cos1 || dot1q)
9666     len = 18;
9667   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9668     len = 22;
9669
9670   vec_validate (mask, len - 1);
9671
9672   if (dst)
9673     memset (mask, 0xff, 6);
9674
9675   if (src)
9676     memset (mask + 6, 0xff, 6);
9677
9678   if (tag2 || dot1ad)
9679     {
9680       /* inner vlan tag */
9681       if (tag2)
9682         {
9683           mask[19] = 0xff;
9684           mask[18] = 0x0f;
9685         }
9686       if (cos2)
9687         mask[18] |= 0xe0;
9688       if (proto)
9689         mask[21] = mask[20] = 0xff;
9690       if (tag1)
9691         {
9692           mask[15] = 0xff;
9693           mask[14] = 0x0f;
9694         }
9695       if (cos1)
9696         mask[14] |= 0xe0;
9697       *maskp = mask;
9698       return 1;
9699     }
9700   if (tag1 | dot1q)
9701     {
9702       if (tag1)
9703         {
9704           mask[15] = 0xff;
9705           mask[14] = 0x0f;
9706         }
9707       if (cos1)
9708         mask[14] |= 0xe0;
9709       if (proto)
9710         mask[16] = mask[17] = 0xff;
9711
9712       *maskp = mask;
9713       return 1;
9714     }
9715   if (cos2)
9716     mask[18] |= 0xe0;
9717   if (cos1)
9718     mask[14] |= 0xe0;
9719   if (proto)
9720     mask[12] = mask[13] = 0xff;
9721
9722   *maskp = mask;
9723   return 1;
9724 }
9725
9726 uword
9727 unformat_classify_mask (unformat_input_t * input, va_list * args)
9728 {
9729   u8 **maskp = va_arg (*args, u8 **);
9730   u32 *skipp = va_arg (*args, u32 *);
9731   u32 *matchp = va_arg (*args, u32 *);
9732   u32 match;
9733   u8 *mask = 0;
9734   u8 *l2 = 0;
9735   u8 *l3 = 0;
9736   u8 *l4 = 0;
9737   int i;
9738
9739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9740     {
9741       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9742         ;
9743       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9744         ;
9745       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9746         ;
9747       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9748         ;
9749       else
9750         break;
9751     }
9752
9753   if (l4 && !l3)
9754     {
9755       vec_free (mask);
9756       vec_free (l2);
9757       vec_free (l4);
9758       return 0;
9759     }
9760
9761   if (mask || l2 || l3 || l4)
9762     {
9763       if (l2 || l3 || l4)
9764         {
9765           /* "With a free Ethernet header in every package" */
9766           if (l2 == 0)
9767             vec_validate (l2, 13);
9768           mask = l2;
9769           if (vec_len (l3))
9770             {
9771               vec_append (mask, l3);
9772               vec_free (l3);
9773             }
9774           if (vec_len (l4))
9775             {
9776               vec_append (mask, l4);
9777               vec_free (l4);
9778             }
9779         }
9780
9781       /* Scan forward looking for the first significant mask octet */
9782       for (i = 0; i < vec_len (mask); i++)
9783         if (mask[i])
9784           break;
9785
9786       /* compute (skip, match) params */
9787       *skipp = i / sizeof (u32x4);
9788       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9789
9790       /* Pad mask to an even multiple of the vector size */
9791       while (vec_len (mask) % sizeof (u32x4))
9792         vec_add1 (mask, 0);
9793
9794       match = vec_len (mask) / sizeof (u32x4);
9795
9796       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9797         {
9798           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9799           if (*tmp || *(tmp + 1))
9800             break;
9801           match--;
9802         }
9803       if (match == 0)
9804         clib_warning ("BUG: match 0");
9805
9806       _vec_len (mask) = match * sizeof (u32x4);
9807
9808       *matchp = match;
9809       *maskp = mask;
9810
9811       return 1;
9812     }
9813
9814   return 0;
9815 }
9816 #endif /* VPP_API_TEST_BUILTIN */
9817
9818 #define foreach_l2_next                         \
9819 _(drop, DROP)                                   \
9820 _(ethernet, ETHERNET_INPUT)                     \
9821 _(ip4, IP4_INPUT)                               \
9822 _(ip6, IP6_INPUT)
9823
9824 uword
9825 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9826 {
9827   u32 *miss_next_indexp = va_arg (*args, u32 *);
9828   u32 next_index = 0;
9829   u32 tmp;
9830
9831 #define _(n,N) \
9832   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9833   foreach_l2_next;
9834 #undef _
9835
9836   if (unformat (input, "%d", &tmp))
9837     {
9838       next_index = tmp;
9839       goto out;
9840     }
9841
9842   return 0;
9843
9844 out:
9845   *miss_next_indexp = next_index;
9846   return 1;
9847 }
9848
9849 #define foreach_ip_next                         \
9850 _(drop, DROP)                                   \
9851 _(local, LOCAL)                                 \
9852 _(rewrite, REWRITE)
9853
9854 uword
9855 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9856 {
9857   u32 *miss_next_indexp = va_arg (*args, u32 *);
9858   u32 next_index = 0;
9859   u32 tmp;
9860
9861 #define _(n,N) \
9862   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9863   foreach_ip_next;
9864 #undef _
9865
9866   if (unformat (input, "%d", &tmp))
9867     {
9868       next_index = tmp;
9869       goto out;
9870     }
9871
9872   return 0;
9873
9874 out:
9875   *miss_next_indexp = next_index;
9876   return 1;
9877 }
9878
9879 #define foreach_acl_next                        \
9880 _(deny, DENY)
9881
9882 uword
9883 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9884 {
9885   u32 *miss_next_indexp = va_arg (*args, u32 *);
9886   u32 next_index = 0;
9887   u32 tmp;
9888
9889 #define _(n,N) \
9890   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9891   foreach_acl_next;
9892 #undef _
9893
9894   if (unformat (input, "permit"))
9895     {
9896       next_index = ~0;
9897       goto out;
9898     }
9899   else if (unformat (input, "%d", &tmp))
9900     {
9901       next_index = tmp;
9902       goto out;
9903     }
9904
9905   return 0;
9906
9907 out:
9908   *miss_next_indexp = next_index;
9909   return 1;
9910 }
9911
9912 uword
9913 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9914 {
9915   u32 *r = va_arg (*args, u32 *);
9916
9917   if (unformat (input, "conform-color"))
9918     *r = POLICE_CONFORM;
9919   else if (unformat (input, "exceed-color"))
9920     *r = POLICE_EXCEED;
9921   else
9922     return 0;
9923
9924   return 1;
9925 }
9926
9927 static int
9928 api_classify_add_del_table (vat_main_t * vam)
9929 {
9930   unformat_input_t *i = vam->input;
9931   vl_api_classify_add_del_table_t *mp;
9932
9933   u32 nbuckets = 2;
9934   u32 skip = ~0;
9935   u32 match = ~0;
9936   int is_add = 1;
9937   int del_chain = 0;
9938   u32 table_index = ~0;
9939   u32 next_table_index = ~0;
9940   u32 miss_next_index = ~0;
9941   u32 memory_size = 32 << 20;
9942   u8 *mask = 0;
9943   u32 current_data_flag = 0;
9944   int current_data_offset = 0;
9945   int ret;
9946
9947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9948     {
9949       if (unformat (i, "del"))
9950         is_add = 0;
9951       else if (unformat (i, "del-chain"))
9952         {
9953           is_add = 0;
9954           del_chain = 1;
9955         }
9956       else if (unformat (i, "buckets %d", &nbuckets))
9957         ;
9958       else if (unformat (i, "memory_size %d", &memory_size))
9959         ;
9960       else if (unformat (i, "skip %d", &skip))
9961         ;
9962       else if (unformat (i, "match %d", &match))
9963         ;
9964       else if (unformat (i, "table %d", &table_index))
9965         ;
9966       else if (unformat (i, "mask %U", unformat_classify_mask,
9967                          &mask, &skip, &match))
9968         ;
9969       else if (unformat (i, "next-table %d", &next_table_index))
9970         ;
9971       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9972                          &miss_next_index))
9973         ;
9974       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9975                          &miss_next_index))
9976         ;
9977       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9978                          &miss_next_index))
9979         ;
9980       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9981         ;
9982       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9983         ;
9984       else
9985         break;
9986     }
9987
9988   if (is_add && mask == 0)
9989     {
9990       errmsg ("Mask required");
9991       return -99;
9992     }
9993
9994   if (is_add && skip == ~0)
9995     {
9996       errmsg ("skip count required");
9997       return -99;
9998     }
9999
10000   if (is_add && match == ~0)
10001     {
10002       errmsg ("match count required");
10003       return -99;
10004     }
10005
10006   if (!is_add && table_index == ~0)
10007     {
10008       errmsg ("table index required for delete");
10009       return -99;
10010     }
10011
10012   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10013
10014   mp->is_add = is_add;
10015   mp->del_chain = del_chain;
10016   mp->table_index = ntohl (table_index);
10017   mp->nbuckets = ntohl (nbuckets);
10018   mp->memory_size = ntohl (memory_size);
10019   mp->skip_n_vectors = ntohl (skip);
10020   mp->match_n_vectors = ntohl (match);
10021   mp->next_table_index = ntohl (next_table_index);
10022   mp->miss_next_index = ntohl (miss_next_index);
10023   mp->current_data_flag = ntohl (current_data_flag);
10024   mp->current_data_offset = ntohl (current_data_offset);
10025   clib_memcpy (mp->mask, mask, vec_len (mask));
10026
10027   vec_free (mask);
10028
10029   S (mp);
10030   W (ret);
10031   return ret;
10032 }
10033
10034 #if VPP_API_TEST_BUILTIN == 0
10035 uword
10036 unformat_l4_match (unformat_input_t * input, va_list * args)
10037 {
10038   u8 **matchp = va_arg (*args, u8 **);
10039
10040   u8 *proto_header = 0;
10041   int src_port = 0;
10042   int dst_port = 0;
10043
10044   tcpudp_header_t h;
10045
10046   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10047     {
10048       if (unformat (input, "src_port %d", &src_port))
10049         ;
10050       else if (unformat (input, "dst_port %d", &dst_port))
10051         ;
10052       else
10053         return 0;
10054     }
10055
10056   h.src_port = clib_host_to_net_u16 (src_port);
10057   h.dst_port = clib_host_to_net_u16 (dst_port);
10058   vec_validate (proto_header, sizeof (h) - 1);
10059   memcpy (proto_header, &h, sizeof (h));
10060
10061   *matchp = proto_header;
10062
10063   return 1;
10064 }
10065
10066 uword
10067 unformat_ip4_match (unformat_input_t * input, va_list * args)
10068 {
10069   u8 **matchp = va_arg (*args, u8 **);
10070   u8 *match = 0;
10071   ip4_header_t *ip;
10072   int version = 0;
10073   u32 version_val;
10074   int hdr_length = 0;
10075   u32 hdr_length_val;
10076   int src = 0, dst = 0;
10077   ip4_address_t src_val, dst_val;
10078   int proto = 0;
10079   u32 proto_val;
10080   int tos = 0;
10081   u32 tos_val;
10082   int length = 0;
10083   u32 length_val;
10084   int fragment_id = 0;
10085   u32 fragment_id_val;
10086   int ttl = 0;
10087   int ttl_val;
10088   int checksum = 0;
10089   u32 checksum_val;
10090
10091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10092     {
10093       if (unformat (input, "version %d", &version_val))
10094         version = 1;
10095       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10096         hdr_length = 1;
10097       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10098         src = 1;
10099       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10100         dst = 1;
10101       else if (unformat (input, "proto %d", &proto_val))
10102         proto = 1;
10103       else if (unformat (input, "tos %d", &tos_val))
10104         tos = 1;
10105       else if (unformat (input, "length %d", &length_val))
10106         length = 1;
10107       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10108         fragment_id = 1;
10109       else if (unformat (input, "ttl %d", &ttl_val))
10110         ttl = 1;
10111       else if (unformat (input, "checksum %d", &checksum_val))
10112         checksum = 1;
10113       else
10114         break;
10115     }
10116
10117   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10118       + ttl + checksum == 0)
10119     return 0;
10120
10121   /*
10122    * Aligned because we use the real comparison functions
10123    */
10124   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10125
10126   ip = (ip4_header_t *) match;
10127
10128   /* These are realistically matched in practice */
10129   if (src)
10130     ip->src_address.as_u32 = src_val.as_u32;
10131
10132   if (dst)
10133     ip->dst_address.as_u32 = dst_val.as_u32;
10134
10135   if (proto)
10136     ip->protocol = proto_val;
10137
10138
10139   /* These are not, but they're included for completeness */
10140   if (version)
10141     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10142
10143   if (hdr_length)
10144     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10145
10146   if (tos)
10147     ip->tos = tos_val;
10148
10149   if (length)
10150     ip->length = clib_host_to_net_u16 (length_val);
10151
10152   if (ttl)
10153     ip->ttl = ttl_val;
10154
10155   if (checksum)
10156     ip->checksum = clib_host_to_net_u16 (checksum_val);
10157
10158   *matchp = match;
10159   return 1;
10160 }
10161
10162 uword
10163 unformat_ip6_match (unformat_input_t * input, va_list * args)
10164 {
10165   u8 **matchp = va_arg (*args, u8 **);
10166   u8 *match = 0;
10167   ip6_header_t *ip;
10168   int version = 0;
10169   u32 version_val;
10170   u8 traffic_class = 0;
10171   u32 traffic_class_val = 0;
10172   u8 flow_label = 0;
10173   u8 flow_label_val;
10174   int src = 0, dst = 0;
10175   ip6_address_t src_val, dst_val;
10176   int proto = 0;
10177   u32 proto_val;
10178   int payload_length = 0;
10179   u32 payload_length_val;
10180   int hop_limit = 0;
10181   int hop_limit_val;
10182   u32 ip_version_traffic_class_and_flow_label;
10183
10184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10185     {
10186       if (unformat (input, "version %d", &version_val))
10187         version = 1;
10188       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10189         traffic_class = 1;
10190       else if (unformat (input, "flow_label %d", &flow_label_val))
10191         flow_label = 1;
10192       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10193         src = 1;
10194       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10195         dst = 1;
10196       else if (unformat (input, "proto %d", &proto_val))
10197         proto = 1;
10198       else if (unformat (input, "payload_length %d", &payload_length_val))
10199         payload_length = 1;
10200       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10201         hop_limit = 1;
10202       else
10203         break;
10204     }
10205
10206   if (version + traffic_class + flow_label + src + dst + proto +
10207       payload_length + hop_limit == 0)
10208     return 0;
10209
10210   /*
10211    * Aligned because we use the real comparison functions
10212    */
10213   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10214
10215   ip = (ip6_header_t *) match;
10216
10217   if (src)
10218     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10219
10220   if (dst)
10221     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10222
10223   if (proto)
10224     ip->protocol = proto_val;
10225
10226   ip_version_traffic_class_and_flow_label = 0;
10227
10228   if (version)
10229     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10230
10231   if (traffic_class)
10232     ip_version_traffic_class_and_flow_label |=
10233       (traffic_class_val & 0xFF) << 20;
10234
10235   if (flow_label)
10236     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10237
10238   ip->ip_version_traffic_class_and_flow_label =
10239     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10240
10241   if (payload_length)
10242     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10243
10244   if (hop_limit)
10245     ip->hop_limit = hop_limit_val;
10246
10247   *matchp = match;
10248   return 1;
10249 }
10250
10251 uword
10252 unformat_l3_match (unformat_input_t * input, va_list * args)
10253 {
10254   u8 **matchp = va_arg (*args, u8 **);
10255
10256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10257     {
10258       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10259         return 1;
10260       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10261         return 1;
10262       else
10263         break;
10264     }
10265   return 0;
10266 }
10267
10268 uword
10269 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10270 {
10271   u8 *tagp = va_arg (*args, u8 *);
10272   u32 tag;
10273
10274   if (unformat (input, "%d", &tag))
10275     {
10276       tagp[0] = (tag >> 8) & 0x0F;
10277       tagp[1] = tag & 0xFF;
10278       return 1;
10279     }
10280
10281   return 0;
10282 }
10283
10284 uword
10285 unformat_l2_match (unformat_input_t * input, va_list * args)
10286 {
10287   u8 **matchp = va_arg (*args, u8 **);
10288   u8 *match = 0;
10289   u8 src = 0;
10290   u8 src_val[6];
10291   u8 dst = 0;
10292   u8 dst_val[6];
10293   u8 proto = 0;
10294   u16 proto_val;
10295   u8 tag1 = 0;
10296   u8 tag1_val[2];
10297   u8 tag2 = 0;
10298   u8 tag2_val[2];
10299   int len = 14;
10300   u8 ignore_tag1 = 0;
10301   u8 ignore_tag2 = 0;
10302   u8 cos1 = 0;
10303   u8 cos2 = 0;
10304   u32 cos1_val = 0;
10305   u32 cos2_val = 0;
10306
10307   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10308     {
10309       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10310         src = 1;
10311       else
10312         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10313         dst = 1;
10314       else if (unformat (input, "proto %U",
10315                          unformat_ethernet_type_host_byte_order, &proto_val))
10316         proto = 1;
10317       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10318         tag1 = 1;
10319       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10320         tag2 = 1;
10321       else if (unformat (input, "ignore-tag1"))
10322         ignore_tag1 = 1;
10323       else if (unformat (input, "ignore-tag2"))
10324         ignore_tag2 = 1;
10325       else if (unformat (input, "cos1 %d", &cos1_val))
10326         cos1 = 1;
10327       else if (unformat (input, "cos2 %d", &cos2_val))
10328         cos2 = 1;
10329       else
10330         break;
10331     }
10332   if ((src + dst + proto + tag1 + tag2 +
10333        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10334     return 0;
10335
10336   if (tag1 || ignore_tag1 || cos1)
10337     len = 18;
10338   if (tag2 || ignore_tag2 || cos2)
10339     len = 22;
10340
10341   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10342
10343   if (dst)
10344     clib_memcpy (match, dst_val, 6);
10345
10346   if (src)
10347     clib_memcpy (match + 6, src_val, 6);
10348
10349   if (tag2)
10350     {
10351       /* inner vlan tag */
10352       match[19] = tag2_val[1];
10353       match[18] = tag2_val[0];
10354       if (cos2)
10355         match[18] |= (cos2_val & 0x7) << 5;
10356       if (proto)
10357         {
10358           match[21] = proto_val & 0xff;
10359           match[20] = proto_val >> 8;
10360         }
10361       if (tag1)
10362         {
10363           match[15] = tag1_val[1];
10364           match[14] = tag1_val[0];
10365         }
10366       if (cos1)
10367         match[14] |= (cos1_val & 0x7) << 5;
10368       *matchp = match;
10369       return 1;
10370     }
10371   if (tag1)
10372     {
10373       match[15] = tag1_val[1];
10374       match[14] = tag1_val[0];
10375       if (proto)
10376         {
10377           match[17] = proto_val & 0xff;
10378           match[16] = proto_val >> 8;
10379         }
10380       if (cos1)
10381         match[14] |= (cos1_val & 0x7) << 5;
10382
10383       *matchp = match;
10384       return 1;
10385     }
10386   if (cos2)
10387     match[18] |= (cos2_val & 0x7) << 5;
10388   if (cos1)
10389     match[14] |= (cos1_val & 0x7) << 5;
10390   if (proto)
10391     {
10392       match[13] = proto_val & 0xff;
10393       match[12] = proto_val >> 8;
10394     }
10395
10396   *matchp = match;
10397   return 1;
10398 }
10399 #endif
10400
10401 uword
10402 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10403 {
10404   u8 **matchp = va_arg (*args, u8 **);
10405   u32 skip_n_vectors = va_arg (*args, u32);
10406   u32 match_n_vectors = va_arg (*args, u32);
10407
10408   u8 *match = 0;
10409   u8 *l2 = 0;
10410   u8 *l3 = 0;
10411   u8 *l4 = 0;
10412
10413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10414     {
10415       if (unformat (input, "hex %U", unformat_hex_string, &match))
10416         ;
10417       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10418         ;
10419       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10420         ;
10421       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10422         ;
10423       else
10424         break;
10425     }
10426
10427   if (l4 && !l3)
10428     {
10429       vec_free (match);
10430       vec_free (l2);
10431       vec_free (l4);
10432       return 0;
10433     }
10434
10435   if (match || l2 || l3 || l4)
10436     {
10437       if (l2 || l3 || l4)
10438         {
10439           /* "Win a free Ethernet header in every packet" */
10440           if (l2 == 0)
10441             vec_validate_aligned (l2, 13, sizeof (u32x4));
10442           match = l2;
10443           if (vec_len (l3))
10444             {
10445               vec_append_aligned (match, l3, sizeof (u32x4));
10446               vec_free (l3);
10447             }
10448           if (vec_len (l4))
10449             {
10450               vec_append_aligned (match, l4, sizeof (u32x4));
10451               vec_free (l4);
10452             }
10453         }
10454
10455       /* Make sure the vector is big enough even if key is all 0's */
10456       vec_validate_aligned
10457         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10458          sizeof (u32x4));
10459
10460       /* Set size, include skipped vectors */
10461       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10462
10463       *matchp = match;
10464
10465       return 1;
10466     }
10467
10468   return 0;
10469 }
10470
10471 static int
10472 api_classify_add_del_session (vat_main_t * vam)
10473 {
10474   unformat_input_t *i = vam->input;
10475   vl_api_classify_add_del_session_t *mp;
10476   int is_add = 1;
10477   u32 table_index = ~0;
10478   u32 hit_next_index = ~0;
10479   u32 opaque_index = ~0;
10480   u8 *match = 0;
10481   i32 advance = 0;
10482   u32 skip_n_vectors = 0;
10483   u32 match_n_vectors = 0;
10484   u32 action = 0;
10485   u32 metadata = 0;
10486   int ret;
10487
10488   /*
10489    * Warning: you have to supply skip_n and match_n
10490    * because the API client cant simply look at the classify
10491    * table object.
10492    */
10493
10494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10495     {
10496       if (unformat (i, "del"))
10497         is_add = 0;
10498       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10499                          &hit_next_index))
10500         ;
10501       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10502                          &hit_next_index))
10503         ;
10504       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10505                          &hit_next_index))
10506         ;
10507       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10508         ;
10509       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10510         ;
10511       else if (unformat (i, "opaque-index %d", &opaque_index))
10512         ;
10513       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10514         ;
10515       else if (unformat (i, "match_n %d", &match_n_vectors))
10516         ;
10517       else if (unformat (i, "match %U", api_unformat_classify_match,
10518                          &match, skip_n_vectors, match_n_vectors))
10519         ;
10520       else if (unformat (i, "advance %d", &advance))
10521         ;
10522       else if (unformat (i, "table-index %d", &table_index))
10523         ;
10524       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10525         action = 1;
10526       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10527         action = 2;
10528       else if (unformat (i, "action %d", &action))
10529         ;
10530       else if (unformat (i, "metadata %d", &metadata))
10531         ;
10532       else
10533         break;
10534     }
10535
10536   if (table_index == ~0)
10537     {
10538       errmsg ("Table index required");
10539       return -99;
10540     }
10541
10542   if (is_add && match == 0)
10543     {
10544       errmsg ("Match value required");
10545       return -99;
10546     }
10547
10548   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10549
10550   mp->is_add = is_add;
10551   mp->table_index = ntohl (table_index);
10552   mp->hit_next_index = ntohl (hit_next_index);
10553   mp->opaque_index = ntohl (opaque_index);
10554   mp->advance = ntohl (advance);
10555   mp->action = action;
10556   mp->metadata = ntohl (metadata);
10557   clib_memcpy (mp->match, match, vec_len (match));
10558   vec_free (match);
10559
10560   S (mp);
10561   W (ret);
10562   return ret;
10563 }
10564
10565 static int
10566 api_classify_set_interface_ip_table (vat_main_t * vam)
10567 {
10568   unformat_input_t *i = vam->input;
10569   vl_api_classify_set_interface_ip_table_t *mp;
10570   u32 sw_if_index;
10571   int sw_if_index_set;
10572   u32 table_index = ~0;
10573   u8 is_ipv6 = 0;
10574   int ret;
10575
10576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10577     {
10578       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10579         sw_if_index_set = 1;
10580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10581         sw_if_index_set = 1;
10582       else if (unformat (i, "table %d", &table_index))
10583         ;
10584       else
10585         {
10586           clib_warning ("parse error '%U'", format_unformat_error, i);
10587           return -99;
10588         }
10589     }
10590
10591   if (sw_if_index_set == 0)
10592     {
10593       errmsg ("missing interface name or sw_if_index");
10594       return -99;
10595     }
10596
10597
10598   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10599
10600   mp->sw_if_index = ntohl (sw_if_index);
10601   mp->table_index = ntohl (table_index);
10602   mp->is_ipv6 = is_ipv6;
10603
10604   S (mp);
10605   W (ret);
10606   return ret;
10607 }
10608
10609 static int
10610 api_classify_set_interface_l2_tables (vat_main_t * vam)
10611 {
10612   unformat_input_t *i = vam->input;
10613   vl_api_classify_set_interface_l2_tables_t *mp;
10614   u32 sw_if_index;
10615   int sw_if_index_set;
10616   u32 ip4_table_index = ~0;
10617   u32 ip6_table_index = ~0;
10618   u32 other_table_index = ~0;
10619   u32 is_input = 1;
10620   int ret;
10621
10622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10623     {
10624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10625         sw_if_index_set = 1;
10626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10627         sw_if_index_set = 1;
10628       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10629         ;
10630       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10631         ;
10632       else if (unformat (i, "other-table %d", &other_table_index))
10633         ;
10634       else if (unformat (i, "is-input %d", &is_input))
10635         ;
10636       else
10637         {
10638           clib_warning ("parse error '%U'", format_unformat_error, i);
10639           return -99;
10640         }
10641     }
10642
10643   if (sw_if_index_set == 0)
10644     {
10645       errmsg ("missing interface name or sw_if_index");
10646       return -99;
10647     }
10648
10649
10650   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10651
10652   mp->sw_if_index = ntohl (sw_if_index);
10653   mp->ip4_table_index = ntohl (ip4_table_index);
10654   mp->ip6_table_index = ntohl (ip6_table_index);
10655   mp->other_table_index = ntohl (other_table_index);
10656   mp->is_input = (u8) is_input;
10657
10658   S (mp);
10659   W (ret);
10660   return ret;
10661 }
10662
10663 static int
10664 api_set_ipfix_exporter (vat_main_t * vam)
10665 {
10666   unformat_input_t *i = vam->input;
10667   vl_api_set_ipfix_exporter_t *mp;
10668   ip4_address_t collector_address;
10669   u8 collector_address_set = 0;
10670   u32 collector_port = ~0;
10671   ip4_address_t src_address;
10672   u8 src_address_set = 0;
10673   u32 vrf_id = ~0;
10674   u32 path_mtu = ~0;
10675   u32 template_interval = ~0;
10676   u8 udp_checksum = 0;
10677   int ret;
10678
10679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (i, "collector_address %U", unformat_ip4_address,
10682                     &collector_address))
10683         collector_address_set = 1;
10684       else if (unformat (i, "collector_port %d", &collector_port))
10685         ;
10686       else if (unformat (i, "src_address %U", unformat_ip4_address,
10687                          &src_address))
10688         src_address_set = 1;
10689       else if (unformat (i, "vrf_id %d", &vrf_id))
10690         ;
10691       else if (unformat (i, "path_mtu %d", &path_mtu))
10692         ;
10693       else if (unformat (i, "template_interval %d", &template_interval))
10694         ;
10695       else if (unformat (i, "udp_checksum"))
10696         udp_checksum = 1;
10697       else
10698         break;
10699     }
10700
10701   if (collector_address_set == 0)
10702     {
10703       errmsg ("collector_address required");
10704       return -99;
10705     }
10706
10707   if (src_address_set == 0)
10708     {
10709       errmsg ("src_address required");
10710       return -99;
10711     }
10712
10713   M (SET_IPFIX_EXPORTER, mp);
10714
10715   memcpy (mp->collector_address, collector_address.data,
10716           sizeof (collector_address.data));
10717   mp->collector_port = htons ((u16) collector_port);
10718   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10719   mp->vrf_id = htonl (vrf_id);
10720   mp->path_mtu = htonl (path_mtu);
10721   mp->template_interval = htonl (template_interval);
10722   mp->udp_checksum = udp_checksum;
10723
10724   S (mp);
10725   W (ret);
10726   return ret;
10727 }
10728
10729 static int
10730 api_set_ipfix_classify_stream (vat_main_t * vam)
10731 {
10732   unformat_input_t *i = vam->input;
10733   vl_api_set_ipfix_classify_stream_t *mp;
10734   u32 domain_id = 0;
10735   u32 src_port = UDP_DST_PORT_ipfix;
10736   int ret;
10737
10738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10739     {
10740       if (unformat (i, "domain %d", &domain_id))
10741         ;
10742       else if (unformat (i, "src_port %d", &src_port))
10743         ;
10744       else
10745         {
10746           errmsg ("unknown input `%U'", format_unformat_error, i);
10747           return -99;
10748         }
10749     }
10750
10751   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10752
10753   mp->domain_id = htonl (domain_id);
10754   mp->src_port = htons ((u16) src_port);
10755
10756   S (mp);
10757   W (ret);
10758   return ret;
10759 }
10760
10761 static int
10762 api_ipfix_classify_table_add_del (vat_main_t * vam)
10763 {
10764   unformat_input_t *i = vam->input;
10765   vl_api_ipfix_classify_table_add_del_t *mp;
10766   int is_add = -1;
10767   u32 classify_table_index = ~0;
10768   u8 ip_version = 0;
10769   u8 transport_protocol = 255;
10770   int ret;
10771
10772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10773     {
10774       if (unformat (i, "add"))
10775         is_add = 1;
10776       else if (unformat (i, "del"))
10777         is_add = 0;
10778       else if (unformat (i, "table %d", &classify_table_index))
10779         ;
10780       else if (unformat (i, "ip4"))
10781         ip_version = 4;
10782       else if (unformat (i, "ip6"))
10783         ip_version = 6;
10784       else if (unformat (i, "tcp"))
10785         transport_protocol = 6;
10786       else if (unformat (i, "udp"))
10787         transport_protocol = 17;
10788       else
10789         {
10790           errmsg ("unknown input `%U'", format_unformat_error, i);
10791           return -99;
10792         }
10793     }
10794
10795   if (is_add == -1)
10796     {
10797       errmsg ("expecting: add|del");
10798       return -99;
10799     }
10800   if (classify_table_index == ~0)
10801     {
10802       errmsg ("classifier table not specified");
10803       return -99;
10804     }
10805   if (ip_version == 0)
10806     {
10807       errmsg ("IP version not specified");
10808       return -99;
10809     }
10810
10811   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10812
10813   mp->is_add = is_add;
10814   mp->table_id = htonl (classify_table_index);
10815   mp->ip_version = ip_version;
10816   mp->transport_protocol = transport_protocol;
10817
10818   S (mp);
10819   W (ret);
10820   return ret;
10821 }
10822
10823 static int
10824 api_get_node_index (vat_main_t * vam)
10825 {
10826   unformat_input_t *i = vam->input;
10827   vl_api_get_node_index_t *mp;
10828   u8 *name = 0;
10829   int ret;
10830
10831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10832     {
10833       if (unformat (i, "node %s", &name))
10834         ;
10835       else
10836         break;
10837     }
10838   if (name == 0)
10839     {
10840       errmsg ("node name required");
10841       return -99;
10842     }
10843   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10844     {
10845       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10846       return -99;
10847     }
10848
10849   M (GET_NODE_INDEX, mp);
10850   clib_memcpy (mp->node_name, name, vec_len (name));
10851   vec_free (name);
10852
10853   S (mp);
10854   W (ret);
10855   return ret;
10856 }
10857
10858 static int
10859 api_get_next_index (vat_main_t * vam)
10860 {
10861   unformat_input_t *i = vam->input;
10862   vl_api_get_next_index_t *mp;
10863   u8 *node_name = 0, *next_node_name = 0;
10864   int ret;
10865
10866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10867     {
10868       if (unformat (i, "node-name %s", &node_name))
10869         ;
10870       else if (unformat (i, "next-node-name %s", &next_node_name))
10871         break;
10872     }
10873
10874   if (node_name == 0)
10875     {
10876       errmsg ("node name required");
10877       return -99;
10878     }
10879   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10880     {
10881       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10882       return -99;
10883     }
10884
10885   if (next_node_name == 0)
10886     {
10887       errmsg ("next node name required");
10888       return -99;
10889     }
10890   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10891     {
10892       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10893       return -99;
10894     }
10895
10896   M (GET_NEXT_INDEX, mp);
10897   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10898   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10899   vec_free (node_name);
10900   vec_free (next_node_name);
10901
10902   S (mp);
10903   W (ret);
10904   return ret;
10905 }
10906
10907 static int
10908 api_add_node_next (vat_main_t * vam)
10909 {
10910   unformat_input_t *i = vam->input;
10911   vl_api_add_node_next_t *mp;
10912   u8 *name = 0;
10913   u8 *next = 0;
10914   int ret;
10915
10916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10917     {
10918       if (unformat (i, "node %s", &name))
10919         ;
10920       else if (unformat (i, "next %s", &next))
10921         ;
10922       else
10923         break;
10924     }
10925   if (name == 0)
10926     {
10927       errmsg ("node name required");
10928       return -99;
10929     }
10930   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10931     {
10932       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10933       return -99;
10934     }
10935   if (next == 0)
10936     {
10937       errmsg ("next node required");
10938       return -99;
10939     }
10940   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10941     {
10942       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10943       return -99;
10944     }
10945
10946   M (ADD_NODE_NEXT, mp);
10947   clib_memcpy (mp->node_name, name, vec_len (name));
10948   clib_memcpy (mp->next_name, next, vec_len (next));
10949   vec_free (name);
10950   vec_free (next);
10951
10952   S (mp);
10953   W (ret);
10954   return ret;
10955 }
10956
10957 static int
10958 api_l2tpv3_create_tunnel (vat_main_t * vam)
10959 {
10960   unformat_input_t *i = vam->input;
10961   ip6_address_t client_address, our_address;
10962   int client_address_set = 0;
10963   int our_address_set = 0;
10964   u32 local_session_id = 0;
10965   u32 remote_session_id = 0;
10966   u64 local_cookie = 0;
10967   u64 remote_cookie = 0;
10968   u8 l2_sublayer_present = 0;
10969   vl_api_l2tpv3_create_tunnel_t *mp;
10970   int ret;
10971
10972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10973     {
10974       if (unformat (i, "client_address %U", unformat_ip6_address,
10975                     &client_address))
10976         client_address_set = 1;
10977       else if (unformat (i, "our_address %U", unformat_ip6_address,
10978                          &our_address))
10979         our_address_set = 1;
10980       else if (unformat (i, "local_session_id %d", &local_session_id))
10981         ;
10982       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10983         ;
10984       else if (unformat (i, "local_cookie %lld", &local_cookie))
10985         ;
10986       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10987         ;
10988       else if (unformat (i, "l2-sublayer-present"))
10989         l2_sublayer_present = 1;
10990       else
10991         break;
10992     }
10993
10994   if (client_address_set == 0)
10995     {
10996       errmsg ("client_address required");
10997       return -99;
10998     }
10999
11000   if (our_address_set == 0)
11001     {
11002       errmsg ("our_address required");
11003       return -99;
11004     }
11005
11006   M (L2TPV3_CREATE_TUNNEL, mp);
11007
11008   clib_memcpy (mp->client_address, client_address.as_u8,
11009                sizeof (mp->client_address));
11010
11011   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11012
11013   mp->local_session_id = ntohl (local_session_id);
11014   mp->remote_session_id = ntohl (remote_session_id);
11015   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11016   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11017   mp->l2_sublayer_present = l2_sublayer_present;
11018   mp->is_ipv6 = 1;
11019
11020   S (mp);
11021   W (ret);
11022   return ret;
11023 }
11024
11025 static int
11026 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11027 {
11028   unformat_input_t *i = vam->input;
11029   u32 sw_if_index;
11030   u8 sw_if_index_set = 0;
11031   u64 new_local_cookie = 0;
11032   u64 new_remote_cookie = 0;
11033   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11034   int ret;
11035
11036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11037     {
11038       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11039         sw_if_index_set = 1;
11040       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11041         sw_if_index_set = 1;
11042       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11043         ;
11044       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11045         ;
11046       else
11047         break;
11048     }
11049
11050   if (sw_if_index_set == 0)
11051     {
11052       errmsg ("missing interface name or sw_if_index");
11053       return -99;
11054     }
11055
11056   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11057
11058   mp->sw_if_index = ntohl (sw_if_index);
11059   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11060   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11061
11062   S (mp);
11063   W (ret);
11064   return ret;
11065 }
11066
11067 static int
11068 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11069 {
11070   unformat_input_t *i = vam->input;
11071   vl_api_l2tpv3_interface_enable_disable_t *mp;
11072   u32 sw_if_index;
11073   u8 sw_if_index_set = 0;
11074   u8 enable_disable = 1;
11075   int ret;
11076
11077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11078     {
11079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11080         sw_if_index_set = 1;
11081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11082         sw_if_index_set = 1;
11083       else if (unformat (i, "enable"))
11084         enable_disable = 1;
11085       else if (unformat (i, "disable"))
11086         enable_disable = 0;
11087       else
11088         break;
11089     }
11090
11091   if (sw_if_index_set == 0)
11092     {
11093       errmsg ("missing interface name or sw_if_index");
11094       return -99;
11095     }
11096
11097   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11098
11099   mp->sw_if_index = ntohl (sw_if_index);
11100   mp->enable_disable = enable_disable;
11101
11102   S (mp);
11103   W (ret);
11104   return ret;
11105 }
11106
11107 static int
11108 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11109 {
11110   unformat_input_t *i = vam->input;
11111   vl_api_l2tpv3_set_lookup_key_t *mp;
11112   u8 key = ~0;
11113   int ret;
11114
11115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11116     {
11117       if (unformat (i, "lookup_v6_src"))
11118         key = L2T_LOOKUP_SRC_ADDRESS;
11119       else if (unformat (i, "lookup_v6_dst"))
11120         key = L2T_LOOKUP_DST_ADDRESS;
11121       else if (unformat (i, "lookup_session_id"))
11122         key = L2T_LOOKUP_SESSION_ID;
11123       else
11124         break;
11125     }
11126
11127   if (key == (u8) ~ 0)
11128     {
11129       errmsg ("l2tp session lookup key unset");
11130       return -99;
11131     }
11132
11133   M (L2TPV3_SET_LOOKUP_KEY, mp);
11134
11135   mp->key = key;
11136
11137   S (mp);
11138   W (ret);
11139   return ret;
11140 }
11141
11142 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11143   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11144 {
11145   vat_main_t *vam = &vat_main;
11146
11147   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11148          format_ip6_address, mp->our_address,
11149          format_ip6_address, mp->client_address,
11150          clib_net_to_host_u32 (mp->sw_if_index));
11151
11152   print (vam->ofp,
11153          "   local cookies %016llx %016llx remote cookie %016llx",
11154          clib_net_to_host_u64 (mp->local_cookie[0]),
11155          clib_net_to_host_u64 (mp->local_cookie[1]),
11156          clib_net_to_host_u64 (mp->remote_cookie));
11157
11158   print (vam->ofp, "   local session-id %d remote session-id %d",
11159          clib_net_to_host_u32 (mp->local_session_id),
11160          clib_net_to_host_u32 (mp->remote_session_id));
11161
11162   print (vam->ofp, "   l2 specific sublayer %s\n",
11163          mp->l2_sublayer_present ? "preset" : "absent");
11164
11165 }
11166
11167 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11168   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11169 {
11170   vat_main_t *vam = &vat_main;
11171   vat_json_node_t *node = NULL;
11172   struct in6_addr addr;
11173
11174   if (VAT_JSON_ARRAY != vam->json_tree.type)
11175     {
11176       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11177       vat_json_init_array (&vam->json_tree);
11178     }
11179   node = vat_json_array_add (&vam->json_tree);
11180
11181   vat_json_init_object (node);
11182
11183   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11184   vat_json_object_add_ip6 (node, "our_address", addr);
11185   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11186   vat_json_object_add_ip6 (node, "client_address", addr);
11187
11188   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11189   vat_json_init_array (lc);
11190   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11191   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11192   vat_json_object_add_uint (node, "remote_cookie",
11193                             clib_net_to_host_u64 (mp->remote_cookie));
11194
11195   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11196   vat_json_object_add_uint (node, "local_session_id",
11197                             clib_net_to_host_u32 (mp->local_session_id));
11198   vat_json_object_add_uint (node, "remote_session_id",
11199                             clib_net_to_host_u32 (mp->remote_session_id));
11200   vat_json_object_add_string_copy (node, "l2_sublayer",
11201                                    mp->l2_sublayer_present ? (u8 *) "present"
11202                                    : (u8 *) "absent");
11203 }
11204
11205 static int
11206 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11207 {
11208   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11209   vl_api_control_ping_t *mp_ping;
11210   int ret;
11211
11212   /* Get list of l2tpv3-tunnel interfaces */
11213   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11214   S (mp);
11215
11216   /* Use a control ping for synchronization */
11217   M (CONTROL_PING, mp_ping);
11218   S (mp_ping);
11219
11220   W (ret);
11221   return ret;
11222 }
11223
11224
11225 static void vl_api_sw_interface_tap_details_t_handler
11226   (vl_api_sw_interface_tap_details_t * mp)
11227 {
11228   vat_main_t *vam = &vat_main;
11229
11230   print (vam->ofp, "%-16s %d",
11231          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11232 }
11233
11234 static void vl_api_sw_interface_tap_details_t_handler_json
11235   (vl_api_sw_interface_tap_details_t * mp)
11236 {
11237   vat_main_t *vam = &vat_main;
11238   vat_json_node_t *node = NULL;
11239
11240   if (VAT_JSON_ARRAY != vam->json_tree.type)
11241     {
11242       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11243       vat_json_init_array (&vam->json_tree);
11244     }
11245   node = vat_json_array_add (&vam->json_tree);
11246
11247   vat_json_init_object (node);
11248   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11249   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11250 }
11251
11252 static int
11253 api_sw_interface_tap_dump (vat_main_t * vam)
11254 {
11255   vl_api_sw_interface_tap_dump_t *mp;
11256   vl_api_control_ping_t *mp_ping;
11257   int ret;
11258
11259   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11260   /* Get list of tap interfaces */
11261   M (SW_INTERFACE_TAP_DUMP, mp);
11262   S (mp);
11263
11264   /* Use a control ping for synchronization */
11265   M (CONTROL_PING, mp_ping);
11266   S (mp_ping);
11267
11268   W (ret);
11269   return ret;
11270 }
11271
11272 static uword unformat_vxlan_decap_next
11273   (unformat_input_t * input, va_list * args)
11274 {
11275   u32 *result = va_arg (*args, u32 *);
11276   u32 tmp;
11277
11278   if (unformat (input, "l2"))
11279     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11280   else if (unformat (input, "%d", &tmp))
11281     *result = tmp;
11282   else
11283     return 0;
11284   return 1;
11285 }
11286
11287 static int
11288 api_vxlan_add_del_tunnel (vat_main_t * vam)
11289 {
11290   unformat_input_t *line_input = vam->input;
11291   vl_api_vxlan_add_del_tunnel_t *mp;
11292   ip46_address_t src, dst;
11293   u8 is_add = 1;
11294   u8 ipv4_set = 0, ipv6_set = 0;
11295   u8 src_set = 0;
11296   u8 dst_set = 0;
11297   u8 grp_set = 0;
11298   u32 mcast_sw_if_index = ~0;
11299   u32 encap_vrf_id = 0;
11300   u32 decap_next_index = ~0;
11301   u32 vni = 0;
11302   int ret;
11303
11304   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11305   memset (&src, 0, sizeof src);
11306   memset (&dst, 0, sizeof dst);
11307
11308   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11309     {
11310       if (unformat (line_input, "del"))
11311         is_add = 0;
11312       else
11313         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11314         {
11315           ipv4_set = 1;
11316           src_set = 1;
11317         }
11318       else
11319         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11320         {
11321           ipv4_set = 1;
11322           dst_set = 1;
11323         }
11324       else
11325         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11326         {
11327           ipv6_set = 1;
11328           src_set = 1;
11329         }
11330       else
11331         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11332         {
11333           ipv6_set = 1;
11334           dst_set = 1;
11335         }
11336       else if (unformat (line_input, "group %U %U",
11337                          unformat_ip4_address, &dst.ip4,
11338                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11339         {
11340           grp_set = dst_set = 1;
11341           ipv4_set = 1;
11342         }
11343       else if (unformat (line_input, "group %U",
11344                          unformat_ip4_address, &dst.ip4))
11345         {
11346           grp_set = dst_set = 1;
11347           ipv4_set = 1;
11348         }
11349       else if (unformat (line_input, "group %U %U",
11350                          unformat_ip6_address, &dst.ip6,
11351                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11352         {
11353           grp_set = dst_set = 1;
11354           ipv6_set = 1;
11355         }
11356       else if (unformat (line_input, "group %U",
11357                          unformat_ip6_address, &dst.ip6))
11358         {
11359           grp_set = dst_set = 1;
11360           ipv6_set = 1;
11361         }
11362       else
11363         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11364         ;
11365       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11366         ;
11367       else if (unformat (line_input, "decap-next %U",
11368                          unformat_vxlan_decap_next, &decap_next_index))
11369         ;
11370       else if (unformat (line_input, "vni %d", &vni))
11371         ;
11372       else
11373         {
11374           errmsg ("parse error '%U'", format_unformat_error, line_input);
11375           return -99;
11376         }
11377     }
11378
11379   if (src_set == 0)
11380     {
11381       errmsg ("tunnel src address not specified");
11382       return -99;
11383     }
11384   if (dst_set == 0)
11385     {
11386       errmsg ("tunnel dst address not specified");
11387       return -99;
11388     }
11389
11390   if (grp_set && !ip46_address_is_multicast (&dst))
11391     {
11392       errmsg ("tunnel group address not multicast");
11393       return -99;
11394     }
11395   if (grp_set && mcast_sw_if_index == ~0)
11396     {
11397       errmsg ("tunnel nonexistent multicast device");
11398       return -99;
11399     }
11400   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11401     {
11402       errmsg ("tunnel dst address must be unicast");
11403       return -99;
11404     }
11405
11406
11407   if (ipv4_set && ipv6_set)
11408     {
11409       errmsg ("both IPv4 and IPv6 addresses specified");
11410       return -99;
11411     }
11412
11413   if ((vni == 0) || (vni >> 24))
11414     {
11415       errmsg ("vni not specified or out of range");
11416       return -99;
11417     }
11418
11419   M (VXLAN_ADD_DEL_TUNNEL, mp);
11420
11421   if (ipv6_set)
11422     {
11423       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11424       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11425     }
11426   else
11427     {
11428       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11429       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11430     }
11431   mp->encap_vrf_id = ntohl (encap_vrf_id);
11432   mp->decap_next_index = ntohl (decap_next_index);
11433   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11434   mp->vni = ntohl (vni);
11435   mp->is_add = is_add;
11436   mp->is_ipv6 = ipv6_set;
11437
11438   S (mp);
11439   W (ret);
11440   return ret;
11441 }
11442
11443 static void vl_api_vxlan_tunnel_details_t_handler
11444   (vl_api_vxlan_tunnel_details_t * mp)
11445 {
11446   vat_main_t *vam = &vat_main;
11447   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11448   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11449
11450   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11451          ntohl (mp->sw_if_index),
11452          format_ip46_address, &src, IP46_TYPE_ANY,
11453          format_ip46_address, &dst, IP46_TYPE_ANY,
11454          ntohl (mp->encap_vrf_id),
11455          ntohl (mp->decap_next_index), ntohl (mp->vni),
11456          ntohl (mp->mcast_sw_if_index));
11457 }
11458
11459 static void vl_api_vxlan_tunnel_details_t_handler_json
11460   (vl_api_vxlan_tunnel_details_t * mp)
11461 {
11462   vat_main_t *vam = &vat_main;
11463   vat_json_node_t *node = NULL;
11464
11465   if (VAT_JSON_ARRAY != vam->json_tree.type)
11466     {
11467       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11468       vat_json_init_array (&vam->json_tree);
11469     }
11470   node = vat_json_array_add (&vam->json_tree);
11471
11472   vat_json_init_object (node);
11473   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11474   if (mp->is_ipv6)
11475     {
11476       struct in6_addr ip6;
11477
11478       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11479       vat_json_object_add_ip6 (node, "src_address", ip6);
11480       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11481       vat_json_object_add_ip6 (node, "dst_address", ip6);
11482     }
11483   else
11484     {
11485       struct in_addr ip4;
11486
11487       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11488       vat_json_object_add_ip4 (node, "src_address", ip4);
11489       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11490       vat_json_object_add_ip4 (node, "dst_address", ip4);
11491     }
11492   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11493   vat_json_object_add_uint (node, "decap_next_index",
11494                             ntohl (mp->decap_next_index));
11495   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11496   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11497   vat_json_object_add_uint (node, "mcast_sw_if_index",
11498                             ntohl (mp->mcast_sw_if_index));
11499 }
11500
11501 static int
11502 api_vxlan_tunnel_dump (vat_main_t * vam)
11503 {
11504   unformat_input_t *i = vam->input;
11505   vl_api_vxlan_tunnel_dump_t *mp;
11506   vl_api_control_ping_t *mp_ping;
11507   u32 sw_if_index;
11508   u8 sw_if_index_set = 0;
11509   int ret;
11510
11511   /* Parse args required to build the message */
11512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11513     {
11514       if (unformat (i, "sw_if_index %d", &sw_if_index))
11515         sw_if_index_set = 1;
11516       else
11517         break;
11518     }
11519
11520   if (sw_if_index_set == 0)
11521     {
11522       sw_if_index = ~0;
11523     }
11524
11525   if (!vam->json_output)
11526     {
11527       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11528              "sw_if_index", "src_address", "dst_address",
11529              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11530     }
11531
11532   /* Get list of vxlan-tunnel interfaces */
11533   M (VXLAN_TUNNEL_DUMP, mp);
11534
11535   mp->sw_if_index = htonl (sw_if_index);
11536
11537   S (mp);
11538
11539   /* Use a control ping for synchronization */
11540   M (CONTROL_PING, mp_ping);
11541   S (mp_ping);
11542
11543   W (ret);
11544   return ret;
11545 }
11546
11547 static int
11548 api_gre_add_del_tunnel (vat_main_t * vam)
11549 {
11550   unformat_input_t *line_input = vam->input;
11551   vl_api_gre_add_del_tunnel_t *mp;
11552   ip4_address_t src4, dst4;
11553   ip6_address_t src6, dst6;
11554   u8 is_add = 1;
11555   u8 ipv4_set = 0;
11556   u8 ipv6_set = 0;
11557   u8 teb = 0;
11558   u8 src_set = 0;
11559   u8 dst_set = 0;
11560   u32 outer_fib_id = 0;
11561   int ret;
11562
11563   memset (&src4, 0, sizeof src4);
11564   memset (&dst4, 0, sizeof dst4);
11565   memset (&src6, 0, sizeof src6);
11566   memset (&dst6, 0, sizeof dst6);
11567
11568   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11569     {
11570       if (unformat (line_input, "del"))
11571         is_add = 0;
11572       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11573         {
11574           src_set = 1;
11575           ipv4_set = 1;
11576         }
11577       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11578         {
11579           dst_set = 1;
11580           ipv4_set = 1;
11581         }
11582       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11583         {
11584           src_set = 1;
11585           ipv6_set = 1;
11586         }
11587       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11588         {
11589           dst_set = 1;
11590           ipv6_set = 1;
11591         }
11592       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11593         ;
11594       else if (unformat (line_input, "teb"))
11595         teb = 1;
11596       else
11597         {
11598           errmsg ("parse error '%U'", format_unformat_error, line_input);
11599           return -99;
11600         }
11601     }
11602
11603   if (src_set == 0)
11604     {
11605       errmsg ("tunnel src address not specified");
11606       return -99;
11607     }
11608   if (dst_set == 0)
11609     {
11610       errmsg ("tunnel dst address not specified");
11611       return -99;
11612     }
11613   if (ipv4_set && ipv6_set)
11614     {
11615       errmsg ("both IPv4 and IPv6 addresses specified");
11616       return -99;
11617     }
11618
11619
11620   M (GRE_ADD_DEL_TUNNEL, mp);
11621
11622   if (ipv4_set)
11623     {
11624       clib_memcpy (&mp->src_address, &src4, 4);
11625       clib_memcpy (&mp->dst_address, &dst4, 4);
11626     }
11627   else
11628     {
11629       clib_memcpy (&mp->src_address, &src6, 16);
11630       clib_memcpy (&mp->dst_address, &dst6, 16);
11631     }
11632   mp->outer_fib_id = ntohl (outer_fib_id);
11633   mp->is_add = is_add;
11634   mp->teb = teb;
11635   mp->is_ipv6 = ipv6_set;
11636
11637   S (mp);
11638   W (ret);
11639   return ret;
11640 }
11641
11642 static void vl_api_gre_tunnel_details_t_handler
11643   (vl_api_gre_tunnel_details_t * mp)
11644 {
11645   vat_main_t *vam = &vat_main;
11646   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11647   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11648
11649   print (vam->ofp, "%11d%24U%24U%6d%14d",
11650          ntohl (mp->sw_if_index),
11651          format_ip46_address, &src, IP46_TYPE_ANY,
11652          format_ip46_address, &dst, IP46_TYPE_ANY,
11653          mp->teb, ntohl (mp->outer_fib_id));
11654 }
11655
11656 static void vl_api_gre_tunnel_details_t_handler_json
11657   (vl_api_gre_tunnel_details_t * mp)
11658 {
11659   vat_main_t *vam = &vat_main;
11660   vat_json_node_t *node = NULL;
11661   struct in_addr ip4;
11662   struct in6_addr ip6;
11663
11664   if (VAT_JSON_ARRAY != vam->json_tree.type)
11665     {
11666       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11667       vat_json_init_array (&vam->json_tree);
11668     }
11669   node = vat_json_array_add (&vam->json_tree);
11670
11671   vat_json_init_object (node);
11672   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11673   if (!mp->is_ipv6)
11674     {
11675       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11676       vat_json_object_add_ip4 (node, "src_address", ip4);
11677       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11678       vat_json_object_add_ip4 (node, "dst_address", ip4);
11679     }
11680   else
11681     {
11682       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11683       vat_json_object_add_ip6 (node, "src_address", ip6);
11684       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11685       vat_json_object_add_ip6 (node, "dst_address", ip6);
11686     }
11687   vat_json_object_add_uint (node, "teb", mp->teb);
11688   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11689   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11690 }
11691
11692 static int
11693 api_gre_tunnel_dump (vat_main_t * vam)
11694 {
11695   unformat_input_t *i = vam->input;
11696   vl_api_gre_tunnel_dump_t *mp;
11697   vl_api_control_ping_t *mp_ping;
11698   u32 sw_if_index;
11699   u8 sw_if_index_set = 0;
11700   int ret;
11701
11702   /* Parse args required to build the message */
11703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11704     {
11705       if (unformat (i, "sw_if_index %d", &sw_if_index))
11706         sw_if_index_set = 1;
11707       else
11708         break;
11709     }
11710
11711   if (sw_if_index_set == 0)
11712     {
11713       sw_if_index = ~0;
11714     }
11715
11716   if (!vam->json_output)
11717     {
11718       print (vam->ofp, "%11s%24s%24s%6s%14s",
11719              "sw_if_index", "src_address", "dst_address", "teb",
11720              "outer_fib_id");
11721     }
11722
11723   /* Get list of gre-tunnel interfaces */
11724   M (GRE_TUNNEL_DUMP, mp);
11725
11726   mp->sw_if_index = htonl (sw_if_index);
11727
11728   S (mp);
11729
11730   /* Use a control ping for synchronization */
11731   M (CONTROL_PING, mp_ping);
11732   S (mp_ping);
11733
11734   W (ret);
11735   return ret;
11736 }
11737
11738 static int
11739 api_l2_fib_clear_table (vat_main_t * vam)
11740 {
11741 //  unformat_input_t * i = vam->input;
11742   vl_api_l2_fib_clear_table_t *mp;
11743   int ret;
11744
11745   M (L2_FIB_CLEAR_TABLE, mp);
11746
11747   S (mp);
11748   W (ret);
11749   return ret;
11750 }
11751
11752 static int
11753 api_l2_interface_efp_filter (vat_main_t * vam)
11754 {
11755   unformat_input_t *i = vam->input;
11756   vl_api_l2_interface_efp_filter_t *mp;
11757   u32 sw_if_index;
11758   u8 enable = 1;
11759   u8 sw_if_index_set = 0;
11760   int ret;
11761
11762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11763     {
11764       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11765         sw_if_index_set = 1;
11766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11767         sw_if_index_set = 1;
11768       else if (unformat (i, "enable"))
11769         enable = 1;
11770       else if (unformat (i, "disable"))
11771         enable = 0;
11772       else
11773         {
11774           clib_warning ("parse error '%U'", format_unformat_error, i);
11775           return -99;
11776         }
11777     }
11778
11779   if (sw_if_index_set == 0)
11780     {
11781       errmsg ("missing sw_if_index");
11782       return -99;
11783     }
11784
11785   M (L2_INTERFACE_EFP_FILTER, mp);
11786
11787   mp->sw_if_index = ntohl (sw_if_index);
11788   mp->enable_disable = enable;
11789
11790   S (mp);
11791   W (ret);
11792   return ret;
11793 }
11794
11795 #define foreach_vtr_op                          \
11796 _("disable",  L2_VTR_DISABLED)                  \
11797 _("push-1",  L2_VTR_PUSH_1)                     \
11798 _("push-2",  L2_VTR_PUSH_2)                     \
11799 _("pop-1",  L2_VTR_POP_1)                       \
11800 _("pop-2",  L2_VTR_POP_2)                       \
11801 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11802 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11803 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11804 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11805
11806 static int
11807 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11808 {
11809   unformat_input_t *i = vam->input;
11810   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11811   u32 sw_if_index;
11812   u8 sw_if_index_set = 0;
11813   u8 vtr_op_set = 0;
11814   u32 vtr_op = 0;
11815   u32 push_dot1q = 1;
11816   u32 tag1 = ~0;
11817   u32 tag2 = ~0;
11818   int ret;
11819
11820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11821     {
11822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11823         sw_if_index_set = 1;
11824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11825         sw_if_index_set = 1;
11826       else if (unformat (i, "vtr_op %d", &vtr_op))
11827         vtr_op_set = 1;
11828 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11829       foreach_vtr_op
11830 #undef _
11831         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11832         ;
11833       else if (unformat (i, "tag1 %d", &tag1))
11834         ;
11835       else if (unformat (i, "tag2 %d", &tag2))
11836         ;
11837       else
11838         {
11839           clib_warning ("parse error '%U'", format_unformat_error, i);
11840           return -99;
11841         }
11842     }
11843
11844   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11845     {
11846       errmsg ("missing vtr operation or sw_if_index");
11847       return -99;
11848     }
11849
11850   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11851   mp->sw_if_index = ntohl (sw_if_index);
11852   mp->vtr_op = ntohl (vtr_op);
11853   mp->push_dot1q = ntohl (push_dot1q);
11854   mp->tag1 = ntohl (tag1);
11855   mp->tag2 = ntohl (tag2);
11856
11857   S (mp);
11858   W (ret);
11859   return ret;
11860 }
11861
11862 static int
11863 api_create_vhost_user_if (vat_main_t * vam)
11864 {
11865   unformat_input_t *i = vam->input;
11866   vl_api_create_vhost_user_if_t *mp;
11867   u8 *file_name;
11868   u8 is_server = 0;
11869   u8 file_name_set = 0;
11870   u32 custom_dev_instance = ~0;
11871   u8 hwaddr[6];
11872   u8 use_custom_mac = 0;
11873   u8 *tag = 0;
11874   int ret;
11875
11876   /* Shut up coverity */
11877   memset (hwaddr, 0, sizeof (hwaddr));
11878
11879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11880     {
11881       if (unformat (i, "socket %s", &file_name))
11882         {
11883           file_name_set = 1;
11884         }
11885       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11886         ;
11887       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11888         use_custom_mac = 1;
11889       else if (unformat (i, "server"))
11890         is_server = 1;
11891       else if (unformat (i, "tag %s", &tag))
11892         ;
11893       else
11894         break;
11895     }
11896
11897   if (file_name_set == 0)
11898     {
11899       errmsg ("missing socket file name");
11900       return -99;
11901     }
11902
11903   if (vec_len (file_name) > 255)
11904     {
11905       errmsg ("socket file name too long");
11906       return -99;
11907     }
11908   vec_add1 (file_name, 0);
11909
11910   M (CREATE_VHOST_USER_IF, mp);
11911
11912   mp->is_server = is_server;
11913   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11914   vec_free (file_name);
11915   if (custom_dev_instance != ~0)
11916     {
11917       mp->renumber = 1;
11918       mp->custom_dev_instance = ntohl (custom_dev_instance);
11919     }
11920   mp->use_custom_mac = use_custom_mac;
11921   clib_memcpy (mp->mac_address, hwaddr, 6);
11922   if (tag)
11923     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11924   vec_free (tag);
11925
11926   S (mp);
11927   W (ret);
11928   return ret;
11929 }
11930
11931 static int
11932 api_modify_vhost_user_if (vat_main_t * vam)
11933 {
11934   unformat_input_t *i = vam->input;
11935   vl_api_modify_vhost_user_if_t *mp;
11936   u8 *file_name;
11937   u8 is_server = 0;
11938   u8 file_name_set = 0;
11939   u32 custom_dev_instance = ~0;
11940   u8 sw_if_index_set = 0;
11941   u32 sw_if_index = (u32) ~ 0;
11942   int ret;
11943
11944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11945     {
11946       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11947         sw_if_index_set = 1;
11948       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11949         sw_if_index_set = 1;
11950       else if (unformat (i, "socket %s", &file_name))
11951         {
11952           file_name_set = 1;
11953         }
11954       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11955         ;
11956       else if (unformat (i, "server"))
11957         is_server = 1;
11958       else
11959         break;
11960     }
11961
11962   if (sw_if_index_set == 0)
11963     {
11964       errmsg ("missing sw_if_index or interface name");
11965       return -99;
11966     }
11967
11968   if (file_name_set == 0)
11969     {
11970       errmsg ("missing socket file name");
11971       return -99;
11972     }
11973
11974   if (vec_len (file_name) > 255)
11975     {
11976       errmsg ("socket file name too long");
11977       return -99;
11978     }
11979   vec_add1 (file_name, 0);
11980
11981   M (MODIFY_VHOST_USER_IF, mp);
11982
11983   mp->sw_if_index = ntohl (sw_if_index);
11984   mp->is_server = is_server;
11985   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11986   vec_free (file_name);
11987   if (custom_dev_instance != ~0)
11988     {
11989       mp->renumber = 1;
11990       mp->custom_dev_instance = ntohl (custom_dev_instance);
11991     }
11992
11993   S (mp);
11994   W (ret);
11995   return ret;
11996 }
11997
11998 static int
11999 api_delete_vhost_user_if (vat_main_t * vam)
12000 {
12001   unformat_input_t *i = vam->input;
12002   vl_api_delete_vhost_user_if_t *mp;
12003   u32 sw_if_index = ~0;
12004   u8 sw_if_index_set = 0;
12005   int ret;
12006
12007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12008     {
12009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12010         sw_if_index_set = 1;
12011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12012         sw_if_index_set = 1;
12013       else
12014         break;
12015     }
12016
12017   if (sw_if_index_set == 0)
12018     {
12019       errmsg ("missing sw_if_index or interface name");
12020       return -99;
12021     }
12022
12023
12024   M (DELETE_VHOST_USER_IF, mp);
12025
12026   mp->sw_if_index = ntohl (sw_if_index);
12027
12028   S (mp);
12029   W (ret);
12030   return ret;
12031 }
12032
12033 static void vl_api_sw_interface_vhost_user_details_t_handler
12034   (vl_api_sw_interface_vhost_user_details_t * mp)
12035 {
12036   vat_main_t *vam = &vat_main;
12037
12038   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12039          (char *) mp->interface_name,
12040          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12041          clib_net_to_host_u64 (mp->features), mp->is_server,
12042          ntohl (mp->num_regions), (char *) mp->sock_filename);
12043   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12044 }
12045
12046 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12047   (vl_api_sw_interface_vhost_user_details_t * mp)
12048 {
12049   vat_main_t *vam = &vat_main;
12050   vat_json_node_t *node = NULL;
12051
12052   if (VAT_JSON_ARRAY != vam->json_tree.type)
12053     {
12054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12055       vat_json_init_array (&vam->json_tree);
12056     }
12057   node = vat_json_array_add (&vam->json_tree);
12058
12059   vat_json_init_object (node);
12060   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12061   vat_json_object_add_string_copy (node, "interface_name",
12062                                    mp->interface_name);
12063   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12064                             ntohl (mp->virtio_net_hdr_sz));
12065   vat_json_object_add_uint (node, "features",
12066                             clib_net_to_host_u64 (mp->features));
12067   vat_json_object_add_uint (node, "is_server", mp->is_server);
12068   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12069   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12070   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12071 }
12072
12073 static int
12074 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12075 {
12076   vl_api_sw_interface_vhost_user_dump_t *mp;
12077   vl_api_control_ping_t *mp_ping;
12078   int ret;
12079   print (vam->ofp,
12080          "Interface name            idx hdr_sz features server regions filename");
12081
12082   /* Get list of vhost-user interfaces */
12083   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12084   S (mp);
12085
12086   /* Use a control ping for synchronization */
12087   M (CONTROL_PING, mp_ping);
12088   S (mp_ping);
12089
12090   W (ret);
12091   return ret;
12092 }
12093
12094 static int
12095 api_show_version (vat_main_t * vam)
12096 {
12097   vl_api_show_version_t *mp;
12098   int ret;
12099
12100   M (SHOW_VERSION, mp);
12101
12102   S (mp);
12103   W (ret);
12104   return ret;
12105 }
12106
12107
12108 static int
12109 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12110 {
12111   unformat_input_t *line_input = vam->input;
12112   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12113   ip4_address_t local4, remote4;
12114   ip6_address_t local6, remote6;
12115   u8 is_add = 1;
12116   u8 ipv4_set = 0, ipv6_set = 0;
12117   u8 local_set = 0;
12118   u8 remote_set = 0;
12119   u8 grp_set = 0;
12120   u32 mcast_sw_if_index = ~0;
12121   u32 encap_vrf_id = 0;
12122   u32 decap_vrf_id = 0;
12123   u8 protocol = ~0;
12124   u32 vni;
12125   u8 vni_set = 0;
12126   int ret;
12127
12128   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12129   memset (&local4, 0, sizeof local4);
12130   memset (&remote4, 0, sizeof remote4);
12131   memset (&local6, 0, sizeof local6);
12132   memset (&remote6, 0, sizeof remote6);
12133
12134   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12135     {
12136       if (unformat (line_input, "del"))
12137         is_add = 0;
12138       else if (unformat (line_input, "local %U",
12139                          unformat_ip4_address, &local4))
12140         {
12141           local_set = 1;
12142           ipv4_set = 1;
12143         }
12144       else if (unformat (line_input, "remote %U",
12145                          unformat_ip4_address, &remote4))
12146         {
12147           remote_set = 1;
12148           ipv4_set = 1;
12149         }
12150       else if (unformat (line_input, "local %U",
12151                          unformat_ip6_address, &local6))
12152         {
12153           local_set = 1;
12154           ipv6_set = 1;
12155         }
12156       else if (unformat (line_input, "remote %U",
12157                          unformat_ip6_address, &remote6))
12158         {
12159           remote_set = 1;
12160           ipv6_set = 1;
12161         }
12162       else if (unformat (line_input, "group %U %U",
12163                          unformat_ip4_address, &remote4,
12164                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12165         {
12166           grp_set = remote_set = 1;
12167           ipv4_set = 1;
12168         }
12169       else if (unformat (line_input, "group %U",
12170                          unformat_ip4_address, &remote4))
12171         {
12172           grp_set = remote_set = 1;
12173           ipv4_set = 1;
12174         }
12175       else if (unformat (line_input, "group %U %U",
12176                          unformat_ip6_address, &remote6,
12177                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12178         {
12179           grp_set = remote_set = 1;
12180           ipv6_set = 1;
12181         }
12182       else if (unformat (line_input, "group %U",
12183                          unformat_ip6_address, &remote6))
12184         {
12185           grp_set = remote_set = 1;
12186           ipv6_set = 1;
12187         }
12188       else
12189         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12190         ;
12191       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12192         ;
12193       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12194         ;
12195       else if (unformat (line_input, "vni %d", &vni))
12196         vni_set = 1;
12197       else if (unformat (line_input, "next-ip4"))
12198         protocol = 1;
12199       else if (unformat (line_input, "next-ip6"))
12200         protocol = 2;
12201       else if (unformat (line_input, "next-ethernet"))
12202         protocol = 3;
12203       else if (unformat (line_input, "next-nsh"))
12204         protocol = 4;
12205       else
12206         {
12207           errmsg ("parse error '%U'", format_unformat_error, line_input);
12208           return -99;
12209         }
12210     }
12211
12212   if (local_set == 0)
12213     {
12214       errmsg ("tunnel local address not specified");
12215       return -99;
12216     }
12217   if (remote_set == 0)
12218     {
12219       errmsg ("tunnel remote address not specified");
12220       return -99;
12221     }
12222   if (grp_set && mcast_sw_if_index == ~0)
12223     {
12224       errmsg ("tunnel nonexistent multicast device");
12225       return -99;
12226     }
12227   if (ipv4_set && ipv6_set)
12228     {
12229       errmsg ("both IPv4 and IPv6 addresses specified");
12230       return -99;
12231     }
12232
12233   if (vni_set == 0)
12234     {
12235       errmsg ("vni not specified");
12236       return -99;
12237     }
12238
12239   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12240
12241
12242   if (ipv6_set)
12243     {
12244       clib_memcpy (&mp->local, &local6, sizeof (local6));
12245       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12246     }
12247   else
12248     {
12249       clib_memcpy (&mp->local, &local4, sizeof (local4));
12250       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12251     }
12252
12253   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12254   mp->encap_vrf_id = ntohl (encap_vrf_id);
12255   mp->decap_vrf_id = ntohl (decap_vrf_id);
12256   mp->protocol = protocol;
12257   mp->vni = ntohl (vni);
12258   mp->is_add = is_add;
12259   mp->is_ipv6 = ipv6_set;
12260
12261   S (mp);
12262   W (ret);
12263   return ret;
12264 }
12265
12266 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12267   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12268 {
12269   vat_main_t *vam = &vat_main;
12270   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12271   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12272
12273   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12274          ntohl (mp->sw_if_index),
12275          format_ip46_address, &local, IP46_TYPE_ANY,
12276          format_ip46_address, &remote, IP46_TYPE_ANY,
12277          ntohl (mp->vni), mp->protocol,
12278          ntohl (mp->mcast_sw_if_index),
12279          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12280 }
12281
12282
12283 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12284   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12285 {
12286   vat_main_t *vam = &vat_main;
12287   vat_json_node_t *node = NULL;
12288   struct in_addr ip4;
12289   struct in6_addr ip6;
12290
12291   if (VAT_JSON_ARRAY != vam->json_tree.type)
12292     {
12293       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12294       vat_json_init_array (&vam->json_tree);
12295     }
12296   node = vat_json_array_add (&vam->json_tree);
12297
12298   vat_json_init_object (node);
12299   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12300   if (mp->is_ipv6)
12301     {
12302       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12303       vat_json_object_add_ip6 (node, "local", ip6);
12304       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12305       vat_json_object_add_ip6 (node, "remote", ip6);
12306     }
12307   else
12308     {
12309       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12310       vat_json_object_add_ip4 (node, "local", ip4);
12311       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12312       vat_json_object_add_ip4 (node, "remote", ip4);
12313     }
12314   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12315   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12316   vat_json_object_add_uint (node, "mcast_sw_if_index",
12317                             ntohl (mp->mcast_sw_if_index));
12318   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12319   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12320   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12321 }
12322
12323 static int
12324 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12325 {
12326   unformat_input_t *i = vam->input;
12327   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12328   vl_api_control_ping_t *mp_ping;
12329   u32 sw_if_index;
12330   u8 sw_if_index_set = 0;
12331   int ret;
12332
12333   /* Parse args required to build the message */
12334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12335     {
12336       if (unformat (i, "sw_if_index %d", &sw_if_index))
12337         sw_if_index_set = 1;
12338       else
12339         break;
12340     }
12341
12342   if (sw_if_index_set == 0)
12343     {
12344       sw_if_index = ~0;
12345     }
12346
12347   if (!vam->json_output)
12348     {
12349       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12350              "sw_if_index", "local", "remote", "vni",
12351              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12352     }
12353
12354   /* Get list of vxlan-tunnel interfaces */
12355   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12356
12357   mp->sw_if_index = htonl (sw_if_index);
12358
12359   S (mp);
12360
12361   /* Use a control ping for synchronization */
12362   M (CONTROL_PING, mp_ping);
12363   S (mp_ping);
12364
12365   W (ret);
12366   return ret;
12367 }
12368
12369
12370 u8 *
12371 format_l2_fib_mac_address (u8 * s, va_list * args)
12372 {
12373   u8 *a = va_arg (*args, u8 *);
12374
12375   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12376                  a[2], a[3], a[4], a[5], a[6], a[7]);
12377 }
12378
12379 static void vl_api_l2_fib_table_details_t_handler
12380   (vl_api_l2_fib_table_details_t * mp)
12381 {
12382   vat_main_t *vam = &vat_main;
12383
12384   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12385          "       %d       %d     %d",
12386          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12387          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12388          mp->bvi_mac);
12389 }
12390
12391 static void vl_api_l2_fib_table_details_t_handler_json
12392   (vl_api_l2_fib_table_details_t * mp)
12393 {
12394   vat_main_t *vam = &vat_main;
12395   vat_json_node_t *node = NULL;
12396
12397   if (VAT_JSON_ARRAY != vam->json_tree.type)
12398     {
12399       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12400       vat_json_init_array (&vam->json_tree);
12401     }
12402   node = vat_json_array_add (&vam->json_tree);
12403
12404   vat_json_init_object (node);
12405   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12406   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12407   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12408   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12409   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12410   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12411 }
12412
12413 static int
12414 api_l2_fib_table_dump (vat_main_t * vam)
12415 {
12416   unformat_input_t *i = vam->input;
12417   vl_api_l2_fib_table_dump_t *mp;
12418   vl_api_control_ping_t *mp_ping;
12419   u32 bd_id;
12420   u8 bd_id_set = 0;
12421   int ret;
12422
12423   /* Parse args required to build the message */
12424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12425     {
12426       if (unformat (i, "bd_id %d", &bd_id))
12427         bd_id_set = 1;
12428       else
12429         break;
12430     }
12431
12432   if (bd_id_set == 0)
12433     {
12434       errmsg ("missing bridge domain");
12435       return -99;
12436     }
12437
12438   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12439
12440   /* Get list of l2 fib entries */
12441   M (L2_FIB_TABLE_DUMP, mp);
12442
12443   mp->bd_id = ntohl (bd_id);
12444   S (mp);
12445
12446   /* Use a control ping for synchronization */
12447   M (CONTROL_PING, mp_ping);
12448   S (mp_ping);
12449
12450   W (ret);
12451   return ret;
12452 }
12453
12454
12455 static int
12456 api_interface_name_renumber (vat_main_t * vam)
12457 {
12458   unformat_input_t *line_input = vam->input;
12459   vl_api_interface_name_renumber_t *mp;
12460   u32 sw_if_index = ~0;
12461   u32 new_show_dev_instance = ~0;
12462   int ret;
12463
12464   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12465     {
12466       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12467                     &sw_if_index))
12468         ;
12469       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12470         ;
12471       else if (unformat (line_input, "new_show_dev_instance %d",
12472                          &new_show_dev_instance))
12473         ;
12474       else
12475         break;
12476     }
12477
12478   if (sw_if_index == ~0)
12479     {
12480       errmsg ("missing interface name or sw_if_index");
12481       return -99;
12482     }
12483
12484   if (new_show_dev_instance == ~0)
12485     {
12486       errmsg ("missing new_show_dev_instance");
12487       return -99;
12488     }
12489
12490   M (INTERFACE_NAME_RENUMBER, mp);
12491
12492   mp->sw_if_index = ntohl (sw_if_index);
12493   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12494
12495   S (mp);
12496   W (ret);
12497   return ret;
12498 }
12499
12500 static int
12501 api_want_ip4_arp_events (vat_main_t * vam)
12502 {
12503   unformat_input_t *line_input = vam->input;
12504   vl_api_want_ip4_arp_events_t *mp;
12505   ip4_address_t address;
12506   int address_set = 0;
12507   u32 enable_disable = 1;
12508   int ret;
12509
12510   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12511     {
12512       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12513         address_set = 1;
12514       else if (unformat (line_input, "del"))
12515         enable_disable = 0;
12516       else
12517         break;
12518     }
12519
12520   if (address_set == 0)
12521     {
12522       errmsg ("missing addresses");
12523       return -99;
12524     }
12525
12526   M (WANT_IP4_ARP_EVENTS, mp);
12527   mp->enable_disable = enable_disable;
12528   mp->pid = htonl (getpid ());
12529   mp->address = address.as_u32;
12530
12531   S (mp);
12532   W (ret);
12533   return ret;
12534 }
12535
12536 static int
12537 api_want_ip6_nd_events (vat_main_t * vam)
12538 {
12539   unformat_input_t *line_input = vam->input;
12540   vl_api_want_ip6_nd_events_t *mp;
12541   ip6_address_t address;
12542   int address_set = 0;
12543   u32 enable_disable = 1;
12544   int ret;
12545
12546   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12547     {
12548       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12549         address_set = 1;
12550       else if (unformat (line_input, "del"))
12551         enable_disable = 0;
12552       else
12553         break;
12554     }
12555
12556   if (address_set == 0)
12557     {
12558       errmsg ("missing addresses");
12559       return -99;
12560     }
12561
12562   M (WANT_IP6_ND_EVENTS, mp);
12563   mp->enable_disable = enable_disable;
12564   mp->pid = htonl (getpid ());
12565   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12566
12567   S (mp);
12568   W (ret);
12569   return ret;
12570 }
12571
12572 static int
12573 api_want_l2_macs_events (vat_main_t * vam)
12574 {
12575   unformat_input_t *line_input = vam->input;
12576   vl_api_want_l2_macs_events_t *mp;
12577   u8 enable_disable = 1;
12578   u32 scan_delay = 0;
12579   u32 max_macs_in_event = 0;
12580   u32 learn_limit = 0;
12581   int ret;
12582
12583   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12584     {
12585       if (unformat (line_input, "learn-limit %d", &learn_limit))
12586         ;
12587       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12588         ;
12589       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12590         ;
12591       else if (unformat (line_input, "disable"))
12592         enable_disable = 0;
12593       else
12594         break;
12595     }
12596
12597   M (WANT_L2_MACS_EVENTS, mp);
12598   mp->enable_disable = enable_disable;
12599   mp->pid = htonl (getpid ());
12600   mp->learn_limit = htonl (learn_limit);
12601   mp->scan_delay = (u8) scan_delay;
12602   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12603   S (mp);
12604   W (ret);
12605   return ret;
12606 }
12607
12608 static int
12609 api_input_acl_set_interface (vat_main_t * vam)
12610 {
12611   unformat_input_t *i = vam->input;
12612   vl_api_input_acl_set_interface_t *mp;
12613   u32 sw_if_index;
12614   int sw_if_index_set;
12615   u32 ip4_table_index = ~0;
12616   u32 ip6_table_index = ~0;
12617   u32 l2_table_index = ~0;
12618   u8 is_add = 1;
12619   int ret;
12620
12621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12622     {
12623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12624         sw_if_index_set = 1;
12625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12626         sw_if_index_set = 1;
12627       else if (unformat (i, "del"))
12628         is_add = 0;
12629       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12630         ;
12631       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12632         ;
12633       else if (unformat (i, "l2-table %d", &l2_table_index))
12634         ;
12635       else
12636         {
12637           clib_warning ("parse error '%U'", format_unformat_error, i);
12638           return -99;
12639         }
12640     }
12641
12642   if (sw_if_index_set == 0)
12643     {
12644       errmsg ("missing interface name or sw_if_index");
12645       return -99;
12646     }
12647
12648   M (INPUT_ACL_SET_INTERFACE, mp);
12649
12650   mp->sw_if_index = ntohl (sw_if_index);
12651   mp->ip4_table_index = ntohl (ip4_table_index);
12652   mp->ip6_table_index = ntohl (ip6_table_index);
12653   mp->l2_table_index = ntohl (l2_table_index);
12654   mp->is_add = is_add;
12655
12656   S (mp);
12657   W (ret);
12658   return ret;
12659 }
12660
12661 static int
12662 api_ip_address_dump (vat_main_t * vam)
12663 {
12664   unformat_input_t *i = vam->input;
12665   vl_api_ip_address_dump_t *mp;
12666   vl_api_control_ping_t *mp_ping;
12667   u32 sw_if_index = ~0;
12668   u8 sw_if_index_set = 0;
12669   u8 ipv4_set = 0;
12670   u8 ipv6_set = 0;
12671   int ret;
12672
12673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12674     {
12675       if (unformat (i, "sw_if_index %d", &sw_if_index))
12676         sw_if_index_set = 1;
12677       else
12678         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12679         sw_if_index_set = 1;
12680       else if (unformat (i, "ipv4"))
12681         ipv4_set = 1;
12682       else if (unformat (i, "ipv6"))
12683         ipv6_set = 1;
12684       else
12685         break;
12686     }
12687
12688   if (ipv4_set && ipv6_set)
12689     {
12690       errmsg ("ipv4 and ipv6 flags cannot be both set");
12691       return -99;
12692     }
12693
12694   if ((!ipv4_set) && (!ipv6_set))
12695     {
12696       errmsg ("no ipv4 nor ipv6 flag set");
12697       return -99;
12698     }
12699
12700   if (sw_if_index_set == 0)
12701     {
12702       errmsg ("missing interface name or sw_if_index");
12703       return -99;
12704     }
12705
12706   vam->current_sw_if_index = sw_if_index;
12707   vam->is_ipv6 = ipv6_set;
12708
12709   M (IP_ADDRESS_DUMP, mp);
12710   mp->sw_if_index = ntohl (sw_if_index);
12711   mp->is_ipv6 = ipv6_set;
12712   S (mp);
12713
12714   /* Use a control ping for synchronization */
12715   M (CONTROL_PING, mp_ping);
12716   S (mp_ping);
12717
12718   W (ret);
12719   return ret;
12720 }
12721
12722 static int
12723 api_ip_dump (vat_main_t * vam)
12724 {
12725   vl_api_ip_dump_t *mp;
12726   vl_api_control_ping_t *mp_ping;
12727   unformat_input_t *in = vam->input;
12728   int ipv4_set = 0;
12729   int ipv6_set = 0;
12730   int is_ipv6;
12731   int i;
12732   int ret;
12733
12734   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12735     {
12736       if (unformat (in, "ipv4"))
12737         ipv4_set = 1;
12738       else if (unformat (in, "ipv6"))
12739         ipv6_set = 1;
12740       else
12741         break;
12742     }
12743
12744   if (ipv4_set && ipv6_set)
12745     {
12746       errmsg ("ipv4 and ipv6 flags cannot be both set");
12747       return -99;
12748     }
12749
12750   if ((!ipv4_set) && (!ipv6_set))
12751     {
12752       errmsg ("no ipv4 nor ipv6 flag set");
12753       return -99;
12754     }
12755
12756   is_ipv6 = ipv6_set;
12757   vam->is_ipv6 = is_ipv6;
12758
12759   /* free old data */
12760   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12761     {
12762       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12763     }
12764   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12765
12766   M (IP_DUMP, mp);
12767   mp->is_ipv6 = ipv6_set;
12768   S (mp);
12769
12770   /* Use a control ping for synchronization */
12771   M (CONTROL_PING, mp_ping);
12772   S (mp_ping);
12773
12774   W (ret);
12775   return ret;
12776 }
12777
12778 static int
12779 api_ipsec_spd_add_del (vat_main_t * vam)
12780 {
12781   unformat_input_t *i = vam->input;
12782   vl_api_ipsec_spd_add_del_t *mp;
12783   u32 spd_id = ~0;
12784   u8 is_add = 1;
12785   int ret;
12786
12787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12788     {
12789       if (unformat (i, "spd_id %d", &spd_id))
12790         ;
12791       else if (unformat (i, "del"))
12792         is_add = 0;
12793       else
12794         {
12795           clib_warning ("parse error '%U'", format_unformat_error, i);
12796           return -99;
12797         }
12798     }
12799   if (spd_id == ~0)
12800     {
12801       errmsg ("spd_id must be set");
12802       return -99;
12803     }
12804
12805   M (IPSEC_SPD_ADD_DEL, mp);
12806
12807   mp->spd_id = ntohl (spd_id);
12808   mp->is_add = is_add;
12809
12810   S (mp);
12811   W (ret);
12812   return ret;
12813 }
12814
12815 static int
12816 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12817 {
12818   unformat_input_t *i = vam->input;
12819   vl_api_ipsec_interface_add_del_spd_t *mp;
12820   u32 sw_if_index;
12821   u8 sw_if_index_set = 0;
12822   u32 spd_id = (u32) ~ 0;
12823   u8 is_add = 1;
12824   int ret;
12825
12826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12827     {
12828       if (unformat (i, "del"))
12829         is_add = 0;
12830       else if (unformat (i, "spd_id %d", &spd_id))
12831         ;
12832       else
12833         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12834         sw_if_index_set = 1;
12835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12836         sw_if_index_set = 1;
12837       else
12838         {
12839           clib_warning ("parse error '%U'", format_unformat_error, i);
12840           return -99;
12841         }
12842
12843     }
12844
12845   if (spd_id == (u32) ~ 0)
12846     {
12847       errmsg ("spd_id must be set");
12848       return -99;
12849     }
12850
12851   if (sw_if_index_set == 0)
12852     {
12853       errmsg ("missing interface name or sw_if_index");
12854       return -99;
12855     }
12856
12857   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12858
12859   mp->spd_id = ntohl (spd_id);
12860   mp->sw_if_index = ntohl (sw_if_index);
12861   mp->is_add = is_add;
12862
12863   S (mp);
12864   W (ret);
12865   return ret;
12866 }
12867
12868 static int
12869 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12870 {
12871   unformat_input_t *i = vam->input;
12872   vl_api_ipsec_spd_add_del_entry_t *mp;
12873   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12874   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12875   i32 priority = 0;
12876   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12877   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12878   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12879   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12880   int ret;
12881
12882   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12883   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12884   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12885   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12886   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12887   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12888
12889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12890     {
12891       if (unformat (i, "del"))
12892         is_add = 0;
12893       if (unformat (i, "outbound"))
12894         is_outbound = 1;
12895       if (unformat (i, "inbound"))
12896         is_outbound = 0;
12897       else if (unformat (i, "spd_id %d", &spd_id))
12898         ;
12899       else if (unformat (i, "sa_id %d", &sa_id))
12900         ;
12901       else if (unformat (i, "priority %d", &priority))
12902         ;
12903       else if (unformat (i, "protocol %d", &protocol))
12904         ;
12905       else if (unformat (i, "lport_start %d", &lport_start))
12906         ;
12907       else if (unformat (i, "lport_stop %d", &lport_stop))
12908         ;
12909       else if (unformat (i, "rport_start %d", &rport_start))
12910         ;
12911       else if (unformat (i, "rport_stop %d", &rport_stop))
12912         ;
12913       else
12914         if (unformat
12915             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12916         {
12917           is_ipv6 = 0;
12918           is_ip_any = 0;
12919         }
12920       else
12921         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12922         {
12923           is_ipv6 = 0;
12924           is_ip_any = 0;
12925         }
12926       else
12927         if (unformat
12928             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12929         {
12930           is_ipv6 = 0;
12931           is_ip_any = 0;
12932         }
12933       else
12934         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12935         {
12936           is_ipv6 = 0;
12937           is_ip_any = 0;
12938         }
12939       else
12940         if (unformat
12941             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12942         {
12943           is_ipv6 = 1;
12944           is_ip_any = 0;
12945         }
12946       else
12947         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12948         {
12949           is_ipv6 = 1;
12950           is_ip_any = 0;
12951         }
12952       else
12953         if (unformat
12954             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12955         {
12956           is_ipv6 = 1;
12957           is_ip_any = 0;
12958         }
12959       else
12960         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12961         {
12962           is_ipv6 = 1;
12963           is_ip_any = 0;
12964         }
12965       else
12966         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12967         {
12968           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12969             {
12970               clib_warning ("unsupported action: 'resolve'");
12971               return -99;
12972             }
12973         }
12974       else
12975         {
12976           clib_warning ("parse error '%U'", format_unformat_error, i);
12977           return -99;
12978         }
12979
12980     }
12981
12982   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12983
12984   mp->spd_id = ntohl (spd_id);
12985   mp->priority = ntohl (priority);
12986   mp->is_outbound = is_outbound;
12987
12988   mp->is_ipv6 = is_ipv6;
12989   if (is_ipv6 || is_ip_any)
12990     {
12991       clib_memcpy (mp->remote_address_start, &raddr6_start,
12992                    sizeof (ip6_address_t));
12993       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12994                    sizeof (ip6_address_t));
12995       clib_memcpy (mp->local_address_start, &laddr6_start,
12996                    sizeof (ip6_address_t));
12997       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12998                    sizeof (ip6_address_t));
12999     }
13000   else
13001     {
13002       clib_memcpy (mp->remote_address_start, &raddr4_start,
13003                    sizeof (ip4_address_t));
13004       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13005                    sizeof (ip4_address_t));
13006       clib_memcpy (mp->local_address_start, &laddr4_start,
13007                    sizeof (ip4_address_t));
13008       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13009                    sizeof (ip4_address_t));
13010     }
13011   mp->protocol = (u8) protocol;
13012   mp->local_port_start = ntohs ((u16) lport_start);
13013   mp->local_port_stop = ntohs ((u16) lport_stop);
13014   mp->remote_port_start = ntohs ((u16) rport_start);
13015   mp->remote_port_stop = ntohs ((u16) rport_stop);
13016   mp->policy = (u8) policy;
13017   mp->sa_id = ntohl (sa_id);
13018   mp->is_add = is_add;
13019   mp->is_ip_any = is_ip_any;
13020   S (mp);
13021   W (ret);
13022   return ret;
13023 }
13024
13025 static int
13026 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13027 {
13028   unformat_input_t *i = vam->input;
13029   vl_api_ipsec_sad_add_del_entry_t *mp;
13030   u32 sad_id = 0, spi = 0;
13031   u8 *ck = 0, *ik = 0;
13032   u8 is_add = 1;
13033
13034   u8 protocol = IPSEC_PROTOCOL_AH;
13035   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13036   u32 crypto_alg = 0, integ_alg = 0;
13037   ip4_address_t tun_src4;
13038   ip4_address_t tun_dst4;
13039   ip6_address_t tun_src6;
13040   ip6_address_t tun_dst6;
13041   int ret;
13042
13043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13044     {
13045       if (unformat (i, "del"))
13046         is_add = 0;
13047       else if (unformat (i, "sad_id %d", &sad_id))
13048         ;
13049       else if (unformat (i, "spi %d", &spi))
13050         ;
13051       else if (unformat (i, "esp"))
13052         protocol = IPSEC_PROTOCOL_ESP;
13053       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13054         {
13055           is_tunnel = 1;
13056           is_tunnel_ipv6 = 0;
13057         }
13058       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13059         {
13060           is_tunnel = 1;
13061           is_tunnel_ipv6 = 0;
13062         }
13063       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13064         {
13065           is_tunnel = 1;
13066           is_tunnel_ipv6 = 1;
13067         }
13068       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13069         {
13070           is_tunnel = 1;
13071           is_tunnel_ipv6 = 1;
13072         }
13073       else
13074         if (unformat
13075             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13076         {
13077           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13078               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13079             {
13080               clib_warning ("unsupported crypto-alg: '%U'",
13081                             format_ipsec_crypto_alg, crypto_alg);
13082               return -99;
13083             }
13084         }
13085       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13086         ;
13087       else
13088         if (unformat
13089             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13090         {
13091           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13092               integ_alg >= IPSEC_INTEG_N_ALG)
13093             {
13094               clib_warning ("unsupported integ-alg: '%U'",
13095                             format_ipsec_integ_alg, integ_alg);
13096               return -99;
13097             }
13098         }
13099       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13100         ;
13101       else
13102         {
13103           clib_warning ("parse error '%U'", format_unformat_error, i);
13104           return -99;
13105         }
13106
13107     }
13108
13109   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13110
13111   mp->sad_id = ntohl (sad_id);
13112   mp->is_add = is_add;
13113   mp->protocol = protocol;
13114   mp->spi = ntohl (spi);
13115   mp->is_tunnel = is_tunnel;
13116   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13117   mp->crypto_algorithm = crypto_alg;
13118   mp->integrity_algorithm = integ_alg;
13119   mp->crypto_key_length = vec_len (ck);
13120   mp->integrity_key_length = vec_len (ik);
13121
13122   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13123     mp->crypto_key_length = sizeof (mp->crypto_key);
13124
13125   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13126     mp->integrity_key_length = sizeof (mp->integrity_key);
13127
13128   if (ck)
13129     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13130   if (ik)
13131     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13132
13133   if (is_tunnel)
13134     {
13135       if (is_tunnel_ipv6)
13136         {
13137           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13138                        sizeof (ip6_address_t));
13139           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13140                        sizeof (ip6_address_t));
13141         }
13142       else
13143         {
13144           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13145                        sizeof (ip4_address_t));
13146           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13147                        sizeof (ip4_address_t));
13148         }
13149     }
13150
13151   S (mp);
13152   W (ret);
13153   return ret;
13154 }
13155
13156 static int
13157 api_ipsec_sa_set_key (vat_main_t * vam)
13158 {
13159   unformat_input_t *i = vam->input;
13160   vl_api_ipsec_sa_set_key_t *mp;
13161   u32 sa_id;
13162   u8 *ck = 0, *ik = 0;
13163   int ret;
13164
13165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13166     {
13167       if (unformat (i, "sa_id %d", &sa_id))
13168         ;
13169       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13170         ;
13171       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13172         ;
13173       else
13174         {
13175           clib_warning ("parse error '%U'", format_unformat_error, i);
13176           return -99;
13177         }
13178     }
13179
13180   M (IPSEC_SA_SET_KEY, mp);
13181
13182   mp->sa_id = ntohl (sa_id);
13183   mp->crypto_key_length = vec_len (ck);
13184   mp->integrity_key_length = vec_len (ik);
13185
13186   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13187     mp->crypto_key_length = sizeof (mp->crypto_key);
13188
13189   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13190     mp->integrity_key_length = sizeof (mp->integrity_key);
13191
13192   if (ck)
13193     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13194   if (ik)
13195     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13196
13197   S (mp);
13198   W (ret);
13199   return ret;
13200 }
13201
13202 static int
13203 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13204 {
13205   unformat_input_t *i = vam->input;
13206   vl_api_ipsec_tunnel_if_add_del_t *mp;
13207   u32 local_spi = 0, remote_spi = 0;
13208   u32 crypto_alg = 0, integ_alg = 0;
13209   u8 *lck = NULL, *rck = NULL;
13210   u8 *lik = NULL, *rik = NULL;
13211   ip4_address_t local_ip = { {0} };
13212   ip4_address_t remote_ip = { {0} };
13213   u8 is_add = 1;
13214   u8 esn = 0;
13215   u8 anti_replay = 0;
13216   int ret;
13217
13218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13219     {
13220       if (unformat (i, "del"))
13221         is_add = 0;
13222       else if (unformat (i, "esn"))
13223         esn = 1;
13224       else if (unformat (i, "anti_replay"))
13225         anti_replay = 1;
13226       else if (unformat (i, "local_spi %d", &local_spi))
13227         ;
13228       else if (unformat (i, "remote_spi %d", &remote_spi))
13229         ;
13230       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13231         ;
13232       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13233         ;
13234       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13235         ;
13236       else
13237         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13238         ;
13239       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13240         ;
13241       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13242         ;
13243       else
13244         if (unformat
13245             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13246         {
13247           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13248               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13249             {
13250               errmsg ("unsupported crypto-alg: '%U'\n",
13251                       format_ipsec_crypto_alg, crypto_alg);
13252               return -99;
13253             }
13254         }
13255       else
13256         if (unformat
13257             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13258         {
13259           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13260               integ_alg >= IPSEC_INTEG_N_ALG)
13261             {
13262               errmsg ("unsupported integ-alg: '%U'\n",
13263                       format_ipsec_integ_alg, integ_alg);
13264               return -99;
13265             }
13266         }
13267       else
13268         {
13269           errmsg ("parse error '%U'\n", format_unformat_error, i);
13270           return -99;
13271         }
13272     }
13273
13274   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13275
13276   mp->is_add = is_add;
13277   mp->esn = esn;
13278   mp->anti_replay = anti_replay;
13279
13280   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13281   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13282
13283   mp->local_spi = htonl (local_spi);
13284   mp->remote_spi = htonl (remote_spi);
13285   mp->crypto_alg = (u8) crypto_alg;
13286
13287   mp->local_crypto_key_len = 0;
13288   if (lck)
13289     {
13290       mp->local_crypto_key_len = vec_len (lck);
13291       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13292         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13293       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13294     }
13295
13296   mp->remote_crypto_key_len = 0;
13297   if (rck)
13298     {
13299       mp->remote_crypto_key_len = vec_len (rck);
13300       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13301         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13302       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13303     }
13304
13305   mp->integ_alg = (u8) integ_alg;
13306
13307   mp->local_integ_key_len = 0;
13308   if (lik)
13309     {
13310       mp->local_integ_key_len = vec_len (lik);
13311       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13312         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13313       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13314     }
13315
13316   mp->remote_integ_key_len = 0;
13317   if (rik)
13318     {
13319       mp->remote_integ_key_len = vec_len (rik);
13320       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13321         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13322       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13323     }
13324
13325   S (mp);
13326   W (ret);
13327   return ret;
13328 }
13329
13330 static int
13331 api_ikev2_profile_add_del (vat_main_t * vam)
13332 {
13333   unformat_input_t *i = vam->input;
13334   vl_api_ikev2_profile_add_del_t *mp;
13335   u8 is_add = 1;
13336   u8 *name = 0;
13337   int ret;
13338
13339   const char *valid_chars = "a-zA-Z0-9_";
13340
13341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13342     {
13343       if (unformat (i, "del"))
13344         is_add = 0;
13345       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13346         vec_add1 (name, 0);
13347       else
13348         {
13349           errmsg ("parse error '%U'", format_unformat_error, i);
13350           return -99;
13351         }
13352     }
13353
13354   if (!vec_len (name))
13355     {
13356       errmsg ("profile name must be specified");
13357       return -99;
13358     }
13359
13360   if (vec_len (name) > 64)
13361     {
13362       errmsg ("profile name too long");
13363       return -99;
13364     }
13365
13366   M (IKEV2_PROFILE_ADD_DEL, mp);
13367
13368   clib_memcpy (mp->name, name, vec_len (name));
13369   mp->is_add = is_add;
13370   vec_free (name);
13371
13372   S (mp);
13373   W (ret);
13374   return ret;
13375 }
13376
13377 static int
13378 api_ikev2_profile_set_auth (vat_main_t * vam)
13379 {
13380   unformat_input_t *i = vam->input;
13381   vl_api_ikev2_profile_set_auth_t *mp;
13382   u8 *name = 0;
13383   u8 *data = 0;
13384   u32 auth_method = 0;
13385   u8 is_hex = 0;
13386   int ret;
13387
13388   const char *valid_chars = "a-zA-Z0-9_";
13389
13390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13391     {
13392       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13393         vec_add1 (name, 0);
13394       else if (unformat (i, "auth_method %U",
13395                          unformat_ikev2_auth_method, &auth_method))
13396         ;
13397       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13398         is_hex = 1;
13399       else if (unformat (i, "auth_data %v", &data))
13400         ;
13401       else
13402         {
13403           errmsg ("parse error '%U'", format_unformat_error, i);
13404           return -99;
13405         }
13406     }
13407
13408   if (!vec_len (name))
13409     {
13410       errmsg ("profile name must be specified");
13411       return -99;
13412     }
13413
13414   if (vec_len (name) > 64)
13415     {
13416       errmsg ("profile name too long");
13417       return -99;
13418     }
13419
13420   if (!vec_len (data))
13421     {
13422       errmsg ("auth_data must be specified");
13423       return -99;
13424     }
13425
13426   if (!auth_method)
13427     {
13428       errmsg ("auth_method must be specified");
13429       return -99;
13430     }
13431
13432   M (IKEV2_PROFILE_SET_AUTH, mp);
13433
13434   mp->is_hex = is_hex;
13435   mp->auth_method = (u8) auth_method;
13436   mp->data_len = vec_len (data);
13437   clib_memcpy (mp->name, name, vec_len (name));
13438   clib_memcpy (mp->data, data, vec_len (data));
13439   vec_free (name);
13440   vec_free (data);
13441
13442   S (mp);
13443   W (ret);
13444   return ret;
13445 }
13446
13447 static int
13448 api_ikev2_profile_set_id (vat_main_t * vam)
13449 {
13450   unformat_input_t *i = vam->input;
13451   vl_api_ikev2_profile_set_id_t *mp;
13452   u8 *name = 0;
13453   u8 *data = 0;
13454   u8 is_local = 0;
13455   u32 id_type = 0;
13456   ip4_address_t ip4;
13457   int ret;
13458
13459   const char *valid_chars = "a-zA-Z0-9_";
13460
13461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13462     {
13463       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13464         vec_add1 (name, 0);
13465       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13466         ;
13467       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13468         {
13469           data = vec_new (u8, 4);
13470           clib_memcpy (data, ip4.as_u8, 4);
13471         }
13472       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13473         ;
13474       else if (unformat (i, "id_data %v", &data))
13475         ;
13476       else if (unformat (i, "local"))
13477         is_local = 1;
13478       else if (unformat (i, "remote"))
13479         is_local = 0;
13480       else
13481         {
13482           errmsg ("parse error '%U'", format_unformat_error, i);
13483           return -99;
13484         }
13485     }
13486
13487   if (!vec_len (name))
13488     {
13489       errmsg ("profile name must be specified");
13490       return -99;
13491     }
13492
13493   if (vec_len (name) > 64)
13494     {
13495       errmsg ("profile name too long");
13496       return -99;
13497     }
13498
13499   if (!vec_len (data))
13500     {
13501       errmsg ("id_data must be specified");
13502       return -99;
13503     }
13504
13505   if (!id_type)
13506     {
13507       errmsg ("id_type must be specified");
13508       return -99;
13509     }
13510
13511   M (IKEV2_PROFILE_SET_ID, mp);
13512
13513   mp->is_local = is_local;
13514   mp->id_type = (u8) id_type;
13515   mp->data_len = vec_len (data);
13516   clib_memcpy (mp->name, name, vec_len (name));
13517   clib_memcpy (mp->data, data, vec_len (data));
13518   vec_free (name);
13519   vec_free (data);
13520
13521   S (mp);
13522   W (ret);
13523   return ret;
13524 }
13525
13526 static int
13527 api_ikev2_profile_set_ts (vat_main_t * vam)
13528 {
13529   unformat_input_t *i = vam->input;
13530   vl_api_ikev2_profile_set_ts_t *mp;
13531   u8 *name = 0;
13532   u8 is_local = 0;
13533   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13534   ip4_address_t start_addr, end_addr;
13535
13536   const char *valid_chars = "a-zA-Z0-9_";
13537   int ret;
13538
13539   start_addr.as_u32 = 0;
13540   end_addr.as_u32 = (u32) ~ 0;
13541
13542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13543     {
13544       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13545         vec_add1 (name, 0);
13546       else if (unformat (i, "protocol %d", &proto))
13547         ;
13548       else if (unformat (i, "start_port %d", &start_port))
13549         ;
13550       else if (unformat (i, "end_port %d", &end_port))
13551         ;
13552       else
13553         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13554         ;
13555       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13556         ;
13557       else if (unformat (i, "local"))
13558         is_local = 1;
13559       else if (unformat (i, "remote"))
13560         is_local = 0;
13561       else
13562         {
13563           errmsg ("parse error '%U'", format_unformat_error, i);
13564           return -99;
13565         }
13566     }
13567
13568   if (!vec_len (name))
13569     {
13570       errmsg ("profile name must be specified");
13571       return -99;
13572     }
13573
13574   if (vec_len (name) > 64)
13575     {
13576       errmsg ("profile name too long");
13577       return -99;
13578     }
13579
13580   M (IKEV2_PROFILE_SET_TS, mp);
13581
13582   mp->is_local = is_local;
13583   mp->proto = (u8) proto;
13584   mp->start_port = (u16) start_port;
13585   mp->end_port = (u16) end_port;
13586   mp->start_addr = start_addr.as_u32;
13587   mp->end_addr = end_addr.as_u32;
13588   clib_memcpy (mp->name, name, vec_len (name));
13589   vec_free (name);
13590
13591   S (mp);
13592   W (ret);
13593   return ret;
13594 }
13595
13596 static int
13597 api_ikev2_set_local_key (vat_main_t * vam)
13598 {
13599   unformat_input_t *i = vam->input;
13600   vl_api_ikev2_set_local_key_t *mp;
13601   u8 *file = 0;
13602   int ret;
13603
13604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13605     {
13606       if (unformat (i, "file %v", &file))
13607         vec_add1 (file, 0);
13608       else
13609         {
13610           errmsg ("parse error '%U'", format_unformat_error, i);
13611           return -99;
13612         }
13613     }
13614
13615   if (!vec_len (file))
13616     {
13617       errmsg ("RSA key file must be specified");
13618       return -99;
13619     }
13620
13621   if (vec_len (file) > 256)
13622     {
13623       errmsg ("file name too long");
13624       return -99;
13625     }
13626
13627   M (IKEV2_SET_LOCAL_KEY, mp);
13628
13629   clib_memcpy (mp->key_file, file, vec_len (file));
13630   vec_free (file);
13631
13632   S (mp);
13633   W (ret);
13634   return ret;
13635 }
13636
13637 static int
13638 api_ikev2_set_responder (vat_main_t * vam)
13639 {
13640   unformat_input_t *i = vam->input;
13641   vl_api_ikev2_set_responder_t *mp;
13642   int ret;
13643   u8 *name = 0;
13644   u32 sw_if_index = ~0;
13645   ip4_address_t address;
13646
13647   const char *valid_chars = "a-zA-Z0-9_";
13648
13649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13650     {
13651       if (unformat
13652           (i, "%U interface %d address %U", unformat_token, valid_chars,
13653            &name, &sw_if_index, unformat_ip4_address, &address))
13654         vec_add1 (name, 0);
13655       else
13656         {
13657           errmsg ("parse error '%U'", format_unformat_error, i);
13658           return -99;
13659         }
13660     }
13661
13662   if (!vec_len (name))
13663     {
13664       errmsg ("profile name must be specified");
13665       return -99;
13666     }
13667
13668   if (vec_len (name) > 64)
13669     {
13670       errmsg ("profile name too long");
13671       return -99;
13672     }
13673
13674   M (IKEV2_SET_RESPONDER, mp);
13675
13676   clib_memcpy (mp->name, name, vec_len (name));
13677   vec_free (name);
13678
13679   mp->sw_if_index = sw_if_index;
13680   clib_memcpy (mp->address, &address, sizeof (address));
13681
13682   S (mp);
13683   W (ret);
13684   return ret;
13685 }
13686
13687 static int
13688 api_ikev2_set_ike_transforms (vat_main_t * vam)
13689 {
13690   unformat_input_t *i = vam->input;
13691   vl_api_ikev2_set_ike_transforms_t *mp;
13692   int ret;
13693   u8 *name = 0;
13694   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13695
13696   const char *valid_chars = "a-zA-Z0-9_";
13697
13698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13699     {
13700       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13701                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13702         vec_add1 (name, 0);
13703       else
13704         {
13705           errmsg ("parse error '%U'", format_unformat_error, i);
13706           return -99;
13707         }
13708     }
13709
13710   if (!vec_len (name))
13711     {
13712       errmsg ("profile name must be specified");
13713       return -99;
13714     }
13715
13716   if (vec_len (name) > 64)
13717     {
13718       errmsg ("profile name too long");
13719       return -99;
13720     }
13721
13722   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13723
13724   clib_memcpy (mp->name, name, vec_len (name));
13725   vec_free (name);
13726   mp->crypto_alg = crypto_alg;
13727   mp->crypto_key_size = crypto_key_size;
13728   mp->integ_alg = integ_alg;
13729   mp->dh_group = dh_group;
13730
13731   S (mp);
13732   W (ret);
13733   return ret;
13734 }
13735
13736
13737 static int
13738 api_ikev2_set_esp_transforms (vat_main_t * vam)
13739 {
13740   unformat_input_t *i = vam->input;
13741   vl_api_ikev2_set_esp_transforms_t *mp;
13742   int ret;
13743   u8 *name = 0;
13744   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13745
13746   const char *valid_chars = "a-zA-Z0-9_";
13747
13748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13749     {
13750       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13751                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13752         vec_add1 (name, 0);
13753       else
13754         {
13755           errmsg ("parse error '%U'", format_unformat_error, i);
13756           return -99;
13757         }
13758     }
13759
13760   if (!vec_len (name))
13761     {
13762       errmsg ("profile name must be specified");
13763       return -99;
13764     }
13765
13766   if (vec_len (name) > 64)
13767     {
13768       errmsg ("profile name too long");
13769       return -99;
13770     }
13771
13772   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13773
13774   clib_memcpy (mp->name, name, vec_len (name));
13775   vec_free (name);
13776   mp->crypto_alg = crypto_alg;
13777   mp->crypto_key_size = crypto_key_size;
13778   mp->integ_alg = integ_alg;
13779   mp->dh_group = dh_group;
13780
13781   S (mp);
13782   W (ret);
13783   return ret;
13784 }
13785
13786 static int
13787 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13788 {
13789   unformat_input_t *i = vam->input;
13790   vl_api_ikev2_set_sa_lifetime_t *mp;
13791   int ret;
13792   u8 *name = 0;
13793   u64 lifetime, lifetime_maxdata;
13794   u32 lifetime_jitter, handover;
13795
13796   const char *valid_chars = "a-zA-Z0-9_";
13797
13798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13799     {
13800       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13801                     &lifetime, &lifetime_jitter, &handover,
13802                     &lifetime_maxdata))
13803         vec_add1 (name, 0);
13804       else
13805         {
13806           errmsg ("parse error '%U'", format_unformat_error, i);
13807           return -99;
13808         }
13809     }
13810
13811   if (!vec_len (name))
13812     {
13813       errmsg ("profile name must be specified");
13814       return -99;
13815     }
13816
13817   if (vec_len (name) > 64)
13818     {
13819       errmsg ("profile name too long");
13820       return -99;
13821     }
13822
13823   M (IKEV2_SET_SA_LIFETIME, mp);
13824
13825   clib_memcpy (mp->name, name, vec_len (name));
13826   vec_free (name);
13827   mp->lifetime = lifetime;
13828   mp->lifetime_jitter = lifetime_jitter;
13829   mp->handover = handover;
13830   mp->lifetime_maxdata = lifetime_maxdata;
13831
13832   S (mp);
13833   W (ret);
13834   return ret;
13835 }
13836
13837 static int
13838 api_ikev2_initiate_sa_init (vat_main_t * vam)
13839 {
13840   unformat_input_t *i = vam->input;
13841   vl_api_ikev2_initiate_sa_init_t *mp;
13842   int ret;
13843   u8 *name = 0;
13844
13845   const char *valid_chars = "a-zA-Z0-9_";
13846
13847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13848     {
13849       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13850         vec_add1 (name, 0);
13851       else
13852         {
13853           errmsg ("parse error '%U'", format_unformat_error, i);
13854           return -99;
13855         }
13856     }
13857
13858   if (!vec_len (name))
13859     {
13860       errmsg ("profile name must be specified");
13861       return -99;
13862     }
13863
13864   if (vec_len (name) > 64)
13865     {
13866       errmsg ("profile name too long");
13867       return -99;
13868     }
13869
13870   M (IKEV2_INITIATE_SA_INIT, mp);
13871
13872   clib_memcpy (mp->name, name, vec_len (name));
13873   vec_free (name);
13874
13875   S (mp);
13876   W (ret);
13877   return ret;
13878 }
13879
13880 static int
13881 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13882 {
13883   unformat_input_t *i = vam->input;
13884   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13885   int ret;
13886   u64 ispi;
13887
13888
13889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13890     {
13891       if (unformat (i, "%lx", &ispi))
13892         ;
13893       else
13894         {
13895           errmsg ("parse error '%U'", format_unformat_error, i);
13896           return -99;
13897         }
13898     }
13899
13900   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13901
13902   mp->ispi = ispi;
13903
13904   S (mp);
13905   W (ret);
13906   return ret;
13907 }
13908
13909 static int
13910 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13911 {
13912   unformat_input_t *i = vam->input;
13913   vl_api_ikev2_initiate_del_child_sa_t *mp;
13914   int ret;
13915   u32 ispi;
13916
13917
13918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13919     {
13920       if (unformat (i, "%x", &ispi))
13921         ;
13922       else
13923         {
13924           errmsg ("parse error '%U'", format_unformat_error, i);
13925           return -99;
13926         }
13927     }
13928
13929   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13930
13931   mp->ispi = ispi;
13932
13933   S (mp);
13934   W (ret);
13935   return ret;
13936 }
13937
13938 static int
13939 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13940 {
13941   unformat_input_t *i = vam->input;
13942   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13943   int ret;
13944   u32 ispi;
13945
13946
13947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13948     {
13949       if (unformat (i, "%x", &ispi))
13950         ;
13951       else
13952         {
13953           errmsg ("parse error '%U'", format_unformat_error, i);
13954           return -99;
13955         }
13956     }
13957
13958   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13959
13960   mp->ispi = ispi;
13961
13962   S (mp);
13963   W (ret);
13964   return ret;
13965 }
13966
13967 /*
13968  * MAP
13969  */
13970 static int
13971 api_map_add_domain (vat_main_t * vam)
13972 {
13973   unformat_input_t *i = vam->input;
13974   vl_api_map_add_domain_t *mp;
13975
13976   ip4_address_t ip4_prefix;
13977   ip6_address_t ip6_prefix;
13978   ip6_address_t ip6_src;
13979   u32 num_m_args = 0;
13980   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13981     0, psid_length = 0;
13982   u8 is_translation = 0;
13983   u32 mtu = 0;
13984   u32 ip6_src_len = 128;
13985   int ret;
13986
13987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13988     {
13989       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13990                     &ip4_prefix, &ip4_prefix_len))
13991         num_m_args++;
13992       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13993                          &ip6_prefix, &ip6_prefix_len))
13994         num_m_args++;
13995       else
13996         if (unformat
13997             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13998              &ip6_src_len))
13999         num_m_args++;
14000       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14001         num_m_args++;
14002       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14003         num_m_args++;
14004       else if (unformat (i, "psid-offset %d", &psid_offset))
14005         num_m_args++;
14006       else if (unformat (i, "psid-len %d", &psid_length))
14007         num_m_args++;
14008       else if (unformat (i, "mtu %d", &mtu))
14009         num_m_args++;
14010       else if (unformat (i, "map-t"))
14011         is_translation = 1;
14012       else
14013         {
14014           clib_warning ("parse error '%U'", format_unformat_error, i);
14015           return -99;
14016         }
14017     }
14018
14019   if (num_m_args < 3)
14020     {
14021       errmsg ("mandatory argument(s) missing");
14022       return -99;
14023     }
14024
14025   /* Construct the API message */
14026   M (MAP_ADD_DOMAIN, mp);
14027
14028   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14029   mp->ip4_prefix_len = ip4_prefix_len;
14030
14031   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14032   mp->ip6_prefix_len = ip6_prefix_len;
14033
14034   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14035   mp->ip6_src_prefix_len = ip6_src_len;
14036
14037   mp->ea_bits_len = ea_bits_len;
14038   mp->psid_offset = psid_offset;
14039   mp->psid_length = psid_length;
14040   mp->is_translation = is_translation;
14041   mp->mtu = htons (mtu);
14042
14043   /* send it... */
14044   S (mp);
14045
14046   /* Wait for a reply, return good/bad news  */
14047   W (ret);
14048   return ret;
14049 }
14050
14051 static int
14052 api_map_del_domain (vat_main_t * vam)
14053 {
14054   unformat_input_t *i = vam->input;
14055   vl_api_map_del_domain_t *mp;
14056
14057   u32 num_m_args = 0;
14058   u32 index;
14059   int ret;
14060
14061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14062     {
14063       if (unformat (i, "index %d", &index))
14064         num_m_args++;
14065       else
14066         {
14067           clib_warning ("parse error '%U'", format_unformat_error, i);
14068           return -99;
14069         }
14070     }
14071
14072   if (num_m_args != 1)
14073     {
14074       errmsg ("mandatory argument(s) missing");
14075       return -99;
14076     }
14077
14078   /* Construct the API message */
14079   M (MAP_DEL_DOMAIN, mp);
14080
14081   mp->index = ntohl (index);
14082
14083   /* send it... */
14084   S (mp);
14085
14086   /* Wait for a reply, return good/bad news  */
14087   W (ret);
14088   return ret;
14089 }
14090
14091 static int
14092 api_map_add_del_rule (vat_main_t * vam)
14093 {
14094   unformat_input_t *i = vam->input;
14095   vl_api_map_add_del_rule_t *mp;
14096   u8 is_add = 1;
14097   ip6_address_t ip6_dst;
14098   u32 num_m_args = 0, index, psid = 0;
14099   int ret;
14100
14101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14102     {
14103       if (unformat (i, "index %d", &index))
14104         num_m_args++;
14105       else if (unformat (i, "psid %d", &psid))
14106         num_m_args++;
14107       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14108         num_m_args++;
14109       else if (unformat (i, "del"))
14110         {
14111           is_add = 0;
14112         }
14113       else
14114         {
14115           clib_warning ("parse error '%U'", format_unformat_error, i);
14116           return -99;
14117         }
14118     }
14119
14120   /* Construct the API message */
14121   M (MAP_ADD_DEL_RULE, mp);
14122
14123   mp->index = ntohl (index);
14124   mp->is_add = is_add;
14125   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14126   mp->psid = ntohs (psid);
14127
14128   /* send it... */
14129   S (mp);
14130
14131   /* Wait for a reply, return good/bad news  */
14132   W (ret);
14133   return ret;
14134 }
14135
14136 static int
14137 api_map_domain_dump (vat_main_t * vam)
14138 {
14139   vl_api_map_domain_dump_t *mp;
14140   vl_api_control_ping_t *mp_ping;
14141   int ret;
14142
14143   /* Construct the API message */
14144   M (MAP_DOMAIN_DUMP, mp);
14145
14146   /* send it... */
14147   S (mp);
14148
14149   /* Use a control ping for synchronization */
14150   M (CONTROL_PING, mp_ping);
14151   S (mp_ping);
14152
14153   W (ret);
14154   return ret;
14155 }
14156
14157 static int
14158 api_map_rule_dump (vat_main_t * vam)
14159 {
14160   unformat_input_t *i = vam->input;
14161   vl_api_map_rule_dump_t *mp;
14162   vl_api_control_ping_t *mp_ping;
14163   u32 domain_index = ~0;
14164   int ret;
14165
14166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14167     {
14168       if (unformat (i, "index %u", &domain_index))
14169         ;
14170       else
14171         break;
14172     }
14173
14174   if (domain_index == ~0)
14175     {
14176       clib_warning ("parse error: domain index expected");
14177       return -99;
14178     }
14179
14180   /* Construct the API message */
14181   M (MAP_RULE_DUMP, mp);
14182
14183   mp->domain_index = htonl (domain_index);
14184
14185   /* send it... */
14186   S (mp);
14187
14188   /* Use a control ping for synchronization */
14189   M (CONTROL_PING, mp_ping);
14190   S (mp_ping);
14191
14192   W (ret);
14193   return ret;
14194 }
14195
14196 static void vl_api_map_add_domain_reply_t_handler
14197   (vl_api_map_add_domain_reply_t * mp)
14198 {
14199   vat_main_t *vam = &vat_main;
14200   i32 retval = ntohl (mp->retval);
14201
14202   if (vam->async_mode)
14203     {
14204       vam->async_errors += (retval < 0);
14205     }
14206   else
14207     {
14208       vam->retval = retval;
14209       vam->result_ready = 1;
14210     }
14211 }
14212
14213 static void vl_api_map_add_domain_reply_t_handler_json
14214   (vl_api_map_add_domain_reply_t * mp)
14215 {
14216   vat_main_t *vam = &vat_main;
14217   vat_json_node_t node;
14218
14219   vat_json_init_object (&node);
14220   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14221   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14222
14223   vat_json_print (vam->ofp, &node);
14224   vat_json_free (&node);
14225
14226   vam->retval = ntohl (mp->retval);
14227   vam->result_ready = 1;
14228 }
14229
14230 static int
14231 api_get_first_msg_id (vat_main_t * vam)
14232 {
14233   vl_api_get_first_msg_id_t *mp;
14234   unformat_input_t *i = vam->input;
14235   u8 *name;
14236   u8 name_set = 0;
14237   int ret;
14238
14239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14240     {
14241       if (unformat (i, "client %s", &name))
14242         name_set = 1;
14243       else
14244         break;
14245     }
14246
14247   if (name_set == 0)
14248     {
14249       errmsg ("missing client name");
14250       return -99;
14251     }
14252   vec_add1 (name, 0);
14253
14254   if (vec_len (name) > 63)
14255     {
14256       errmsg ("client name too long");
14257       return -99;
14258     }
14259
14260   M (GET_FIRST_MSG_ID, mp);
14261   clib_memcpy (mp->name, name, vec_len (name));
14262   S (mp);
14263   W (ret);
14264   return ret;
14265 }
14266
14267 static int
14268 api_cop_interface_enable_disable (vat_main_t * vam)
14269 {
14270   unformat_input_t *line_input = vam->input;
14271   vl_api_cop_interface_enable_disable_t *mp;
14272   u32 sw_if_index = ~0;
14273   u8 enable_disable = 1;
14274   int ret;
14275
14276   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14277     {
14278       if (unformat (line_input, "disable"))
14279         enable_disable = 0;
14280       if (unformat (line_input, "enable"))
14281         enable_disable = 1;
14282       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14283                          vam, &sw_if_index))
14284         ;
14285       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14286         ;
14287       else
14288         break;
14289     }
14290
14291   if (sw_if_index == ~0)
14292     {
14293       errmsg ("missing interface name or sw_if_index");
14294       return -99;
14295     }
14296
14297   /* Construct the API message */
14298   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14299   mp->sw_if_index = ntohl (sw_if_index);
14300   mp->enable_disable = enable_disable;
14301
14302   /* send it... */
14303   S (mp);
14304   /* Wait for the reply */
14305   W (ret);
14306   return ret;
14307 }
14308
14309 static int
14310 api_cop_whitelist_enable_disable (vat_main_t * vam)
14311 {
14312   unformat_input_t *line_input = vam->input;
14313   vl_api_cop_whitelist_enable_disable_t *mp;
14314   u32 sw_if_index = ~0;
14315   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14316   u32 fib_id = 0;
14317   int ret;
14318
14319   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14320     {
14321       if (unformat (line_input, "ip4"))
14322         ip4 = 1;
14323       else if (unformat (line_input, "ip6"))
14324         ip6 = 1;
14325       else if (unformat (line_input, "default"))
14326         default_cop = 1;
14327       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14328                          vam, &sw_if_index))
14329         ;
14330       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14331         ;
14332       else if (unformat (line_input, "fib-id %d", &fib_id))
14333         ;
14334       else
14335         break;
14336     }
14337
14338   if (sw_if_index == ~0)
14339     {
14340       errmsg ("missing interface name or sw_if_index");
14341       return -99;
14342     }
14343
14344   /* Construct the API message */
14345   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14346   mp->sw_if_index = ntohl (sw_if_index);
14347   mp->fib_id = ntohl (fib_id);
14348   mp->ip4 = ip4;
14349   mp->ip6 = ip6;
14350   mp->default_cop = default_cop;
14351
14352   /* send it... */
14353   S (mp);
14354   /* Wait for the reply */
14355   W (ret);
14356   return ret;
14357 }
14358
14359 static int
14360 api_get_node_graph (vat_main_t * vam)
14361 {
14362   vl_api_get_node_graph_t *mp;
14363   int ret;
14364
14365   M (GET_NODE_GRAPH, mp);
14366
14367   /* send it... */
14368   S (mp);
14369   /* Wait for the reply */
14370   W (ret);
14371   return ret;
14372 }
14373
14374 /* *INDENT-OFF* */
14375 /** Used for parsing LISP eids */
14376 typedef CLIB_PACKED(struct{
14377   u8 addr[16];   /**< eid address */
14378   u32 len;       /**< prefix length if IP */
14379   u8 type;      /**< type of eid */
14380 }) lisp_eid_vat_t;
14381 /* *INDENT-ON* */
14382
14383 static uword
14384 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14385 {
14386   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14387
14388   memset (a, 0, sizeof (a[0]));
14389
14390   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14391     {
14392       a->type = 0;              /* ipv4 type */
14393     }
14394   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14395     {
14396       a->type = 1;              /* ipv6 type */
14397     }
14398   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14399     {
14400       a->type = 2;              /* mac type */
14401     }
14402   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14403     {
14404       a->type = 3;              /* NSH type */
14405       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14406       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14407     }
14408   else
14409     {
14410       return 0;
14411     }
14412
14413   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14414     {
14415       return 0;
14416     }
14417
14418   return 1;
14419 }
14420
14421 static int
14422 lisp_eid_size_vat (u8 type)
14423 {
14424   switch (type)
14425     {
14426     case 0:
14427       return 4;
14428     case 1:
14429       return 16;
14430     case 2:
14431       return 6;
14432     case 3:
14433       return 5;
14434     }
14435   return 0;
14436 }
14437
14438 static void
14439 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14440 {
14441   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14442 }
14443
14444 static int
14445 api_one_add_del_locator_set (vat_main_t * vam)
14446 {
14447   unformat_input_t *input = vam->input;
14448   vl_api_one_add_del_locator_set_t *mp;
14449   u8 is_add = 1;
14450   u8 *locator_set_name = NULL;
14451   u8 locator_set_name_set = 0;
14452   vl_api_local_locator_t locator, *locators = 0;
14453   u32 sw_if_index, priority, weight;
14454   u32 data_len = 0;
14455
14456   int ret;
14457   /* Parse args required to build the message */
14458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14459     {
14460       if (unformat (input, "del"))
14461         {
14462           is_add = 0;
14463         }
14464       else if (unformat (input, "locator-set %s", &locator_set_name))
14465         {
14466           locator_set_name_set = 1;
14467         }
14468       else if (unformat (input, "sw_if_index %u p %u w %u",
14469                          &sw_if_index, &priority, &weight))
14470         {
14471           locator.sw_if_index = htonl (sw_if_index);
14472           locator.priority = priority;
14473           locator.weight = weight;
14474           vec_add1 (locators, locator);
14475         }
14476       else
14477         if (unformat
14478             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14479              &sw_if_index, &priority, &weight))
14480         {
14481           locator.sw_if_index = htonl (sw_if_index);
14482           locator.priority = priority;
14483           locator.weight = weight;
14484           vec_add1 (locators, locator);
14485         }
14486       else
14487         break;
14488     }
14489
14490   if (locator_set_name_set == 0)
14491     {
14492       errmsg ("missing locator-set name");
14493       vec_free (locators);
14494       return -99;
14495     }
14496
14497   if (vec_len (locator_set_name) > 64)
14498     {
14499       errmsg ("locator-set name too long");
14500       vec_free (locator_set_name);
14501       vec_free (locators);
14502       return -99;
14503     }
14504   vec_add1 (locator_set_name, 0);
14505
14506   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14507
14508   /* Construct the API message */
14509   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14510
14511   mp->is_add = is_add;
14512   clib_memcpy (mp->locator_set_name, locator_set_name,
14513                vec_len (locator_set_name));
14514   vec_free (locator_set_name);
14515
14516   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14517   if (locators)
14518     clib_memcpy (mp->locators, locators, data_len);
14519   vec_free (locators);
14520
14521   /* send it... */
14522   S (mp);
14523
14524   /* Wait for a reply... */
14525   W (ret);
14526   return ret;
14527 }
14528
14529 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14530
14531 static int
14532 api_one_add_del_locator (vat_main_t * vam)
14533 {
14534   unformat_input_t *input = vam->input;
14535   vl_api_one_add_del_locator_t *mp;
14536   u32 tmp_if_index = ~0;
14537   u32 sw_if_index = ~0;
14538   u8 sw_if_index_set = 0;
14539   u8 sw_if_index_if_name_set = 0;
14540   u32 priority = ~0;
14541   u8 priority_set = 0;
14542   u32 weight = ~0;
14543   u8 weight_set = 0;
14544   u8 is_add = 1;
14545   u8 *locator_set_name = NULL;
14546   u8 locator_set_name_set = 0;
14547   int ret;
14548
14549   /* Parse args required to build the message */
14550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14551     {
14552       if (unformat (input, "del"))
14553         {
14554           is_add = 0;
14555         }
14556       else if (unformat (input, "locator-set %s", &locator_set_name))
14557         {
14558           locator_set_name_set = 1;
14559         }
14560       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14561                          &tmp_if_index))
14562         {
14563           sw_if_index_if_name_set = 1;
14564           sw_if_index = tmp_if_index;
14565         }
14566       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14567         {
14568           sw_if_index_set = 1;
14569           sw_if_index = tmp_if_index;
14570         }
14571       else if (unformat (input, "p %d", &priority))
14572         {
14573           priority_set = 1;
14574         }
14575       else if (unformat (input, "w %d", &weight))
14576         {
14577           weight_set = 1;
14578         }
14579       else
14580         break;
14581     }
14582
14583   if (locator_set_name_set == 0)
14584     {
14585       errmsg ("missing locator-set name");
14586       return -99;
14587     }
14588
14589   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14590     {
14591       errmsg ("missing sw_if_index");
14592       vec_free (locator_set_name);
14593       return -99;
14594     }
14595
14596   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14597     {
14598       errmsg ("cannot use both params interface name and sw_if_index");
14599       vec_free (locator_set_name);
14600       return -99;
14601     }
14602
14603   if (priority_set == 0)
14604     {
14605       errmsg ("missing locator-set priority");
14606       vec_free (locator_set_name);
14607       return -99;
14608     }
14609
14610   if (weight_set == 0)
14611     {
14612       errmsg ("missing locator-set weight");
14613       vec_free (locator_set_name);
14614       return -99;
14615     }
14616
14617   if (vec_len (locator_set_name) > 64)
14618     {
14619       errmsg ("locator-set name too long");
14620       vec_free (locator_set_name);
14621       return -99;
14622     }
14623   vec_add1 (locator_set_name, 0);
14624
14625   /* Construct the API message */
14626   M (ONE_ADD_DEL_LOCATOR, mp);
14627
14628   mp->is_add = is_add;
14629   mp->sw_if_index = ntohl (sw_if_index);
14630   mp->priority = priority;
14631   mp->weight = weight;
14632   clib_memcpy (mp->locator_set_name, locator_set_name,
14633                vec_len (locator_set_name));
14634   vec_free (locator_set_name);
14635
14636   /* send it... */
14637   S (mp);
14638
14639   /* Wait for a reply... */
14640   W (ret);
14641   return ret;
14642 }
14643
14644 #define api_lisp_add_del_locator api_one_add_del_locator
14645
14646 uword
14647 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14648 {
14649   u32 *key_id = va_arg (*args, u32 *);
14650   u8 *s = 0;
14651
14652   if (unformat (input, "%s", &s))
14653     {
14654       if (!strcmp ((char *) s, "sha1"))
14655         key_id[0] = HMAC_SHA_1_96;
14656       else if (!strcmp ((char *) s, "sha256"))
14657         key_id[0] = HMAC_SHA_256_128;
14658       else
14659         {
14660           clib_warning ("invalid key_id: '%s'", s);
14661           key_id[0] = HMAC_NO_KEY;
14662         }
14663     }
14664   else
14665     return 0;
14666
14667   vec_free (s);
14668   return 1;
14669 }
14670
14671 static int
14672 api_one_add_del_local_eid (vat_main_t * vam)
14673 {
14674   unformat_input_t *input = vam->input;
14675   vl_api_one_add_del_local_eid_t *mp;
14676   u8 is_add = 1;
14677   u8 eid_set = 0;
14678   lisp_eid_vat_t _eid, *eid = &_eid;
14679   u8 *locator_set_name = 0;
14680   u8 locator_set_name_set = 0;
14681   u32 vni = 0;
14682   u16 key_id = 0;
14683   u8 *key = 0;
14684   int ret;
14685
14686   /* Parse args required to build the message */
14687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14688     {
14689       if (unformat (input, "del"))
14690         {
14691           is_add = 0;
14692         }
14693       else if (unformat (input, "vni %d", &vni))
14694         {
14695           ;
14696         }
14697       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14698         {
14699           eid_set = 1;
14700         }
14701       else if (unformat (input, "locator-set %s", &locator_set_name))
14702         {
14703           locator_set_name_set = 1;
14704         }
14705       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14706         ;
14707       else if (unformat (input, "secret-key %_%v%_", &key))
14708         ;
14709       else
14710         break;
14711     }
14712
14713   if (locator_set_name_set == 0)
14714     {
14715       errmsg ("missing locator-set name");
14716       return -99;
14717     }
14718
14719   if (0 == eid_set)
14720     {
14721       errmsg ("EID address not set!");
14722       vec_free (locator_set_name);
14723       return -99;
14724     }
14725
14726   if (key && (0 == key_id))
14727     {
14728       errmsg ("invalid key_id!");
14729       return -99;
14730     }
14731
14732   if (vec_len (key) > 64)
14733     {
14734       errmsg ("key too long");
14735       vec_free (key);
14736       return -99;
14737     }
14738
14739   if (vec_len (locator_set_name) > 64)
14740     {
14741       errmsg ("locator-set name too long");
14742       vec_free (locator_set_name);
14743       return -99;
14744     }
14745   vec_add1 (locator_set_name, 0);
14746
14747   /* Construct the API message */
14748   M (ONE_ADD_DEL_LOCAL_EID, mp);
14749
14750   mp->is_add = is_add;
14751   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14752   mp->eid_type = eid->type;
14753   mp->prefix_len = eid->len;
14754   mp->vni = clib_host_to_net_u32 (vni);
14755   mp->key_id = clib_host_to_net_u16 (key_id);
14756   clib_memcpy (mp->locator_set_name, locator_set_name,
14757                vec_len (locator_set_name));
14758   clib_memcpy (mp->key, key, vec_len (key));
14759
14760   vec_free (locator_set_name);
14761   vec_free (key);
14762
14763   /* send it... */
14764   S (mp);
14765
14766   /* Wait for a reply... */
14767   W (ret);
14768   return ret;
14769 }
14770
14771 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14772
14773 static int
14774 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14775 {
14776   u32 dp_table = 0, vni = 0;;
14777   unformat_input_t *input = vam->input;
14778   vl_api_gpe_add_del_fwd_entry_t *mp;
14779   u8 is_add = 1;
14780   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14781   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14782   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14783   u32 action = ~0, w;
14784   ip4_address_t rmt_rloc4, lcl_rloc4;
14785   ip6_address_t rmt_rloc6, lcl_rloc6;
14786   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14787   int ret;
14788
14789   memset (&rloc, 0, sizeof (rloc));
14790
14791   /* Parse args required to build the message */
14792   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14793     {
14794       if (unformat (input, "del"))
14795         is_add = 0;
14796       else if (unformat (input, "add"))
14797         is_add = 1;
14798       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14799         {
14800           rmt_eid_set = 1;
14801         }
14802       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14803         {
14804           lcl_eid_set = 1;
14805         }
14806       else if (unformat (input, "vrf %d", &dp_table))
14807         ;
14808       else if (unformat (input, "bd %d", &dp_table))
14809         ;
14810       else if (unformat (input, "vni %d", &vni))
14811         ;
14812       else if (unformat (input, "w %d", &w))
14813         {
14814           if (!curr_rloc)
14815             {
14816               errmsg ("No RLOC configured for setting priority/weight!");
14817               return -99;
14818             }
14819           curr_rloc->weight = w;
14820         }
14821       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14822                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14823         {
14824           rloc.is_ip4 = 1;
14825
14826           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14827           rloc.weight = 0;
14828           vec_add1 (lcl_locs, rloc);
14829
14830           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14831           vec_add1 (rmt_locs, rloc);
14832           /* weight saved in rmt loc */
14833           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14834         }
14835       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14836                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14837         {
14838           rloc.is_ip4 = 0;
14839           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14840           rloc.weight = 0;
14841           vec_add1 (lcl_locs, rloc);
14842
14843           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14844           vec_add1 (rmt_locs, rloc);
14845           /* weight saved in rmt loc */
14846           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14847         }
14848       else if (unformat (input, "action %d", &action))
14849         {
14850           ;
14851         }
14852       else
14853         {
14854           clib_warning ("parse error '%U'", format_unformat_error, input);
14855           return -99;
14856         }
14857     }
14858
14859   if (!rmt_eid_set)
14860     {
14861       errmsg ("remote eid addresses not set");
14862       return -99;
14863     }
14864
14865   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14866     {
14867       errmsg ("eid types don't match");
14868       return -99;
14869     }
14870
14871   if (0 == rmt_locs && (u32) ~ 0 == action)
14872     {
14873       errmsg ("action not set for negative mapping");
14874       return -99;
14875     }
14876
14877   /* Construct the API message */
14878   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14879       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14880
14881   mp->is_add = is_add;
14882   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14883   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14884   mp->eid_type = rmt_eid->type;
14885   mp->dp_table = clib_host_to_net_u32 (dp_table);
14886   mp->vni = clib_host_to_net_u32 (vni);
14887   mp->rmt_len = rmt_eid->len;
14888   mp->lcl_len = lcl_eid->len;
14889   mp->action = action;
14890
14891   if (0 != rmt_locs && 0 != lcl_locs)
14892     {
14893       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14894       clib_memcpy (mp->locs, lcl_locs,
14895                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14896
14897       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14898       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14899                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14900     }
14901   vec_free (lcl_locs);
14902   vec_free (rmt_locs);
14903
14904   /* send it... */
14905   S (mp);
14906
14907   /* Wait for a reply... */
14908   W (ret);
14909   return ret;
14910 }
14911
14912 static int
14913 api_one_add_del_map_server (vat_main_t * vam)
14914 {
14915   unformat_input_t *input = vam->input;
14916   vl_api_one_add_del_map_server_t *mp;
14917   u8 is_add = 1;
14918   u8 ipv4_set = 0;
14919   u8 ipv6_set = 0;
14920   ip4_address_t ipv4;
14921   ip6_address_t ipv6;
14922   int ret;
14923
14924   /* Parse args required to build the message */
14925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14926     {
14927       if (unformat (input, "del"))
14928         {
14929           is_add = 0;
14930         }
14931       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14932         {
14933           ipv4_set = 1;
14934         }
14935       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14936         {
14937           ipv6_set = 1;
14938         }
14939       else
14940         break;
14941     }
14942
14943   if (ipv4_set && ipv6_set)
14944     {
14945       errmsg ("both eid v4 and v6 addresses set");
14946       return -99;
14947     }
14948
14949   if (!ipv4_set && !ipv6_set)
14950     {
14951       errmsg ("eid addresses not set");
14952       return -99;
14953     }
14954
14955   /* Construct the API message */
14956   M (ONE_ADD_DEL_MAP_SERVER, mp);
14957
14958   mp->is_add = is_add;
14959   if (ipv6_set)
14960     {
14961       mp->is_ipv6 = 1;
14962       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14963     }
14964   else
14965     {
14966       mp->is_ipv6 = 0;
14967       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14968     }
14969
14970   /* send it... */
14971   S (mp);
14972
14973   /* Wait for a reply... */
14974   W (ret);
14975   return ret;
14976 }
14977
14978 #define api_lisp_add_del_map_server api_one_add_del_map_server
14979
14980 static int
14981 api_one_add_del_map_resolver (vat_main_t * vam)
14982 {
14983   unformat_input_t *input = vam->input;
14984   vl_api_one_add_del_map_resolver_t *mp;
14985   u8 is_add = 1;
14986   u8 ipv4_set = 0;
14987   u8 ipv6_set = 0;
14988   ip4_address_t ipv4;
14989   ip6_address_t ipv6;
14990   int ret;
14991
14992   /* Parse args required to build the message */
14993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14994     {
14995       if (unformat (input, "del"))
14996         {
14997           is_add = 0;
14998         }
14999       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15000         {
15001           ipv4_set = 1;
15002         }
15003       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15004         {
15005           ipv6_set = 1;
15006         }
15007       else
15008         break;
15009     }
15010
15011   if (ipv4_set && ipv6_set)
15012     {
15013       errmsg ("both eid v4 and v6 addresses set");
15014       return -99;
15015     }
15016
15017   if (!ipv4_set && !ipv6_set)
15018     {
15019       errmsg ("eid addresses not set");
15020       return -99;
15021     }
15022
15023   /* Construct the API message */
15024   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15025
15026   mp->is_add = is_add;
15027   if (ipv6_set)
15028     {
15029       mp->is_ipv6 = 1;
15030       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15031     }
15032   else
15033     {
15034       mp->is_ipv6 = 0;
15035       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15036     }
15037
15038   /* send it... */
15039   S (mp);
15040
15041   /* Wait for a reply... */
15042   W (ret);
15043   return ret;
15044 }
15045
15046 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15047
15048 static int
15049 api_lisp_gpe_enable_disable (vat_main_t * vam)
15050 {
15051   unformat_input_t *input = vam->input;
15052   vl_api_gpe_enable_disable_t *mp;
15053   u8 is_set = 0;
15054   u8 is_en = 1;
15055   int ret;
15056
15057   /* Parse args required to build the message */
15058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15059     {
15060       if (unformat (input, "enable"))
15061         {
15062           is_set = 1;
15063           is_en = 1;
15064         }
15065       else if (unformat (input, "disable"))
15066         {
15067           is_set = 1;
15068           is_en = 0;
15069         }
15070       else
15071         break;
15072     }
15073
15074   if (is_set == 0)
15075     {
15076       errmsg ("Value not set");
15077       return -99;
15078     }
15079
15080   /* Construct the API message */
15081   M (GPE_ENABLE_DISABLE, mp);
15082
15083   mp->is_en = is_en;
15084
15085   /* send it... */
15086   S (mp);
15087
15088   /* Wait for a reply... */
15089   W (ret);
15090   return ret;
15091 }
15092
15093 static int
15094 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15095 {
15096   unformat_input_t *input = vam->input;
15097   vl_api_one_rloc_probe_enable_disable_t *mp;
15098   u8 is_set = 0;
15099   u8 is_en = 0;
15100   int ret;
15101
15102   /* Parse args required to build the message */
15103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15104     {
15105       if (unformat (input, "enable"))
15106         {
15107           is_set = 1;
15108           is_en = 1;
15109         }
15110       else if (unformat (input, "disable"))
15111         is_set = 1;
15112       else
15113         break;
15114     }
15115
15116   if (!is_set)
15117     {
15118       errmsg ("Value not set");
15119       return -99;
15120     }
15121
15122   /* Construct the API message */
15123   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15124
15125   mp->is_enabled = is_en;
15126
15127   /* send it... */
15128   S (mp);
15129
15130   /* Wait for a reply... */
15131   W (ret);
15132   return ret;
15133 }
15134
15135 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15136
15137 static int
15138 api_one_map_register_enable_disable (vat_main_t * vam)
15139 {
15140   unformat_input_t *input = vam->input;
15141   vl_api_one_map_register_enable_disable_t *mp;
15142   u8 is_set = 0;
15143   u8 is_en = 0;
15144   int ret;
15145
15146   /* Parse args required to build the message */
15147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15148     {
15149       if (unformat (input, "enable"))
15150         {
15151           is_set = 1;
15152           is_en = 1;
15153         }
15154       else if (unformat (input, "disable"))
15155         is_set = 1;
15156       else
15157         break;
15158     }
15159
15160   if (!is_set)
15161     {
15162       errmsg ("Value not set");
15163       return -99;
15164     }
15165
15166   /* Construct the API message */
15167   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15168
15169   mp->is_enabled = is_en;
15170
15171   /* send it... */
15172   S (mp);
15173
15174   /* Wait for a reply... */
15175   W (ret);
15176   return ret;
15177 }
15178
15179 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15180
15181 static int
15182 api_one_enable_disable (vat_main_t * vam)
15183 {
15184   unformat_input_t *input = vam->input;
15185   vl_api_one_enable_disable_t *mp;
15186   u8 is_set = 0;
15187   u8 is_en = 0;
15188   int ret;
15189
15190   /* Parse args required to build the message */
15191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15192     {
15193       if (unformat (input, "enable"))
15194         {
15195           is_set = 1;
15196           is_en = 1;
15197         }
15198       else if (unformat (input, "disable"))
15199         {
15200           is_set = 1;
15201         }
15202       else
15203         break;
15204     }
15205
15206   if (!is_set)
15207     {
15208       errmsg ("Value not set");
15209       return -99;
15210     }
15211
15212   /* Construct the API message */
15213   M (ONE_ENABLE_DISABLE, mp);
15214
15215   mp->is_en = is_en;
15216
15217   /* send it... */
15218   S (mp);
15219
15220   /* Wait for a reply... */
15221   W (ret);
15222   return ret;
15223 }
15224
15225 #define api_lisp_enable_disable api_one_enable_disable
15226
15227 static int
15228 api_show_one_map_register_state (vat_main_t * vam)
15229 {
15230   vl_api_show_one_map_register_state_t *mp;
15231   int ret;
15232
15233   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15234
15235   /* send */
15236   S (mp);
15237
15238   /* wait for reply */
15239   W (ret);
15240   return ret;
15241 }
15242
15243 #define api_show_lisp_map_register_state api_show_one_map_register_state
15244
15245 static int
15246 api_show_one_rloc_probe_state (vat_main_t * vam)
15247 {
15248   vl_api_show_one_rloc_probe_state_t *mp;
15249   int ret;
15250
15251   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15252
15253   /* send */
15254   S (mp);
15255
15256   /* wait for reply */
15257   W (ret);
15258   return ret;
15259 }
15260
15261 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15262
15263 static int
15264 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15265 {
15266   vl_api_one_add_del_l2_arp_entry_t *mp;
15267   unformat_input_t *input = vam->input;
15268   u8 is_add = 1;
15269   u8 mac_set = 0;
15270   u8 bd_set = 0;
15271   u8 ip_set = 0;
15272   u8 mac[6] = { 0, };
15273   u32 ip4 = 0, bd = ~0;
15274   int ret;
15275
15276   /* Parse args required to build the message */
15277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15278     {
15279       if (unformat (input, "del"))
15280         is_add = 0;
15281       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15282         mac_set = 1;
15283       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15284         ip_set = 1;
15285       else if (unformat (input, "bd %d", &bd))
15286         bd_set = 1;
15287       else
15288         {
15289           errmsg ("parse error '%U'", format_unformat_error, input);
15290           return -99;
15291         }
15292     }
15293
15294   if (!bd_set || !ip_set || (!mac_set && is_add))
15295     {
15296       errmsg ("Missing BD, IP or MAC!");
15297       return -99;
15298     }
15299
15300   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15301   mp->is_add = is_add;
15302   clib_memcpy (mp->mac, mac, 6);
15303   mp->bd = clib_host_to_net_u32 (bd);
15304   mp->ip4 = ip4;
15305
15306   /* send */
15307   S (mp);
15308
15309   /* wait for reply */
15310   W (ret);
15311   return ret;
15312 }
15313
15314 static int
15315 api_one_l2_arp_bd_get (vat_main_t * vam)
15316 {
15317   vl_api_one_l2_arp_bd_get_t *mp;
15318   int ret;
15319
15320   M (ONE_L2_ARP_BD_GET, mp);
15321
15322   /* send */
15323   S (mp);
15324
15325   /* wait for reply */
15326   W (ret);
15327   return ret;
15328 }
15329
15330 static int
15331 api_one_l2_arp_entries_get (vat_main_t * vam)
15332 {
15333   vl_api_one_l2_arp_entries_get_t *mp;
15334   unformat_input_t *input = vam->input;
15335   u8 bd_set = 0;
15336   u32 bd = ~0;
15337   int ret;
15338
15339   /* Parse args required to build the message */
15340   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15341     {
15342       if (unformat (input, "bd %d", &bd))
15343         bd_set = 1;
15344       else
15345         {
15346           errmsg ("parse error '%U'", format_unformat_error, input);
15347           return -99;
15348         }
15349     }
15350
15351   if (!bd_set)
15352     {
15353       errmsg ("Expected bridge domain!");
15354       return -99;
15355     }
15356
15357   M (ONE_L2_ARP_ENTRIES_GET, mp);
15358   mp->bd = clib_host_to_net_u32 (bd);
15359
15360   /* send */
15361   S (mp);
15362
15363   /* wait for reply */
15364   W (ret);
15365   return ret;
15366 }
15367
15368 static int
15369 api_one_stats_enable_disable (vat_main_t * vam)
15370 {
15371   vl_api_one_stats_enable_disable_t *mp;
15372   unformat_input_t *input = vam->input;
15373   u8 is_set = 0;
15374   u8 is_en = 0;
15375   int ret;
15376
15377   /* Parse args required to build the message */
15378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15379     {
15380       if (unformat (input, "enable"))
15381         {
15382           is_set = 1;
15383           is_en = 1;
15384         }
15385       else if (unformat (input, "disable"))
15386         {
15387           is_set = 1;
15388         }
15389       else
15390         break;
15391     }
15392
15393   if (!is_set)
15394     {
15395       errmsg ("Value not set");
15396       return -99;
15397     }
15398
15399   M (ONE_STATS_ENABLE_DISABLE, mp);
15400   mp->is_en = is_en;
15401
15402   /* send */
15403   S (mp);
15404
15405   /* wait for reply */
15406   W (ret);
15407   return ret;
15408 }
15409
15410 static int
15411 api_show_one_stats_enable_disable (vat_main_t * vam)
15412 {
15413   vl_api_show_one_stats_enable_disable_t *mp;
15414   int ret;
15415
15416   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15417
15418   /* send */
15419   S (mp);
15420
15421   /* wait for reply */
15422   W (ret);
15423   return ret;
15424 }
15425
15426 static int
15427 api_show_one_map_request_mode (vat_main_t * vam)
15428 {
15429   vl_api_show_one_map_request_mode_t *mp;
15430   int ret;
15431
15432   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15433
15434   /* send */
15435   S (mp);
15436
15437   /* wait for reply */
15438   W (ret);
15439   return ret;
15440 }
15441
15442 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15443
15444 static int
15445 api_one_map_request_mode (vat_main_t * vam)
15446 {
15447   unformat_input_t *input = vam->input;
15448   vl_api_one_map_request_mode_t *mp;
15449   u8 mode = 0;
15450   int ret;
15451
15452   /* Parse args required to build the message */
15453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15454     {
15455       if (unformat (input, "dst-only"))
15456         mode = 0;
15457       else if (unformat (input, "src-dst"))
15458         mode = 1;
15459       else
15460         {
15461           errmsg ("parse error '%U'", format_unformat_error, input);
15462           return -99;
15463         }
15464     }
15465
15466   M (ONE_MAP_REQUEST_MODE, mp);
15467
15468   mp->mode = mode;
15469
15470   /* send */
15471   S (mp);
15472
15473   /* wait for reply */
15474   W (ret);
15475   return ret;
15476 }
15477
15478 #define api_lisp_map_request_mode api_one_map_request_mode
15479
15480 /**
15481  * Enable/disable ONE proxy ITR.
15482  *
15483  * @param vam vpp API test context
15484  * @return return code
15485  */
15486 static int
15487 api_one_pitr_set_locator_set (vat_main_t * vam)
15488 {
15489   u8 ls_name_set = 0;
15490   unformat_input_t *input = vam->input;
15491   vl_api_one_pitr_set_locator_set_t *mp;
15492   u8 is_add = 1;
15493   u8 *ls_name = 0;
15494   int ret;
15495
15496   /* Parse args required to build the message */
15497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15498     {
15499       if (unformat (input, "del"))
15500         is_add = 0;
15501       else if (unformat (input, "locator-set %s", &ls_name))
15502         ls_name_set = 1;
15503       else
15504         {
15505           errmsg ("parse error '%U'", format_unformat_error, input);
15506           return -99;
15507         }
15508     }
15509
15510   if (!ls_name_set)
15511     {
15512       errmsg ("locator-set name not set!");
15513       return -99;
15514     }
15515
15516   M (ONE_PITR_SET_LOCATOR_SET, mp);
15517
15518   mp->is_add = is_add;
15519   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15520   vec_free (ls_name);
15521
15522   /* send */
15523   S (mp);
15524
15525   /* wait for reply */
15526   W (ret);
15527   return ret;
15528 }
15529
15530 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15531
15532 static int
15533 api_one_nsh_set_locator_set (vat_main_t * vam)
15534 {
15535   u8 ls_name_set = 0;
15536   unformat_input_t *input = vam->input;
15537   vl_api_one_nsh_set_locator_set_t *mp;
15538   u8 is_add = 1;
15539   u8 *ls_name = 0;
15540   int ret;
15541
15542   /* Parse args required to build the message */
15543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15544     {
15545       if (unformat (input, "del"))
15546         is_add = 0;
15547       else if (unformat (input, "ls %s", &ls_name))
15548         ls_name_set = 1;
15549       else
15550         {
15551           errmsg ("parse error '%U'", format_unformat_error, input);
15552           return -99;
15553         }
15554     }
15555
15556   if (!ls_name_set && is_add)
15557     {
15558       errmsg ("locator-set name not set!");
15559       return -99;
15560     }
15561
15562   M (ONE_NSH_SET_LOCATOR_SET, mp);
15563
15564   mp->is_add = is_add;
15565   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15566   vec_free (ls_name);
15567
15568   /* send */
15569   S (mp);
15570
15571   /* wait for reply */
15572   W (ret);
15573   return ret;
15574 }
15575
15576 static int
15577 api_show_one_pitr (vat_main_t * vam)
15578 {
15579   vl_api_show_one_pitr_t *mp;
15580   int ret;
15581
15582   if (!vam->json_output)
15583     {
15584       print (vam->ofp, "%=20s", "lisp status:");
15585     }
15586
15587   M (SHOW_ONE_PITR, mp);
15588   /* send it... */
15589   S (mp);
15590
15591   /* Wait for a reply... */
15592   W (ret);
15593   return ret;
15594 }
15595
15596 #define api_show_lisp_pitr api_show_one_pitr
15597
15598 static int
15599 api_one_use_petr (vat_main_t * vam)
15600 {
15601   unformat_input_t *input = vam->input;
15602   vl_api_one_use_petr_t *mp;
15603   u8 is_add = 0;
15604   ip_address_t ip;
15605   int ret;
15606
15607   memset (&ip, 0, sizeof (ip));
15608
15609   /* Parse args required to build the message */
15610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15611     {
15612       if (unformat (input, "disable"))
15613         is_add = 0;
15614       else
15615         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15616         {
15617           is_add = 1;
15618           ip_addr_version (&ip) = IP4;
15619         }
15620       else
15621         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15622         {
15623           is_add = 1;
15624           ip_addr_version (&ip) = IP6;
15625         }
15626       else
15627         {
15628           errmsg ("parse error '%U'", format_unformat_error, input);
15629           return -99;
15630         }
15631     }
15632
15633   M (ONE_USE_PETR, mp);
15634
15635   mp->is_add = is_add;
15636   if (is_add)
15637     {
15638       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15639       if (mp->is_ip4)
15640         clib_memcpy (mp->address, &ip, 4);
15641       else
15642         clib_memcpy (mp->address, &ip, 16);
15643     }
15644
15645   /* send */
15646   S (mp);
15647
15648   /* wait for reply */
15649   W (ret);
15650   return ret;
15651 }
15652
15653 #define api_lisp_use_petr api_one_use_petr
15654
15655 static int
15656 api_show_one_nsh_mapping (vat_main_t * vam)
15657 {
15658   vl_api_show_one_use_petr_t *mp;
15659   int ret;
15660
15661   if (!vam->json_output)
15662     {
15663       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15664     }
15665
15666   M (SHOW_ONE_NSH_MAPPING, mp);
15667   /* send it... */
15668   S (mp);
15669
15670   /* Wait for a reply... */
15671   W (ret);
15672   return ret;
15673 }
15674
15675 static int
15676 api_show_one_use_petr (vat_main_t * vam)
15677 {
15678   vl_api_show_one_use_petr_t *mp;
15679   int ret;
15680
15681   if (!vam->json_output)
15682     {
15683       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15684     }
15685
15686   M (SHOW_ONE_USE_PETR, mp);
15687   /* send it... */
15688   S (mp);
15689
15690   /* Wait for a reply... */
15691   W (ret);
15692   return ret;
15693 }
15694
15695 #define api_show_lisp_use_petr api_show_one_use_petr
15696
15697 /**
15698  * Add/delete mapping between vni and vrf
15699  */
15700 static int
15701 api_one_eid_table_add_del_map (vat_main_t * vam)
15702 {
15703   unformat_input_t *input = vam->input;
15704   vl_api_one_eid_table_add_del_map_t *mp;
15705   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15706   u32 vni, vrf, bd_index;
15707   int ret;
15708
15709   /* Parse args required to build the message */
15710   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15711     {
15712       if (unformat (input, "del"))
15713         is_add = 0;
15714       else if (unformat (input, "vrf %d", &vrf))
15715         vrf_set = 1;
15716       else if (unformat (input, "bd_index %d", &bd_index))
15717         bd_index_set = 1;
15718       else if (unformat (input, "vni %d", &vni))
15719         vni_set = 1;
15720       else
15721         break;
15722     }
15723
15724   if (!vni_set || (!vrf_set && !bd_index_set))
15725     {
15726       errmsg ("missing arguments!");
15727       return -99;
15728     }
15729
15730   if (vrf_set && bd_index_set)
15731     {
15732       errmsg ("error: both vrf and bd entered!");
15733       return -99;
15734     }
15735
15736   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15737
15738   mp->is_add = is_add;
15739   mp->vni = htonl (vni);
15740   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15741   mp->is_l2 = bd_index_set;
15742
15743   /* send */
15744   S (mp);
15745
15746   /* wait for reply */
15747   W (ret);
15748   return ret;
15749 }
15750
15751 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15752
15753 uword
15754 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15755 {
15756   u32 *action = va_arg (*args, u32 *);
15757   u8 *s = 0;
15758
15759   if (unformat (input, "%s", &s))
15760     {
15761       if (!strcmp ((char *) s, "no-action"))
15762         action[0] = 0;
15763       else if (!strcmp ((char *) s, "natively-forward"))
15764         action[0] = 1;
15765       else if (!strcmp ((char *) s, "send-map-request"))
15766         action[0] = 2;
15767       else if (!strcmp ((char *) s, "drop"))
15768         action[0] = 3;
15769       else
15770         {
15771           clib_warning ("invalid action: '%s'", s);
15772           action[0] = 3;
15773         }
15774     }
15775   else
15776     return 0;
15777
15778   vec_free (s);
15779   return 1;
15780 }
15781
15782 /**
15783  * Add/del remote mapping to/from ONE control plane
15784  *
15785  * @param vam vpp API test context
15786  * @return return code
15787  */
15788 static int
15789 api_one_add_del_remote_mapping (vat_main_t * vam)
15790 {
15791   unformat_input_t *input = vam->input;
15792   vl_api_one_add_del_remote_mapping_t *mp;
15793   u32 vni = 0;
15794   lisp_eid_vat_t _eid, *eid = &_eid;
15795   lisp_eid_vat_t _seid, *seid = &_seid;
15796   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15797   u32 action = ~0, p, w, data_len;
15798   ip4_address_t rloc4;
15799   ip6_address_t rloc6;
15800   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15801   int ret;
15802
15803   memset (&rloc, 0, sizeof (rloc));
15804
15805   /* Parse args required to build the message */
15806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15807     {
15808       if (unformat (input, "del-all"))
15809         {
15810           del_all = 1;
15811         }
15812       else if (unformat (input, "del"))
15813         {
15814           is_add = 0;
15815         }
15816       else if (unformat (input, "add"))
15817         {
15818           is_add = 1;
15819         }
15820       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15821         {
15822           eid_set = 1;
15823         }
15824       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15825         {
15826           seid_set = 1;
15827         }
15828       else if (unformat (input, "vni %d", &vni))
15829         {
15830           ;
15831         }
15832       else if (unformat (input, "p %d w %d", &p, &w))
15833         {
15834           if (!curr_rloc)
15835             {
15836               errmsg ("No RLOC configured for setting priority/weight!");
15837               return -99;
15838             }
15839           curr_rloc->priority = p;
15840           curr_rloc->weight = w;
15841         }
15842       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15843         {
15844           rloc.is_ip4 = 1;
15845           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15846           vec_add1 (rlocs, rloc);
15847           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15848         }
15849       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15850         {
15851           rloc.is_ip4 = 0;
15852           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15853           vec_add1 (rlocs, rloc);
15854           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15855         }
15856       else if (unformat (input, "action %U",
15857                          unformat_negative_mapping_action, &action))
15858         {
15859           ;
15860         }
15861       else
15862         {
15863           clib_warning ("parse error '%U'", format_unformat_error, input);
15864           return -99;
15865         }
15866     }
15867
15868   if (0 == eid_set)
15869     {
15870       errmsg ("missing params!");
15871       return -99;
15872     }
15873
15874   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15875     {
15876       errmsg ("no action set for negative map-reply!");
15877       return -99;
15878     }
15879
15880   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15881
15882   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15883   mp->is_add = is_add;
15884   mp->vni = htonl (vni);
15885   mp->action = (u8) action;
15886   mp->is_src_dst = seid_set;
15887   mp->eid_len = eid->len;
15888   mp->seid_len = seid->len;
15889   mp->del_all = del_all;
15890   mp->eid_type = eid->type;
15891   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15892   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15893
15894   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15895   clib_memcpy (mp->rlocs, rlocs, data_len);
15896   vec_free (rlocs);
15897
15898   /* send it... */
15899   S (mp);
15900
15901   /* Wait for a reply... */
15902   W (ret);
15903   return ret;
15904 }
15905
15906 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15907
15908 /**
15909  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15910  * forwarding entries in data-plane accordingly.
15911  *
15912  * @param vam vpp API test context
15913  * @return return code
15914  */
15915 static int
15916 api_one_add_del_adjacency (vat_main_t * vam)
15917 {
15918   unformat_input_t *input = vam->input;
15919   vl_api_one_add_del_adjacency_t *mp;
15920   u32 vni = 0;
15921   ip4_address_t leid4, reid4;
15922   ip6_address_t leid6, reid6;
15923   u8 reid_mac[6] = { 0 };
15924   u8 leid_mac[6] = { 0 };
15925   u8 reid_type, leid_type;
15926   u32 leid_len = 0, reid_len = 0, len;
15927   u8 is_add = 1;
15928   int ret;
15929
15930   leid_type = reid_type = (u8) ~ 0;
15931
15932   /* Parse args required to build the message */
15933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15934     {
15935       if (unformat (input, "del"))
15936         {
15937           is_add = 0;
15938         }
15939       else if (unformat (input, "add"))
15940         {
15941           is_add = 1;
15942         }
15943       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15944                          &reid4, &len))
15945         {
15946           reid_type = 0;        /* ipv4 */
15947           reid_len = len;
15948         }
15949       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15950                          &reid6, &len))
15951         {
15952           reid_type = 1;        /* ipv6 */
15953           reid_len = len;
15954         }
15955       else if (unformat (input, "reid %U", unformat_ethernet_address,
15956                          reid_mac))
15957         {
15958           reid_type = 2;        /* mac */
15959         }
15960       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15961                          &leid4, &len))
15962         {
15963           leid_type = 0;        /* ipv4 */
15964           leid_len = len;
15965         }
15966       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15967                          &leid6, &len))
15968         {
15969           leid_type = 1;        /* ipv6 */
15970           leid_len = len;
15971         }
15972       else if (unformat (input, "leid %U", unformat_ethernet_address,
15973                          leid_mac))
15974         {
15975           leid_type = 2;        /* mac */
15976         }
15977       else if (unformat (input, "vni %d", &vni))
15978         {
15979           ;
15980         }
15981       else
15982         {
15983           errmsg ("parse error '%U'", format_unformat_error, input);
15984           return -99;
15985         }
15986     }
15987
15988   if ((u8) ~ 0 == reid_type)
15989     {
15990       errmsg ("missing params!");
15991       return -99;
15992     }
15993
15994   if (leid_type != reid_type)
15995     {
15996       errmsg ("remote and local EIDs are of different types!");
15997       return -99;
15998     }
15999
16000   M (ONE_ADD_DEL_ADJACENCY, mp);
16001   mp->is_add = is_add;
16002   mp->vni = htonl (vni);
16003   mp->leid_len = leid_len;
16004   mp->reid_len = reid_len;
16005   mp->eid_type = reid_type;
16006
16007   switch (mp->eid_type)
16008     {
16009     case 0:
16010       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16011       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16012       break;
16013     case 1:
16014       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16015       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16016       break;
16017     case 2:
16018       clib_memcpy (mp->leid, leid_mac, 6);
16019       clib_memcpy (mp->reid, reid_mac, 6);
16020       break;
16021     default:
16022       errmsg ("unknown EID type %d!", mp->eid_type);
16023       return 0;
16024     }
16025
16026   /* send it... */
16027   S (mp);
16028
16029   /* Wait for a reply... */
16030   W (ret);
16031   return ret;
16032 }
16033
16034 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16035
16036 uword
16037 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16038 {
16039   u32 *mode = va_arg (*args, u32 *);
16040
16041   if (unformat (input, "lisp"))
16042     *mode = 0;
16043   else if (unformat (input, "vxlan"))
16044     *mode = 1;
16045   else
16046     return 0;
16047
16048   return 1;
16049 }
16050
16051 static int
16052 api_gpe_get_encap_mode (vat_main_t * vam)
16053 {
16054   vl_api_gpe_get_encap_mode_t *mp;
16055   int ret;
16056
16057   /* Construct the API message */
16058   M (GPE_GET_ENCAP_MODE, mp);
16059
16060   /* send it... */
16061   S (mp);
16062
16063   /* Wait for a reply... */
16064   W (ret);
16065   return ret;
16066 }
16067
16068 static int
16069 api_gpe_set_encap_mode (vat_main_t * vam)
16070 {
16071   unformat_input_t *input = vam->input;
16072   vl_api_gpe_set_encap_mode_t *mp;
16073   int ret;
16074   u32 mode = 0;
16075
16076   /* Parse args required to build the message */
16077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16078     {
16079       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16080         ;
16081       else
16082         break;
16083     }
16084
16085   /* Construct the API message */
16086   M (GPE_SET_ENCAP_MODE, mp);
16087
16088   mp->mode = mode;
16089
16090   /* send it... */
16091   S (mp);
16092
16093   /* Wait for a reply... */
16094   W (ret);
16095   return ret;
16096 }
16097
16098 static int
16099 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16100 {
16101   unformat_input_t *input = vam->input;
16102   vl_api_gpe_add_del_iface_t *mp;
16103   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16104   u32 dp_table = 0, vni = 0;
16105   int ret;
16106
16107   /* Parse args required to build the message */
16108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16109     {
16110       if (unformat (input, "up"))
16111         {
16112           action_set = 1;
16113           is_add = 1;
16114         }
16115       else if (unformat (input, "down"))
16116         {
16117           action_set = 1;
16118           is_add = 0;
16119         }
16120       else if (unformat (input, "table_id %d", &dp_table))
16121         {
16122           dp_table_set = 1;
16123         }
16124       else if (unformat (input, "bd_id %d", &dp_table))
16125         {
16126           dp_table_set = 1;
16127           is_l2 = 1;
16128         }
16129       else if (unformat (input, "vni %d", &vni))
16130         {
16131           vni_set = 1;
16132         }
16133       else
16134         break;
16135     }
16136
16137   if (action_set == 0)
16138     {
16139       errmsg ("Action not set");
16140       return -99;
16141     }
16142   if (dp_table_set == 0 || vni_set == 0)
16143     {
16144       errmsg ("vni and dp_table must be set");
16145       return -99;
16146     }
16147
16148   /* Construct the API message */
16149   M (GPE_ADD_DEL_IFACE, mp);
16150
16151   mp->is_add = is_add;
16152   mp->dp_table = clib_host_to_net_u32 (dp_table);
16153   mp->is_l2 = is_l2;
16154   mp->vni = clib_host_to_net_u32 (vni);
16155
16156   /* send it... */
16157   S (mp);
16158
16159   /* Wait for a reply... */
16160   W (ret);
16161   return ret;
16162 }
16163
16164 static int
16165 api_one_map_register_set_ttl (vat_main_t * vam)
16166 {
16167   unformat_input_t *input = vam->input;
16168   vl_api_one_map_register_set_ttl_t *mp;
16169   u32 ttl = 0;
16170   u8 is_set = 0;
16171   int ret;
16172
16173   /* Parse args required to build the message */
16174   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16175     {
16176       if (unformat (input, "%u", &ttl))
16177         is_set = 1;
16178       else
16179         {
16180           clib_warning ("parse error '%U'", format_unformat_error, input);
16181           return -99;
16182         }
16183     }
16184
16185   if (!is_set)
16186     {
16187       errmsg ("TTL value missing!");
16188       return -99;
16189     }
16190
16191   M (ONE_MAP_REGISTER_SET_TTL, mp);
16192   mp->ttl = clib_host_to_net_u32 (ttl);
16193
16194   /* send it... */
16195   S (mp);
16196
16197   /* Wait for a reply... */
16198   W (ret);
16199   return ret;
16200 }
16201
16202 static int
16203 api_show_one_map_register_ttl (vat_main_t * vam)
16204 {
16205   vl_api_show_one_map_register_ttl_t *mp;
16206   int ret;
16207
16208   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16209
16210   /* send it... */
16211   S (mp);
16212
16213   /* Wait for a reply... */
16214   W (ret);
16215   return ret;
16216 }
16217
16218 /**
16219  * Add/del map request itr rlocs from ONE control plane and updates
16220  *
16221  * @param vam vpp API test context
16222  * @return return code
16223  */
16224 static int
16225 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16226 {
16227   unformat_input_t *input = vam->input;
16228   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16229   u8 *locator_set_name = 0;
16230   u8 locator_set_name_set = 0;
16231   u8 is_add = 1;
16232   int ret;
16233
16234   /* Parse args required to build the message */
16235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16236     {
16237       if (unformat (input, "del"))
16238         {
16239           is_add = 0;
16240         }
16241       else if (unformat (input, "%_%v%_", &locator_set_name))
16242         {
16243           locator_set_name_set = 1;
16244         }
16245       else
16246         {
16247           clib_warning ("parse error '%U'", format_unformat_error, input);
16248           return -99;
16249         }
16250     }
16251
16252   if (is_add && !locator_set_name_set)
16253     {
16254       errmsg ("itr-rloc is not set!");
16255       return -99;
16256     }
16257
16258   if (is_add && vec_len (locator_set_name) > 64)
16259     {
16260       errmsg ("itr-rloc locator-set name too long");
16261       vec_free (locator_set_name);
16262       return -99;
16263     }
16264
16265   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16266   mp->is_add = is_add;
16267   if (is_add)
16268     {
16269       clib_memcpy (mp->locator_set_name, locator_set_name,
16270                    vec_len (locator_set_name));
16271     }
16272   else
16273     {
16274       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16275     }
16276   vec_free (locator_set_name);
16277
16278   /* send it... */
16279   S (mp);
16280
16281   /* Wait for a reply... */
16282   W (ret);
16283   return ret;
16284 }
16285
16286 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16287
16288 static int
16289 api_one_locator_dump (vat_main_t * vam)
16290 {
16291   unformat_input_t *input = vam->input;
16292   vl_api_one_locator_dump_t *mp;
16293   vl_api_control_ping_t *mp_ping;
16294   u8 is_index_set = 0, is_name_set = 0;
16295   u8 *ls_name = 0;
16296   u32 ls_index = ~0;
16297   int ret;
16298
16299   /* Parse args required to build the message */
16300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16301     {
16302       if (unformat (input, "ls_name %_%v%_", &ls_name))
16303         {
16304           is_name_set = 1;
16305         }
16306       else if (unformat (input, "ls_index %d", &ls_index))
16307         {
16308           is_index_set = 1;
16309         }
16310       else
16311         {
16312           errmsg ("parse error '%U'", format_unformat_error, input);
16313           return -99;
16314         }
16315     }
16316
16317   if (!is_index_set && !is_name_set)
16318     {
16319       errmsg ("error: expected one of index or name!");
16320       return -99;
16321     }
16322
16323   if (is_index_set && is_name_set)
16324     {
16325       errmsg ("error: only one param expected!");
16326       return -99;
16327     }
16328
16329   if (vec_len (ls_name) > 62)
16330     {
16331       errmsg ("error: locator set name too long!");
16332       return -99;
16333     }
16334
16335   if (!vam->json_output)
16336     {
16337       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16338     }
16339
16340   M (ONE_LOCATOR_DUMP, mp);
16341   mp->is_index_set = is_index_set;
16342
16343   if (is_index_set)
16344     mp->ls_index = clib_host_to_net_u32 (ls_index);
16345   else
16346     {
16347       vec_add1 (ls_name, 0);
16348       strncpy ((char *) mp->ls_name, (char *) ls_name,
16349                sizeof (mp->ls_name) - 1);
16350     }
16351
16352   /* send it... */
16353   S (mp);
16354
16355   /* Use a control ping for synchronization */
16356   M (CONTROL_PING, mp_ping);
16357   S (mp_ping);
16358
16359   /* Wait for a reply... */
16360   W (ret);
16361   return ret;
16362 }
16363
16364 #define api_lisp_locator_dump api_one_locator_dump
16365
16366 static int
16367 api_one_locator_set_dump (vat_main_t * vam)
16368 {
16369   vl_api_one_locator_set_dump_t *mp;
16370   vl_api_control_ping_t *mp_ping;
16371   unformat_input_t *input = vam->input;
16372   u8 filter = 0;
16373   int ret;
16374
16375   /* Parse args required to build the message */
16376   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16377     {
16378       if (unformat (input, "local"))
16379         {
16380           filter = 1;
16381         }
16382       else if (unformat (input, "remote"))
16383         {
16384           filter = 2;
16385         }
16386       else
16387         {
16388           errmsg ("parse error '%U'", format_unformat_error, input);
16389           return -99;
16390         }
16391     }
16392
16393   if (!vam->json_output)
16394     {
16395       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16396     }
16397
16398   M (ONE_LOCATOR_SET_DUMP, mp);
16399
16400   mp->filter = filter;
16401
16402   /* send it... */
16403   S (mp);
16404
16405   /* Use a control ping for synchronization */
16406   M (CONTROL_PING, mp_ping);
16407   S (mp_ping);
16408
16409   /* Wait for a reply... */
16410   W (ret);
16411   return ret;
16412 }
16413
16414 #define api_lisp_locator_set_dump api_one_locator_set_dump
16415
16416 static int
16417 api_one_eid_table_map_dump (vat_main_t * vam)
16418 {
16419   u8 is_l2 = 0;
16420   u8 mode_set = 0;
16421   unformat_input_t *input = vam->input;
16422   vl_api_one_eid_table_map_dump_t *mp;
16423   vl_api_control_ping_t *mp_ping;
16424   int ret;
16425
16426   /* Parse args required to build the message */
16427   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16428     {
16429       if (unformat (input, "l2"))
16430         {
16431           is_l2 = 1;
16432           mode_set = 1;
16433         }
16434       else if (unformat (input, "l3"))
16435         {
16436           is_l2 = 0;
16437           mode_set = 1;
16438         }
16439       else
16440         {
16441           errmsg ("parse error '%U'", format_unformat_error, input);
16442           return -99;
16443         }
16444     }
16445
16446   if (!mode_set)
16447     {
16448       errmsg ("expected one of 'l2' or 'l3' parameter!");
16449       return -99;
16450     }
16451
16452   if (!vam->json_output)
16453     {
16454       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16455     }
16456
16457   M (ONE_EID_TABLE_MAP_DUMP, mp);
16458   mp->is_l2 = is_l2;
16459
16460   /* send it... */
16461   S (mp);
16462
16463   /* Use a control ping for synchronization */
16464   M (CONTROL_PING, mp_ping);
16465   S (mp_ping);
16466
16467   /* Wait for a reply... */
16468   W (ret);
16469   return ret;
16470 }
16471
16472 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16473
16474 static int
16475 api_one_eid_table_vni_dump (vat_main_t * vam)
16476 {
16477   vl_api_one_eid_table_vni_dump_t *mp;
16478   vl_api_control_ping_t *mp_ping;
16479   int ret;
16480
16481   if (!vam->json_output)
16482     {
16483       print (vam->ofp, "VNI");
16484     }
16485
16486   M (ONE_EID_TABLE_VNI_DUMP, mp);
16487
16488   /* send it... */
16489   S (mp);
16490
16491   /* Use a control ping for synchronization */
16492   M (CONTROL_PING, mp_ping);
16493   S (mp_ping);
16494
16495   /* Wait for a reply... */
16496   W (ret);
16497   return ret;
16498 }
16499
16500 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16501
16502 static int
16503 api_one_eid_table_dump (vat_main_t * vam)
16504 {
16505   unformat_input_t *i = vam->input;
16506   vl_api_one_eid_table_dump_t *mp;
16507   vl_api_control_ping_t *mp_ping;
16508   struct in_addr ip4;
16509   struct in6_addr ip6;
16510   u8 mac[6];
16511   u8 eid_type = ~0, eid_set = 0;
16512   u32 prefix_length = ~0, t, vni = 0;
16513   u8 filter = 0;
16514   int ret;
16515   lisp_nsh_api_t nsh;
16516
16517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16518     {
16519       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16520         {
16521           eid_set = 1;
16522           eid_type = 0;
16523           prefix_length = t;
16524         }
16525       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16526         {
16527           eid_set = 1;
16528           eid_type = 1;
16529           prefix_length = t;
16530         }
16531       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16532         {
16533           eid_set = 1;
16534           eid_type = 2;
16535         }
16536       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16537         {
16538           eid_set = 1;
16539           eid_type = 3;
16540         }
16541       else if (unformat (i, "vni %d", &t))
16542         {
16543           vni = t;
16544         }
16545       else if (unformat (i, "local"))
16546         {
16547           filter = 1;
16548         }
16549       else if (unformat (i, "remote"))
16550         {
16551           filter = 2;
16552         }
16553       else
16554         {
16555           errmsg ("parse error '%U'", format_unformat_error, i);
16556           return -99;
16557         }
16558     }
16559
16560   if (!vam->json_output)
16561     {
16562       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16563              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16564     }
16565
16566   M (ONE_EID_TABLE_DUMP, mp);
16567
16568   mp->filter = filter;
16569   if (eid_set)
16570     {
16571       mp->eid_set = 1;
16572       mp->vni = htonl (vni);
16573       mp->eid_type = eid_type;
16574       switch (eid_type)
16575         {
16576         case 0:
16577           mp->prefix_length = prefix_length;
16578           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16579           break;
16580         case 1:
16581           mp->prefix_length = prefix_length;
16582           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16583           break;
16584         case 2:
16585           clib_memcpy (mp->eid, mac, sizeof (mac));
16586           break;
16587         case 3:
16588           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16589           break;
16590         default:
16591           errmsg ("unknown EID type %d!", eid_type);
16592           return -99;
16593         }
16594     }
16595
16596   /* send it... */
16597   S (mp);
16598
16599   /* Use a control ping for synchronization */
16600   M (CONTROL_PING, mp_ping);
16601   S (mp_ping);
16602
16603   /* Wait for a reply... */
16604   W (ret);
16605   return ret;
16606 }
16607
16608 #define api_lisp_eid_table_dump api_one_eid_table_dump
16609
16610 static int
16611 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16612 {
16613   unformat_input_t *i = vam->input;
16614   vl_api_gpe_fwd_entries_get_t *mp;
16615   u8 vni_set = 0;
16616   u32 vni = ~0;
16617   int ret;
16618
16619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16620     {
16621       if (unformat (i, "vni %d", &vni))
16622         {
16623           vni_set = 1;
16624         }
16625       else
16626         {
16627           errmsg ("parse error '%U'", format_unformat_error, i);
16628           return -99;
16629         }
16630     }
16631
16632   if (!vni_set)
16633     {
16634       errmsg ("vni not set!");
16635       return -99;
16636     }
16637
16638   if (!vam->json_output)
16639     {
16640       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16641              "leid", "reid");
16642     }
16643
16644   M (GPE_FWD_ENTRIES_GET, mp);
16645   mp->vni = clib_host_to_net_u32 (vni);
16646
16647   /* send it... */
16648   S (mp);
16649
16650   /* Wait for a reply... */
16651   W (ret);
16652   return ret;
16653 }
16654
16655 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16656 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16657 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16658 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16659 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16660 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16661 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16662 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16663
16664 static int
16665 api_one_adjacencies_get (vat_main_t * vam)
16666 {
16667   unformat_input_t *i = vam->input;
16668   vl_api_one_adjacencies_get_t *mp;
16669   u8 vni_set = 0;
16670   u32 vni = ~0;
16671   int ret;
16672
16673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16674     {
16675       if (unformat (i, "vni %d", &vni))
16676         {
16677           vni_set = 1;
16678         }
16679       else
16680         {
16681           errmsg ("parse error '%U'", format_unformat_error, i);
16682           return -99;
16683         }
16684     }
16685
16686   if (!vni_set)
16687     {
16688       errmsg ("vni not set!");
16689       return -99;
16690     }
16691
16692   if (!vam->json_output)
16693     {
16694       print (vam->ofp, "%s %40s", "leid", "reid");
16695     }
16696
16697   M (ONE_ADJACENCIES_GET, mp);
16698   mp->vni = clib_host_to_net_u32 (vni);
16699
16700   /* send it... */
16701   S (mp);
16702
16703   /* Wait for a reply... */
16704   W (ret);
16705   return ret;
16706 }
16707
16708 #define api_lisp_adjacencies_get api_one_adjacencies_get
16709
16710 static int
16711 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16712 {
16713   unformat_input_t *i = vam->input;
16714   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16715   int ret;
16716   u8 ip_family_set = 0, is_ip4 = 1;
16717
16718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16719     {
16720       if (unformat (i, "ip4"))
16721         {
16722           ip_family_set = 1;
16723           is_ip4 = 1;
16724         }
16725       else if (unformat (i, "ip6"))
16726         {
16727           ip_family_set = 1;
16728           is_ip4 = 0;
16729         }
16730       else
16731         {
16732           errmsg ("parse error '%U'", format_unformat_error, i);
16733           return -99;
16734         }
16735     }
16736
16737   if (!ip_family_set)
16738     {
16739       errmsg ("ip family not set!");
16740       return -99;
16741     }
16742
16743   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16744   mp->is_ip4 = is_ip4;
16745
16746   /* send it... */
16747   S (mp);
16748
16749   /* Wait for a reply... */
16750   W (ret);
16751   return ret;
16752 }
16753
16754 static int
16755 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16756 {
16757   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16758   int ret;
16759
16760   if (!vam->json_output)
16761     {
16762       print (vam->ofp, "VNIs");
16763     }
16764
16765   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16766
16767   /* send it... */
16768   S (mp);
16769
16770   /* Wait for a reply... */
16771   W (ret);
16772   return ret;
16773 }
16774
16775 static int
16776 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16777 {
16778   unformat_input_t *i = vam->input;
16779   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16780   int ret = 0;
16781   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16782   struct in_addr ip4;
16783   struct in6_addr ip6;
16784   u32 table_id = 0, nh_sw_if_index = ~0;
16785
16786   memset (&ip4, 0, sizeof (ip4));
16787   memset (&ip6, 0, sizeof (ip6));
16788
16789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16790     {
16791       if (unformat (i, "del"))
16792         is_add = 0;
16793       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16794                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16795         {
16796           ip_set = 1;
16797           is_ip4 = 1;
16798         }
16799       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16800                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16801         {
16802           ip_set = 1;
16803           is_ip4 = 0;
16804         }
16805       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16806         {
16807           ip_set = 1;
16808           is_ip4 = 1;
16809           nh_sw_if_index = ~0;
16810         }
16811       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16812         {
16813           ip_set = 1;
16814           is_ip4 = 0;
16815           nh_sw_if_index = ~0;
16816         }
16817       else if (unformat (i, "table %d", &table_id))
16818         ;
16819       else
16820         {
16821           errmsg ("parse error '%U'", format_unformat_error, i);
16822           return -99;
16823         }
16824     }
16825
16826   if (!ip_set)
16827     {
16828       errmsg ("nh addr not set!");
16829       return -99;
16830     }
16831
16832   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16833   mp->is_add = is_add;
16834   mp->table_id = clib_host_to_net_u32 (table_id);
16835   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16836   mp->is_ip4 = is_ip4;
16837   if (is_ip4)
16838     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16839   else
16840     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16841
16842   /* send it... */
16843   S (mp);
16844
16845   /* Wait for a reply... */
16846   W (ret);
16847   return ret;
16848 }
16849
16850 static int
16851 api_one_map_server_dump (vat_main_t * vam)
16852 {
16853   vl_api_one_map_server_dump_t *mp;
16854   vl_api_control_ping_t *mp_ping;
16855   int ret;
16856
16857   if (!vam->json_output)
16858     {
16859       print (vam->ofp, "%=20s", "Map server");
16860     }
16861
16862   M (ONE_MAP_SERVER_DUMP, mp);
16863   /* send it... */
16864   S (mp);
16865
16866   /* Use a control ping for synchronization */
16867   M (CONTROL_PING, mp_ping);
16868   S (mp_ping);
16869
16870   /* Wait for a reply... */
16871   W (ret);
16872   return ret;
16873 }
16874
16875 #define api_lisp_map_server_dump api_one_map_server_dump
16876
16877 static int
16878 api_one_map_resolver_dump (vat_main_t * vam)
16879 {
16880   vl_api_one_map_resolver_dump_t *mp;
16881   vl_api_control_ping_t *mp_ping;
16882   int ret;
16883
16884   if (!vam->json_output)
16885     {
16886       print (vam->ofp, "%=20s", "Map resolver");
16887     }
16888
16889   M (ONE_MAP_RESOLVER_DUMP, mp);
16890   /* send it... */
16891   S (mp);
16892
16893   /* Use a control ping for synchronization */
16894   M (CONTROL_PING, mp_ping);
16895   S (mp_ping);
16896
16897   /* Wait for a reply... */
16898   W (ret);
16899   return ret;
16900 }
16901
16902 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16903
16904 static int
16905 api_one_stats_flush (vat_main_t * vam)
16906 {
16907   vl_api_one_stats_flush_t *mp;
16908   int ret = 0;
16909
16910   M (ONE_STATS_FLUSH, mp);
16911   S (mp);
16912   W (ret);
16913   return ret;
16914 }
16915
16916 static int
16917 api_one_stats_dump (vat_main_t * vam)
16918 {
16919   vl_api_one_stats_dump_t *mp;
16920   vl_api_control_ping_t *mp_ping;
16921   int ret;
16922
16923   M (ONE_STATS_DUMP, mp);
16924   /* send it... */
16925   S (mp);
16926
16927   /* Use a control ping for synchronization */
16928   M (CONTROL_PING, mp_ping);
16929   S (mp_ping);
16930
16931   /* Wait for a reply... */
16932   W (ret);
16933   return ret;
16934 }
16935
16936 static int
16937 api_show_one_status (vat_main_t * vam)
16938 {
16939   vl_api_show_one_status_t *mp;
16940   int ret;
16941
16942   if (!vam->json_output)
16943     {
16944       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16945     }
16946
16947   M (SHOW_ONE_STATUS, mp);
16948   /* send it... */
16949   S (mp);
16950   /* Wait for a reply... */
16951   W (ret);
16952   return ret;
16953 }
16954
16955 #define api_show_lisp_status api_show_one_status
16956
16957 static int
16958 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16959 {
16960   vl_api_gpe_fwd_entry_path_dump_t *mp;
16961   vl_api_control_ping_t *mp_ping;
16962   unformat_input_t *i = vam->input;
16963   u32 fwd_entry_index = ~0;
16964   int ret;
16965
16966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16967     {
16968       if (unformat (i, "index %d", &fwd_entry_index))
16969         ;
16970       else
16971         break;
16972     }
16973
16974   if (~0 == fwd_entry_index)
16975     {
16976       errmsg ("no index specified!");
16977       return -99;
16978     }
16979
16980   if (!vam->json_output)
16981     {
16982       print (vam->ofp, "first line");
16983     }
16984
16985   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16986
16987   /* send it... */
16988   S (mp);
16989   /* Use a control ping for synchronization */
16990   M (CONTROL_PING, mp_ping);
16991   S (mp_ping);
16992
16993   /* Wait for a reply... */
16994   W (ret);
16995   return ret;
16996 }
16997
16998 static int
16999 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17000 {
17001   vl_api_one_get_map_request_itr_rlocs_t *mp;
17002   int ret;
17003
17004   if (!vam->json_output)
17005     {
17006       print (vam->ofp, "%=20s", "itr-rlocs:");
17007     }
17008
17009   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17010   /* send it... */
17011   S (mp);
17012   /* Wait for a reply... */
17013   W (ret);
17014   return ret;
17015 }
17016
17017 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17018
17019 static int
17020 api_af_packet_create (vat_main_t * vam)
17021 {
17022   unformat_input_t *i = vam->input;
17023   vl_api_af_packet_create_t *mp;
17024   u8 *host_if_name = 0;
17025   u8 hw_addr[6];
17026   u8 random_hw_addr = 1;
17027   int ret;
17028
17029   memset (hw_addr, 0, sizeof (hw_addr));
17030
17031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17032     {
17033       if (unformat (i, "name %s", &host_if_name))
17034         vec_add1 (host_if_name, 0);
17035       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17036         random_hw_addr = 0;
17037       else
17038         break;
17039     }
17040
17041   if (!vec_len (host_if_name))
17042     {
17043       errmsg ("host-interface name must be specified");
17044       return -99;
17045     }
17046
17047   if (vec_len (host_if_name) > 64)
17048     {
17049       errmsg ("host-interface name too long");
17050       return -99;
17051     }
17052
17053   M (AF_PACKET_CREATE, mp);
17054
17055   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17056   clib_memcpy (mp->hw_addr, hw_addr, 6);
17057   mp->use_random_hw_addr = random_hw_addr;
17058   vec_free (host_if_name);
17059
17060   S (mp);
17061
17062   /* *INDENT-OFF* */
17063   W2 (ret,
17064       ({
17065         if (ret == 0)
17066           fprintf (vam->ofp ? vam->ofp : stderr,
17067                    " new sw_if_index = %d\n", vam->sw_if_index);
17068       }));
17069   /* *INDENT-ON* */
17070   return ret;
17071 }
17072
17073 static int
17074 api_af_packet_delete (vat_main_t * vam)
17075 {
17076   unformat_input_t *i = vam->input;
17077   vl_api_af_packet_delete_t *mp;
17078   u8 *host_if_name = 0;
17079   int ret;
17080
17081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17082     {
17083       if (unformat (i, "name %s", &host_if_name))
17084         vec_add1 (host_if_name, 0);
17085       else
17086         break;
17087     }
17088
17089   if (!vec_len (host_if_name))
17090     {
17091       errmsg ("host-interface name must be specified");
17092       return -99;
17093     }
17094
17095   if (vec_len (host_if_name) > 64)
17096     {
17097       errmsg ("host-interface name too long");
17098       return -99;
17099     }
17100
17101   M (AF_PACKET_DELETE, mp);
17102
17103   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17104   vec_free (host_if_name);
17105
17106   S (mp);
17107   W (ret);
17108   return ret;
17109 }
17110
17111 static int
17112 api_policer_add_del (vat_main_t * vam)
17113 {
17114   unformat_input_t *i = vam->input;
17115   vl_api_policer_add_del_t *mp;
17116   u8 is_add = 1;
17117   u8 *name = 0;
17118   u32 cir = 0;
17119   u32 eir = 0;
17120   u64 cb = 0;
17121   u64 eb = 0;
17122   u8 rate_type = 0;
17123   u8 round_type = 0;
17124   u8 type = 0;
17125   u8 color_aware = 0;
17126   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17127   int ret;
17128
17129   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17130   conform_action.dscp = 0;
17131   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17132   exceed_action.dscp = 0;
17133   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17134   violate_action.dscp = 0;
17135
17136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17137     {
17138       if (unformat (i, "del"))
17139         is_add = 0;
17140       else if (unformat (i, "name %s", &name))
17141         vec_add1 (name, 0);
17142       else if (unformat (i, "cir %u", &cir))
17143         ;
17144       else if (unformat (i, "eir %u", &eir))
17145         ;
17146       else if (unformat (i, "cb %u", &cb))
17147         ;
17148       else if (unformat (i, "eb %u", &eb))
17149         ;
17150       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17151                          &rate_type))
17152         ;
17153       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17154                          &round_type))
17155         ;
17156       else if (unformat (i, "type %U", unformat_policer_type, &type))
17157         ;
17158       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17159                          &conform_action))
17160         ;
17161       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17162                          &exceed_action))
17163         ;
17164       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17165                          &violate_action))
17166         ;
17167       else if (unformat (i, "color-aware"))
17168         color_aware = 1;
17169       else
17170         break;
17171     }
17172
17173   if (!vec_len (name))
17174     {
17175       errmsg ("policer name must be specified");
17176       return -99;
17177     }
17178
17179   if (vec_len (name) > 64)
17180     {
17181       errmsg ("policer name too long");
17182       return -99;
17183     }
17184
17185   M (POLICER_ADD_DEL, mp);
17186
17187   clib_memcpy (mp->name, name, vec_len (name));
17188   vec_free (name);
17189   mp->is_add = is_add;
17190   mp->cir = cir;
17191   mp->eir = eir;
17192   mp->cb = cb;
17193   mp->eb = eb;
17194   mp->rate_type = rate_type;
17195   mp->round_type = round_type;
17196   mp->type = type;
17197   mp->conform_action_type = conform_action.action_type;
17198   mp->conform_dscp = conform_action.dscp;
17199   mp->exceed_action_type = exceed_action.action_type;
17200   mp->exceed_dscp = exceed_action.dscp;
17201   mp->violate_action_type = violate_action.action_type;
17202   mp->violate_dscp = violate_action.dscp;
17203   mp->color_aware = color_aware;
17204
17205   S (mp);
17206   W (ret);
17207   return ret;
17208 }
17209
17210 static int
17211 api_policer_dump (vat_main_t * vam)
17212 {
17213   unformat_input_t *i = vam->input;
17214   vl_api_policer_dump_t *mp;
17215   vl_api_control_ping_t *mp_ping;
17216   u8 *match_name = 0;
17217   u8 match_name_valid = 0;
17218   int ret;
17219
17220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17221     {
17222       if (unformat (i, "name %s", &match_name))
17223         {
17224           vec_add1 (match_name, 0);
17225           match_name_valid = 1;
17226         }
17227       else
17228         break;
17229     }
17230
17231   M (POLICER_DUMP, mp);
17232   mp->match_name_valid = match_name_valid;
17233   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17234   vec_free (match_name);
17235   /* send it... */
17236   S (mp);
17237
17238   /* Use a control ping for synchronization */
17239   M (CONTROL_PING, mp_ping);
17240   S (mp_ping);
17241
17242   /* Wait for a reply... */
17243   W (ret);
17244   return ret;
17245 }
17246
17247 static int
17248 api_policer_classify_set_interface (vat_main_t * vam)
17249 {
17250   unformat_input_t *i = vam->input;
17251   vl_api_policer_classify_set_interface_t *mp;
17252   u32 sw_if_index;
17253   int sw_if_index_set;
17254   u32 ip4_table_index = ~0;
17255   u32 ip6_table_index = ~0;
17256   u32 l2_table_index = ~0;
17257   u8 is_add = 1;
17258   int ret;
17259
17260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17261     {
17262       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17263         sw_if_index_set = 1;
17264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17265         sw_if_index_set = 1;
17266       else if (unformat (i, "del"))
17267         is_add = 0;
17268       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17269         ;
17270       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17271         ;
17272       else if (unformat (i, "l2-table %d", &l2_table_index))
17273         ;
17274       else
17275         {
17276           clib_warning ("parse error '%U'", format_unformat_error, i);
17277           return -99;
17278         }
17279     }
17280
17281   if (sw_if_index_set == 0)
17282     {
17283       errmsg ("missing interface name or sw_if_index");
17284       return -99;
17285     }
17286
17287   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17288
17289   mp->sw_if_index = ntohl (sw_if_index);
17290   mp->ip4_table_index = ntohl (ip4_table_index);
17291   mp->ip6_table_index = ntohl (ip6_table_index);
17292   mp->l2_table_index = ntohl (l2_table_index);
17293   mp->is_add = is_add;
17294
17295   S (mp);
17296   W (ret);
17297   return ret;
17298 }
17299
17300 static int
17301 api_policer_classify_dump (vat_main_t * vam)
17302 {
17303   unformat_input_t *i = vam->input;
17304   vl_api_policer_classify_dump_t *mp;
17305   vl_api_control_ping_t *mp_ping;
17306   u8 type = POLICER_CLASSIFY_N_TABLES;
17307   int ret;
17308
17309   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17310     ;
17311   else
17312     {
17313       errmsg ("classify table type must be specified");
17314       return -99;
17315     }
17316
17317   if (!vam->json_output)
17318     {
17319       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17320     }
17321
17322   M (POLICER_CLASSIFY_DUMP, mp);
17323   mp->type = type;
17324   /* send it... */
17325   S (mp);
17326
17327   /* Use a control ping for synchronization */
17328   M (CONTROL_PING, mp_ping);
17329   S (mp_ping);
17330
17331   /* Wait for a reply... */
17332   W (ret);
17333   return ret;
17334 }
17335
17336 static int
17337 api_netmap_create (vat_main_t * vam)
17338 {
17339   unformat_input_t *i = vam->input;
17340   vl_api_netmap_create_t *mp;
17341   u8 *if_name = 0;
17342   u8 hw_addr[6];
17343   u8 random_hw_addr = 1;
17344   u8 is_pipe = 0;
17345   u8 is_master = 0;
17346   int ret;
17347
17348   memset (hw_addr, 0, sizeof (hw_addr));
17349
17350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17351     {
17352       if (unformat (i, "name %s", &if_name))
17353         vec_add1 (if_name, 0);
17354       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17355         random_hw_addr = 0;
17356       else if (unformat (i, "pipe"))
17357         is_pipe = 1;
17358       else if (unformat (i, "master"))
17359         is_master = 1;
17360       else if (unformat (i, "slave"))
17361         is_master = 0;
17362       else
17363         break;
17364     }
17365
17366   if (!vec_len (if_name))
17367     {
17368       errmsg ("interface name must be specified");
17369       return -99;
17370     }
17371
17372   if (vec_len (if_name) > 64)
17373     {
17374       errmsg ("interface name too long");
17375       return -99;
17376     }
17377
17378   M (NETMAP_CREATE, mp);
17379
17380   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17381   clib_memcpy (mp->hw_addr, hw_addr, 6);
17382   mp->use_random_hw_addr = random_hw_addr;
17383   mp->is_pipe = is_pipe;
17384   mp->is_master = is_master;
17385   vec_free (if_name);
17386
17387   S (mp);
17388   W (ret);
17389   return ret;
17390 }
17391
17392 static int
17393 api_netmap_delete (vat_main_t * vam)
17394 {
17395   unformat_input_t *i = vam->input;
17396   vl_api_netmap_delete_t *mp;
17397   u8 *if_name = 0;
17398   int ret;
17399
17400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17401     {
17402       if (unformat (i, "name %s", &if_name))
17403         vec_add1 (if_name, 0);
17404       else
17405         break;
17406     }
17407
17408   if (!vec_len (if_name))
17409     {
17410       errmsg ("interface name must be specified");
17411       return -99;
17412     }
17413
17414   if (vec_len (if_name) > 64)
17415     {
17416       errmsg ("interface name too long");
17417       return -99;
17418     }
17419
17420   M (NETMAP_DELETE, mp);
17421
17422   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17423   vec_free (if_name);
17424
17425   S (mp);
17426   W (ret);
17427   return ret;
17428 }
17429
17430 static void
17431 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17432 {
17433   if (fp->afi == IP46_TYPE_IP6)
17434     print (vam->ofp,
17435            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17436            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17437            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17438            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17439            format_ip6_address, fp->next_hop);
17440   else if (fp->afi == IP46_TYPE_IP4)
17441     print (vam->ofp,
17442            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17443            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17444            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17445            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17446            format_ip4_address, fp->next_hop);
17447 }
17448
17449 static void
17450 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17451                                  vl_api_fib_path2_t * fp)
17452 {
17453   struct in_addr ip4;
17454   struct in6_addr ip6;
17455
17456   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17457   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17458   vat_json_object_add_uint (node, "is_local", fp->is_local);
17459   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17460   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17461   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17462   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17463   if (fp->afi == IP46_TYPE_IP4)
17464     {
17465       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17466       vat_json_object_add_ip4 (node, "next_hop", ip4);
17467     }
17468   else if (fp->afi == IP46_TYPE_IP6)
17469     {
17470       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17471       vat_json_object_add_ip6 (node, "next_hop", ip6);
17472     }
17473 }
17474
17475 static void
17476 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17477 {
17478   vat_main_t *vam = &vat_main;
17479   int count = ntohl (mp->mt_count);
17480   vl_api_fib_path2_t *fp;
17481   i32 i;
17482
17483   print (vam->ofp, "[%d]: sw_if_index %d via:",
17484          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17485   fp = mp->mt_paths;
17486   for (i = 0; i < count; i++)
17487     {
17488       vl_api_mpls_fib_path_print (vam, fp);
17489       fp++;
17490     }
17491
17492   print (vam->ofp, "");
17493 }
17494
17495 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17496 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17497
17498 static void
17499 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17500 {
17501   vat_main_t *vam = &vat_main;
17502   vat_json_node_t *node = NULL;
17503   int count = ntohl (mp->mt_count);
17504   vl_api_fib_path2_t *fp;
17505   i32 i;
17506
17507   if (VAT_JSON_ARRAY != vam->json_tree.type)
17508     {
17509       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17510       vat_json_init_array (&vam->json_tree);
17511     }
17512   node = vat_json_array_add (&vam->json_tree);
17513
17514   vat_json_init_object (node);
17515   vat_json_object_add_uint (node, "tunnel_index",
17516                             ntohl (mp->mt_tunnel_index));
17517   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17518
17519   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17520
17521   fp = mp->mt_paths;
17522   for (i = 0; i < count; i++)
17523     {
17524       vl_api_mpls_fib_path_json_print (node, fp);
17525       fp++;
17526     }
17527 }
17528
17529 static int
17530 api_mpls_tunnel_dump (vat_main_t * vam)
17531 {
17532   vl_api_mpls_tunnel_dump_t *mp;
17533   vl_api_control_ping_t *mp_ping;
17534   i32 index = -1;
17535   int ret;
17536
17537   /* Parse args required to build the message */
17538   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17539     {
17540       if (!unformat (vam->input, "tunnel_index %d", &index))
17541         {
17542           index = -1;
17543           break;
17544         }
17545     }
17546
17547   print (vam->ofp, "  tunnel_index %d", index);
17548
17549   M (MPLS_TUNNEL_DUMP, mp);
17550   mp->tunnel_index = htonl (index);
17551   S (mp);
17552
17553   /* Use a control ping for synchronization */
17554   M (CONTROL_PING, mp_ping);
17555   S (mp_ping);
17556
17557   W (ret);
17558   return ret;
17559 }
17560
17561 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17562 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17563
17564
17565 static void
17566 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17567 {
17568   vat_main_t *vam = &vat_main;
17569   int count = ntohl (mp->count);
17570   vl_api_fib_path2_t *fp;
17571   int i;
17572
17573   print (vam->ofp,
17574          "table-id %d, label %u, ess_bit %u",
17575          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17576   fp = mp->path;
17577   for (i = 0; i < count; i++)
17578     {
17579       vl_api_mpls_fib_path_print (vam, fp);
17580       fp++;
17581     }
17582 }
17583
17584 static void vl_api_mpls_fib_details_t_handler_json
17585   (vl_api_mpls_fib_details_t * mp)
17586 {
17587   vat_main_t *vam = &vat_main;
17588   int count = ntohl (mp->count);
17589   vat_json_node_t *node = NULL;
17590   vl_api_fib_path2_t *fp;
17591   int i;
17592
17593   if (VAT_JSON_ARRAY != vam->json_tree.type)
17594     {
17595       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17596       vat_json_init_array (&vam->json_tree);
17597     }
17598   node = vat_json_array_add (&vam->json_tree);
17599
17600   vat_json_init_object (node);
17601   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17602   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17603   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17604   vat_json_object_add_uint (node, "path_count", count);
17605   fp = mp->path;
17606   for (i = 0; i < count; i++)
17607     {
17608       vl_api_mpls_fib_path_json_print (node, fp);
17609       fp++;
17610     }
17611 }
17612
17613 static int
17614 api_mpls_fib_dump (vat_main_t * vam)
17615 {
17616   vl_api_mpls_fib_dump_t *mp;
17617   vl_api_control_ping_t *mp_ping;
17618   int ret;
17619
17620   M (MPLS_FIB_DUMP, mp);
17621   S (mp);
17622
17623   /* Use a control ping for synchronization */
17624   M (CONTROL_PING, mp_ping);
17625   S (mp_ping);
17626
17627   W (ret);
17628   return ret;
17629 }
17630
17631 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17632 #define vl_api_ip_fib_details_t_print vl_noop_handler
17633
17634 static void
17635 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17636 {
17637   vat_main_t *vam = &vat_main;
17638   int count = ntohl (mp->count);
17639   vl_api_fib_path_t *fp;
17640   int i;
17641
17642   print (vam->ofp,
17643          "table-id %d, prefix %U/%d",
17644          ntohl (mp->table_id), format_ip4_address, mp->address,
17645          mp->address_length);
17646   fp = mp->path;
17647   for (i = 0; i < count; i++)
17648     {
17649       if (fp->afi == IP46_TYPE_IP6)
17650         print (vam->ofp,
17651                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17652                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17653                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17654                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17655                format_ip6_address, fp->next_hop);
17656       else if (fp->afi == IP46_TYPE_IP4)
17657         print (vam->ofp,
17658                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17659                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17660                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17661                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17662                format_ip4_address, fp->next_hop);
17663       fp++;
17664     }
17665 }
17666
17667 static void vl_api_ip_fib_details_t_handler_json
17668   (vl_api_ip_fib_details_t * mp)
17669 {
17670   vat_main_t *vam = &vat_main;
17671   int count = ntohl (mp->count);
17672   vat_json_node_t *node = NULL;
17673   struct in_addr ip4;
17674   struct in6_addr ip6;
17675   vl_api_fib_path_t *fp;
17676   int i;
17677
17678   if (VAT_JSON_ARRAY != vam->json_tree.type)
17679     {
17680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17681       vat_json_init_array (&vam->json_tree);
17682     }
17683   node = vat_json_array_add (&vam->json_tree);
17684
17685   vat_json_init_object (node);
17686   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17687   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17688   vat_json_object_add_ip4 (node, "prefix", ip4);
17689   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17690   vat_json_object_add_uint (node, "path_count", count);
17691   fp = mp->path;
17692   for (i = 0; i < count; i++)
17693     {
17694       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17695       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17696       vat_json_object_add_uint (node, "is_local", fp->is_local);
17697       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17698       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17699       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17700       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17701       if (fp->afi == IP46_TYPE_IP4)
17702         {
17703           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17704           vat_json_object_add_ip4 (node, "next_hop", ip4);
17705         }
17706       else if (fp->afi == IP46_TYPE_IP6)
17707         {
17708           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17709           vat_json_object_add_ip6 (node, "next_hop", ip6);
17710         }
17711     }
17712 }
17713
17714 static int
17715 api_ip_fib_dump (vat_main_t * vam)
17716 {
17717   vl_api_ip_fib_dump_t *mp;
17718   vl_api_control_ping_t *mp_ping;
17719   int ret;
17720
17721   M (IP_FIB_DUMP, mp);
17722   S (mp);
17723
17724   /* Use a control ping for synchronization */
17725   M (CONTROL_PING, mp_ping);
17726   S (mp_ping);
17727
17728   W (ret);
17729   return ret;
17730 }
17731
17732 static int
17733 api_ip_mfib_dump (vat_main_t * vam)
17734 {
17735   vl_api_ip_mfib_dump_t *mp;
17736   vl_api_control_ping_t *mp_ping;
17737   int ret;
17738
17739   M (IP_MFIB_DUMP, mp);
17740   S (mp);
17741
17742   /* Use a control ping for synchronization */
17743   M (CONTROL_PING, mp_ping);
17744   S (mp_ping);
17745
17746   W (ret);
17747   return ret;
17748 }
17749
17750 static void vl_api_ip_neighbor_details_t_handler
17751   (vl_api_ip_neighbor_details_t * mp)
17752 {
17753   vat_main_t *vam = &vat_main;
17754
17755   print (vam->ofp, "%c %U %U",
17756          (mp->is_static) ? 'S' : 'D',
17757          format_ethernet_address, &mp->mac_address,
17758          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17759          &mp->ip_address);
17760 }
17761
17762 static void vl_api_ip_neighbor_details_t_handler_json
17763   (vl_api_ip_neighbor_details_t * mp)
17764 {
17765
17766   vat_main_t *vam = &vat_main;
17767   vat_json_node_t *node;
17768   struct in_addr ip4;
17769   struct in6_addr ip6;
17770
17771   if (VAT_JSON_ARRAY != vam->json_tree.type)
17772     {
17773       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17774       vat_json_init_array (&vam->json_tree);
17775     }
17776   node = vat_json_array_add (&vam->json_tree);
17777
17778   vat_json_init_object (node);
17779   vat_json_object_add_string_copy (node, "flag",
17780                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17781                                    "dynamic");
17782
17783   vat_json_object_add_string_copy (node, "link_layer",
17784                                    format (0, "%U", format_ethernet_address,
17785                                            &mp->mac_address));
17786
17787   if (mp->is_ipv6)
17788     {
17789       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17790       vat_json_object_add_ip6 (node, "ip_address", ip6);
17791     }
17792   else
17793     {
17794       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17795       vat_json_object_add_ip4 (node, "ip_address", ip4);
17796     }
17797 }
17798
17799 static int
17800 api_ip_neighbor_dump (vat_main_t * vam)
17801 {
17802   unformat_input_t *i = vam->input;
17803   vl_api_ip_neighbor_dump_t *mp;
17804   vl_api_control_ping_t *mp_ping;
17805   u8 is_ipv6 = 0;
17806   u32 sw_if_index = ~0;
17807   int ret;
17808
17809   /* Parse args required to build the message */
17810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17811     {
17812       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17813         ;
17814       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17815         ;
17816       else if (unformat (i, "ip6"))
17817         is_ipv6 = 1;
17818       else
17819         break;
17820     }
17821
17822   if (sw_if_index == ~0)
17823     {
17824       errmsg ("missing interface name or sw_if_index");
17825       return -99;
17826     }
17827
17828   M (IP_NEIGHBOR_DUMP, mp);
17829   mp->is_ipv6 = (u8) is_ipv6;
17830   mp->sw_if_index = ntohl (sw_if_index);
17831   S (mp);
17832
17833   /* Use a control ping for synchronization */
17834   M (CONTROL_PING, mp_ping);
17835   S (mp_ping);
17836
17837   W (ret);
17838   return ret;
17839 }
17840
17841 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17842 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17843
17844 static void
17845 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17846 {
17847   vat_main_t *vam = &vat_main;
17848   int count = ntohl (mp->count);
17849   vl_api_fib_path_t *fp;
17850   int i;
17851
17852   print (vam->ofp,
17853          "table-id %d, prefix %U/%d",
17854          ntohl (mp->table_id), format_ip6_address, mp->address,
17855          mp->address_length);
17856   fp = mp->path;
17857   for (i = 0; i < count; i++)
17858     {
17859       if (fp->afi == IP46_TYPE_IP6)
17860         print (vam->ofp,
17861                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17862                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17863                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17864                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17865                format_ip6_address, fp->next_hop);
17866       else if (fp->afi == IP46_TYPE_IP4)
17867         print (vam->ofp,
17868                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17869                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17870                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17871                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17872                format_ip4_address, fp->next_hop);
17873       fp++;
17874     }
17875 }
17876
17877 static void vl_api_ip6_fib_details_t_handler_json
17878   (vl_api_ip6_fib_details_t * mp)
17879 {
17880   vat_main_t *vam = &vat_main;
17881   int count = ntohl (mp->count);
17882   vat_json_node_t *node = NULL;
17883   struct in_addr ip4;
17884   struct in6_addr ip6;
17885   vl_api_fib_path_t *fp;
17886   int i;
17887
17888   if (VAT_JSON_ARRAY != vam->json_tree.type)
17889     {
17890       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17891       vat_json_init_array (&vam->json_tree);
17892     }
17893   node = vat_json_array_add (&vam->json_tree);
17894
17895   vat_json_init_object (node);
17896   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17897   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17898   vat_json_object_add_ip6 (node, "prefix", ip6);
17899   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17900   vat_json_object_add_uint (node, "path_count", count);
17901   fp = mp->path;
17902   for (i = 0; i < count; i++)
17903     {
17904       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17905       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17906       vat_json_object_add_uint (node, "is_local", fp->is_local);
17907       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17908       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17909       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17910       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17911       if (fp->afi == IP46_TYPE_IP4)
17912         {
17913           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17914           vat_json_object_add_ip4 (node, "next_hop", ip4);
17915         }
17916       else if (fp->afi == IP46_TYPE_IP6)
17917         {
17918           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17919           vat_json_object_add_ip6 (node, "next_hop", ip6);
17920         }
17921     }
17922 }
17923
17924 static int
17925 api_ip6_fib_dump (vat_main_t * vam)
17926 {
17927   vl_api_ip6_fib_dump_t *mp;
17928   vl_api_control_ping_t *mp_ping;
17929   int ret;
17930
17931   M (IP6_FIB_DUMP, mp);
17932   S (mp);
17933
17934   /* Use a control ping for synchronization */
17935   M (CONTROL_PING, mp_ping);
17936   S (mp_ping);
17937
17938   W (ret);
17939   return ret;
17940 }
17941
17942 static int
17943 api_ip6_mfib_dump (vat_main_t * vam)
17944 {
17945   vl_api_ip6_mfib_dump_t *mp;
17946   vl_api_control_ping_t *mp_ping;
17947   int ret;
17948
17949   M (IP6_MFIB_DUMP, mp);
17950   S (mp);
17951
17952   /* Use a control ping for synchronization */
17953   M (CONTROL_PING, mp_ping);
17954   S (mp_ping);
17955
17956   W (ret);
17957   return ret;
17958 }
17959
17960 int
17961 api_classify_table_ids (vat_main_t * vam)
17962 {
17963   vl_api_classify_table_ids_t *mp;
17964   int ret;
17965
17966   /* Construct the API message */
17967   M (CLASSIFY_TABLE_IDS, mp);
17968   mp->context = 0;
17969
17970   S (mp);
17971   W (ret);
17972   return ret;
17973 }
17974
17975 int
17976 api_classify_table_by_interface (vat_main_t * vam)
17977 {
17978   unformat_input_t *input = vam->input;
17979   vl_api_classify_table_by_interface_t *mp;
17980
17981   u32 sw_if_index = ~0;
17982   int ret;
17983   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17984     {
17985       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17986         ;
17987       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17988         ;
17989       else
17990         break;
17991     }
17992   if (sw_if_index == ~0)
17993     {
17994       errmsg ("missing interface name or sw_if_index");
17995       return -99;
17996     }
17997
17998   /* Construct the API message */
17999   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18000   mp->context = 0;
18001   mp->sw_if_index = ntohl (sw_if_index);
18002
18003   S (mp);
18004   W (ret);
18005   return ret;
18006 }
18007
18008 int
18009 api_classify_table_info (vat_main_t * vam)
18010 {
18011   unformat_input_t *input = vam->input;
18012   vl_api_classify_table_info_t *mp;
18013
18014   u32 table_id = ~0;
18015   int ret;
18016   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18017     {
18018       if (unformat (input, "table_id %d", &table_id))
18019         ;
18020       else
18021         break;
18022     }
18023   if (table_id == ~0)
18024     {
18025       errmsg ("missing table id");
18026       return -99;
18027     }
18028
18029   /* Construct the API message */
18030   M (CLASSIFY_TABLE_INFO, mp);
18031   mp->context = 0;
18032   mp->table_id = ntohl (table_id);
18033
18034   S (mp);
18035   W (ret);
18036   return ret;
18037 }
18038
18039 int
18040 api_classify_session_dump (vat_main_t * vam)
18041 {
18042   unformat_input_t *input = vam->input;
18043   vl_api_classify_session_dump_t *mp;
18044   vl_api_control_ping_t *mp_ping;
18045
18046   u32 table_id = ~0;
18047   int ret;
18048   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18049     {
18050       if (unformat (input, "table_id %d", &table_id))
18051         ;
18052       else
18053         break;
18054     }
18055   if (table_id == ~0)
18056     {
18057       errmsg ("missing table id");
18058       return -99;
18059     }
18060
18061   /* Construct the API message */
18062   M (CLASSIFY_SESSION_DUMP, mp);
18063   mp->context = 0;
18064   mp->table_id = ntohl (table_id);
18065   S (mp);
18066
18067   /* Use a control ping for synchronization */
18068   M (CONTROL_PING, mp_ping);
18069   S (mp_ping);
18070
18071   W (ret);
18072   return ret;
18073 }
18074
18075 static void
18076 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18077 {
18078   vat_main_t *vam = &vat_main;
18079
18080   print (vam->ofp, "collector_address %U, collector_port %d, "
18081          "src_address %U, vrf_id %d, path_mtu %u, "
18082          "template_interval %u, udp_checksum %d",
18083          format_ip4_address, mp->collector_address,
18084          ntohs (mp->collector_port),
18085          format_ip4_address, mp->src_address,
18086          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18087          ntohl (mp->template_interval), mp->udp_checksum);
18088
18089   vam->retval = 0;
18090   vam->result_ready = 1;
18091 }
18092
18093 static void
18094   vl_api_ipfix_exporter_details_t_handler_json
18095   (vl_api_ipfix_exporter_details_t * mp)
18096 {
18097   vat_main_t *vam = &vat_main;
18098   vat_json_node_t node;
18099   struct in_addr collector_address;
18100   struct in_addr src_address;
18101
18102   vat_json_init_object (&node);
18103   clib_memcpy (&collector_address, &mp->collector_address,
18104                sizeof (collector_address));
18105   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18106   vat_json_object_add_uint (&node, "collector_port",
18107                             ntohs (mp->collector_port));
18108   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18109   vat_json_object_add_ip4 (&node, "src_address", src_address);
18110   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18111   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18112   vat_json_object_add_uint (&node, "template_interval",
18113                             ntohl (mp->template_interval));
18114   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18115
18116   vat_json_print (vam->ofp, &node);
18117   vat_json_free (&node);
18118   vam->retval = 0;
18119   vam->result_ready = 1;
18120 }
18121
18122 int
18123 api_ipfix_exporter_dump (vat_main_t * vam)
18124 {
18125   vl_api_ipfix_exporter_dump_t *mp;
18126   int ret;
18127
18128   /* Construct the API message */
18129   M (IPFIX_EXPORTER_DUMP, mp);
18130   mp->context = 0;
18131
18132   S (mp);
18133   W (ret);
18134   return ret;
18135 }
18136
18137 static int
18138 api_ipfix_classify_stream_dump (vat_main_t * vam)
18139 {
18140   vl_api_ipfix_classify_stream_dump_t *mp;
18141   int ret;
18142
18143   /* Construct the API message */
18144   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18145   mp->context = 0;
18146
18147   S (mp);
18148   W (ret);
18149   return ret;
18150   /* NOTREACHED */
18151   return 0;
18152 }
18153
18154 static void
18155   vl_api_ipfix_classify_stream_details_t_handler
18156   (vl_api_ipfix_classify_stream_details_t * mp)
18157 {
18158   vat_main_t *vam = &vat_main;
18159   print (vam->ofp, "domain_id %d, src_port %d",
18160          ntohl (mp->domain_id), ntohs (mp->src_port));
18161   vam->retval = 0;
18162   vam->result_ready = 1;
18163 }
18164
18165 static void
18166   vl_api_ipfix_classify_stream_details_t_handler_json
18167   (vl_api_ipfix_classify_stream_details_t * mp)
18168 {
18169   vat_main_t *vam = &vat_main;
18170   vat_json_node_t node;
18171
18172   vat_json_init_object (&node);
18173   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18174   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18175
18176   vat_json_print (vam->ofp, &node);
18177   vat_json_free (&node);
18178   vam->retval = 0;
18179   vam->result_ready = 1;
18180 }
18181
18182 static int
18183 api_ipfix_classify_table_dump (vat_main_t * vam)
18184 {
18185   vl_api_ipfix_classify_table_dump_t *mp;
18186   vl_api_control_ping_t *mp_ping;
18187   int ret;
18188
18189   if (!vam->json_output)
18190     {
18191       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18192              "transport_protocol");
18193     }
18194
18195   /* Construct the API message */
18196   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18197
18198   /* send it... */
18199   S (mp);
18200
18201   /* Use a control ping for synchronization */
18202   M (CONTROL_PING, mp_ping);
18203   S (mp_ping);
18204
18205   W (ret);
18206   return ret;
18207 }
18208
18209 static void
18210   vl_api_ipfix_classify_table_details_t_handler
18211   (vl_api_ipfix_classify_table_details_t * mp)
18212 {
18213   vat_main_t *vam = &vat_main;
18214   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18215          mp->transport_protocol);
18216 }
18217
18218 static void
18219   vl_api_ipfix_classify_table_details_t_handler_json
18220   (vl_api_ipfix_classify_table_details_t * mp)
18221 {
18222   vat_json_node_t *node = NULL;
18223   vat_main_t *vam = &vat_main;
18224
18225   if (VAT_JSON_ARRAY != vam->json_tree.type)
18226     {
18227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18228       vat_json_init_array (&vam->json_tree);
18229     }
18230
18231   node = vat_json_array_add (&vam->json_tree);
18232   vat_json_init_object (node);
18233
18234   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18235   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18236   vat_json_object_add_uint (node, "transport_protocol",
18237                             mp->transport_protocol);
18238 }
18239
18240 static int
18241 api_sw_interface_span_enable_disable (vat_main_t * vam)
18242 {
18243   unformat_input_t *i = vam->input;
18244   vl_api_sw_interface_span_enable_disable_t *mp;
18245   u32 src_sw_if_index = ~0;
18246   u32 dst_sw_if_index = ~0;
18247   u8 state = 3;
18248   int ret;
18249   u8 is_l2 = 0;
18250
18251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18252     {
18253       if (unformat
18254           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18255         ;
18256       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18257         ;
18258       else
18259         if (unformat
18260             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18261         ;
18262       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18263         ;
18264       else if (unformat (i, "disable"))
18265         state = 0;
18266       else if (unformat (i, "rx"))
18267         state = 1;
18268       else if (unformat (i, "tx"))
18269         state = 2;
18270       else if (unformat (i, "both"))
18271         state = 3;
18272       else if (unformat (i, "l2"))
18273         is_l2 = 1;
18274       else
18275         break;
18276     }
18277
18278   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18279
18280   mp->sw_if_index_from = htonl (src_sw_if_index);
18281   mp->sw_if_index_to = htonl (dst_sw_if_index);
18282   mp->state = state;
18283   mp->is_l2 = is_l2;
18284
18285   S (mp);
18286   W (ret);
18287   return ret;
18288 }
18289
18290 static void
18291 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18292                                             * mp)
18293 {
18294   vat_main_t *vam = &vat_main;
18295   u8 *sw_if_from_name = 0;
18296   u8 *sw_if_to_name = 0;
18297   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18298   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18299   char *states[] = { "none", "rx", "tx", "both" };
18300   hash_pair_t *p;
18301
18302   /* *INDENT-OFF* */
18303   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18304   ({
18305     if ((u32) p->value[0] == sw_if_index_from)
18306       {
18307         sw_if_from_name = (u8 *)(p->key);
18308         if (sw_if_to_name)
18309           break;
18310       }
18311     if ((u32) p->value[0] == sw_if_index_to)
18312       {
18313         sw_if_to_name = (u8 *)(p->key);
18314         if (sw_if_from_name)
18315           break;
18316       }
18317   }));
18318   /* *INDENT-ON* */
18319   print (vam->ofp, "%20s => %20s (%s)",
18320          sw_if_from_name, sw_if_to_name, states[mp->state]);
18321 }
18322
18323 static void
18324   vl_api_sw_interface_span_details_t_handler_json
18325   (vl_api_sw_interface_span_details_t * mp)
18326 {
18327   vat_main_t *vam = &vat_main;
18328   vat_json_node_t *node = NULL;
18329   u8 *sw_if_from_name = 0;
18330   u8 *sw_if_to_name = 0;
18331   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18332   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18333   hash_pair_t *p;
18334
18335   /* *INDENT-OFF* */
18336   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18337   ({
18338     if ((u32) p->value[0] == sw_if_index_from)
18339       {
18340         sw_if_from_name = (u8 *)(p->key);
18341         if (sw_if_to_name)
18342           break;
18343       }
18344     if ((u32) p->value[0] == sw_if_index_to)
18345       {
18346         sw_if_to_name = (u8 *)(p->key);
18347         if (sw_if_from_name)
18348           break;
18349       }
18350   }));
18351   /* *INDENT-ON* */
18352
18353   if (VAT_JSON_ARRAY != vam->json_tree.type)
18354     {
18355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18356       vat_json_init_array (&vam->json_tree);
18357     }
18358   node = vat_json_array_add (&vam->json_tree);
18359
18360   vat_json_init_object (node);
18361   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18362   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18363   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18364   if (0 != sw_if_to_name)
18365     {
18366       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18367     }
18368   vat_json_object_add_uint (node, "state", mp->state);
18369 }
18370
18371 static int
18372 api_sw_interface_span_dump (vat_main_t * vam)
18373 {
18374   unformat_input_t *input = vam->input;
18375   vl_api_sw_interface_span_dump_t *mp;
18376   vl_api_control_ping_t *mp_ping;
18377   u8 is_l2 = 0;
18378   int ret;
18379
18380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18381     {
18382       if (unformat (input, "l2"))
18383         is_l2 = 1;
18384       else
18385         break;
18386     }
18387
18388   M (SW_INTERFACE_SPAN_DUMP, mp);
18389   mp->is_l2 = is_l2;
18390   S (mp);
18391
18392   /* Use a control ping for synchronization */
18393   M (CONTROL_PING, mp_ping);
18394   S (mp_ping);
18395
18396   W (ret);
18397   return ret;
18398 }
18399
18400 int
18401 api_pg_create_interface (vat_main_t * vam)
18402 {
18403   unformat_input_t *input = vam->input;
18404   vl_api_pg_create_interface_t *mp;
18405
18406   u32 if_id = ~0;
18407   int ret;
18408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18409     {
18410       if (unformat (input, "if_id %d", &if_id))
18411         ;
18412       else
18413         break;
18414     }
18415   if (if_id == ~0)
18416     {
18417       errmsg ("missing pg interface index");
18418       return -99;
18419     }
18420
18421   /* Construct the API message */
18422   M (PG_CREATE_INTERFACE, mp);
18423   mp->context = 0;
18424   mp->interface_id = ntohl (if_id);
18425
18426   S (mp);
18427   W (ret);
18428   return ret;
18429 }
18430
18431 int
18432 api_pg_capture (vat_main_t * vam)
18433 {
18434   unformat_input_t *input = vam->input;
18435   vl_api_pg_capture_t *mp;
18436
18437   u32 if_id = ~0;
18438   u8 enable = 1;
18439   u32 count = 1;
18440   u8 pcap_file_set = 0;
18441   u8 *pcap_file = 0;
18442   int ret;
18443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18444     {
18445       if (unformat (input, "if_id %d", &if_id))
18446         ;
18447       else if (unformat (input, "pcap %s", &pcap_file))
18448         pcap_file_set = 1;
18449       else if (unformat (input, "count %d", &count))
18450         ;
18451       else if (unformat (input, "disable"))
18452         enable = 0;
18453       else
18454         break;
18455     }
18456   if (if_id == ~0)
18457     {
18458       errmsg ("missing pg interface index");
18459       return -99;
18460     }
18461   if (pcap_file_set > 0)
18462     {
18463       if (vec_len (pcap_file) > 255)
18464         {
18465           errmsg ("pcap file name is too long");
18466           return -99;
18467         }
18468     }
18469
18470   u32 name_len = vec_len (pcap_file);
18471   /* Construct the API message */
18472   M (PG_CAPTURE, mp);
18473   mp->context = 0;
18474   mp->interface_id = ntohl (if_id);
18475   mp->is_enabled = enable;
18476   mp->count = ntohl (count);
18477   mp->pcap_name_length = ntohl (name_len);
18478   if (pcap_file_set != 0)
18479     {
18480       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18481     }
18482   vec_free (pcap_file);
18483
18484   S (mp);
18485   W (ret);
18486   return ret;
18487 }
18488
18489 int
18490 api_pg_enable_disable (vat_main_t * vam)
18491 {
18492   unformat_input_t *input = vam->input;
18493   vl_api_pg_enable_disable_t *mp;
18494
18495   u8 enable = 1;
18496   u8 stream_name_set = 0;
18497   u8 *stream_name = 0;
18498   int ret;
18499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18500     {
18501       if (unformat (input, "stream %s", &stream_name))
18502         stream_name_set = 1;
18503       else if (unformat (input, "disable"))
18504         enable = 0;
18505       else
18506         break;
18507     }
18508
18509   if (stream_name_set > 0)
18510     {
18511       if (vec_len (stream_name) > 255)
18512         {
18513           errmsg ("stream name too long");
18514           return -99;
18515         }
18516     }
18517
18518   u32 name_len = vec_len (stream_name);
18519   /* Construct the API message */
18520   M (PG_ENABLE_DISABLE, mp);
18521   mp->context = 0;
18522   mp->is_enabled = enable;
18523   if (stream_name_set != 0)
18524     {
18525       mp->stream_name_length = ntohl (name_len);
18526       clib_memcpy (mp->stream_name, stream_name, name_len);
18527     }
18528   vec_free (stream_name);
18529
18530   S (mp);
18531   W (ret);
18532   return ret;
18533 }
18534
18535 int
18536 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18537 {
18538   unformat_input_t *input = vam->input;
18539   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18540
18541   u16 *low_ports = 0;
18542   u16 *high_ports = 0;
18543   u16 this_low;
18544   u16 this_hi;
18545   ip4_address_t ip4_addr;
18546   ip6_address_t ip6_addr;
18547   u32 length;
18548   u32 tmp, tmp2;
18549   u8 prefix_set = 0;
18550   u32 vrf_id = ~0;
18551   u8 is_add = 1;
18552   u8 is_ipv6 = 0;
18553   int ret;
18554
18555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18556     {
18557       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18558         {
18559           prefix_set = 1;
18560         }
18561       else
18562         if (unformat
18563             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18564         {
18565           prefix_set = 1;
18566           is_ipv6 = 1;
18567         }
18568       else if (unformat (input, "vrf %d", &vrf_id))
18569         ;
18570       else if (unformat (input, "del"))
18571         is_add = 0;
18572       else if (unformat (input, "port %d", &tmp))
18573         {
18574           if (tmp == 0 || tmp > 65535)
18575             {
18576               errmsg ("port %d out of range", tmp);
18577               return -99;
18578             }
18579           this_low = tmp;
18580           this_hi = this_low + 1;
18581           vec_add1 (low_ports, this_low);
18582           vec_add1 (high_ports, this_hi);
18583         }
18584       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18585         {
18586           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18587             {
18588               errmsg ("incorrect range parameters");
18589               return -99;
18590             }
18591           this_low = tmp;
18592           /* Note: in debug CLI +1 is added to high before
18593              passing to real fn that does "the work"
18594              (ip_source_and_port_range_check_add_del).
18595              This fn is a wrapper around the binary API fn a
18596              control plane will call, which expects this increment
18597              to have occurred. Hence letting the binary API control
18598              plane fn do the increment for consistency between VAT
18599              and other control planes.
18600            */
18601           this_hi = tmp2;
18602           vec_add1 (low_ports, this_low);
18603           vec_add1 (high_ports, this_hi);
18604         }
18605       else
18606         break;
18607     }
18608
18609   if (prefix_set == 0)
18610     {
18611       errmsg ("<address>/<mask> not specified");
18612       return -99;
18613     }
18614
18615   if (vrf_id == ~0)
18616     {
18617       errmsg ("VRF ID required, not specified");
18618       return -99;
18619     }
18620
18621   if (vrf_id == 0)
18622     {
18623       errmsg
18624         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18625       return -99;
18626     }
18627
18628   if (vec_len (low_ports) == 0)
18629     {
18630       errmsg ("At least one port or port range required");
18631       return -99;
18632     }
18633
18634   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18635
18636   mp->is_add = is_add;
18637
18638   if (is_ipv6)
18639     {
18640       mp->is_ipv6 = 1;
18641       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18642     }
18643   else
18644     {
18645       mp->is_ipv6 = 0;
18646       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18647     }
18648
18649   mp->mask_length = length;
18650   mp->number_of_ranges = vec_len (low_ports);
18651
18652   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18653   vec_free (low_ports);
18654
18655   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18656   vec_free (high_ports);
18657
18658   mp->vrf_id = ntohl (vrf_id);
18659
18660   S (mp);
18661   W (ret);
18662   return ret;
18663 }
18664
18665 int
18666 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18667 {
18668   unformat_input_t *input = vam->input;
18669   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18670   u32 sw_if_index = ~0;
18671   int vrf_set = 0;
18672   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18673   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18674   u8 is_add = 1;
18675   int ret;
18676
18677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18678     {
18679       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18680         ;
18681       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18682         ;
18683       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18684         vrf_set = 1;
18685       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18686         vrf_set = 1;
18687       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18688         vrf_set = 1;
18689       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18690         vrf_set = 1;
18691       else if (unformat (input, "del"))
18692         is_add = 0;
18693       else
18694         break;
18695     }
18696
18697   if (sw_if_index == ~0)
18698     {
18699       errmsg ("Interface required but not specified");
18700       return -99;
18701     }
18702
18703   if (vrf_set == 0)
18704     {
18705       errmsg ("VRF ID required but not specified");
18706       return -99;
18707     }
18708
18709   if (tcp_out_vrf_id == 0
18710       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18711     {
18712       errmsg
18713         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18714       return -99;
18715     }
18716
18717   /* Construct the API message */
18718   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18719
18720   mp->sw_if_index = ntohl (sw_if_index);
18721   mp->is_add = is_add;
18722   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18723   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18724   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18725   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18726
18727   /* send it... */
18728   S (mp);
18729
18730   /* Wait for a reply... */
18731   W (ret);
18732   return ret;
18733 }
18734
18735 static int
18736 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18737 {
18738   unformat_input_t *i = vam->input;
18739   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18740   u32 local_sa_id = 0;
18741   u32 remote_sa_id = 0;
18742   ip4_address_t src_address;
18743   ip4_address_t dst_address;
18744   u8 is_add = 1;
18745   int ret;
18746
18747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18748     {
18749       if (unformat (i, "local_sa %d", &local_sa_id))
18750         ;
18751       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18752         ;
18753       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18754         ;
18755       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18756         ;
18757       else if (unformat (i, "del"))
18758         is_add = 0;
18759       else
18760         {
18761           clib_warning ("parse error '%U'", format_unformat_error, i);
18762           return -99;
18763         }
18764     }
18765
18766   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18767
18768   mp->local_sa_id = ntohl (local_sa_id);
18769   mp->remote_sa_id = ntohl (remote_sa_id);
18770   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18771   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18772   mp->is_add = is_add;
18773
18774   S (mp);
18775   W (ret);
18776   return ret;
18777 }
18778
18779 static int
18780 api_punt (vat_main_t * vam)
18781 {
18782   unformat_input_t *i = vam->input;
18783   vl_api_punt_t *mp;
18784   u32 ipv = ~0;
18785   u32 protocol = ~0;
18786   u32 port = ~0;
18787   int is_add = 1;
18788   int ret;
18789
18790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18791     {
18792       if (unformat (i, "ip %d", &ipv))
18793         ;
18794       else if (unformat (i, "protocol %d", &protocol))
18795         ;
18796       else if (unformat (i, "port %d", &port))
18797         ;
18798       else if (unformat (i, "del"))
18799         is_add = 0;
18800       else
18801         {
18802           clib_warning ("parse error '%U'", format_unformat_error, i);
18803           return -99;
18804         }
18805     }
18806
18807   M (PUNT, mp);
18808
18809   mp->is_add = (u8) is_add;
18810   mp->ipv = (u8) ipv;
18811   mp->l4_protocol = (u8) protocol;
18812   mp->l4_port = htons ((u16) port);
18813
18814   S (mp);
18815   W (ret);
18816   return ret;
18817 }
18818
18819 static void vl_api_ipsec_gre_tunnel_details_t_handler
18820   (vl_api_ipsec_gre_tunnel_details_t * mp)
18821 {
18822   vat_main_t *vam = &vat_main;
18823
18824   print (vam->ofp, "%11d%15U%15U%14d%14d",
18825          ntohl (mp->sw_if_index),
18826          format_ip4_address, &mp->src_address,
18827          format_ip4_address, &mp->dst_address,
18828          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18829 }
18830
18831 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18832   (vl_api_ipsec_gre_tunnel_details_t * mp)
18833 {
18834   vat_main_t *vam = &vat_main;
18835   vat_json_node_t *node = NULL;
18836   struct in_addr ip4;
18837
18838   if (VAT_JSON_ARRAY != vam->json_tree.type)
18839     {
18840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18841       vat_json_init_array (&vam->json_tree);
18842     }
18843   node = vat_json_array_add (&vam->json_tree);
18844
18845   vat_json_init_object (node);
18846   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18847   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18848   vat_json_object_add_ip4 (node, "src_address", ip4);
18849   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18850   vat_json_object_add_ip4 (node, "dst_address", ip4);
18851   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18852   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18853 }
18854
18855 static int
18856 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18857 {
18858   unformat_input_t *i = vam->input;
18859   vl_api_ipsec_gre_tunnel_dump_t *mp;
18860   vl_api_control_ping_t *mp_ping;
18861   u32 sw_if_index;
18862   u8 sw_if_index_set = 0;
18863   int ret;
18864
18865   /* Parse args required to build the message */
18866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18867     {
18868       if (unformat (i, "sw_if_index %d", &sw_if_index))
18869         sw_if_index_set = 1;
18870       else
18871         break;
18872     }
18873
18874   if (sw_if_index_set == 0)
18875     {
18876       sw_if_index = ~0;
18877     }
18878
18879   if (!vam->json_output)
18880     {
18881       print (vam->ofp, "%11s%15s%15s%14s%14s",
18882              "sw_if_index", "src_address", "dst_address",
18883              "local_sa_id", "remote_sa_id");
18884     }
18885
18886   /* Get list of gre-tunnel interfaces */
18887   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18888
18889   mp->sw_if_index = htonl (sw_if_index);
18890
18891   S (mp);
18892
18893   /* Use a control ping for synchronization */
18894   M (CONTROL_PING, mp_ping);
18895   S (mp_ping);
18896
18897   W (ret);
18898   return ret;
18899 }
18900
18901 static int
18902 api_delete_subif (vat_main_t * vam)
18903 {
18904   unformat_input_t *i = vam->input;
18905   vl_api_delete_subif_t *mp;
18906   u32 sw_if_index = ~0;
18907   int ret;
18908
18909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18910     {
18911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18912         ;
18913       if (unformat (i, "sw_if_index %d", &sw_if_index))
18914         ;
18915       else
18916         break;
18917     }
18918
18919   if (sw_if_index == ~0)
18920     {
18921       errmsg ("missing sw_if_index");
18922       return -99;
18923     }
18924
18925   /* Construct the API message */
18926   M (DELETE_SUBIF, mp);
18927   mp->sw_if_index = ntohl (sw_if_index);
18928
18929   S (mp);
18930   W (ret);
18931   return ret;
18932 }
18933
18934 #define foreach_pbb_vtr_op      \
18935 _("disable",  L2_VTR_DISABLED)  \
18936 _("pop",  L2_VTR_POP_2)         \
18937 _("push",  L2_VTR_PUSH_2)
18938
18939 static int
18940 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18941 {
18942   unformat_input_t *i = vam->input;
18943   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18944   u32 sw_if_index = ~0, vtr_op = ~0;
18945   u16 outer_tag = ~0;
18946   u8 dmac[6], smac[6];
18947   u8 dmac_set = 0, smac_set = 0;
18948   u16 vlanid = 0;
18949   u32 sid = ~0;
18950   u32 tmp;
18951   int ret;
18952
18953   /* Shut up coverity */
18954   memset (dmac, 0, sizeof (dmac));
18955   memset (smac, 0, sizeof (smac));
18956
18957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18958     {
18959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18960         ;
18961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18962         ;
18963       else if (unformat (i, "vtr_op %d", &vtr_op))
18964         ;
18965 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18966       foreach_pbb_vtr_op
18967 #undef _
18968         else if (unformat (i, "translate_pbb_stag"))
18969         {
18970           if (unformat (i, "%d", &tmp))
18971             {
18972               vtr_op = L2_VTR_TRANSLATE_2_1;
18973               outer_tag = tmp;
18974             }
18975           else
18976             {
18977               errmsg
18978                 ("translate_pbb_stag operation requires outer tag definition");
18979               return -99;
18980             }
18981         }
18982       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18983         dmac_set++;
18984       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18985         smac_set++;
18986       else if (unformat (i, "sid %d", &sid))
18987         ;
18988       else if (unformat (i, "vlanid %d", &tmp))
18989         vlanid = tmp;
18990       else
18991         {
18992           clib_warning ("parse error '%U'", format_unformat_error, i);
18993           return -99;
18994         }
18995     }
18996
18997   if ((sw_if_index == ~0) || (vtr_op == ~0))
18998     {
18999       errmsg ("missing sw_if_index or vtr operation");
19000       return -99;
19001     }
19002   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19003       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19004     {
19005       errmsg
19006         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19007       return -99;
19008     }
19009
19010   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19011   mp->sw_if_index = ntohl (sw_if_index);
19012   mp->vtr_op = ntohl (vtr_op);
19013   mp->outer_tag = ntohs (outer_tag);
19014   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19015   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19016   mp->b_vlanid = ntohs (vlanid);
19017   mp->i_sid = ntohl (sid);
19018
19019   S (mp);
19020   W (ret);
19021   return ret;
19022 }
19023
19024 static int
19025 api_flow_classify_set_interface (vat_main_t * vam)
19026 {
19027   unformat_input_t *i = vam->input;
19028   vl_api_flow_classify_set_interface_t *mp;
19029   u32 sw_if_index;
19030   int sw_if_index_set;
19031   u32 ip4_table_index = ~0;
19032   u32 ip6_table_index = ~0;
19033   u8 is_add = 1;
19034   int ret;
19035
19036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19037     {
19038       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19039         sw_if_index_set = 1;
19040       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19041         sw_if_index_set = 1;
19042       else if (unformat (i, "del"))
19043         is_add = 0;
19044       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19045         ;
19046       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19047         ;
19048       else
19049         {
19050           clib_warning ("parse error '%U'", format_unformat_error, i);
19051           return -99;
19052         }
19053     }
19054
19055   if (sw_if_index_set == 0)
19056     {
19057       errmsg ("missing interface name or sw_if_index");
19058       return -99;
19059     }
19060
19061   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19062
19063   mp->sw_if_index = ntohl (sw_if_index);
19064   mp->ip4_table_index = ntohl (ip4_table_index);
19065   mp->ip6_table_index = ntohl (ip6_table_index);
19066   mp->is_add = is_add;
19067
19068   S (mp);
19069   W (ret);
19070   return ret;
19071 }
19072
19073 static int
19074 api_flow_classify_dump (vat_main_t * vam)
19075 {
19076   unformat_input_t *i = vam->input;
19077   vl_api_flow_classify_dump_t *mp;
19078   vl_api_control_ping_t *mp_ping;
19079   u8 type = FLOW_CLASSIFY_N_TABLES;
19080   int ret;
19081
19082   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19083     ;
19084   else
19085     {
19086       errmsg ("classify table type must be specified");
19087       return -99;
19088     }
19089
19090   if (!vam->json_output)
19091     {
19092       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19093     }
19094
19095   M (FLOW_CLASSIFY_DUMP, mp);
19096   mp->type = type;
19097   /* send it... */
19098   S (mp);
19099
19100   /* Use a control ping for synchronization */
19101   M (CONTROL_PING, mp_ping);
19102   S (mp_ping);
19103
19104   /* Wait for a reply... */
19105   W (ret);
19106   return ret;
19107 }
19108
19109 static int
19110 api_feature_enable_disable (vat_main_t * vam)
19111 {
19112   unformat_input_t *i = vam->input;
19113   vl_api_feature_enable_disable_t *mp;
19114   u8 *arc_name = 0;
19115   u8 *feature_name = 0;
19116   u32 sw_if_index = ~0;
19117   u8 enable = 1;
19118   int ret;
19119
19120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19121     {
19122       if (unformat (i, "arc_name %s", &arc_name))
19123         ;
19124       else if (unformat (i, "feature_name %s", &feature_name))
19125         ;
19126       else
19127         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19128         ;
19129       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19130         ;
19131       else if (unformat (i, "disable"))
19132         enable = 0;
19133       else
19134         break;
19135     }
19136
19137   if (arc_name == 0)
19138     {
19139       errmsg ("missing arc name");
19140       return -99;
19141     }
19142   if (vec_len (arc_name) > 63)
19143     {
19144       errmsg ("arc name too long");
19145     }
19146
19147   if (feature_name == 0)
19148     {
19149       errmsg ("missing feature name");
19150       return -99;
19151     }
19152   if (vec_len (feature_name) > 63)
19153     {
19154       errmsg ("feature name too long");
19155     }
19156
19157   if (sw_if_index == ~0)
19158     {
19159       errmsg ("missing interface name or sw_if_index");
19160       return -99;
19161     }
19162
19163   /* Construct the API message */
19164   M (FEATURE_ENABLE_DISABLE, mp);
19165   mp->sw_if_index = ntohl (sw_if_index);
19166   mp->enable = enable;
19167   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19168   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19169   vec_free (arc_name);
19170   vec_free (feature_name);
19171
19172   S (mp);
19173   W (ret);
19174   return ret;
19175 }
19176
19177 static int
19178 api_sw_interface_tag_add_del (vat_main_t * vam)
19179 {
19180   unformat_input_t *i = vam->input;
19181   vl_api_sw_interface_tag_add_del_t *mp;
19182   u32 sw_if_index = ~0;
19183   u8 *tag = 0;
19184   u8 enable = 1;
19185   int ret;
19186
19187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19188     {
19189       if (unformat (i, "tag %s", &tag))
19190         ;
19191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19192         ;
19193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19194         ;
19195       else if (unformat (i, "del"))
19196         enable = 0;
19197       else
19198         break;
19199     }
19200
19201   if (sw_if_index == ~0)
19202     {
19203       errmsg ("missing interface name or sw_if_index");
19204       return -99;
19205     }
19206
19207   if (enable && (tag == 0))
19208     {
19209       errmsg ("no tag specified");
19210       return -99;
19211     }
19212
19213   /* Construct the API message */
19214   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19215   mp->sw_if_index = ntohl (sw_if_index);
19216   mp->is_add = enable;
19217   if (enable)
19218     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19219   vec_free (tag);
19220
19221   S (mp);
19222   W (ret);
19223   return ret;
19224 }
19225
19226 static void vl_api_l2_xconnect_details_t_handler
19227   (vl_api_l2_xconnect_details_t * mp)
19228 {
19229   vat_main_t *vam = &vat_main;
19230
19231   print (vam->ofp, "%15d%15d",
19232          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19233 }
19234
19235 static void vl_api_l2_xconnect_details_t_handler_json
19236   (vl_api_l2_xconnect_details_t * mp)
19237 {
19238   vat_main_t *vam = &vat_main;
19239   vat_json_node_t *node = NULL;
19240
19241   if (VAT_JSON_ARRAY != vam->json_tree.type)
19242     {
19243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19244       vat_json_init_array (&vam->json_tree);
19245     }
19246   node = vat_json_array_add (&vam->json_tree);
19247
19248   vat_json_init_object (node);
19249   vat_json_object_add_uint (node, "rx_sw_if_index",
19250                             ntohl (mp->rx_sw_if_index));
19251   vat_json_object_add_uint (node, "tx_sw_if_index",
19252                             ntohl (mp->tx_sw_if_index));
19253 }
19254
19255 static int
19256 api_l2_xconnect_dump (vat_main_t * vam)
19257 {
19258   vl_api_l2_xconnect_dump_t *mp;
19259   vl_api_control_ping_t *mp_ping;
19260   int ret;
19261
19262   if (!vam->json_output)
19263     {
19264       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19265     }
19266
19267   M (L2_XCONNECT_DUMP, mp);
19268
19269   S (mp);
19270
19271   /* Use a control ping for synchronization */
19272   M (CONTROL_PING, mp_ping);
19273   S (mp_ping);
19274
19275   W (ret);
19276   return ret;
19277 }
19278
19279 static int
19280 api_sw_interface_set_mtu (vat_main_t * vam)
19281 {
19282   unformat_input_t *i = vam->input;
19283   vl_api_sw_interface_set_mtu_t *mp;
19284   u32 sw_if_index = ~0;
19285   u32 mtu = 0;
19286   int ret;
19287
19288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19289     {
19290       if (unformat (i, "mtu %d", &mtu))
19291         ;
19292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19293         ;
19294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19295         ;
19296       else
19297         break;
19298     }
19299
19300   if (sw_if_index == ~0)
19301     {
19302       errmsg ("missing interface name or sw_if_index");
19303       return -99;
19304     }
19305
19306   if (mtu == 0)
19307     {
19308       errmsg ("no mtu specified");
19309       return -99;
19310     }
19311
19312   /* Construct the API message */
19313   M (SW_INTERFACE_SET_MTU, mp);
19314   mp->sw_if_index = ntohl (sw_if_index);
19315   mp->mtu = ntohs ((u16) mtu);
19316
19317   S (mp);
19318   W (ret);
19319   return ret;
19320 }
19321
19322 static int
19323 api_p2p_ethernet_add (vat_main_t * vam)
19324 {
19325   unformat_input_t *i = vam->input;
19326   vl_api_p2p_ethernet_add_t *mp;
19327   u32 parent_if_index = ~0;
19328   u32 sub_id = ~0;
19329   u8 remote_mac[6];
19330   u8 mac_set = 0;
19331   int ret;
19332
19333   memset (remote_mac, 0, sizeof (remote_mac));
19334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19335     {
19336       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19337         ;
19338       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19339         ;
19340       else
19341         if (unformat
19342             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19343         mac_set++;
19344       else if (unformat (i, "sub_id %d", &sub_id))
19345         ;
19346       else
19347         {
19348           clib_warning ("parse error '%U'", format_unformat_error, i);
19349           return -99;
19350         }
19351     }
19352
19353   if (parent_if_index == ~0)
19354     {
19355       errmsg ("missing interface name or sw_if_index");
19356       return -99;
19357     }
19358   if (mac_set == 0)
19359     {
19360       errmsg ("missing remote mac address");
19361       return -99;
19362     }
19363   if (sub_id == ~0)
19364     {
19365       errmsg ("missing sub-interface id");
19366       return -99;
19367     }
19368
19369   M (P2P_ETHERNET_ADD, mp);
19370   mp->parent_if_index = ntohl (parent_if_index);
19371   mp->subif_id = ntohl (sub_id);
19372   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19373
19374   S (mp);
19375   W (ret);
19376   return ret;
19377 }
19378
19379 static int
19380 api_p2p_ethernet_del (vat_main_t * vam)
19381 {
19382   unformat_input_t *i = vam->input;
19383   vl_api_p2p_ethernet_del_t *mp;
19384   u32 parent_if_index = ~0;
19385   u8 remote_mac[6];
19386   u8 mac_set = 0;
19387   int ret;
19388
19389   memset (remote_mac, 0, sizeof (remote_mac));
19390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19391     {
19392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19393         ;
19394       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19395         ;
19396       else
19397         if (unformat
19398             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19399         mac_set++;
19400       else
19401         {
19402           clib_warning ("parse error '%U'", format_unformat_error, i);
19403           return -99;
19404         }
19405     }
19406
19407   if (parent_if_index == ~0)
19408     {
19409       errmsg ("missing interface name or sw_if_index");
19410       return -99;
19411     }
19412   if (mac_set == 0)
19413     {
19414       errmsg ("missing remote mac address");
19415       return -99;
19416     }
19417
19418   M (P2P_ETHERNET_DEL, mp);
19419   mp->parent_if_index = ntohl (parent_if_index);
19420   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19421
19422   S (mp);
19423   W (ret);
19424   return ret;
19425 }
19426
19427 static int
19428 api_lldp_config (vat_main_t * vam)
19429 {
19430   unformat_input_t *i = vam->input;
19431   vl_api_lldp_config_t *mp;
19432   int tx_hold = 0;
19433   int tx_interval = 0;
19434   u8 *sys_name = NULL;
19435   int ret;
19436
19437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19438     {
19439       if (unformat (i, "system-name %s", &sys_name))
19440         ;
19441       else if (unformat (i, "tx-hold %d", &tx_hold))
19442         ;
19443       else if (unformat (i, "tx-interval %d", &tx_interval))
19444         ;
19445       else
19446         {
19447           clib_warning ("parse error '%U'", format_unformat_error, i);
19448           return -99;
19449         }
19450     }
19451
19452   vec_add1 (sys_name, 0);
19453
19454   M (LLDP_CONFIG, mp);
19455   mp->tx_hold = htonl (tx_hold);
19456   mp->tx_interval = htonl (tx_interval);
19457   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19458   vec_free (sys_name);
19459
19460   S (mp);
19461   W (ret);
19462   return ret;
19463 }
19464
19465 static int
19466 api_sw_interface_set_lldp (vat_main_t * vam)
19467 {
19468   unformat_input_t *i = vam->input;
19469   vl_api_sw_interface_set_lldp_t *mp;
19470   u32 sw_if_index = ~0;
19471   u32 enable = 1;
19472   u8 *port_desc = NULL;
19473   int ret;
19474
19475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19476     {
19477       if (unformat (i, "disable"))
19478         enable = 0;
19479       else
19480         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19481         ;
19482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19483         ;
19484       else if (unformat (i, "port-desc %s", &port_desc))
19485         ;
19486       else
19487         break;
19488     }
19489
19490   if (sw_if_index == ~0)
19491     {
19492       errmsg ("missing interface name or sw_if_index");
19493       return -99;
19494     }
19495
19496   /* Construct the API message */
19497   vec_add1 (port_desc, 0);
19498   M (SW_INTERFACE_SET_LLDP, mp);
19499   mp->sw_if_index = ntohl (sw_if_index);
19500   mp->enable = enable;
19501   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19502   vec_free (port_desc);
19503
19504   S (mp);
19505   W (ret);
19506   return ret;
19507 }
19508
19509 static int
19510 q_or_quit (vat_main_t * vam)
19511 {
19512 #if VPP_API_TEST_BUILTIN == 0
19513   longjmp (vam->jump_buf, 1);
19514 #endif
19515   return 0;                     /* not so much */
19516 }
19517
19518 static int
19519 q (vat_main_t * vam)
19520 {
19521   return q_or_quit (vam);
19522 }
19523
19524 static int
19525 quit (vat_main_t * vam)
19526 {
19527   return q_or_quit (vam);
19528 }
19529
19530 static int
19531 comment (vat_main_t * vam)
19532 {
19533   return 0;
19534 }
19535
19536 static int
19537 cmd_cmp (void *a1, void *a2)
19538 {
19539   u8 **c1 = a1;
19540   u8 **c2 = a2;
19541
19542   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19543 }
19544
19545 static int
19546 help (vat_main_t * vam)
19547 {
19548   u8 **cmds = 0;
19549   u8 *name = 0;
19550   hash_pair_t *p;
19551   unformat_input_t *i = vam->input;
19552   int j;
19553
19554   if (unformat (i, "%s", &name))
19555     {
19556       uword *hs;
19557
19558       vec_add1 (name, 0);
19559
19560       hs = hash_get_mem (vam->help_by_name, name);
19561       if (hs)
19562         print (vam->ofp, "usage: %s %s", name, hs[0]);
19563       else
19564         print (vam->ofp, "No such msg / command '%s'", name);
19565       vec_free (name);
19566       return 0;
19567     }
19568
19569   print (vam->ofp, "Help is available for the following:");
19570
19571     /* *INDENT-OFF* */
19572     hash_foreach_pair (p, vam->function_by_name,
19573     ({
19574       vec_add1 (cmds, (u8 *)(p->key));
19575     }));
19576     /* *INDENT-ON* */
19577
19578   vec_sort_with_function (cmds, cmd_cmp);
19579
19580   for (j = 0; j < vec_len (cmds); j++)
19581     print (vam->ofp, "%s", cmds[j]);
19582
19583   vec_free (cmds);
19584   return 0;
19585 }
19586
19587 static int
19588 set (vat_main_t * vam)
19589 {
19590   u8 *name = 0, *value = 0;
19591   unformat_input_t *i = vam->input;
19592
19593   if (unformat (i, "%s", &name))
19594     {
19595       /* The input buffer is a vector, not a string. */
19596       value = vec_dup (i->buffer);
19597       vec_delete (value, i->index, 0);
19598       /* Almost certainly has a trailing newline */
19599       if (value[vec_len (value) - 1] == '\n')
19600         value[vec_len (value) - 1] = 0;
19601       /* Make sure it's a proper string, one way or the other */
19602       vec_add1 (value, 0);
19603       (void) clib_macro_set_value (&vam->macro_main,
19604                                    (char *) name, (char *) value);
19605     }
19606   else
19607     errmsg ("usage: set <name> <value>");
19608
19609   vec_free (name);
19610   vec_free (value);
19611   return 0;
19612 }
19613
19614 static int
19615 unset (vat_main_t * vam)
19616 {
19617   u8 *name = 0;
19618
19619   if (unformat (vam->input, "%s", &name))
19620     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19621       errmsg ("unset: %s wasn't set", name);
19622   vec_free (name);
19623   return 0;
19624 }
19625
19626 typedef struct
19627 {
19628   u8 *name;
19629   u8 *value;
19630 } macro_sort_t;
19631
19632
19633 static int
19634 macro_sort_cmp (void *a1, void *a2)
19635 {
19636   macro_sort_t *s1 = a1;
19637   macro_sort_t *s2 = a2;
19638
19639   return strcmp ((char *) (s1->name), (char *) (s2->name));
19640 }
19641
19642 static int
19643 dump_macro_table (vat_main_t * vam)
19644 {
19645   macro_sort_t *sort_me = 0, *sm;
19646   int i;
19647   hash_pair_t *p;
19648
19649     /* *INDENT-OFF* */
19650     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19651     ({
19652       vec_add2 (sort_me, sm, 1);
19653       sm->name = (u8 *)(p->key);
19654       sm->value = (u8 *) (p->value[0]);
19655     }));
19656     /* *INDENT-ON* */
19657
19658   vec_sort_with_function (sort_me, macro_sort_cmp);
19659
19660   if (vec_len (sort_me))
19661     print (vam->ofp, "%-15s%s", "Name", "Value");
19662   else
19663     print (vam->ofp, "The macro table is empty...");
19664
19665   for (i = 0; i < vec_len (sort_me); i++)
19666     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19667   return 0;
19668 }
19669
19670 static int
19671 dump_node_table (vat_main_t * vam)
19672 {
19673   int i, j;
19674   vlib_node_t *node, *next_node;
19675
19676   if (vec_len (vam->graph_nodes) == 0)
19677     {
19678       print (vam->ofp, "Node table empty, issue get_node_graph...");
19679       return 0;
19680     }
19681
19682   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19683     {
19684       node = vam->graph_nodes[i];
19685       print (vam->ofp, "[%d] %s", i, node->name);
19686       for (j = 0; j < vec_len (node->next_nodes); j++)
19687         {
19688           if (node->next_nodes[j] != ~0)
19689             {
19690               next_node = vam->graph_nodes[node->next_nodes[j]];
19691               print (vam->ofp, "  [%d] %s", j, next_node->name);
19692             }
19693         }
19694     }
19695   return 0;
19696 }
19697
19698 static int
19699 value_sort_cmp (void *a1, void *a2)
19700 {
19701   name_sort_t *n1 = a1;
19702   name_sort_t *n2 = a2;
19703
19704   if (n1->value < n2->value)
19705     return -1;
19706   if (n1->value > n2->value)
19707     return 1;
19708   return 0;
19709 }
19710
19711
19712 static int
19713 dump_msg_api_table (vat_main_t * vam)
19714 {
19715   api_main_t *am = &api_main;
19716   name_sort_t *nses = 0, *ns;
19717   hash_pair_t *hp;
19718   int i;
19719
19720   /* *INDENT-OFF* */
19721   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19722   ({
19723     vec_add2 (nses, ns, 1);
19724     ns->name = (u8 *)(hp->key);
19725     ns->value = (u32) hp->value[0];
19726   }));
19727   /* *INDENT-ON* */
19728
19729   vec_sort_with_function (nses, value_sort_cmp);
19730
19731   for (i = 0; i < vec_len (nses); i++)
19732     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19733   vec_free (nses);
19734   return 0;
19735 }
19736
19737 static int
19738 get_msg_id (vat_main_t * vam)
19739 {
19740   u8 *name_and_crc;
19741   u32 message_index;
19742
19743   if (unformat (vam->input, "%s", &name_and_crc))
19744     {
19745       message_index = vl_api_get_msg_index (name_and_crc);
19746       if (message_index == ~0)
19747         {
19748           print (vam->ofp, " '%s' not found", name_and_crc);
19749           return 0;
19750         }
19751       print (vam->ofp, " '%s' has message index %d",
19752              name_and_crc, message_index);
19753       return 0;
19754     }
19755   errmsg ("name_and_crc required...");
19756   return 0;
19757 }
19758
19759 static int
19760 search_node_table (vat_main_t * vam)
19761 {
19762   unformat_input_t *line_input = vam->input;
19763   u8 *node_to_find;
19764   int j;
19765   vlib_node_t *node, *next_node;
19766   uword *p;
19767
19768   if (vam->graph_node_index_by_name == 0)
19769     {
19770       print (vam->ofp, "Node table empty, issue get_node_graph...");
19771       return 0;
19772     }
19773
19774   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19775     {
19776       if (unformat (line_input, "%s", &node_to_find))
19777         {
19778           vec_add1 (node_to_find, 0);
19779           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19780           if (p == 0)
19781             {
19782               print (vam->ofp, "%s not found...", node_to_find);
19783               goto out;
19784             }
19785           node = vam->graph_nodes[p[0]];
19786           print (vam->ofp, "[%d] %s", p[0], node->name);
19787           for (j = 0; j < vec_len (node->next_nodes); j++)
19788             {
19789               if (node->next_nodes[j] != ~0)
19790                 {
19791                   next_node = vam->graph_nodes[node->next_nodes[j]];
19792                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19793                 }
19794             }
19795         }
19796
19797       else
19798         {
19799           clib_warning ("parse error '%U'", format_unformat_error,
19800                         line_input);
19801           return -99;
19802         }
19803
19804     out:
19805       vec_free (node_to_find);
19806
19807     }
19808
19809   return 0;
19810 }
19811
19812
19813 static int
19814 script (vat_main_t * vam)
19815 {
19816 #if (VPP_API_TEST_BUILTIN==0)
19817   u8 *s = 0;
19818   char *save_current_file;
19819   unformat_input_t save_input;
19820   jmp_buf save_jump_buf;
19821   u32 save_line_number;
19822
19823   FILE *new_fp, *save_ifp;
19824
19825   if (unformat (vam->input, "%s", &s))
19826     {
19827       new_fp = fopen ((char *) s, "r");
19828       if (new_fp == 0)
19829         {
19830           errmsg ("Couldn't open script file %s", s);
19831           vec_free (s);
19832           return -99;
19833         }
19834     }
19835   else
19836     {
19837       errmsg ("Missing script name");
19838       return -99;
19839     }
19840
19841   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19842   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19843   save_ifp = vam->ifp;
19844   save_line_number = vam->input_line_number;
19845   save_current_file = (char *) vam->current_file;
19846
19847   vam->input_line_number = 0;
19848   vam->ifp = new_fp;
19849   vam->current_file = s;
19850   do_one_file (vam);
19851
19852   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19853   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19854   vam->ifp = save_ifp;
19855   vam->input_line_number = save_line_number;
19856   vam->current_file = (u8 *) save_current_file;
19857   vec_free (s);
19858
19859   return 0;
19860 #else
19861   clib_warning ("use the exec command...");
19862   return -99;
19863 #endif
19864 }
19865
19866 static int
19867 echo (vat_main_t * vam)
19868 {
19869   print (vam->ofp, "%v", vam->input->buffer);
19870   return 0;
19871 }
19872
19873 /* List of API message constructors, CLI names map to api_xxx */
19874 #define foreach_vpe_api_msg                                             \
19875 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19876 _(sw_interface_dump,"")                                                 \
19877 _(sw_interface_set_flags,                                               \
19878   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19879 _(sw_interface_add_del_address,                                         \
19880   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19881 _(sw_interface_set_table,                                               \
19882   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19883 _(sw_interface_set_mpls_enable,                                         \
19884   "<intfc> | sw_if_index [disable | dis]")                              \
19885 _(sw_interface_set_vpath,                                               \
19886   "<intfc> | sw_if_index <id> enable | disable")                        \
19887 _(sw_interface_set_vxlan_bypass,                                        \
19888   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19889 _(sw_interface_set_l2_xconnect,                                         \
19890   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19891   "enable | disable")                                                   \
19892 _(sw_interface_set_l2_bridge,                                           \
19893   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19894   "[shg <split-horizon-group>] [bvi]\n"                                 \
19895   "enable | disable")                                                   \
19896 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19897 _(bridge_domain_add_del,                                                \
19898   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [del]\n") \
19899 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19900 _(l2fib_add_del,                                                        \
19901   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19902 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19903 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19904 _(l2_flags,                                                             \
19905   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19906 _(bridge_flags,                                                         \
19907   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19908 _(tap_connect,                                                          \
19909   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19910 _(tap_modify,                                                           \
19911   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
19912 _(tap_delete,                                                           \
19913   "<vpp-if-name> | sw_if_index <id>")                                   \
19914 _(sw_interface_tap_dump, "")                                            \
19915 _(ip_add_del_route,                                                     \
19916   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
19917   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19918   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19919   "[multipath] [count <n>]")                                            \
19920 _(ip_mroute_add_del,                                                    \
19921   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
19922   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
19923 _(mpls_route_add_del,                                                   \
19924   "<label> <eos> via <addr> [table-id <n>]\n"                           \
19925   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19926   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19927   "[multipath] [count <n>]")                                            \
19928 _(mpls_ip_bind_unbind,                                                  \
19929   "<label> <addr/len>")                                                 \
19930 _(mpls_tunnel_add_del,                                                  \
19931   " via <addr> [table-id <n>]\n"                                        \
19932   "sw_if_index <id>] [l2]  [del]")                                      \
19933 _(proxy_arp_add_del,                                                    \
19934   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
19935 _(proxy_arp_intfc_enable_disable,                                       \
19936   "<intfc> | sw_if_index <id> enable | disable")                        \
19937 _(sw_interface_set_unnumbered,                                          \
19938   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
19939 _(ip_neighbor_add_del,                                                  \
19940   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
19941   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
19942 _(reset_vrf, "vrf <id> [ipv6]")                                         \
19943 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
19944 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
19945   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
19946   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
19947   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
19948 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
19949 _(reset_fib, "vrf <n> [ipv6]")                                          \
19950 _(dhcp_proxy_config,                                                    \
19951   "svr <v46-address> src <v46-address>\n"                               \
19952    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
19953 _(dhcp_proxy_set_vss,                                                   \
19954   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
19955 _(dhcp_proxy_dump, "ip6")                                               \
19956 _(dhcp_client_config,                                                   \
19957   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
19958 _(set_ip_flow_hash,                                                     \
19959   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
19960 _(sw_interface_ip6_enable_disable,                                      \
19961   "<intfc> | sw_if_index <id> enable | disable")                        \
19962 _(sw_interface_ip6_set_link_local_address,                              \
19963   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
19964 _(ip6nd_proxy_add_del,                                                  \
19965   "<intfc> | sw_if_index <id> <ip6-address>")                           \
19966 _(ip6nd_proxy_dump, "")                                                 \
19967 _(sw_interface_ip6nd_ra_prefix,                                         \
19968   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
19969   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
19970   "[nolink] [isno]")                                                    \
19971 _(sw_interface_ip6nd_ra_config,                                         \
19972   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
19973   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
19974   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
19975 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
19976 _(l2_patch_add_del,                                                     \
19977   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19978   "enable | disable")                                                   \
19979 _(sr_localsid_add_del,                                                  \
19980   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
19981   "fib-table <num> (end.psp) sw_if_index <num>")                        \
19982 _(classify_add_del_table,                                               \
19983   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
19984   " [del] [del-chain] mask <mask-value>\n"                              \
19985   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
19986   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
19987 _(classify_add_del_session,                                             \
19988   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
19989   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
19990   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
19991   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
19992 _(classify_set_interface_ip_table,                                      \
19993   "<intfc> | sw_if_index <nn> table <nn>")                              \
19994 _(classify_set_interface_l2_tables,                                     \
19995   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19996   "  [other-table <nn>]")                                               \
19997 _(get_node_index, "node <node-name")                                    \
19998 _(add_node_next, "node <node-name> next <next-node-name>")              \
19999 _(l2tpv3_create_tunnel,                                                 \
20000   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20001   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20002   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20003 _(l2tpv3_set_tunnel_cookies,                                            \
20004   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20005   "[new_remote_cookie <nn>]\n")                                         \
20006 _(l2tpv3_interface_enable_disable,                                      \
20007   "<intfc> | sw_if_index <nn> enable | disable")                        \
20008 _(l2tpv3_set_lookup_key,                                                \
20009   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20010 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20011 _(vxlan_add_del_tunnel,                                                 \
20012   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20013   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20014   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20015 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20016 _(gre_add_del_tunnel,                                                   \
20017   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20018 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20019 _(l2_fib_clear_table, "")                                               \
20020 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20021 _(l2_interface_vlan_tag_rewrite,                                        \
20022   "<intfc> | sw_if_index <nn> \n"                                       \
20023   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20024   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20025 _(create_vhost_user_if,                                                 \
20026         "socket <filename> [server] [renumber <dev_instance>] "         \
20027         "[mac <mac_address>]")                                          \
20028 _(modify_vhost_user_if,                                                 \
20029         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20030         "[server] [renumber <dev_instance>]")                           \
20031 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20032 _(sw_interface_vhost_user_dump, "")                                     \
20033 _(show_version, "")                                                     \
20034 _(vxlan_gpe_add_del_tunnel,                                             \
20035   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20036   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20037   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20038   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20039 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20040 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20041 _(interface_name_renumber,                                              \
20042   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20043 _(input_acl_set_interface,                                              \
20044   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20045   "  [l2-table <nn>] [del]")                                            \
20046 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20047 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20048 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20049 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20050 _(ip_dump, "ipv4 | ipv6")                                               \
20051 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20052 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20053   "  spid_id <n> ")                                                     \
20054 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20055   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20056   "  integ_alg <alg> integ_key <hex>")                                  \
20057 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20058   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20059   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20060   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20061 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20062 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20063   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20064   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20065   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20066 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20067 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20068   "(auth_data 0x<data> | auth_data <data>)")                            \
20069 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20070   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20071 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20072   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20073   "(local|remote)")                                                     \
20074 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20075 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20076 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20077 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20078 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20079 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20080 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20081 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20082 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20083 _(delete_loopback,"sw_if_index <nn>")                                   \
20084 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20085 _(map_add_domain,                                                       \
20086   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20087   "ip6-src <ip6addr> "                                                  \
20088   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20089 _(map_del_domain, "index <n>")                                          \
20090 _(map_add_del_rule,                                                     \
20091   "index <n> psid <n> dst <ip6addr> [del]")                             \
20092 _(map_domain_dump, "")                                                  \
20093 _(map_rule_dump, "index <map-domain>")                                  \
20094 _(want_interface_events,  "enable|disable")                             \
20095 _(want_stats,"enable|disable")                                          \
20096 _(get_first_msg_id, "client <name>")                                    \
20097 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20098 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20099   "fib-id <nn> [ip4][ip6][default]")                                    \
20100 _(get_node_graph, " ")                                                  \
20101 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20102 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20103 _(ioam_disable, "")                                                     \
20104 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20105                             " sw_if_index <sw_if_index> p <priority> "  \
20106                             "w <weight>] [del]")                        \
20107 _(one_add_del_locator, "locator-set <locator_name> "                    \
20108                         "iface <intf> | sw_if_index <sw_if_index> "     \
20109                         "p <priority> w <weight> [del]")                \
20110 _(one_add_del_local_eid,"vni <vni> eid "                                \
20111                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20112                          "locator-set <locator_name> [del]"             \
20113                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20114 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20115 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20116 _(one_enable_disable, "enable|disable")                                 \
20117 _(one_map_register_enable_disable, "enable|disable")                    \
20118 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20119 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20120                                "[seid <seid>] "                         \
20121                                "rloc <locator> p <prio> "               \
20122                                "w <weight> [rloc <loc> ... ] "          \
20123                                "action <action> [del-all]")             \
20124 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20125                           "<local-eid>")                                \
20126 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20127 _(one_use_petr, "ip-address> | disable")                                \
20128 _(one_map_request_mode, "src-dst|dst-only")                             \
20129 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20130 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20131 _(one_locator_set_dump, "[local | remote]")                             \
20132 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20133 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20134                        "[local] | [remote]")                            \
20135 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20136 _(one_l2_arp_bd_get, "")                                                \
20137 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20138 _(one_stats_enable_disable, "enable|disalbe")                           \
20139 _(show_one_stats_enable_disable, "")                                    \
20140 _(one_eid_table_vni_dump, "")                                           \
20141 _(one_eid_table_map_dump, "l2|l3")                                      \
20142 _(one_map_resolver_dump, "")                                            \
20143 _(one_map_server_dump, "")                                              \
20144 _(one_adjacencies_get, "vni <vni>")                                     \
20145 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20146 _(show_one_rloc_probe_state, "")                                        \
20147 _(show_one_map_register_state, "")                                      \
20148 _(show_one_status, "")                                                  \
20149 _(one_stats_dump, "")                                                   \
20150 _(one_stats_flush, "")                                                  \
20151 _(one_get_map_request_itr_rlocs, "")                                    \
20152 _(one_map_register_set_ttl, "<ttl>")                                    \
20153 _(show_one_nsh_mapping, "")                                             \
20154 _(show_one_pitr, "")                                                    \
20155 _(show_one_use_petr, "")                                                \
20156 _(show_one_map_request_mode, "")                                        \
20157 _(show_one_map_register_ttl, "")                                        \
20158 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20159                             " sw_if_index <sw_if_index> p <priority> "  \
20160                             "w <weight>] [del]")                        \
20161 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20162                         "iface <intf> | sw_if_index <sw_if_index> "     \
20163                         "p <priority> w <weight> [del]")                \
20164 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20165                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20166                          "locator-set <locator_name> [del]"             \
20167                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20168 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20169 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20170 _(lisp_enable_disable, "enable|disable")                                \
20171 _(lisp_map_register_enable_disable, "enable|disable")                   \
20172 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20173 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20174                                "[seid <seid>] "                         \
20175                                "rloc <locator> p <prio> "               \
20176                                "w <weight> [rloc <loc> ... ] "          \
20177                                "action <action> [del-all]")             \
20178 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20179                           "<local-eid>")                                \
20180 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20181 _(lisp_use_petr, "<ip-address> | disable")                              \
20182 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20183 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20184 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20185 _(lisp_locator_set_dump, "[local | remote]")                            \
20186 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20187 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20188                        "[local] | [remote]")                            \
20189 _(lisp_eid_table_vni_dump, "")                                          \
20190 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20191 _(lisp_map_resolver_dump, "")                                           \
20192 _(lisp_map_server_dump, "")                                             \
20193 _(lisp_adjacencies_get, "vni <vni>")                                    \
20194 _(gpe_fwd_entry_vnis_get, "")                                           \
20195 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20196 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20197                                 "[table <table-id>]")                   \
20198 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20199 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20200 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20201 _(gpe_get_encap_mode, "")                                               \
20202 _(lisp_gpe_add_del_iface, "up|down")                                    \
20203 _(lisp_gpe_enable_disable, "enable|disable")                            \
20204 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20205   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20206 _(show_lisp_rloc_probe_state, "")                                       \
20207 _(show_lisp_map_register_state, "")                                     \
20208 _(show_lisp_status, "")                                                 \
20209 _(lisp_get_map_request_itr_rlocs, "")                                   \
20210 _(show_lisp_pitr, "")                                                   \
20211 _(show_lisp_use_petr, "")                                               \
20212 _(show_lisp_map_request_mode, "")                                       \
20213 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20214 _(af_packet_delete, "name <host interface name>")                       \
20215 _(policer_add_del, "name <policer name> <params> [del]")                \
20216 _(policer_dump, "[name <policer name>]")                                \
20217 _(policer_classify_set_interface,                                       \
20218   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20219   "  [l2-table <nn>] [del]")                                            \
20220 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20221 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20222     "[master|slave]")                                                   \
20223 _(netmap_delete, "name <interface name>")                               \
20224 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20225 _(mpls_fib_dump, "")                                                    \
20226 _(classify_table_ids, "")                                               \
20227 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20228 _(classify_table_info, "table_id <nn>")                                 \
20229 _(classify_session_dump, "table_id <nn>")                               \
20230 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20231     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20232     "[template_interval <nn>] [udp_checksum]")                          \
20233 _(ipfix_exporter_dump, "")                                              \
20234 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20235 _(ipfix_classify_stream_dump, "")                                       \
20236 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20237 _(ipfix_classify_table_dump, "")                                        \
20238 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20239 _(sw_interface_span_dump, "[l2]")                                           \
20240 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20241 _(pg_create_interface, "if_id <nn>")                                    \
20242 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20243 _(pg_enable_disable, "[stream <id>] disable")                           \
20244 _(ip_source_and_port_range_check_add_del,                               \
20245   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20246 _(ip_source_and_port_range_check_interface_add_del,                     \
20247   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20248   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20249 _(ipsec_gre_add_del_tunnel,                                             \
20250   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20251 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20252 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20253 _(l2_interface_pbb_tag_rewrite,                                         \
20254   "<intfc> | sw_if_index <nn> \n"                                       \
20255   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20256   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20257 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20258 _(flow_classify_set_interface,                                          \
20259   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20260 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20261 _(ip_fib_dump, "")                                                      \
20262 _(ip_mfib_dump, "")                                                     \
20263 _(ip6_fib_dump, "")                                                     \
20264 _(ip6_mfib_dump, "")                                                    \
20265 _(feature_enable_disable, "arc_name <arc_name> "                        \
20266   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20267 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20268 "[disable]")                                                            \
20269 _(l2_xconnect_dump, "")                                                 \
20270 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20271 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20272 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20273 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20274 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20275 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20276 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]")
20277
20278 /* List of command functions, CLI names map directly to functions */
20279 #define foreach_cli_function                                    \
20280 _(comment, "usage: comment <ignore-rest-of-line>")              \
20281 _(dump_interface_table, "usage: dump_interface_table")          \
20282 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20283 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20284 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20285 _(dump_stats_table, "usage: dump_stats_table")                  \
20286 _(dump_macro_table, "usage: dump_macro_table ")                 \
20287 _(dump_node_table, "usage: dump_node_table")                    \
20288 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20289 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20290 _(echo, "usage: echo <message>")                                \
20291 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20292 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20293 _(help, "usage: help")                                          \
20294 _(q, "usage: quit")                                             \
20295 _(quit, "usage: quit")                                          \
20296 _(search_node_table, "usage: search_node_table <name>...")      \
20297 _(set, "usage: set <variable-name> <value>")                    \
20298 _(script, "usage: script <file-name>")                          \
20299 _(unset, "usage: unset <variable-name>")
20300 #define _(N,n)                                  \
20301     static void vl_api_##n##_t_handler_uni      \
20302     (vl_api_##n##_t * mp)                       \
20303     {                                           \
20304         vat_main_t * vam = &vat_main;           \
20305         if (vam->json_output) {                 \
20306             vl_api_##n##_t_handler_json(mp);    \
20307         } else {                                \
20308             vl_api_##n##_t_handler(mp);         \
20309         }                                       \
20310     }
20311 foreach_vpe_api_reply_msg;
20312 #if VPP_API_TEST_BUILTIN == 0
20313 foreach_standalone_reply_msg;
20314 #endif
20315 #undef _
20316
20317 void
20318 vat_api_hookup (vat_main_t * vam)
20319 {
20320 #define _(N,n)                                                  \
20321     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20322                            vl_api_##n##_t_handler_uni,          \
20323                            vl_noop_handler,                     \
20324                            vl_api_##n##_t_endian,               \
20325                            vl_api_##n##_t_print,                \
20326                            sizeof(vl_api_##n##_t), 1);
20327   foreach_vpe_api_reply_msg;
20328 #if VPP_API_TEST_BUILTIN == 0
20329   foreach_standalone_reply_msg;
20330 #endif
20331 #undef _
20332
20333 #if (VPP_API_TEST_BUILTIN==0)
20334   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20335
20336   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20337
20338   vam->function_by_name = hash_create_string (0, sizeof (uword));
20339
20340   vam->help_by_name = hash_create_string (0, sizeof (uword));
20341 #endif
20342
20343   /* API messages we can send */
20344 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20345   foreach_vpe_api_msg;
20346 #undef _
20347
20348   /* Help strings */
20349 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20350   foreach_vpe_api_msg;
20351 #undef _
20352
20353   /* CLI functions */
20354 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20355   foreach_cli_function;
20356 #undef _
20357
20358   /* Help strings */
20359 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20360   foreach_cli_function;
20361 #undef _
20362 }
20363
20364 #if VPP_API_TEST_BUILTIN
20365 static clib_error_t *
20366 vat_api_hookup_shim (vlib_main_t * vm)
20367 {
20368   vat_api_hookup (&vat_main);
20369   return 0;
20370 }
20371
20372 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20373 #endif
20374
20375 /*
20376  * fd.io coding-style-patch-verification: ON
20377  *
20378  * Local Variables:
20379  * eval: (c-set-style "gnu")
20380  * End:
20381  */