vhost: migrate to use device infra for worker thread assignment, rx-mode.
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1287 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1288
1289 /*
1290  * Special-case: build the bridge domain table, maintain
1291  * the next bd id vbl.
1292  */
1293 static void vl_api_bridge_domain_details_t_handler
1294   (vl_api_bridge_domain_details_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1298   int i;
1299
1300   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1301          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1302
1303   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1304          ntohl (mp->bd_id), mp->learn, mp->forward,
1305          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1306
1307   if (n_sw_ifs)
1308     {
1309       vl_api_bridge_domain_sw_if_t *sw_ifs;
1310       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1311              "Interface Name");
1312
1313       sw_ifs = mp->sw_if_details;
1314       for (i = 0; i < n_sw_ifs; i++)
1315         {
1316           u8 *sw_if_name = 0;
1317           u32 sw_if_index;
1318           hash_pair_t *p;
1319
1320           sw_if_index = ntohl (sw_ifs->sw_if_index);
1321
1322           /* *INDENT-OFF* */
1323           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1324                              ({
1325                                if ((u32) p->value[0] == sw_if_index)
1326                                  {
1327                                    sw_if_name = (u8 *)(p->key);
1328                                    break;
1329                                  }
1330                              }));
1331           /* *INDENT-ON* */
1332           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1333                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1334                  "sw_if_index not found!");
1335
1336           sw_ifs++;
1337         }
1338     }
1339 }
1340
1341 static void vl_api_bridge_domain_details_t_handler_json
1342   (vl_api_bridge_domain_details_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   vat_json_node_t *node, *array = NULL;
1346   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1347
1348   if (VAT_JSON_ARRAY != vam->json_tree.type)
1349     {
1350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1351       vat_json_init_array (&vam->json_tree);
1352     }
1353   node = vat_json_array_add (&vam->json_tree);
1354
1355   vat_json_init_object (node);
1356   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1357   vat_json_object_add_uint (node, "flood", mp->flood);
1358   vat_json_object_add_uint (node, "forward", mp->forward);
1359   vat_json_object_add_uint (node, "learn", mp->learn);
1360   vat_json_object_add_uint (node, "bvi_sw_if_index",
1361                             ntohl (mp->bvi_sw_if_index));
1362   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1363   array = vat_json_object_add (node, "sw_if");
1364   vat_json_init_array (array);
1365
1366
1367
1368   if (n_sw_ifs)
1369     {
1370       vl_api_bridge_domain_sw_if_t *sw_ifs;
1371       int i;
1372
1373       sw_ifs = mp->sw_if_details;
1374       for (i = 0; i < n_sw_ifs; i++)
1375         {
1376           node = vat_json_array_add (array);
1377           vat_json_init_object (node);
1378           vat_json_object_add_uint (node, "sw_if_index",
1379                                     ntohl (sw_ifs->sw_if_index));
1380           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1381           sw_ifs++;
1382         }
1383     }
1384 }
1385
1386 static void vl_api_control_ping_reply_t_handler
1387   (vl_api_control_ping_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->result_ready = 1;
1399     }
1400 }
1401
1402 static void vl_api_control_ping_reply_t_handler_json
1403   (vl_api_control_ping_reply_t * mp)
1404 {
1405   vat_main_t *vam = &vat_main;
1406   i32 retval = ntohl (mp->retval);
1407
1408   if (VAT_JSON_NONE != vam->json_tree.type)
1409     {
1410       vat_json_print (vam->ofp, &vam->json_tree);
1411       vat_json_free (&vam->json_tree);
1412       vam->json_tree.type = VAT_JSON_NONE;
1413     }
1414   else
1415     {
1416       /* just print [] */
1417       vat_json_init_array (&vam->json_tree);
1418       vat_json_print (vam->ofp, &vam->json_tree);
1419       vam->json_tree.type = VAT_JSON_NONE;
1420     }
1421
1422   vam->retval = retval;
1423   vam->result_ready = 1;
1424 }
1425
1426 static void
1427   vl_api_bridge_domain_set_mac_age_reply_t_handler
1428   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   i32 retval = ntohl (mp->retval);
1432   if (vam->async_mode)
1433     {
1434       vam->async_errors += (retval < 0);
1435     }
1436   else
1437     {
1438       vam->retval = retval;
1439       vam->result_ready = 1;
1440     }
1441 }
1442
1443 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1444   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   vat_json_node_t node;
1448
1449   vat_json_init_object (&node);
1450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1451
1452   vat_json_print (vam->ofp, &node);
1453   vat_json_free (&node);
1454
1455   vam->retval = ntohl (mp->retval);
1456   vam->result_ready = 1;
1457 }
1458
1459 static void
1460 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   i32 retval = ntohl (mp->retval);
1464   if (vam->async_mode)
1465     {
1466       vam->async_errors += (retval < 0);
1467     }
1468   else
1469     {
1470       vam->retval = retval;
1471       vam->result_ready = 1;
1472     }
1473 }
1474
1475 static void vl_api_l2_flags_reply_t_handler_json
1476   (vl_api_l2_flags_reply_t * mp)
1477 {
1478   vat_main_t *vam = &vat_main;
1479   vat_json_node_t node;
1480
1481   vat_json_init_object (&node);
1482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1483   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1484                             ntohl (mp->resulting_feature_bitmap));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491 }
1492
1493 static void vl_api_bridge_flags_reply_t_handler
1494   (vl_api_bridge_flags_reply_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   i32 retval = ntohl (mp->retval);
1498   if (vam->async_mode)
1499     {
1500       vam->async_errors += (retval < 0);
1501     }
1502   else
1503     {
1504       vam->retval = retval;
1505       vam->result_ready = 1;
1506     }
1507 }
1508
1509 static void vl_api_bridge_flags_reply_t_handler_json
1510   (vl_api_bridge_flags_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   vat_json_node_t node;
1514
1515   vat_json_init_object (&node);
1516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1518                             ntohl (mp->resulting_feature_bitmap));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void vl_api_tap_connect_reply_t_handler
1528   (vl_api_tap_connect_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->sw_if_index = ntohl (mp->sw_if_index);
1540       vam->result_ready = 1;
1541     }
1542
1543 }
1544
1545 static void vl_api_tap_connect_reply_t_handler_json
1546   (vl_api_tap_connect_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t node;
1550
1551   vat_json_init_object (&node);
1552   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1553   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560
1561 }
1562
1563 static void
1564 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1565 {
1566   vat_main_t *vam = &vat_main;
1567   i32 retval = ntohl (mp->retval);
1568   if (vam->async_mode)
1569     {
1570       vam->async_errors += (retval < 0);
1571     }
1572   else
1573     {
1574       vam->retval = retval;
1575       vam->sw_if_index = ntohl (mp->sw_if_index);
1576       vam->result_ready = 1;
1577     }
1578 }
1579
1580 static void vl_api_tap_modify_reply_t_handler_json
1581   (vl_api_tap_modify_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595 }
1596
1597 static void
1598 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611 }
1612
1613 static void vl_api_tap_delete_reply_t_handler_json
1614   (vl_api_tap_delete_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627 }
1628
1629 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1630   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1646   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1654                             ntohl (mp->sw_if_index));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1664   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->sw_if_index = ntohl (mp->sw_if_index);
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1681   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697
1698 static void vl_api_one_add_del_locator_set_reply_t_handler
1699   (vl_api_one_add_del_locator_set_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->result_ready = 1;
1711     }
1712 }
1713
1714 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1715   (vl_api_one_add_del_locator_set_reply_t * mp)
1716 {
1717   vat_main_t *vam = &vat_main;
1718   vat_json_node_t node;
1719
1720   vat_json_init_object (&node);
1721   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1722   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1732   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->sw_if_index = ntohl (mp->sw_if_index);
1744       vam->result_ready = 1;
1745     }
1746 }
1747
1748 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1749   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1750 {
1751   vat_main_t *vam = &vat_main;
1752   vat_json_node_t node;
1753
1754   vat_json_init_object (&node);
1755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1756   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1757
1758   vat_json_print (vam->ofp, &node);
1759   vat_json_free (&node);
1760
1761   vam->retval = ntohl (mp->retval);
1762   vam->result_ready = 1;
1763 }
1764
1765 static void vl_api_gre_add_del_tunnel_reply_t_handler
1766   (vl_api_gre_add_del_tunnel_reply_t * mp)
1767 {
1768   vat_main_t *vam = &vat_main;
1769   i32 retval = ntohl (mp->retval);
1770   if (vam->async_mode)
1771     {
1772       vam->async_errors += (retval < 0);
1773     }
1774   else
1775     {
1776       vam->retval = retval;
1777       vam->sw_if_index = ntohl (mp->sw_if_index);
1778       vam->result_ready = 1;
1779     }
1780 }
1781
1782 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1783   (vl_api_gre_add_del_tunnel_reply_t * mp)
1784 {
1785   vat_main_t *vam = &vat_main;
1786   vat_json_node_t node;
1787
1788   vat_json_init_object (&node);
1789   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1790   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1791
1792   vat_json_print (vam->ofp, &node);
1793   vat_json_free (&node);
1794
1795   vam->retval = ntohl (mp->retval);
1796   vam->result_ready = 1;
1797 }
1798
1799 static void vl_api_create_vhost_user_if_reply_t_handler
1800   (vl_api_create_vhost_user_if_reply_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   i32 retval = ntohl (mp->retval);
1804   if (vam->async_mode)
1805     {
1806       vam->async_errors += (retval < 0);
1807     }
1808   else
1809     {
1810       vam->retval = retval;
1811       vam->sw_if_index = ntohl (mp->sw_if_index);
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_create_vhost_user_if_reply_t_handler_json
1817   (vl_api_create_vhost_user_if_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831 }
1832
1833 static void vl_api_ip_address_details_t_handler
1834   (vl_api_ip_address_details_t * mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   static ip_address_details_t empty_ip_address_details = { {0} };
1838   ip_address_details_t *address = NULL;
1839   ip_details_t *current_ip_details = NULL;
1840   ip_details_t *details = NULL;
1841
1842   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1843
1844   if (!details || vam->current_sw_if_index >= vec_len (details)
1845       || !details[vam->current_sw_if_index].present)
1846     {
1847       errmsg ("ip address details arrived but not stored");
1848       errmsg ("ip_dump should be called first");
1849       return;
1850     }
1851
1852   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1853
1854 #define addresses (current_ip_details->addr)
1855
1856   vec_validate_init_empty (addresses, vec_len (addresses),
1857                            empty_ip_address_details);
1858
1859   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1860
1861   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1862   address->prefix_length = mp->prefix_length;
1863 #undef addresses
1864 }
1865
1866 static void vl_api_ip_address_details_t_handler_json
1867   (vl_api_ip_address_details_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   vat_json_node_t *node = NULL;
1871   struct in6_addr ip6;
1872   struct in_addr ip4;
1873
1874   if (VAT_JSON_ARRAY != vam->json_tree.type)
1875     {
1876       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1877       vat_json_init_array (&vam->json_tree);
1878     }
1879   node = vat_json_array_add (&vam->json_tree);
1880
1881   vat_json_init_object (node);
1882   if (vam->is_ipv6)
1883     {
1884       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1885       vat_json_object_add_ip6 (node, "ip", ip6);
1886     }
1887   else
1888     {
1889       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1890       vat_json_object_add_ip4 (node, "ip", ip4);
1891     }
1892   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1893 }
1894
1895 static void
1896 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1897 {
1898   vat_main_t *vam = &vat_main;
1899   static ip_details_t empty_ip_details = { 0 };
1900   ip_details_t *ip = NULL;
1901   u32 sw_if_index = ~0;
1902
1903   sw_if_index = ntohl (mp->sw_if_index);
1904
1905   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1906                            sw_if_index, empty_ip_details);
1907
1908   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1909                          sw_if_index);
1910
1911   ip->present = 1;
1912 }
1913
1914 static void
1915 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1916 {
1917   vat_main_t *vam = &vat_main;
1918
1919   if (VAT_JSON_ARRAY != vam->json_tree.type)
1920     {
1921       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1922       vat_json_init_array (&vam->json_tree);
1923     }
1924   vat_json_array_add_uint (&vam->json_tree,
1925                            clib_net_to_host_u32 (mp->sw_if_index));
1926 }
1927
1928 static void vl_api_map_domain_details_t_handler_json
1929   (vl_api_map_domain_details_t * mp)
1930 {
1931   vat_json_node_t *node = NULL;
1932   vat_main_t *vam = &vat_main;
1933   struct in6_addr ip6;
1934   struct in_addr ip4;
1935
1936   if (VAT_JSON_ARRAY != vam->json_tree.type)
1937     {
1938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1939       vat_json_init_array (&vam->json_tree);
1940     }
1941
1942   node = vat_json_array_add (&vam->json_tree);
1943   vat_json_init_object (node);
1944
1945   vat_json_object_add_uint (node, "domain_index",
1946                             clib_net_to_host_u32 (mp->domain_index));
1947   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1948   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1949   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1950   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1951   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1952   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1953   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1954   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1955   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1956   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1957   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1958   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1959   vat_json_object_add_uint (node, "flags", mp->flags);
1960   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1961   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1962 }
1963
1964 static void vl_api_map_domain_details_t_handler
1965   (vl_api_map_domain_details_t * mp)
1966 {
1967   vat_main_t *vam = &vat_main;
1968
1969   if (mp->is_translation)
1970     {
1971       print (vam->ofp,
1972              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1973              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1974              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1975              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1976              clib_net_to_host_u32 (mp->domain_index));
1977     }
1978   else
1979     {
1980       print (vam->ofp,
1981              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1982              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1983              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1984              format_ip6_address, mp->ip6_src,
1985              clib_net_to_host_u32 (mp->domain_index));
1986     }
1987   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1988          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1989          mp->is_translation ? "map-t" : "");
1990 }
1991
1992 static void vl_api_map_rule_details_t_handler_json
1993   (vl_api_map_rule_details_t * mp)
1994 {
1995   struct in6_addr ip6;
1996   vat_json_node_t *node = NULL;
1997   vat_main_t *vam = &vat_main;
1998
1999   if (VAT_JSON_ARRAY != vam->json_tree.type)
2000     {
2001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2002       vat_json_init_array (&vam->json_tree);
2003     }
2004
2005   node = vat_json_array_add (&vam->json_tree);
2006   vat_json_init_object (node);
2007
2008   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2009   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2010   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2011 }
2012
2013 static void
2014 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2015 {
2016   vat_main_t *vam = &vat_main;
2017   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2018          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2019 }
2020
2021 static void
2022 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2023 {
2024   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2025           "router_addr %U host_mac %U",
2026           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2027           format_ip4_address, &mp->host_address,
2028           format_ip4_address, &mp->router_address,
2029           format_ethernet_address, mp->host_mac);
2030 }
2031
2032 static void vl_api_dhcp_compl_event_t_handler_json
2033   (vl_api_dhcp_compl_event_t * mp)
2034 {
2035   /* JSON output not supported */
2036 }
2037
2038 static void
2039 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2040                               u32 counter)
2041 {
2042   vat_main_t *vam = &vat_main;
2043   static u64 default_counter = 0;
2044
2045   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2046                            NULL);
2047   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2048                            sw_if_index, default_counter);
2049   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2050 }
2051
2052 static void
2053 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2054                                 interface_counter_t counter)
2055 {
2056   vat_main_t *vam = &vat_main;
2057   static interface_counter_t default_counter = { 0, };
2058
2059   vec_validate_init_empty (vam->combined_interface_counters,
2060                            vnet_counter_type, NULL);
2061   vec_validate_init_empty (vam->combined_interface_counters
2062                            [vnet_counter_type], sw_if_index, default_counter);
2063   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2064 }
2065
2066 static void vl_api_vnet_interface_simple_counters_t_handler
2067   (vl_api_vnet_interface_simple_counters_t * mp)
2068 {
2069   /* not supported */
2070 }
2071
2072 static void vl_api_vnet_interface_combined_counters_t_handler
2073   (vl_api_vnet_interface_combined_counters_t * mp)
2074 {
2075   /* not supported */
2076 }
2077
2078 static void vl_api_vnet_interface_simple_counters_t_handler_json
2079   (vl_api_vnet_interface_simple_counters_t * mp)
2080 {
2081   u64 *v_packets;
2082   u64 packets;
2083   u32 count;
2084   u32 first_sw_if_index;
2085   int i;
2086
2087   count = ntohl (mp->count);
2088   first_sw_if_index = ntohl (mp->first_sw_if_index);
2089
2090   v_packets = (u64 *) & mp->data;
2091   for (i = 0; i < count; i++)
2092     {
2093       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2094       set_simple_interface_counter (mp->vnet_counter_type,
2095                                     first_sw_if_index + i, packets);
2096       v_packets++;
2097     }
2098 }
2099
2100 static void vl_api_vnet_interface_combined_counters_t_handler_json
2101   (vl_api_vnet_interface_combined_counters_t * mp)
2102 {
2103   interface_counter_t counter;
2104   vlib_counter_t *v;
2105   u32 first_sw_if_index;
2106   int i;
2107   u32 count;
2108
2109   count = ntohl (mp->count);
2110   first_sw_if_index = ntohl (mp->first_sw_if_index);
2111
2112   v = (vlib_counter_t *) & mp->data;
2113   for (i = 0; i < count; i++)
2114     {
2115       counter.packets =
2116         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2117       counter.bytes =
2118         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2119       set_combined_interface_counter (mp->vnet_counter_type,
2120                                       first_sw_if_index + i, counter);
2121       v++;
2122     }
2123 }
2124
2125 static u32
2126 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2127 {
2128   vat_main_t *vam = &vat_main;
2129   u32 i;
2130
2131   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2132     {
2133       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2134         {
2135           return i;
2136         }
2137     }
2138   return ~0;
2139 }
2140
2141 static u32
2142 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2143 {
2144   vat_main_t *vam = &vat_main;
2145   u32 i;
2146
2147   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2148     {
2149       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2150         {
2151           return i;
2152         }
2153     }
2154   return ~0;
2155 }
2156
2157 static void vl_api_vnet_ip4_fib_counters_t_handler
2158   (vl_api_vnet_ip4_fib_counters_t * mp)
2159 {
2160   /* not supported */
2161 }
2162
2163 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2164   (vl_api_vnet_ip4_fib_counters_t * mp)
2165 {
2166   vat_main_t *vam = &vat_main;
2167   vl_api_ip4_fib_counter_t *v;
2168   ip4_fib_counter_t *counter;
2169   struct in_addr ip4;
2170   u32 vrf_id;
2171   u32 vrf_index;
2172   u32 count;
2173   int i;
2174
2175   vrf_id = ntohl (mp->vrf_id);
2176   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2177   if (~0 == vrf_index)
2178     {
2179       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2180       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2181       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2182       vec_validate (vam->ip4_fib_counters, vrf_index);
2183       vam->ip4_fib_counters[vrf_index] = NULL;
2184     }
2185
2186   vec_free (vam->ip4_fib_counters[vrf_index]);
2187   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2188   count = ntohl (mp->count);
2189   for (i = 0; i < count; i++)
2190     {
2191       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2192       counter = &vam->ip4_fib_counters[vrf_index][i];
2193       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2194       counter->address = ip4;
2195       counter->address_length = v->address_length;
2196       counter->packets = clib_net_to_host_u64 (v->packets);
2197       counter->bytes = clib_net_to_host_u64 (v->bytes);
2198       v++;
2199     }
2200 }
2201
2202 static void vl_api_vnet_ip4_nbr_counters_t_handler
2203   (vl_api_vnet_ip4_nbr_counters_t * mp)
2204 {
2205   /* not supported */
2206 }
2207
2208 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2209   (vl_api_vnet_ip4_nbr_counters_t * mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vl_api_ip4_nbr_counter_t *v;
2213   ip4_nbr_counter_t *counter;
2214   u32 sw_if_index;
2215   u32 count;
2216   int i;
2217
2218   sw_if_index = ntohl (mp->sw_if_index);
2219   count = ntohl (mp->count);
2220   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2221
2222   if (mp->begin)
2223     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2224
2225   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2226   for (i = 0; i < count; i++)
2227     {
2228       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2229       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2230       counter->address.s_addr = v->address;
2231       counter->packets = clib_net_to_host_u64 (v->packets);
2232       counter->bytes = clib_net_to_host_u64 (v->bytes);
2233       counter->linkt = v->link_type;
2234       v++;
2235     }
2236 }
2237
2238 static void vl_api_vnet_ip6_fib_counters_t_handler
2239   (vl_api_vnet_ip6_fib_counters_t * mp)
2240 {
2241   /* not supported */
2242 }
2243
2244 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2245   (vl_api_vnet_ip6_fib_counters_t * mp)
2246 {
2247   vat_main_t *vam = &vat_main;
2248   vl_api_ip6_fib_counter_t *v;
2249   ip6_fib_counter_t *counter;
2250   struct in6_addr ip6;
2251   u32 vrf_id;
2252   u32 vrf_index;
2253   u32 count;
2254   int i;
2255
2256   vrf_id = ntohl (mp->vrf_id);
2257   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2258   if (~0 == vrf_index)
2259     {
2260       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2261       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2262       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2263       vec_validate (vam->ip6_fib_counters, vrf_index);
2264       vam->ip6_fib_counters[vrf_index] = NULL;
2265     }
2266
2267   vec_free (vam->ip6_fib_counters[vrf_index]);
2268   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2269   count = ntohl (mp->count);
2270   for (i = 0; i < count; i++)
2271     {
2272       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2273       counter = &vam->ip6_fib_counters[vrf_index][i];
2274       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2275       counter->address = ip6;
2276       counter->address_length = v->address_length;
2277       counter->packets = clib_net_to_host_u64 (v->packets);
2278       counter->bytes = clib_net_to_host_u64 (v->bytes);
2279       v++;
2280     }
2281 }
2282
2283 static void vl_api_vnet_ip6_nbr_counters_t_handler
2284   (vl_api_vnet_ip6_nbr_counters_t * mp)
2285 {
2286   /* not supported */
2287 }
2288
2289 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2290   (vl_api_vnet_ip6_nbr_counters_t * mp)
2291 {
2292   vat_main_t *vam = &vat_main;
2293   vl_api_ip6_nbr_counter_t *v;
2294   ip6_nbr_counter_t *counter;
2295   struct in6_addr ip6;
2296   u32 sw_if_index;
2297   u32 count;
2298   int i;
2299
2300   sw_if_index = ntohl (mp->sw_if_index);
2301   count = ntohl (mp->count);
2302   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2303
2304   if (mp->begin)
2305     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2306
2307   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2308   for (i = 0; i < count; i++)
2309     {
2310       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2311       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2312       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2313       counter->address = ip6;
2314       counter->packets = clib_net_to_host_u64 (v->packets);
2315       counter->bytes = clib_net_to_host_u64 (v->bytes);
2316       v++;
2317     }
2318 }
2319
2320 static void vl_api_get_first_msg_id_reply_t_handler
2321   (vl_api_get_first_msg_id_reply_t * mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   i32 retval = ntohl (mp->retval);
2325
2326   if (vam->async_mode)
2327     {
2328       vam->async_errors += (retval < 0);
2329     }
2330   else
2331     {
2332       vam->retval = retval;
2333       vam->result_ready = 1;
2334     }
2335   if (retval >= 0)
2336     {
2337       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2338     }
2339 }
2340
2341 static void vl_api_get_first_msg_id_reply_t_handler_json
2342   (vl_api_get_first_msg_id_reply_t * mp)
2343 {
2344   vat_main_t *vam = &vat_main;
2345   vat_json_node_t node;
2346
2347   vat_json_init_object (&node);
2348   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2349   vat_json_object_add_uint (&node, "first_msg_id",
2350                             (uint) ntohs (mp->first_msg_id));
2351
2352   vat_json_print (vam->ofp, &node);
2353   vat_json_free (&node);
2354
2355   vam->retval = ntohl (mp->retval);
2356   vam->result_ready = 1;
2357 }
2358
2359 static void vl_api_get_node_graph_reply_t_handler
2360   (vl_api_get_node_graph_reply_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   api_main_t *am = &api_main;
2364   i32 retval = ntohl (mp->retval);
2365   u8 *pvt_copy, *reply;
2366   void *oldheap;
2367   vlib_node_t *node;
2368   int i;
2369
2370   if (vam->async_mode)
2371     {
2372       vam->async_errors += (retval < 0);
2373     }
2374   else
2375     {
2376       vam->retval = retval;
2377       vam->result_ready = 1;
2378     }
2379
2380   /* "Should never happen..." */
2381   if (retval != 0)
2382     return;
2383
2384   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2385   pvt_copy = vec_dup (reply);
2386
2387   /* Toss the shared-memory original... */
2388   pthread_mutex_lock (&am->vlib_rp->mutex);
2389   oldheap = svm_push_data_heap (am->vlib_rp);
2390
2391   vec_free (reply);
2392
2393   svm_pop_heap (oldheap);
2394   pthread_mutex_unlock (&am->vlib_rp->mutex);
2395
2396   if (vam->graph_nodes)
2397     {
2398       hash_free (vam->graph_node_index_by_name);
2399
2400       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2401         {
2402           node = vam->graph_nodes[i];
2403           vec_free (node->name);
2404           vec_free (node->next_nodes);
2405           vec_free (node);
2406         }
2407       vec_free (vam->graph_nodes);
2408     }
2409
2410   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2411   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2412   vec_free (pvt_copy);
2413
2414   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2415     {
2416       node = vam->graph_nodes[i];
2417       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2418     }
2419 }
2420
2421 static void vl_api_get_node_graph_reply_t_handler_json
2422   (vl_api_get_node_graph_reply_t * mp)
2423 {
2424   vat_main_t *vam = &vat_main;
2425   api_main_t *am = &api_main;
2426   void *oldheap;
2427   vat_json_node_t node;
2428   u8 *reply;
2429
2430   /* $$$$ make this real? */
2431   vat_json_init_object (&node);
2432   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2433   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2434
2435   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2436
2437   /* Toss the shared-memory original... */
2438   pthread_mutex_lock (&am->vlib_rp->mutex);
2439   oldheap = svm_push_data_heap (am->vlib_rp);
2440
2441   vec_free (reply);
2442
2443   svm_pop_heap (oldheap);
2444   pthread_mutex_unlock (&am->vlib_rp->mutex);
2445
2446   vat_json_print (vam->ofp, &node);
2447   vat_json_free (&node);
2448
2449   vam->retval = ntohl (mp->retval);
2450   vam->result_ready = 1;
2451 }
2452
2453 static void
2454 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2455 {
2456   vat_main_t *vam = &vat_main;
2457   u8 *s = 0;
2458
2459   if (mp->local)
2460     {
2461       s = format (s, "%=16d%=16d%=16d",
2462                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2463     }
2464   else
2465     {
2466       s = format (s, "%=16U%=16d%=16d",
2467                   mp->is_ipv6 ? format_ip6_address :
2468                   format_ip4_address,
2469                   mp->ip_address, mp->priority, mp->weight);
2470     }
2471
2472   print (vam->ofp, "%v", s);
2473   vec_free (s);
2474 }
2475
2476 static void
2477 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2478 {
2479   vat_main_t *vam = &vat_main;
2480   vat_json_node_t *node = NULL;
2481   struct in6_addr ip6;
2482   struct in_addr ip4;
2483
2484   if (VAT_JSON_ARRAY != vam->json_tree.type)
2485     {
2486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2487       vat_json_init_array (&vam->json_tree);
2488     }
2489   node = vat_json_array_add (&vam->json_tree);
2490   vat_json_init_object (node);
2491
2492   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2493   vat_json_object_add_uint (node, "priority", mp->priority);
2494   vat_json_object_add_uint (node, "weight", mp->weight);
2495
2496   if (mp->local)
2497     vat_json_object_add_uint (node, "sw_if_index",
2498                               clib_net_to_host_u32 (mp->sw_if_index));
2499   else
2500     {
2501       if (mp->is_ipv6)
2502         {
2503           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2504           vat_json_object_add_ip6 (node, "address", ip6);
2505         }
2506       else
2507         {
2508           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2509           vat_json_object_add_ip4 (node, "address", ip4);
2510         }
2511     }
2512 }
2513
2514 static void
2515 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2516                                           mp)
2517 {
2518   vat_main_t *vam = &vat_main;
2519   u8 *ls_name = 0;
2520
2521   ls_name = format (0, "%s", mp->ls_name);
2522
2523   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2524          ls_name);
2525   vec_free (ls_name);
2526 }
2527
2528 static void
2529   vl_api_one_locator_set_details_t_handler_json
2530   (vl_api_one_locator_set_details_t * mp)
2531 {
2532   vat_main_t *vam = &vat_main;
2533   vat_json_node_t *node = 0;
2534   u8 *ls_name = 0;
2535
2536   ls_name = format (0, "%s", mp->ls_name);
2537   vec_add1 (ls_name, 0);
2538
2539   if (VAT_JSON_ARRAY != vam->json_tree.type)
2540     {
2541       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2542       vat_json_init_array (&vam->json_tree);
2543     }
2544   node = vat_json_array_add (&vam->json_tree);
2545
2546   vat_json_init_object (node);
2547   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2548   vat_json_object_add_uint (node, "ls_index",
2549                             clib_net_to_host_u32 (mp->ls_index));
2550   vec_free (ls_name);
2551 }
2552
2553 static u8 *
2554 format_lisp_flat_eid (u8 * s, va_list * args)
2555 {
2556   u32 type = va_arg (*args, u32);
2557   u8 *eid = va_arg (*args, u8 *);
2558   u32 eid_len = va_arg (*args, u32);
2559
2560   switch (type)
2561     {
2562     case 0:
2563       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2564     case 1:
2565       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2566     case 2:
2567       return format (s, "%U", format_ethernet_address, eid);
2568     }
2569   return 0;
2570 }
2571
2572 static u8 *
2573 format_lisp_eid_vat (u8 * s, va_list * args)
2574 {
2575   u32 type = va_arg (*args, u32);
2576   u8 *eid = va_arg (*args, u8 *);
2577   u32 eid_len = va_arg (*args, u32);
2578   u8 *seid = va_arg (*args, u8 *);
2579   u32 seid_len = va_arg (*args, u32);
2580   u32 is_src_dst = va_arg (*args, u32);
2581
2582   if (is_src_dst)
2583     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2584
2585   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2586
2587   return s;
2588 }
2589
2590 static void
2591 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2592 {
2593   vat_main_t *vam = &vat_main;
2594   u8 *s = 0, *eid = 0;
2595
2596   if (~0 == mp->locator_set_index)
2597     s = format (0, "action: %d", mp->action);
2598   else
2599     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2600
2601   eid = format (0, "%U", format_lisp_eid_vat,
2602                 mp->eid_type,
2603                 mp->eid,
2604                 mp->eid_prefix_len,
2605                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2606   vec_add1 (eid, 0);
2607
2608   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2609          clib_net_to_host_u32 (mp->vni),
2610          eid,
2611          mp->is_local ? "local" : "remote",
2612          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2613          clib_net_to_host_u16 (mp->key_id), mp->key);
2614
2615   vec_free (s);
2616   vec_free (eid);
2617 }
2618
2619 static void
2620 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2621                                              * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = 0;
2625   u8 *eid = 0;
2626
2627   if (VAT_JSON_ARRAY != vam->json_tree.type)
2628     {
2629       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2630       vat_json_init_array (&vam->json_tree);
2631     }
2632   node = vat_json_array_add (&vam->json_tree);
2633
2634   vat_json_init_object (node);
2635   if (~0 == mp->locator_set_index)
2636     vat_json_object_add_uint (node, "action", mp->action);
2637   else
2638     vat_json_object_add_uint (node, "locator_set_index",
2639                               clib_net_to_host_u32 (mp->locator_set_index));
2640
2641   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2642   eid = format (0, "%U", format_lisp_eid_vat,
2643                 mp->eid_type,
2644                 mp->eid,
2645                 mp->eid_prefix_len,
2646                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2647   vec_add1 (eid, 0);
2648   vat_json_object_add_string_copy (node, "eid", eid);
2649   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2650   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2651   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2652
2653   if (mp->key_id)
2654     {
2655       vat_json_object_add_uint (node, "key_id",
2656                                 clib_net_to_host_u16 (mp->key_id));
2657       vat_json_object_add_string_copy (node, "key", mp->key);
2658     }
2659   vec_free (eid);
2660 }
2661
2662 static void
2663 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2664 {
2665   vat_main_t *vam = &vat_main;
2666   u8 *seid = 0, *deid = 0;
2667   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2668
2669   deid = format (0, "%U", format_lisp_eid_vat,
2670                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2671
2672   seid = format (0, "%U", format_lisp_eid_vat,
2673                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2674
2675   vec_add1 (deid, 0);
2676   vec_add1 (seid, 0);
2677
2678   if (mp->is_ip4)
2679     format_ip_address_fcn = format_ip4_address;
2680   else
2681     format_ip_address_fcn = format_ip6_address;
2682
2683
2684   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2685          clib_net_to_host_u32 (mp->vni),
2686          seid, deid,
2687          format_ip_address_fcn, mp->lloc,
2688          format_ip_address_fcn, mp->rloc,
2689          clib_net_to_host_u32 (mp->pkt_count),
2690          clib_net_to_host_u32 (mp->bytes));
2691
2692   vec_free (deid);
2693   vec_free (seid);
2694 }
2695
2696 static void
2697 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2698 {
2699   struct in6_addr ip6;
2700   struct in_addr ip4;
2701   vat_main_t *vam = &vat_main;
2702   vat_json_node_t *node = 0;
2703   u8 *deid = 0, *seid = 0;
2704
2705   if (VAT_JSON_ARRAY != vam->json_tree.type)
2706     {
2707       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2708       vat_json_init_array (&vam->json_tree);
2709     }
2710   node = vat_json_array_add (&vam->json_tree);
2711
2712   vat_json_init_object (node);
2713   deid = format (0, "%U", format_lisp_eid_vat,
2714                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2715
2716   seid = format (0, "%U", format_lisp_eid_vat,
2717                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2718
2719   vec_add1 (deid, 0);
2720   vec_add1 (seid, 0);
2721
2722   vat_json_object_add_string_copy (node, "seid", seid);
2723   vat_json_object_add_string_copy (node, "deid", deid);
2724   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2725
2726   if (mp->is_ip4)
2727     {
2728       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2729       vat_json_object_add_ip4 (node, "lloc", ip4);
2730       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2731       vat_json_object_add_ip4 (node, "rloc", ip4);
2732     }
2733   else
2734     {
2735       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2736       vat_json_object_add_ip6 (node, "lloc", ip6);
2737       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2738       vat_json_object_add_ip6 (node, "rloc", ip6);
2739     }
2740   vat_json_object_add_uint (node, "pkt_count",
2741                             clib_net_to_host_u32 (mp->pkt_count));
2742   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2743
2744   vec_free (deid);
2745   vec_free (seid);
2746 }
2747
2748 static void
2749   vl_api_one_eid_table_map_details_t_handler
2750   (vl_api_one_eid_table_map_details_t * mp)
2751 {
2752   vat_main_t *vam = &vat_main;
2753
2754   u8 *line = format (0, "%=10d%=10d",
2755                      clib_net_to_host_u32 (mp->vni),
2756                      clib_net_to_host_u32 (mp->dp_table));
2757   print (vam->ofp, "%v", line);
2758   vec_free (line);
2759 }
2760
2761 static void
2762   vl_api_one_eid_table_map_details_t_handler_json
2763   (vl_api_one_eid_table_map_details_t * mp)
2764 {
2765   vat_main_t *vam = &vat_main;
2766   vat_json_node_t *node = NULL;
2767
2768   if (VAT_JSON_ARRAY != vam->json_tree.type)
2769     {
2770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2771       vat_json_init_array (&vam->json_tree);
2772     }
2773   node = vat_json_array_add (&vam->json_tree);
2774   vat_json_init_object (node);
2775   vat_json_object_add_uint (node, "dp_table",
2776                             clib_net_to_host_u32 (mp->dp_table));
2777   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2778 }
2779
2780 static void
2781   vl_api_one_eid_table_vni_details_t_handler
2782   (vl_api_one_eid_table_vni_details_t * mp)
2783 {
2784   vat_main_t *vam = &vat_main;
2785
2786   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2787   print (vam->ofp, "%v", line);
2788   vec_free (line);
2789 }
2790
2791 static void
2792   vl_api_one_eid_table_vni_details_t_handler_json
2793   (vl_api_one_eid_table_vni_details_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   vat_json_node_t *node = NULL;
2797
2798   if (VAT_JSON_ARRAY != vam->json_tree.type)
2799     {
2800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2801       vat_json_init_array (&vam->json_tree);
2802     }
2803   node = vat_json_array_add (&vam->json_tree);
2804   vat_json_init_object (node);
2805   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2806 }
2807
2808 static void
2809   vl_api_show_one_map_register_state_reply_t_handler
2810   (vl_api_show_one_map_register_state_reply_t * mp)
2811 {
2812   vat_main_t *vam = &vat_main;
2813   int retval = clib_net_to_host_u32 (mp->retval);
2814
2815   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2816
2817   vam->retval = retval;
2818   vam->result_ready = 1;
2819 }
2820
2821 static void
2822   vl_api_show_one_map_register_state_reply_t_handler_json
2823   (vl_api_show_one_map_register_state_reply_t * mp)
2824 {
2825   vat_main_t *vam = &vat_main;
2826   vat_json_node_t _node, *node = &_node;
2827   int retval = clib_net_to_host_u32 (mp->retval);
2828
2829   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2830
2831   vat_json_init_object (node);
2832   vat_json_object_add_string_copy (node, "state", s);
2833
2834   vat_json_print (vam->ofp, node);
2835   vat_json_free (node);
2836
2837   vam->retval = retval;
2838   vam->result_ready = 1;
2839   vec_free (s);
2840 }
2841
2842 static void
2843   vl_api_show_one_rloc_probe_state_reply_t_handler
2844   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2845 {
2846   vat_main_t *vam = &vat_main;
2847   int retval = clib_net_to_host_u32 (mp->retval);
2848
2849   if (retval)
2850     goto end;
2851
2852   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2853 end:
2854   vam->retval = retval;
2855   vam->result_ready = 1;
2856 }
2857
2858 static void
2859   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2860   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2861 {
2862   vat_main_t *vam = &vat_main;
2863   vat_json_node_t _node, *node = &_node;
2864   int retval = clib_net_to_host_u32 (mp->retval);
2865
2866   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2867   vat_json_init_object (node);
2868   vat_json_object_add_string_copy (node, "state", s);
2869
2870   vat_json_print (vam->ofp, node);
2871   vat_json_free (node);
2872
2873   vam->retval = retval;
2874   vam->result_ready = 1;
2875   vec_free (s);
2876 }
2877
2878 static void
2879   vl_api_show_one_stats_enable_disable_reply_t_handler
2880   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2881 {
2882   vat_main_t *vam = &vat_main;
2883   int retval = clib_net_to_host_u32 (mp->retval);
2884
2885   if (retval)
2886     goto end;
2887
2888   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2889 end:
2890   vam->retval = retval;
2891   vam->result_ready = 1;
2892 }
2893
2894 static void
2895   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2896   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2897 {
2898   vat_main_t *vam = &vat_main;
2899   vat_json_node_t _node, *node = &_node;
2900   int retval = clib_net_to_host_u32 (mp->retval);
2901
2902   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2903   vat_json_init_object (node);
2904   vat_json_object_add_string_copy (node, "state", s);
2905
2906   vat_json_print (vam->ofp, node);
2907   vat_json_free (node);
2908
2909   vam->retval = retval;
2910   vam->result_ready = 1;
2911   vec_free (s);
2912 }
2913
2914 static void
2915 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2916 {
2917   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2918   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2919   e->vni = clib_net_to_host_u32 (e->vni);
2920 }
2921
2922 static void
2923   gpe_fwd_entries_get_reply_t_net_to_host
2924   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2925 {
2926   u32 i;
2927
2928   mp->count = clib_net_to_host_u32 (mp->count);
2929   for (i = 0; i < mp->count; i++)
2930     {
2931       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2932     }
2933 }
2934
2935 static u8 *
2936 format_gpe_encap_mode (u8 * s, va_list * args)
2937 {
2938   u32 mode = va_arg (*args, u32);
2939
2940   switch (mode)
2941     {
2942     case 0:
2943       return format (s, "lisp");
2944     case 1:
2945       return format (s, "vxlan");
2946     }
2947   return 0;
2948 }
2949
2950 static void
2951   vl_api_gpe_get_encap_mode_reply_t_handler
2952   (vl_api_gpe_get_encap_mode_reply_t * mp)
2953 {
2954   vat_main_t *vam = &vat_main;
2955
2956   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2957   vam->retval = ntohl (mp->retval);
2958   vam->result_ready = 1;
2959 }
2960
2961 static void
2962   vl_api_gpe_get_encap_mode_reply_t_handler_json
2963   (vl_api_gpe_get_encap_mode_reply_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   vat_json_node_t node;
2967
2968   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2969   vec_add1 (encap_mode, 0);
2970
2971   vat_json_init_object (&node);
2972   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2973
2974   vec_free (encap_mode);
2975   vat_json_print (vam->ofp, &node);
2976   vat_json_free (&node);
2977
2978   vam->retval = ntohl (mp->retval);
2979   vam->result_ready = 1;
2980 }
2981
2982 static void
2983   vl_api_gpe_fwd_entry_path_details_t_handler
2984   (vl_api_gpe_fwd_entry_path_details_t * mp)
2985 {
2986   vat_main_t *vam = &vat_main;
2987   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2988
2989   if (mp->lcl_loc.is_ip4)
2990     format_ip_address_fcn = format_ip4_address;
2991   else
2992     format_ip_address_fcn = format_ip6_address;
2993
2994   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2995          format_ip_address_fcn, &mp->lcl_loc,
2996          format_ip_address_fcn, &mp->rmt_loc);
2997 }
2998
2999 static void
3000 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3001 {
3002   struct in6_addr ip6;
3003   struct in_addr ip4;
3004
3005   if (loc->is_ip4)
3006     {
3007       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3008       vat_json_object_add_ip4 (n, "address", ip4);
3009     }
3010   else
3011     {
3012       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3013       vat_json_object_add_ip6 (n, "address", ip6);
3014     }
3015   vat_json_object_add_uint (n, "weight", loc->weight);
3016 }
3017
3018 static void
3019   vl_api_gpe_fwd_entry_path_details_t_handler_json
3020   (vl_api_gpe_fwd_entry_path_details_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   vat_json_node_t *node = NULL;
3024   vat_json_node_t *loc_node;
3025
3026   if (VAT_JSON_ARRAY != vam->json_tree.type)
3027     {
3028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3029       vat_json_init_array (&vam->json_tree);
3030     }
3031   node = vat_json_array_add (&vam->json_tree);
3032   vat_json_init_object (node);
3033
3034   loc_node = vat_json_object_add (node, "local_locator");
3035   vat_json_init_object (loc_node);
3036   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3037
3038   loc_node = vat_json_object_add (node, "remote_locator");
3039   vat_json_init_object (loc_node);
3040   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3041 }
3042
3043 static void
3044   vl_api_gpe_fwd_entries_get_reply_t_handler
3045   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3046 {
3047   vat_main_t *vam = &vat_main;
3048   u32 i;
3049   int retval = clib_net_to_host_u32 (mp->retval);
3050   vl_api_gpe_fwd_entry_t *e;
3051
3052   if (retval)
3053     goto end;
3054
3055   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3056
3057   for (i = 0; i < mp->count; i++)
3058     {
3059       e = &mp->entries[i];
3060       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3061              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3062              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3063     }
3064
3065 end:
3066   vam->retval = retval;
3067   vam->result_ready = 1;
3068 }
3069
3070 static void
3071   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3072   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3073 {
3074   u8 *s = 0;
3075   vat_main_t *vam = &vat_main;
3076   vat_json_node_t *e = 0, root;
3077   u32 i;
3078   int retval = clib_net_to_host_u32 (mp->retval);
3079   vl_api_gpe_fwd_entry_t *fwd;
3080
3081   if (retval)
3082     goto end;
3083
3084   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3085   vat_json_init_array (&root);
3086
3087   for (i = 0; i < mp->count; i++)
3088     {
3089       e = vat_json_array_add (&root);
3090       fwd = &mp->entries[i];
3091
3092       vat_json_init_object (e);
3093       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3094       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3095       vat_json_object_add_int (e, "vni", fwd->vni);
3096       vat_json_object_add_int (e, "action", fwd->action);
3097
3098       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3099                   fwd->leid_prefix_len);
3100       vec_add1 (s, 0);
3101       vat_json_object_add_string_copy (e, "leid", s);
3102       vec_free (s);
3103
3104       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3105                   fwd->reid_prefix_len);
3106       vec_add1 (s, 0);
3107       vat_json_object_add_string_copy (e, "reid", s);
3108       vec_free (s);
3109     }
3110
3111   vat_json_print (vam->ofp, &root);
3112   vat_json_free (&root);
3113
3114 end:
3115   vam->retval = retval;
3116   vam->result_ready = 1;
3117 }
3118
3119 static void
3120   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3121   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   u32 i, n;
3125   int retval = clib_net_to_host_u32 (mp->retval);
3126
3127   if (retval)
3128     goto end;
3129
3130   n = clib_net_to_host_u32 (mp->count);
3131
3132   for (i = 0; i < n; i++)
3133     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3134
3135 end:
3136   vam->retval = retval;
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3142   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   vat_json_node_t root;
3146   u32 i, n;
3147   int retval = clib_net_to_host_u32 (mp->retval);
3148
3149   if (retval)
3150     goto end;
3151
3152   n = clib_net_to_host_u32 (mp->count);
3153   vat_json_init_array (&root);
3154
3155   for (i = 0; i < n; i++)
3156     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3157
3158   vat_json_print (vam->ofp, &root);
3159   vat_json_free (&root);
3160
3161 end:
3162   vam->retval = retval;
3163   vam->result_ready = 1;
3164 }
3165
3166 static void
3167   vl_api_one_adjacencies_get_reply_t_handler
3168   (vl_api_one_adjacencies_get_reply_t * mp)
3169 {
3170   vat_main_t *vam = &vat_main;
3171   u32 i, n;
3172   int retval = clib_net_to_host_u32 (mp->retval);
3173   vl_api_one_adjacency_t *a;
3174
3175   if (retval)
3176     goto end;
3177
3178   n = clib_net_to_host_u32 (mp->count);
3179
3180   for (i = 0; i < n; i++)
3181     {
3182       a = &mp->adjacencies[i];
3183       print (vam->ofp, "%U %40U",
3184              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3185              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3186     }
3187
3188 end:
3189   vam->retval = retval;
3190   vam->result_ready = 1;
3191 }
3192
3193 static void
3194   vl_api_one_adjacencies_get_reply_t_handler_json
3195   (vl_api_one_adjacencies_get_reply_t * mp)
3196 {
3197   u8 *s = 0;
3198   vat_main_t *vam = &vat_main;
3199   vat_json_node_t *e = 0, root;
3200   u32 i, n;
3201   int retval = clib_net_to_host_u32 (mp->retval);
3202   vl_api_one_adjacency_t *a;
3203
3204   if (retval)
3205     goto end;
3206
3207   n = clib_net_to_host_u32 (mp->count);
3208   vat_json_init_array (&root);
3209
3210   for (i = 0; i < n; i++)
3211     {
3212       e = vat_json_array_add (&root);
3213       a = &mp->adjacencies[i];
3214
3215       vat_json_init_object (e);
3216       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3217                   a->leid_prefix_len);
3218       vec_add1 (s, 0);
3219       vat_json_object_add_string_copy (e, "leid", s);
3220       vec_free (s);
3221
3222       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3223                   a->reid_prefix_len);
3224       vec_add1 (s, 0);
3225       vat_json_object_add_string_copy (e, "reid", s);
3226       vec_free (s);
3227     }
3228
3229   vat_json_print (vam->ofp, &root);
3230   vat_json_free (&root);
3231
3232 end:
3233   vam->retval = retval;
3234   vam->result_ready = 1;
3235 }
3236
3237 static void
3238 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3239 {
3240   vat_main_t *vam = &vat_main;
3241
3242   print (vam->ofp, "%=20U",
3243          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3244          mp->ip_address);
3245 }
3246
3247 static void
3248   vl_api_one_map_server_details_t_handler_json
3249   (vl_api_one_map_server_details_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252   vat_json_node_t *node = NULL;
3253   struct in6_addr ip6;
3254   struct in_addr ip4;
3255
3256   if (VAT_JSON_ARRAY != vam->json_tree.type)
3257     {
3258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3259       vat_json_init_array (&vam->json_tree);
3260     }
3261   node = vat_json_array_add (&vam->json_tree);
3262
3263   vat_json_init_object (node);
3264   if (mp->is_ipv6)
3265     {
3266       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3267       vat_json_object_add_ip6 (node, "map-server", ip6);
3268     }
3269   else
3270     {
3271       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3272       vat_json_object_add_ip4 (node, "map-server", ip4);
3273     }
3274 }
3275
3276 static void
3277 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3278                                            * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281
3282   print (vam->ofp, "%=20U",
3283          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3284          mp->ip_address);
3285 }
3286
3287 static void
3288   vl_api_one_map_resolver_details_t_handler_json
3289   (vl_api_one_map_resolver_details_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   vat_json_node_t *node = NULL;
3293   struct in6_addr ip6;
3294   struct in_addr ip4;
3295
3296   if (VAT_JSON_ARRAY != vam->json_tree.type)
3297     {
3298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3299       vat_json_init_array (&vam->json_tree);
3300     }
3301   node = vat_json_array_add (&vam->json_tree);
3302
3303   vat_json_init_object (node);
3304   if (mp->is_ipv6)
3305     {
3306       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3307       vat_json_object_add_ip6 (node, "map resolver", ip6);
3308     }
3309   else
3310     {
3311       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3312       vat_json_object_add_ip4 (node, "map resolver", ip4);
3313     }
3314 }
3315
3316 static void
3317 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3318 {
3319   vat_main_t *vam = &vat_main;
3320   i32 retval = ntohl (mp->retval);
3321
3322   if (0 <= retval)
3323     {
3324       print (vam->ofp, "feature: %s\ngpe: %s",
3325              mp->feature_status ? "enabled" : "disabled",
3326              mp->gpe_status ? "enabled" : "disabled");
3327     }
3328
3329   vam->retval = retval;
3330   vam->result_ready = 1;
3331 }
3332
3333 static void
3334   vl_api_show_one_status_reply_t_handler_json
3335   (vl_api_show_one_status_reply_t * mp)
3336 {
3337   vat_main_t *vam = &vat_main;
3338   vat_json_node_t node;
3339   u8 *gpe_status = NULL;
3340   u8 *feature_status = NULL;
3341
3342   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3343   feature_status = format (0, "%s",
3344                            mp->feature_status ? "enabled" : "disabled");
3345   vec_add1 (gpe_status, 0);
3346   vec_add1 (feature_status, 0);
3347
3348   vat_json_init_object (&node);
3349   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3350   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3351
3352   vec_free (gpe_status);
3353   vec_free (feature_status);
3354
3355   vat_json_print (vam->ofp, &node);
3356   vat_json_free (&node);
3357
3358   vam->retval = ntohl (mp->retval);
3359   vam->result_ready = 1;
3360 }
3361
3362 static void
3363   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3364   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3365 {
3366   vat_main_t *vam = &vat_main;
3367   i32 retval = ntohl (mp->retval);
3368
3369   if (retval >= 0)
3370     {
3371       print (vam->ofp, "%=20s", mp->locator_set_name);
3372     }
3373
3374   vam->retval = retval;
3375   vam->result_ready = 1;
3376 }
3377
3378 static void
3379   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3380   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3381 {
3382   vat_main_t *vam = &vat_main;
3383   vat_json_node_t *node = NULL;
3384
3385   if (VAT_JSON_ARRAY != vam->json_tree.type)
3386     {
3387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3388       vat_json_init_array (&vam->json_tree);
3389     }
3390   node = vat_json_array_add (&vam->json_tree);
3391
3392   vat_json_init_object (node);
3393   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3394
3395   vat_json_print (vam->ofp, node);
3396   vat_json_free (node);
3397
3398   vam->retval = ntohl (mp->retval);
3399   vam->result_ready = 1;
3400 }
3401
3402 static u8 *
3403 format_lisp_map_request_mode (u8 * s, va_list * args)
3404 {
3405   u32 mode = va_arg (*args, u32);
3406
3407   switch (mode)
3408     {
3409     case 0:
3410       return format (0, "dst-only");
3411     case 1:
3412       return format (0, "src-dst");
3413     }
3414   return 0;
3415 }
3416
3417 static void
3418   vl_api_show_one_map_request_mode_reply_t_handler
3419   (vl_api_show_one_map_request_mode_reply_t * mp)
3420 {
3421   vat_main_t *vam = &vat_main;
3422   i32 retval = ntohl (mp->retval);
3423
3424   if (0 <= retval)
3425     {
3426       u32 mode = mp->mode;
3427       print (vam->ofp, "map_request_mode: %U",
3428              format_lisp_map_request_mode, mode);
3429     }
3430
3431   vam->retval = retval;
3432   vam->result_ready = 1;
3433 }
3434
3435 static void
3436   vl_api_show_one_map_request_mode_reply_t_handler_json
3437   (vl_api_show_one_map_request_mode_reply_t * mp)
3438 {
3439   vat_main_t *vam = &vat_main;
3440   vat_json_node_t node;
3441   u8 *s = 0;
3442   u32 mode;
3443
3444   mode = mp->mode;
3445   s = format (0, "%U", format_lisp_map_request_mode, mode);
3446   vec_add1 (s, 0);
3447
3448   vat_json_init_object (&node);
3449   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3450   vat_json_print (vam->ofp, &node);
3451   vat_json_free (&node);
3452
3453   vec_free (s);
3454   vam->retval = ntohl (mp->retval);
3455   vam->result_ready = 1;
3456 }
3457
3458 static void
3459   vl_api_show_one_use_petr_reply_t_handler
3460   (vl_api_show_one_use_petr_reply_t * mp)
3461 {
3462   vat_main_t *vam = &vat_main;
3463   i32 retval = ntohl (mp->retval);
3464
3465   if (0 <= retval)
3466     {
3467       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3468       if (mp->status)
3469         {
3470           print (vam->ofp, "Proxy-ETR address; %U",
3471                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3472                  mp->address);
3473         }
3474     }
3475
3476   vam->retval = retval;
3477   vam->result_ready = 1;
3478 }
3479
3480 static void
3481   vl_api_show_one_use_petr_reply_t_handler_json
3482   (vl_api_show_one_use_petr_reply_t * mp)
3483 {
3484   vat_main_t *vam = &vat_main;
3485   vat_json_node_t node;
3486   u8 *status = 0;
3487   struct in_addr ip4;
3488   struct in6_addr ip6;
3489
3490   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3491   vec_add1 (status, 0);
3492
3493   vat_json_init_object (&node);
3494   vat_json_object_add_string_copy (&node, "status", status);
3495   if (mp->status)
3496     {
3497       if (mp->is_ip4)
3498         {
3499           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3500           vat_json_object_add_ip6 (&node, "address", ip6);
3501         }
3502       else
3503         {
3504           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3505           vat_json_object_add_ip4 (&node, "address", ip4);
3506         }
3507     }
3508
3509   vec_free (status);
3510
3511   vat_json_print (vam->ofp, &node);
3512   vat_json_free (&node);
3513
3514   vam->retval = ntohl (mp->retval);
3515   vam->result_ready = 1;
3516 }
3517
3518 static void
3519 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3520 {
3521   vat_main_t *vam = &vat_main;
3522   i32 retval = ntohl (mp->retval);
3523
3524   if (0 <= retval)
3525     {
3526       print (vam->ofp, "%-20s%-16s",
3527              mp->status ? "enabled" : "disabled",
3528              mp->status ? (char *) mp->locator_set_name : "");
3529     }
3530
3531   vam->retval = retval;
3532   vam->result_ready = 1;
3533 }
3534
3535 static void
3536 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3537 {
3538   vat_main_t *vam = &vat_main;
3539   vat_json_node_t node;
3540   u8 *status = 0;
3541
3542   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3543   vec_add1 (status, 0);
3544
3545   vat_json_init_object (&node);
3546   vat_json_object_add_string_copy (&node, "status", status);
3547   if (mp->status)
3548     {
3549       vat_json_object_add_string_copy (&node, "locator_set",
3550                                        mp->locator_set_name);
3551     }
3552
3553   vec_free (status);
3554
3555   vat_json_print (vam->ofp, &node);
3556   vat_json_free (&node);
3557
3558   vam->retval = ntohl (mp->retval);
3559   vam->result_ready = 1;
3560 }
3561
3562 static u8 *
3563 format_policer_type (u8 * s, va_list * va)
3564 {
3565   u32 i = va_arg (*va, u32);
3566
3567   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3568     s = format (s, "1r2c");
3569   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3570     s = format (s, "1r3c");
3571   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3572     s = format (s, "2r3c-2698");
3573   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3574     s = format (s, "2r3c-4115");
3575   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3576     s = format (s, "2r3c-mef5cf1");
3577   else
3578     s = format (s, "ILLEGAL");
3579   return s;
3580 }
3581
3582 static u8 *
3583 format_policer_rate_type (u8 * s, va_list * va)
3584 {
3585   u32 i = va_arg (*va, u32);
3586
3587   if (i == SSE2_QOS_RATE_KBPS)
3588     s = format (s, "kbps");
3589   else if (i == SSE2_QOS_RATE_PPS)
3590     s = format (s, "pps");
3591   else
3592     s = format (s, "ILLEGAL");
3593   return s;
3594 }
3595
3596 static u8 *
3597 format_policer_round_type (u8 * s, va_list * va)
3598 {
3599   u32 i = va_arg (*va, u32);
3600
3601   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3602     s = format (s, "closest");
3603   else if (i == SSE2_QOS_ROUND_TO_UP)
3604     s = format (s, "up");
3605   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3606     s = format (s, "down");
3607   else
3608     s = format (s, "ILLEGAL");
3609   return s;
3610 }
3611
3612 static u8 *
3613 format_policer_action_type (u8 * s, va_list * va)
3614 {
3615   u32 i = va_arg (*va, u32);
3616
3617   if (i == SSE2_QOS_ACTION_DROP)
3618     s = format (s, "drop");
3619   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3620     s = format (s, "transmit");
3621   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3622     s = format (s, "mark-and-transmit");
3623   else
3624     s = format (s, "ILLEGAL");
3625   return s;
3626 }
3627
3628 static u8 *
3629 format_dscp (u8 * s, va_list * va)
3630 {
3631   u32 i = va_arg (*va, u32);
3632   char *t = 0;
3633
3634   switch (i)
3635     {
3636 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3637       foreach_vnet_dscp
3638 #undef _
3639     default:
3640       return format (s, "ILLEGAL");
3641     }
3642   s = format (s, "%s", t);
3643   return s;
3644 }
3645
3646 static void
3647 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3648 {
3649   vat_main_t *vam = &vat_main;
3650   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3651
3652   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3653     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3654   else
3655     conform_dscp_str = format (0, "");
3656
3657   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3658     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3659   else
3660     exceed_dscp_str = format (0, "");
3661
3662   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3663     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3664   else
3665     violate_dscp_str = format (0, "");
3666
3667   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3668          "rate type %U, round type %U, %s rate, %s color-aware, "
3669          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3670          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3671          "conform action %U%s, exceed action %U%s, violate action %U%s",
3672          mp->name,
3673          format_policer_type, mp->type,
3674          ntohl (mp->cir),
3675          ntohl (mp->eir),
3676          clib_net_to_host_u64 (mp->cb),
3677          clib_net_to_host_u64 (mp->eb),
3678          format_policer_rate_type, mp->rate_type,
3679          format_policer_round_type, mp->round_type,
3680          mp->single_rate ? "single" : "dual",
3681          mp->color_aware ? "is" : "not",
3682          ntohl (mp->cir_tokens_per_period),
3683          ntohl (mp->pir_tokens_per_period),
3684          ntohl (mp->scale),
3685          ntohl (mp->current_limit),
3686          ntohl (mp->current_bucket),
3687          ntohl (mp->extended_limit),
3688          ntohl (mp->extended_bucket),
3689          clib_net_to_host_u64 (mp->last_update_time),
3690          format_policer_action_type, mp->conform_action_type,
3691          conform_dscp_str,
3692          format_policer_action_type, mp->exceed_action_type,
3693          exceed_dscp_str,
3694          format_policer_action_type, mp->violate_action_type,
3695          violate_dscp_str);
3696
3697   vec_free (conform_dscp_str);
3698   vec_free (exceed_dscp_str);
3699   vec_free (violate_dscp_str);
3700 }
3701
3702 static void vl_api_policer_details_t_handler_json
3703   (vl_api_policer_details_t * mp)
3704 {
3705   vat_main_t *vam = &vat_main;
3706   vat_json_node_t *node;
3707   u8 *rate_type_str, *round_type_str, *type_str;
3708   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3709
3710   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3711   round_type_str =
3712     format (0, "%U", format_policer_round_type, mp->round_type);
3713   type_str = format (0, "%U", format_policer_type, mp->type);
3714   conform_action_str = format (0, "%U", format_policer_action_type,
3715                                mp->conform_action_type);
3716   exceed_action_str = format (0, "%U", format_policer_action_type,
3717                               mp->exceed_action_type);
3718   violate_action_str = format (0, "%U", format_policer_action_type,
3719                                mp->violate_action_type);
3720
3721   if (VAT_JSON_ARRAY != vam->json_tree.type)
3722     {
3723       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3724       vat_json_init_array (&vam->json_tree);
3725     }
3726   node = vat_json_array_add (&vam->json_tree);
3727
3728   vat_json_init_object (node);
3729   vat_json_object_add_string_copy (node, "name", mp->name);
3730   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3731   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3732   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3733   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3734   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3735   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3736   vat_json_object_add_string_copy (node, "type", type_str);
3737   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3738   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3739   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3740   vat_json_object_add_uint (node, "cir_tokens_per_period",
3741                             ntohl (mp->cir_tokens_per_period));
3742   vat_json_object_add_uint (node, "eir_tokens_per_period",
3743                             ntohl (mp->pir_tokens_per_period));
3744   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3745   vat_json_object_add_uint (node, "current_bucket",
3746                             ntohl (mp->current_bucket));
3747   vat_json_object_add_uint (node, "extended_limit",
3748                             ntohl (mp->extended_limit));
3749   vat_json_object_add_uint (node, "extended_bucket",
3750                             ntohl (mp->extended_bucket));
3751   vat_json_object_add_uint (node, "last_update_time",
3752                             ntohl (mp->last_update_time));
3753   vat_json_object_add_string_copy (node, "conform_action",
3754                                    conform_action_str);
3755   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3756     {
3757       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3758       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3759       vec_free (dscp_str);
3760     }
3761   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3762   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3763     {
3764       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3765       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3766       vec_free (dscp_str);
3767     }
3768   vat_json_object_add_string_copy (node, "violate_action",
3769                                    violate_action_str);
3770   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3771     {
3772       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3773       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3774       vec_free (dscp_str);
3775     }
3776
3777   vec_free (rate_type_str);
3778   vec_free (round_type_str);
3779   vec_free (type_str);
3780   vec_free (conform_action_str);
3781   vec_free (exceed_action_str);
3782   vec_free (violate_action_str);
3783 }
3784
3785 static void
3786 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3787                                            mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   int i, count = ntohl (mp->count);
3791
3792   if (count > 0)
3793     print (vam->ofp, "classify table ids (%d) : ", count);
3794   for (i = 0; i < count; i++)
3795     {
3796       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3797       print (vam->ofp, (i < count - 1) ? "," : "");
3798     }
3799   vam->retval = ntohl (mp->retval);
3800   vam->result_ready = 1;
3801 }
3802
3803 static void
3804   vl_api_classify_table_ids_reply_t_handler_json
3805   (vl_api_classify_table_ids_reply_t * mp)
3806 {
3807   vat_main_t *vam = &vat_main;
3808   int i, count = ntohl (mp->count);
3809
3810   if (count > 0)
3811     {
3812       vat_json_node_t node;
3813
3814       vat_json_init_object (&node);
3815       for (i = 0; i < count; i++)
3816         {
3817           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3818         }
3819       vat_json_print (vam->ofp, &node);
3820       vat_json_free (&node);
3821     }
3822   vam->retval = ntohl (mp->retval);
3823   vam->result_ready = 1;
3824 }
3825
3826 static void
3827   vl_api_classify_table_by_interface_reply_t_handler
3828   (vl_api_classify_table_by_interface_reply_t * mp)
3829 {
3830   vat_main_t *vam = &vat_main;
3831   u32 table_id;
3832
3833   table_id = ntohl (mp->l2_table_id);
3834   if (table_id != ~0)
3835     print (vam->ofp, "l2 table id : %d", table_id);
3836   else
3837     print (vam->ofp, "l2 table id : No input ACL tables configured");
3838   table_id = ntohl (mp->ip4_table_id);
3839   if (table_id != ~0)
3840     print (vam->ofp, "ip4 table id : %d", table_id);
3841   else
3842     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3843   table_id = ntohl (mp->ip6_table_id);
3844   if (table_id != ~0)
3845     print (vam->ofp, "ip6 table id : %d", table_id);
3846   else
3847     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3848   vam->retval = ntohl (mp->retval);
3849   vam->result_ready = 1;
3850 }
3851
3852 static void
3853   vl_api_classify_table_by_interface_reply_t_handler_json
3854   (vl_api_classify_table_by_interface_reply_t * mp)
3855 {
3856   vat_main_t *vam = &vat_main;
3857   vat_json_node_t node;
3858
3859   vat_json_init_object (&node);
3860
3861   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3862   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3863   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3864
3865   vat_json_print (vam->ofp, &node);
3866   vat_json_free (&node);
3867
3868   vam->retval = ntohl (mp->retval);
3869   vam->result_ready = 1;
3870 }
3871
3872 static void vl_api_policer_add_del_reply_t_handler
3873   (vl_api_policer_add_del_reply_t * mp)
3874 {
3875   vat_main_t *vam = &vat_main;
3876   i32 retval = ntohl (mp->retval);
3877   if (vam->async_mode)
3878     {
3879       vam->async_errors += (retval < 0);
3880     }
3881   else
3882     {
3883       vam->retval = retval;
3884       vam->result_ready = 1;
3885       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3886         /*
3887          * Note: this is just barely thread-safe, depends on
3888          * the main thread spinning waiting for an answer...
3889          */
3890         errmsg ("policer index %d", ntohl (mp->policer_index));
3891     }
3892 }
3893
3894 static void vl_api_policer_add_del_reply_t_handler_json
3895   (vl_api_policer_add_del_reply_t * mp)
3896 {
3897   vat_main_t *vam = &vat_main;
3898   vat_json_node_t node;
3899
3900   vat_json_init_object (&node);
3901   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3902   vat_json_object_add_uint (&node, "policer_index",
3903                             ntohl (mp->policer_index));
3904
3905   vat_json_print (vam->ofp, &node);
3906   vat_json_free (&node);
3907
3908   vam->retval = ntohl (mp->retval);
3909   vam->result_ready = 1;
3910 }
3911
3912 /* Format hex dump. */
3913 u8 *
3914 format_hex_bytes (u8 * s, va_list * va)
3915 {
3916   u8 *bytes = va_arg (*va, u8 *);
3917   int n_bytes = va_arg (*va, int);
3918   uword i;
3919
3920   /* Print short or long form depending on byte count. */
3921   uword short_form = n_bytes <= 32;
3922   uword indent = format_get_indent (s);
3923
3924   if (n_bytes == 0)
3925     return s;
3926
3927   for (i = 0; i < n_bytes; i++)
3928     {
3929       if (!short_form && (i % 32) == 0)
3930         s = format (s, "%08x: ", i);
3931       s = format (s, "%02x", bytes[i]);
3932       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3933         s = format (s, "\n%U", format_white_space, indent);
3934     }
3935
3936   return s;
3937 }
3938
3939 static void
3940 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3941                                             * mp)
3942 {
3943   vat_main_t *vam = &vat_main;
3944   i32 retval = ntohl (mp->retval);
3945   if (retval == 0)
3946     {
3947       print (vam->ofp, "classify table info :");
3948       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3949              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3950              ntohl (mp->miss_next_index));
3951       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3952              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3953              ntohl (mp->match_n_vectors));
3954       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3955              ntohl (mp->mask_length));
3956     }
3957   vam->retval = retval;
3958   vam->result_ready = 1;
3959 }
3960
3961 static void
3962   vl_api_classify_table_info_reply_t_handler_json
3963   (vl_api_classify_table_info_reply_t * mp)
3964 {
3965   vat_main_t *vam = &vat_main;
3966   vat_json_node_t node;
3967
3968   i32 retval = ntohl (mp->retval);
3969   if (retval == 0)
3970     {
3971       vat_json_init_object (&node);
3972
3973       vat_json_object_add_int (&node, "sessions",
3974                                ntohl (mp->active_sessions));
3975       vat_json_object_add_int (&node, "nexttbl",
3976                                ntohl (mp->next_table_index));
3977       vat_json_object_add_int (&node, "nextnode",
3978                                ntohl (mp->miss_next_index));
3979       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3980       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3981       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3982       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3983                       ntohl (mp->mask_length), 0);
3984       vat_json_object_add_string_copy (&node, "mask", s);
3985
3986       vat_json_print (vam->ofp, &node);
3987       vat_json_free (&node);
3988     }
3989   vam->retval = ntohl (mp->retval);
3990   vam->result_ready = 1;
3991 }
3992
3993 static void
3994 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3995                                            mp)
3996 {
3997   vat_main_t *vam = &vat_main;
3998
3999   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4000          ntohl (mp->hit_next_index), ntohl (mp->advance),
4001          ntohl (mp->opaque_index));
4002   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4003          ntohl (mp->match_length));
4004 }
4005
4006 static void
4007   vl_api_classify_session_details_t_handler_json
4008   (vl_api_classify_session_details_t * mp)
4009 {
4010   vat_main_t *vam = &vat_main;
4011   vat_json_node_t *node = NULL;
4012
4013   if (VAT_JSON_ARRAY != vam->json_tree.type)
4014     {
4015       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4016       vat_json_init_array (&vam->json_tree);
4017     }
4018   node = vat_json_array_add (&vam->json_tree);
4019
4020   vat_json_init_object (node);
4021   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4022   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4023   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4024   u8 *s =
4025     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4026             0);
4027   vat_json_object_add_string_copy (node, "match", s);
4028 }
4029
4030 static void vl_api_pg_create_interface_reply_t_handler
4031   (vl_api_pg_create_interface_reply_t * mp)
4032 {
4033   vat_main_t *vam = &vat_main;
4034
4035   vam->retval = ntohl (mp->retval);
4036   vam->result_ready = 1;
4037 }
4038
4039 static void vl_api_pg_create_interface_reply_t_handler_json
4040   (vl_api_pg_create_interface_reply_t * mp)
4041 {
4042   vat_main_t *vam = &vat_main;
4043   vat_json_node_t node;
4044
4045   i32 retval = ntohl (mp->retval);
4046   if (retval == 0)
4047     {
4048       vat_json_init_object (&node);
4049
4050       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4051
4052       vat_json_print (vam->ofp, &node);
4053       vat_json_free (&node);
4054     }
4055   vam->retval = ntohl (mp->retval);
4056   vam->result_ready = 1;
4057 }
4058
4059 static void vl_api_policer_classify_details_t_handler
4060   (vl_api_policer_classify_details_t * mp)
4061 {
4062   vat_main_t *vam = &vat_main;
4063
4064   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4065          ntohl (mp->table_index));
4066 }
4067
4068 static void vl_api_policer_classify_details_t_handler_json
4069   (vl_api_policer_classify_details_t * mp)
4070 {
4071   vat_main_t *vam = &vat_main;
4072   vat_json_node_t *node;
4073
4074   if (VAT_JSON_ARRAY != vam->json_tree.type)
4075     {
4076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4077       vat_json_init_array (&vam->json_tree);
4078     }
4079   node = vat_json_array_add (&vam->json_tree);
4080
4081   vat_json_init_object (node);
4082   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4083   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4084 }
4085
4086 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4087   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4088 {
4089   vat_main_t *vam = &vat_main;
4090   i32 retval = ntohl (mp->retval);
4091   if (vam->async_mode)
4092     {
4093       vam->async_errors += (retval < 0);
4094     }
4095   else
4096     {
4097       vam->retval = retval;
4098       vam->sw_if_index = ntohl (mp->sw_if_index);
4099       vam->result_ready = 1;
4100     }
4101 }
4102
4103 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4104   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4105 {
4106   vat_main_t *vam = &vat_main;
4107   vat_json_node_t node;
4108
4109   vat_json_init_object (&node);
4110   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4111   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4112
4113   vat_json_print (vam->ofp, &node);
4114   vat_json_free (&node);
4115
4116   vam->retval = ntohl (mp->retval);
4117   vam->result_ready = 1;
4118 }
4119
4120 static void vl_api_flow_classify_details_t_handler
4121   (vl_api_flow_classify_details_t * mp)
4122 {
4123   vat_main_t *vam = &vat_main;
4124
4125   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4126          ntohl (mp->table_index));
4127 }
4128
4129 static void vl_api_flow_classify_details_t_handler_json
4130   (vl_api_flow_classify_details_t * mp)
4131 {
4132   vat_main_t *vam = &vat_main;
4133   vat_json_node_t *node;
4134
4135   if (VAT_JSON_ARRAY != vam->json_tree.type)
4136     {
4137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4138       vat_json_init_array (&vam->json_tree);
4139     }
4140   node = vat_json_array_add (&vam->json_tree);
4141
4142   vat_json_init_object (node);
4143   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4144   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4145 }
4146
4147 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4148 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4149 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4150 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4151 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4152 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4153 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4154 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4155 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4156 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4157 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4158 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4159 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4160 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4161
4162 /*
4163  * Generate boilerplate reply handlers, which
4164  * dig the return value out of the xxx_reply_t API message,
4165  * stick it into vam->retval, and set vam->result_ready
4166  *
4167  * Could also do this by pointing N message decode slots at
4168  * a single function, but that could break in subtle ways.
4169  */
4170
4171 #define foreach_standard_reply_retval_handler           \
4172 _(sw_interface_set_flags_reply)                         \
4173 _(sw_interface_add_del_address_reply)                   \
4174 _(sw_interface_set_table_reply)                         \
4175 _(sw_interface_set_mpls_enable_reply)                   \
4176 _(sw_interface_set_vpath_reply)                         \
4177 _(sw_interface_set_vxlan_bypass_reply)                  \
4178 _(sw_interface_set_l2_bridge_reply)                     \
4179 _(bridge_domain_add_del_reply)                          \
4180 _(sw_interface_set_l2_xconnect_reply)                   \
4181 _(l2fib_add_del_reply)                                  \
4182 _(l2fib_flush_int_reply)                                \
4183 _(l2fib_flush_bd_reply)                                 \
4184 _(ip_add_del_route_reply)                               \
4185 _(ip_mroute_add_del_reply)                              \
4186 _(mpls_route_add_del_reply)                             \
4187 _(mpls_ip_bind_unbind_reply)                            \
4188 _(proxy_arp_add_del_reply)                              \
4189 _(proxy_arp_intfc_enable_disable_reply)                 \
4190 _(sw_interface_set_unnumbered_reply)                    \
4191 _(ip_neighbor_add_del_reply)                            \
4192 _(reset_vrf_reply)                                      \
4193 _(oam_add_del_reply)                                    \
4194 _(reset_fib_reply)                                      \
4195 _(dhcp_proxy_config_reply)                              \
4196 _(dhcp_proxy_set_vss_reply)                             \
4197 _(dhcp_client_config_reply)                             \
4198 _(set_ip_flow_hash_reply)                               \
4199 _(sw_interface_ip6_enable_disable_reply)                \
4200 _(sw_interface_ip6_set_link_local_address_reply)        \
4201 _(ip6nd_proxy_add_del_reply)                            \
4202 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4203 _(sw_interface_ip6nd_ra_config_reply)                   \
4204 _(set_arp_neighbor_limit_reply)                         \
4205 _(l2_patch_add_del_reply)                               \
4206 _(sr_policy_add_reply)                                  \
4207 _(sr_policy_mod_reply)                                  \
4208 _(sr_policy_del_reply)                                  \
4209 _(sr_localsid_add_del_reply)                            \
4210 _(sr_steering_add_del_reply)                            \
4211 _(classify_add_del_session_reply)                       \
4212 _(classify_set_interface_ip_table_reply)                \
4213 _(classify_set_interface_l2_tables_reply)               \
4214 _(l2tpv3_set_tunnel_cookies_reply)                      \
4215 _(l2tpv3_interface_enable_disable_reply)                \
4216 _(l2tpv3_set_lookup_key_reply)                          \
4217 _(l2_fib_clear_table_reply)                             \
4218 _(l2_interface_efp_filter_reply)                        \
4219 _(l2_interface_vlan_tag_rewrite_reply)                  \
4220 _(modify_vhost_user_if_reply)                           \
4221 _(delete_vhost_user_if_reply)                           \
4222 _(want_ip4_arp_events_reply)                            \
4223 _(want_ip6_nd_events_reply)                             \
4224 _(input_acl_set_interface_reply)                        \
4225 _(ipsec_spd_add_del_reply)                              \
4226 _(ipsec_interface_add_del_spd_reply)                    \
4227 _(ipsec_spd_add_del_entry_reply)                        \
4228 _(ipsec_sad_add_del_entry_reply)                        \
4229 _(ipsec_sa_set_key_reply)                               \
4230 _(ipsec_tunnel_if_add_del_reply)                        \
4231 _(ikev2_profile_add_del_reply)                          \
4232 _(ikev2_profile_set_auth_reply)                         \
4233 _(ikev2_profile_set_id_reply)                           \
4234 _(ikev2_profile_set_ts_reply)                           \
4235 _(ikev2_set_local_key_reply)                            \
4236 _(ikev2_set_responder_reply)                            \
4237 _(ikev2_set_ike_transforms_reply)                       \
4238 _(ikev2_set_esp_transforms_reply)                       \
4239 _(ikev2_set_sa_lifetime_reply)                          \
4240 _(ikev2_initiate_sa_init_reply)                         \
4241 _(ikev2_initiate_del_ike_sa_reply)                      \
4242 _(ikev2_initiate_del_child_sa_reply)                    \
4243 _(ikev2_initiate_rekey_child_sa_reply)                  \
4244 _(delete_loopback_reply)                                \
4245 _(bd_ip_mac_add_del_reply)                              \
4246 _(map_del_domain_reply)                                 \
4247 _(map_add_del_rule_reply)                               \
4248 _(want_interface_events_reply)                          \
4249 _(want_stats_reply)                                     \
4250 _(cop_interface_enable_disable_reply)                   \
4251 _(cop_whitelist_enable_disable_reply)                   \
4252 _(sw_interface_clear_stats_reply)                       \
4253 _(ioam_enable_reply)                              \
4254 _(ioam_disable_reply)                              \
4255 _(one_add_del_locator_reply)                            \
4256 _(one_add_del_local_eid_reply)                          \
4257 _(one_add_del_remote_mapping_reply)                     \
4258 _(one_add_del_adjacency_reply)                          \
4259 _(one_add_del_map_resolver_reply)                       \
4260 _(one_add_del_map_server_reply)                         \
4261 _(one_enable_disable_reply)                             \
4262 _(one_rloc_probe_enable_disable_reply)                  \
4263 _(one_map_register_enable_disable_reply)                \
4264 _(one_pitr_set_locator_set_reply)                       \
4265 _(one_map_request_mode_reply)                           \
4266 _(one_add_del_map_request_itr_rlocs_reply)              \
4267 _(one_eid_table_add_del_map_reply)                      \
4268 _(one_use_petr_reply)                                   \
4269 _(one_stats_enable_disable_reply)                       \
4270 _(one_stats_flush_reply)                                \
4271 _(gpe_add_del_fwd_entry_reply)                          \
4272 _(gpe_enable_disable_reply)                             \
4273 _(gpe_set_encap_mode_reply)                             \
4274 _(gpe_add_del_iface_reply)                              \
4275 _(vxlan_gpe_add_del_tunnel_reply)                       \
4276 _(af_packet_delete_reply)                               \
4277 _(policer_classify_set_interface_reply)                 \
4278 _(netmap_create_reply)                                  \
4279 _(netmap_delete_reply)                                  \
4280 _(set_ipfix_exporter_reply)                             \
4281 _(set_ipfix_classify_stream_reply)                      \
4282 _(ipfix_classify_table_add_del_reply)                   \
4283 _(flow_classify_set_interface_reply)                    \
4284 _(sw_interface_span_enable_disable_reply)               \
4285 _(pg_capture_reply)                                     \
4286 _(pg_enable_disable_reply)                              \
4287 _(ip_source_and_port_range_check_add_del_reply)         \
4288 _(ip_source_and_port_range_check_interface_add_del_reply)\
4289 _(delete_subif_reply)                                   \
4290 _(l2_interface_pbb_tag_rewrite_reply)                   \
4291 _(punt_reply)                                           \
4292 _(feature_enable_disable_reply)                         \
4293 _(sw_interface_tag_add_del_reply)                       \
4294 _(sw_interface_set_mtu_reply)
4295
4296 #define _(n)                                    \
4297     static void vl_api_##n##_t_handler          \
4298     (vl_api_##n##_t * mp)                       \
4299     {                                           \
4300         vat_main_t * vam = &vat_main;           \
4301         i32 retval = ntohl(mp->retval);         \
4302         if (vam->async_mode) {                  \
4303             vam->async_errors += (retval < 0);  \
4304         } else {                                \
4305             vam->retval = retval;               \
4306             vam->result_ready = 1;              \
4307         }                                       \
4308     }
4309 foreach_standard_reply_retval_handler;
4310 #undef _
4311
4312 #define _(n)                                    \
4313     static void vl_api_##n##_t_handler_json     \
4314     (vl_api_##n##_t * mp)                       \
4315     {                                           \
4316         vat_main_t * vam = &vat_main;           \
4317         vat_json_node_t node;                   \
4318         vat_json_init_object(&node);            \
4319         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4320         vat_json_print(vam->ofp, &node);        \
4321         vam->retval = ntohl(mp->retval);        \
4322         vam->result_ready = 1;                  \
4323     }
4324 foreach_standard_reply_retval_handler;
4325 #undef _
4326
4327 /*
4328  * Table of message reply handlers, must include boilerplate handlers
4329  * we just generated
4330  */
4331
4332 #define foreach_vpe_api_reply_msg                                       \
4333 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4334 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4335 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4336 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4337 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4338 _(CLI_REPLY, cli_reply)                                                 \
4339 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4340 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4341   sw_interface_add_del_address_reply)                                   \
4342 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4343 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4344 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4345 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4346 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4347   sw_interface_set_l2_xconnect_reply)                                   \
4348 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4349   sw_interface_set_l2_bridge_reply)                                     \
4350 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4351 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4352 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4353 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4354 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4355 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4356 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4357 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4358 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4359 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4360 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4361 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4362 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4363 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4364 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4365 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4366 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4367 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4368   proxy_arp_intfc_enable_disable_reply)                                 \
4369 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4370 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4371   sw_interface_set_unnumbered_reply)                                    \
4372 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4373 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4374 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4375 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4376 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4377 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4378 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4379 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4380 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4381 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4382 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4383 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4384   sw_interface_ip6_enable_disable_reply)                                \
4385 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4386   sw_interface_ip6_set_link_local_address_reply)                        \
4387 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4388 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4389 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4390   sw_interface_ip6nd_ra_prefix_reply)                                   \
4391 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4392   sw_interface_ip6nd_ra_config_reply)                                   \
4393 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4394 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4395 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4396 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4397 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4398 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4399 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4400 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4401 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4402 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4403 classify_set_interface_ip_table_reply)                                  \
4404 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4405   classify_set_interface_l2_tables_reply)                               \
4406 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4407 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4408 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4409 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4410 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4411   l2tpv3_interface_enable_disable_reply)                                \
4412 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4413 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4414 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4415 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4416 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4417 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4418 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4419 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4420 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4421 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4422 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4423 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4424 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4425 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4426 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4427 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4428 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4429 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4430 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4431 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4432 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4433 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4434 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4435 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4436 _(IP_DETAILS, ip_details)                                               \
4437 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4438 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4439 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4440 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4441 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4442 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4443 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4444 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4445 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4446 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4447 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4448 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4449 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4450 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4451 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4452 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4453 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4454 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4455 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4456 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4457 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4458 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4459 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4460 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4461 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4462 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4463 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4464 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4465 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4466 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4467 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4468 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4469 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4470 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4471 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4472 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4473 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4474 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4475 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4476 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4477 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4478 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4479 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4480 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4481 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4482   one_map_register_enable_disable_reply)                                \
4483 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4484   one_rloc_probe_enable_disable_reply)                                  \
4485 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4486 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4487 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4488 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4489 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4490 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4491 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4492 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4493 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4494 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4495 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4496 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4497 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4498 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4499 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4500 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4501   show_one_stats_enable_disable_reply)                                  \
4502 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4503 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4504 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4505 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4506 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4507 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4508 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4509 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4510   gpe_fwd_entry_path_details)                                           \
4511 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4512 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4513   one_add_del_map_request_itr_rlocs_reply)                              \
4514 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4515   one_get_map_request_itr_rlocs_reply)                                  \
4516 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4517 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4518 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4519 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4520 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4521   show_one_map_register_state_reply)                                    \
4522 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4523 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4524 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4525 _(POLICER_DETAILS, policer_details)                                     \
4526 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4527 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4528 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4529 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4530 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4531 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4532 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4533 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4534 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4535 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4536 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4537 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4538 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4539 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4540 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4541 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4542 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4543 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4544 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4545 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4546 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4547 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4548 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4549 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4550 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4551  ip_source_and_port_range_check_add_del_reply)                          \
4552 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4553  ip_source_and_port_range_check_interface_add_del_reply)                \
4554 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4555 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4556 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4557 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4558 _(PUNT_REPLY, punt_reply)                                               \
4559 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4560 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4561 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4562 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4563 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4564 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4565 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4566 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4567
4568 #define foreach_standalone_reply_msg                                    \
4569 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4570 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4571 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4572 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4573 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4574 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4575 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4576
4577 typedef struct
4578 {
4579   u8 *name;
4580   u32 value;
4581 } name_sort_t;
4582
4583
4584 #define STR_VTR_OP_CASE(op)     \
4585     case L2_VTR_ ## op:         \
4586         return "" # op;
4587
4588 static const char *
4589 str_vtr_op (u32 vtr_op)
4590 {
4591   switch (vtr_op)
4592     {
4593       STR_VTR_OP_CASE (DISABLED);
4594       STR_VTR_OP_CASE (PUSH_1);
4595       STR_VTR_OP_CASE (PUSH_2);
4596       STR_VTR_OP_CASE (POP_1);
4597       STR_VTR_OP_CASE (POP_2);
4598       STR_VTR_OP_CASE (TRANSLATE_1_1);
4599       STR_VTR_OP_CASE (TRANSLATE_1_2);
4600       STR_VTR_OP_CASE (TRANSLATE_2_1);
4601       STR_VTR_OP_CASE (TRANSLATE_2_2);
4602     }
4603
4604   return "UNKNOWN";
4605 }
4606
4607 static int
4608 dump_sub_interface_table (vat_main_t * vam)
4609 {
4610   const sw_interface_subif_t *sub = NULL;
4611
4612   if (vam->json_output)
4613     {
4614       clib_warning
4615         ("JSON output supported only for VPE API calls and dump_stats_table");
4616       return -99;
4617     }
4618
4619   print (vam->ofp,
4620          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4621          "Interface", "sw_if_index",
4622          "sub id", "dot1ad", "tags", "outer id",
4623          "inner id", "exact", "default", "outer any", "inner any");
4624
4625   vec_foreach (sub, vam->sw_if_subif_table)
4626   {
4627     print (vam->ofp,
4628            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4629            sub->interface_name,
4630            sub->sw_if_index,
4631            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4632            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4633            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4634            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4635     if (sub->vtr_op != L2_VTR_DISABLED)
4636       {
4637         print (vam->ofp,
4638                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4639                "tag1: %d tag2: %d ]",
4640                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4641                sub->vtr_tag1, sub->vtr_tag2);
4642       }
4643   }
4644
4645   return 0;
4646 }
4647
4648 static int
4649 name_sort_cmp (void *a1, void *a2)
4650 {
4651   name_sort_t *n1 = a1;
4652   name_sort_t *n2 = a2;
4653
4654   return strcmp ((char *) n1->name, (char *) n2->name);
4655 }
4656
4657 static int
4658 dump_interface_table (vat_main_t * vam)
4659 {
4660   hash_pair_t *p;
4661   name_sort_t *nses = 0, *ns;
4662
4663   if (vam->json_output)
4664     {
4665       clib_warning
4666         ("JSON output supported only for VPE API calls and dump_stats_table");
4667       return -99;
4668     }
4669
4670   /* *INDENT-OFF* */
4671   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4672   ({
4673     vec_add2 (nses, ns, 1);
4674     ns->name = (u8 *)(p->key);
4675     ns->value = (u32) p->value[0];
4676   }));
4677   /* *INDENT-ON* */
4678
4679   vec_sort_with_function (nses, name_sort_cmp);
4680
4681   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4682   vec_foreach (ns, nses)
4683   {
4684     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4685   }
4686   vec_free (nses);
4687   return 0;
4688 }
4689
4690 static int
4691 dump_ip_table (vat_main_t * vam, int is_ipv6)
4692 {
4693   const ip_details_t *det = NULL;
4694   const ip_address_details_t *address = NULL;
4695   u32 i = ~0;
4696
4697   print (vam->ofp, "%-12s", "sw_if_index");
4698
4699   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4700   {
4701     i++;
4702     if (!det->present)
4703       {
4704         continue;
4705       }
4706     print (vam->ofp, "%-12d", i);
4707     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4708     if (!det->addr)
4709       {
4710         continue;
4711       }
4712     vec_foreach (address, det->addr)
4713     {
4714       print (vam->ofp,
4715              "            %-30U%-13d",
4716              is_ipv6 ? format_ip6_address : format_ip4_address,
4717              address->ip, address->prefix_length);
4718     }
4719   }
4720
4721   return 0;
4722 }
4723
4724 static int
4725 dump_ipv4_table (vat_main_t * vam)
4726 {
4727   if (vam->json_output)
4728     {
4729       clib_warning
4730         ("JSON output supported only for VPE API calls and dump_stats_table");
4731       return -99;
4732     }
4733
4734   return dump_ip_table (vam, 0);
4735 }
4736
4737 static int
4738 dump_ipv6_table (vat_main_t * vam)
4739 {
4740   if (vam->json_output)
4741     {
4742       clib_warning
4743         ("JSON output supported only for VPE API calls and dump_stats_table");
4744       return -99;
4745     }
4746
4747   return dump_ip_table (vam, 1);
4748 }
4749
4750 static char *
4751 counter_type_to_str (u8 counter_type, u8 is_combined)
4752 {
4753   if (!is_combined)
4754     {
4755       switch (counter_type)
4756         {
4757         case VNET_INTERFACE_COUNTER_DROP:
4758           return "drop";
4759         case VNET_INTERFACE_COUNTER_PUNT:
4760           return "punt";
4761         case VNET_INTERFACE_COUNTER_IP4:
4762           return "ip4";
4763         case VNET_INTERFACE_COUNTER_IP6:
4764           return "ip6";
4765         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4766           return "rx-no-buf";
4767         case VNET_INTERFACE_COUNTER_RX_MISS:
4768           return "rx-miss";
4769         case VNET_INTERFACE_COUNTER_RX_ERROR:
4770           return "rx-error";
4771         case VNET_INTERFACE_COUNTER_TX_ERROR:
4772           return "tx-error";
4773         default:
4774           return "INVALID-COUNTER-TYPE";
4775         }
4776     }
4777   else
4778     {
4779       switch (counter_type)
4780         {
4781         case VNET_INTERFACE_COUNTER_RX:
4782           return "rx";
4783         case VNET_INTERFACE_COUNTER_TX:
4784           return "tx";
4785         default:
4786           return "INVALID-COUNTER-TYPE";
4787         }
4788     }
4789 }
4790
4791 static int
4792 dump_stats_table (vat_main_t * vam)
4793 {
4794   vat_json_node_t node;
4795   vat_json_node_t *msg_array;
4796   vat_json_node_t *msg;
4797   vat_json_node_t *counter_array;
4798   vat_json_node_t *counter;
4799   interface_counter_t c;
4800   u64 packets;
4801   ip4_fib_counter_t *c4;
4802   ip6_fib_counter_t *c6;
4803   ip4_nbr_counter_t *n4;
4804   ip6_nbr_counter_t *n6;
4805   int i, j;
4806
4807   if (!vam->json_output)
4808     {
4809       clib_warning ("dump_stats_table supported only in JSON format");
4810       return -99;
4811     }
4812
4813   vat_json_init_object (&node);
4814
4815   /* interface counters */
4816   msg_array = vat_json_object_add (&node, "interface_counters");
4817   vat_json_init_array (msg_array);
4818   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4819     {
4820       msg = vat_json_array_add (msg_array);
4821       vat_json_init_object (msg);
4822       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4823                                        (u8 *) counter_type_to_str (i, 0));
4824       vat_json_object_add_int (msg, "is_combined", 0);
4825       counter_array = vat_json_object_add (msg, "data");
4826       vat_json_init_array (counter_array);
4827       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4828         {
4829           packets = vam->simple_interface_counters[i][j];
4830           vat_json_array_add_uint (counter_array, packets);
4831         }
4832     }
4833   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4834     {
4835       msg = vat_json_array_add (msg_array);
4836       vat_json_init_object (msg);
4837       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4838                                        (u8 *) counter_type_to_str (i, 1));
4839       vat_json_object_add_int (msg, "is_combined", 1);
4840       counter_array = vat_json_object_add (msg, "data");
4841       vat_json_init_array (counter_array);
4842       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4843         {
4844           c = vam->combined_interface_counters[i][j];
4845           counter = vat_json_array_add (counter_array);
4846           vat_json_init_object (counter);
4847           vat_json_object_add_uint (counter, "packets", c.packets);
4848           vat_json_object_add_uint (counter, "bytes", c.bytes);
4849         }
4850     }
4851
4852   /* ip4 fib counters */
4853   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4854   vat_json_init_array (msg_array);
4855   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4856     {
4857       msg = vat_json_array_add (msg_array);
4858       vat_json_init_object (msg);
4859       vat_json_object_add_uint (msg, "vrf_id",
4860                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4861       counter_array = vat_json_object_add (msg, "c");
4862       vat_json_init_array (counter_array);
4863       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4864         {
4865           counter = vat_json_array_add (counter_array);
4866           vat_json_init_object (counter);
4867           c4 = &vam->ip4_fib_counters[i][j];
4868           vat_json_object_add_ip4 (counter, "address", c4->address);
4869           vat_json_object_add_uint (counter, "address_length",
4870                                     c4->address_length);
4871           vat_json_object_add_uint (counter, "packets", c4->packets);
4872           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4873         }
4874     }
4875
4876   /* ip6 fib counters */
4877   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4878   vat_json_init_array (msg_array);
4879   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4880     {
4881       msg = vat_json_array_add (msg_array);
4882       vat_json_init_object (msg);
4883       vat_json_object_add_uint (msg, "vrf_id",
4884                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4885       counter_array = vat_json_object_add (msg, "c");
4886       vat_json_init_array (counter_array);
4887       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4888         {
4889           counter = vat_json_array_add (counter_array);
4890           vat_json_init_object (counter);
4891           c6 = &vam->ip6_fib_counters[i][j];
4892           vat_json_object_add_ip6 (counter, "address", c6->address);
4893           vat_json_object_add_uint (counter, "address_length",
4894                                     c6->address_length);
4895           vat_json_object_add_uint (counter, "packets", c6->packets);
4896           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4897         }
4898     }
4899
4900   /* ip4 nbr counters */
4901   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4902   vat_json_init_array (msg_array);
4903   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4904     {
4905       msg = vat_json_array_add (msg_array);
4906       vat_json_init_object (msg);
4907       vat_json_object_add_uint (msg, "sw_if_index", i);
4908       counter_array = vat_json_object_add (msg, "c");
4909       vat_json_init_array (counter_array);
4910       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4911         {
4912           counter = vat_json_array_add (counter_array);
4913           vat_json_init_object (counter);
4914           n4 = &vam->ip4_nbr_counters[i][j];
4915           vat_json_object_add_ip4 (counter, "address", n4->address);
4916           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4917           vat_json_object_add_uint (counter, "packets", n4->packets);
4918           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4919         }
4920     }
4921
4922   /* ip6 nbr counters */
4923   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4924   vat_json_init_array (msg_array);
4925   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4926     {
4927       msg = vat_json_array_add (msg_array);
4928       vat_json_init_object (msg);
4929       vat_json_object_add_uint (msg, "sw_if_index", i);
4930       counter_array = vat_json_object_add (msg, "c");
4931       vat_json_init_array (counter_array);
4932       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4933         {
4934           counter = vat_json_array_add (counter_array);
4935           vat_json_init_object (counter);
4936           n6 = &vam->ip6_nbr_counters[i][j];
4937           vat_json_object_add_ip6 (counter, "address", n6->address);
4938           vat_json_object_add_uint (counter, "packets", n6->packets);
4939           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4940         }
4941     }
4942
4943   vat_json_print (vam->ofp, &node);
4944   vat_json_free (&node);
4945
4946   return 0;
4947 }
4948
4949 int
4950 exec (vat_main_t * vam)
4951 {
4952   api_main_t *am = &api_main;
4953   vl_api_cli_t *mp;
4954   f64 timeout;
4955   void *oldheap;
4956   u8 *cmd = 0;
4957   unformat_input_t *i = vam->input;
4958
4959   if (vec_len (i->buffer) == 0)
4960     return -1;
4961
4962   if (vam->exec_mode == 0 && unformat (i, "mode"))
4963     {
4964       vam->exec_mode = 1;
4965       return 0;
4966     }
4967   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4968     {
4969       vam->exec_mode = 0;
4970       return 0;
4971     }
4972
4973
4974   M (CLI, mp);
4975
4976   /*
4977    * Copy cmd into shared memory.
4978    * In order for the CLI command to work, it
4979    * must be a vector ending in \n, not a C-string ending
4980    * in \n\0.
4981    */
4982   pthread_mutex_lock (&am->vlib_rp->mutex);
4983   oldheap = svm_push_data_heap (am->vlib_rp);
4984
4985   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4986   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4987
4988   svm_pop_heap (oldheap);
4989   pthread_mutex_unlock (&am->vlib_rp->mutex);
4990
4991   mp->cmd_in_shmem = pointer_to_uword (cmd);
4992   S (mp);
4993   timeout = vat_time_now (vam) + 10.0;
4994
4995   while (vat_time_now (vam) < timeout)
4996     {
4997       if (vam->result_ready == 1)
4998         {
4999           u8 *free_me;
5000           if (vam->shmem_result != NULL)
5001             print (vam->ofp, "%s", vam->shmem_result);
5002           pthread_mutex_lock (&am->vlib_rp->mutex);
5003           oldheap = svm_push_data_heap (am->vlib_rp);
5004
5005           free_me = (u8 *) vam->shmem_result;
5006           vec_free (free_me);
5007
5008           svm_pop_heap (oldheap);
5009           pthread_mutex_unlock (&am->vlib_rp->mutex);
5010           return 0;
5011         }
5012     }
5013   return -99;
5014 }
5015
5016 /*
5017  * Future replacement of exec() that passes CLI buffers directly in
5018  * the API messages instead of an additional shared memory area.
5019  */
5020 static int
5021 exec_inband (vat_main_t * vam)
5022 {
5023   vl_api_cli_inband_t *mp;
5024   unformat_input_t *i = vam->input;
5025   int ret;
5026
5027   if (vec_len (i->buffer) == 0)
5028     return -1;
5029
5030   if (vam->exec_mode == 0 && unformat (i, "mode"))
5031     {
5032       vam->exec_mode = 1;
5033       return 0;
5034     }
5035   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5036     {
5037       vam->exec_mode = 0;
5038       return 0;
5039     }
5040
5041   /*
5042    * In order for the CLI command to work, it
5043    * must be a vector ending in \n, not a C-string ending
5044    * in \n\0.
5045    */
5046   u32 len = vec_len (vam->input->buffer);
5047   M2 (CLI_INBAND, mp, len);
5048   clib_memcpy (mp->cmd, vam->input->buffer, len);
5049   mp->length = htonl (len);
5050
5051   S (mp);
5052   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5053   return ret;
5054 }
5055
5056 static int
5057 api_create_loopback (vat_main_t * vam)
5058 {
5059   unformat_input_t *i = vam->input;
5060   vl_api_create_loopback_t *mp;
5061   vl_api_create_loopback_instance_t *mp_lbi;
5062   u8 mac_address[6];
5063   u8 mac_set = 0;
5064   u8 is_specified = 0;
5065   u32 user_instance = 0;
5066   int ret;
5067
5068   memset (mac_address, 0, sizeof (mac_address));
5069
5070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5071     {
5072       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5073         mac_set = 1;
5074       if (unformat (i, "instance %d", &user_instance))
5075         is_specified = 1;
5076       else
5077         break;
5078     }
5079
5080   if (is_specified)
5081     {
5082       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5083       mp_lbi->is_specified = is_specified;
5084       if (is_specified)
5085         mp_lbi->user_instance = htonl (user_instance);
5086       if (mac_set)
5087         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5088       S (mp_lbi);
5089     }
5090   else
5091     {
5092       /* Construct the API message */
5093       M (CREATE_LOOPBACK, mp);
5094       if (mac_set)
5095         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5096       S (mp);
5097     }
5098
5099   W (ret);
5100   return ret;
5101 }
5102
5103 static int
5104 api_delete_loopback (vat_main_t * vam)
5105 {
5106   unformat_input_t *i = vam->input;
5107   vl_api_delete_loopback_t *mp;
5108   u32 sw_if_index = ~0;
5109   int ret;
5110
5111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5112     {
5113       if (unformat (i, "sw_if_index %d", &sw_if_index))
5114         ;
5115       else
5116         break;
5117     }
5118
5119   if (sw_if_index == ~0)
5120     {
5121       errmsg ("missing sw_if_index");
5122       return -99;
5123     }
5124
5125   /* Construct the API message */
5126   M (DELETE_LOOPBACK, mp);
5127   mp->sw_if_index = ntohl (sw_if_index);
5128
5129   S (mp);
5130   W (ret);
5131   return ret;
5132 }
5133
5134 static int
5135 api_want_stats (vat_main_t * vam)
5136 {
5137   unformat_input_t *i = vam->input;
5138   vl_api_want_stats_t *mp;
5139   int enable = -1;
5140   int ret;
5141
5142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5143     {
5144       if (unformat (i, "enable"))
5145         enable = 1;
5146       else if (unformat (i, "disable"))
5147         enable = 0;
5148       else
5149         break;
5150     }
5151
5152   if (enable == -1)
5153     {
5154       errmsg ("missing enable|disable");
5155       return -99;
5156     }
5157
5158   M (WANT_STATS, mp);
5159   mp->enable_disable = enable;
5160
5161   S (mp);
5162   W (ret);
5163   return ret;
5164 }
5165
5166 static int
5167 api_want_interface_events (vat_main_t * vam)
5168 {
5169   unformat_input_t *i = vam->input;
5170   vl_api_want_interface_events_t *mp;
5171   int enable = -1;
5172   int ret;
5173
5174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5175     {
5176       if (unformat (i, "enable"))
5177         enable = 1;
5178       else if (unformat (i, "disable"))
5179         enable = 0;
5180       else
5181         break;
5182     }
5183
5184   if (enable == -1)
5185     {
5186       errmsg ("missing enable|disable");
5187       return -99;
5188     }
5189
5190   M (WANT_INTERFACE_EVENTS, mp);
5191   mp->enable_disable = enable;
5192
5193   vam->interface_event_display = enable;
5194
5195   S (mp);
5196   W (ret);
5197   return ret;
5198 }
5199
5200
5201 /* Note: non-static, called once to set up the initial intfc table */
5202 int
5203 api_sw_interface_dump (vat_main_t * vam)
5204 {
5205   vl_api_sw_interface_dump_t *mp;
5206   vl_api_control_ping_t *mp_ping;
5207   hash_pair_t *p;
5208   name_sort_t *nses = 0, *ns;
5209   sw_interface_subif_t *sub = NULL;
5210   int ret;
5211
5212   /* Toss the old name table */
5213   /* *INDENT-OFF* */
5214   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5215   ({
5216     vec_add2 (nses, ns, 1);
5217     ns->name = (u8 *)(p->key);
5218     ns->value = (u32) p->value[0];
5219   }));
5220   /* *INDENT-ON* */
5221
5222   hash_free (vam->sw_if_index_by_interface_name);
5223
5224   vec_foreach (ns, nses) vec_free (ns->name);
5225
5226   vec_free (nses);
5227
5228   vec_foreach (sub, vam->sw_if_subif_table)
5229   {
5230     vec_free (sub->interface_name);
5231   }
5232   vec_free (vam->sw_if_subif_table);
5233
5234   /* recreate the interface name hash table */
5235   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5236
5237   /* Get list of ethernets */
5238   M (SW_INTERFACE_DUMP, mp);
5239   mp->name_filter_valid = 1;
5240   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5241   S (mp);
5242
5243   /* and local / loopback interfaces */
5244   M (SW_INTERFACE_DUMP, mp);
5245   mp->name_filter_valid = 1;
5246   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5247   S (mp);
5248
5249   /* and packet-generator interfaces */
5250   M (SW_INTERFACE_DUMP, mp);
5251   mp->name_filter_valid = 1;
5252   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5253   S (mp);
5254
5255   /* and vxlan-gpe tunnel interfaces */
5256   M (SW_INTERFACE_DUMP, mp);
5257   mp->name_filter_valid = 1;
5258   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5259            sizeof (mp->name_filter) - 1);
5260   S (mp);
5261
5262   /* and vxlan tunnel interfaces */
5263   M (SW_INTERFACE_DUMP, mp);
5264   mp->name_filter_valid = 1;
5265   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5266   S (mp);
5267
5268   /* and host (af_packet) interfaces */
5269   M (SW_INTERFACE_DUMP, mp);
5270   mp->name_filter_valid = 1;
5271   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5272   S (mp);
5273
5274   /* and l2tpv3 tunnel interfaces */
5275   M (SW_INTERFACE_DUMP, mp);
5276   mp->name_filter_valid = 1;
5277   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5278            sizeof (mp->name_filter) - 1);
5279   S (mp);
5280
5281   /* and GRE tunnel interfaces */
5282   M (SW_INTERFACE_DUMP, mp);
5283   mp->name_filter_valid = 1;
5284   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5285   S (mp);
5286
5287   /* and LISP-GPE interfaces */
5288   M (SW_INTERFACE_DUMP, mp);
5289   mp->name_filter_valid = 1;
5290   strncpy ((char *) mp->name_filter, "lisp_gpe",
5291            sizeof (mp->name_filter) - 1);
5292   S (mp);
5293
5294   /* and IPSEC tunnel interfaces */
5295   M (SW_INTERFACE_DUMP, mp);
5296   mp->name_filter_valid = 1;
5297   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5298   S (mp);
5299
5300   /* Use a control ping for synchronization */
5301   M (CONTROL_PING, mp_ping);
5302   S (mp_ping);
5303
5304   W (ret);
5305   return ret;
5306 }
5307
5308 static int
5309 api_sw_interface_set_flags (vat_main_t * vam)
5310 {
5311   unformat_input_t *i = vam->input;
5312   vl_api_sw_interface_set_flags_t *mp;
5313   u32 sw_if_index;
5314   u8 sw_if_index_set = 0;
5315   u8 admin_up = 0, link_up = 0;
5316   int ret;
5317
5318   /* Parse args required to build the message */
5319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5320     {
5321       if (unformat (i, "admin-up"))
5322         admin_up = 1;
5323       else if (unformat (i, "admin-down"))
5324         admin_up = 0;
5325       else if (unformat (i, "link-up"))
5326         link_up = 1;
5327       else if (unformat (i, "link-down"))
5328         link_up = 0;
5329       else
5330         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5331         sw_if_index_set = 1;
5332       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5333         sw_if_index_set = 1;
5334       else
5335         break;
5336     }
5337
5338   if (sw_if_index_set == 0)
5339     {
5340       errmsg ("missing interface name or sw_if_index");
5341       return -99;
5342     }
5343
5344   /* Construct the API message */
5345   M (SW_INTERFACE_SET_FLAGS, mp);
5346   mp->sw_if_index = ntohl (sw_if_index);
5347   mp->admin_up_down = admin_up;
5348   mp->link_up_down = link_up;
5349
5350   /* send it... */
5351   S (mp);
5352
5353   /* Wait for a reply, return the good/bad news... */
5354   W (ret);
5355   return ret;
5356 }
5357
5358 static int
5359 api_sw_interface_clear_stats (vat_main_t * vam)
5360 {
5361   unformat_input_t *i = vam->input;
5362   vl_api_sw_interface_clear_stats_t *mp;
5363   u32 sw_if_index;
5364   u8 sw_if_index_set = 0;
5365   int ret;
5366
5367   /* Parse args required to build the message */
5368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5369     {
5370       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5371         sw_if_index_set = 1;
5372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5373         sw_if_index_set = 1;
5374       else
5375         break;
5376     }
5377
5378   /* Construct the API message */
5379   M (SW_INTERFACE_CLEAR_STATS, mp);
5380
5381   if (sw_if_index_set == 1)
5382     mp->sw_if_index = ntohl (sw_if_index);
5383   else
5384     mp->sw_if_index = ~0;
5385
5386   /* send it... */
5387   S (mp);
5388
5389   /* Wait for a reply, return the good/bad news... */
5390   W (ret);
5391   return ret;
5392 }
5393
5394 static int
5395 api_sw_interface_add_del_address (vat_main_t * vam)
5396 {
5397   unformat_input_t *i = vam->input;
5398   vl_api_sw_interface_add_del_address_t *mp;
5399   u32 sw_if_index;
5400   u8 sw_if_index_set = 0;
5401   u8 is_add = 1, del_all = 0;
5402   u32 address_length = 0;
5403   u8 v4_address_set = 0;
5404   u8 v6_address_set = 0;
5405   ip4_address_t v4address;
5406   ip6_address_t v6address;
5407   int ret;
5408
5409   /* Parse args required to build the message */
5410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5411     {
5412       if (unformat (i, "del-all"))
5413         del_all = 1;
5414       else if (unformat (i, "del"))
5415         is_add = 0;
5416       else
5417         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5418         sw_if_index_set = 1;
5419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5420         sw_if_index_set = 1;
5421       else if (unformat (i, "%U/%d",
5422                          unformat_ip4_address, &v4address, &address_length))
5423         v4_address_set = 1;
5424       else if (unformat (i, "%U/%d",
5425                          unformat_ip6_address, &v6address, &address_length))
5426         v6_address_set = 1;
5427       else
5428         break;
5429     }
5430
5431   if (sw_if_index_set == 0)
5432     {
5433       errmsg ("missing interface name or sw_if_index");
5434       return -99;
5435     }
5436   if (v4_address_set && v6_address_set)
5437     {
5438       errmsg ("both v4 and v6 addresses set");
5439       return -99;
5440     }
5441   if (!v4_address_set && !v6_address_set && !del_all)
5442     {
5443       errmsg ("no addresses set");
5444       return -99;
5445     }
5446
5447   /* Construct the API message */
5448   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5449
5450   mp->sw_if_index = ntohl (sw_if_index);
5451   mp->is_add = is_add;
5452   mp->del_all = del_all;
5453   if (v6_address_set)
5454     {
5455       mp->is_ipv6 = 1;
5456       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5457     }
5458   else
5459     {
5460       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5461     }
5462   mp->address_length = address_length;
5463
5464   /* send it... */
5465   S (mp);
5466
5467   /* Wait for a reply, return good/bad news  */
5468   W (ret);
5469   return ret;
5470 }
5471
5472 static int
5473 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5474 {
5475   unformat_input_t *i = vam->input;
5476   vl_api_sw_interface_set_mpls_enable_t *mp;
5477   u32 sw_if_index;
5478   u8 sw_if_index_set = 0;
5479   u8 enable = 1;
5480   int ret;
5481
5482   /* Parse args required to build the message */
5483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5484     {
5485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5486         sw_if_index_set = 1;
5487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5488         sw_if_index_set = 1;
5489       else if (unformat (i, "disable"))
5490         enable = 0;
5491       else if (unformat (i, "dis"))
5492         enable = 0;
5493       else
5494         break;
5495     }
5496
5497   if (sw_if_index_set == 0)
5498     {
5499       errmsg ("missing interface name or sw_if_index");
5500       return -99;
5501     }
5502
5503   /* Construct the API message */
5504   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5505
5506   mp->sw_if_index = ntohl (sw_if_index);
5507   mp->enable = enable;
5508
5509   /* send it... */
5510   S (mp);
5511
5512   /* Wait for a reply... */
5513   W (ret);
5514   return ret;
5515 }
5516
5517 static int
5518 api_sw_interface_set_table (vat_main_t * vam)
5519 {
5520   unformat_input_t *i = vam->input;
5521   vl_api_sw_interface_set_table_t *mp;
5522   u32 sw_if_index, vrf_id = 0;
5523   u8 sw_if_index_set = 0;
5524   u8 is_ipv6 = 0;
5525   int ret;
5526
5527   /* Parse args required to build the message */
5528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5529     {
5530       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5531         sw_if_index_set = 1;
5532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5533         sw_if_index_set = 1;
5534       else if (unformat (i, "vrf %d", &vrf_id))
5535         ;
5536       else if (unformat (i, "ipv6"))
5537         is_ipv6 = 1;
5538       else
5539         break;
5540     }
5541
5542   if (sw_if_index_set == 0)
5543     {
5544       errmsg ("missing interface name or sw_if_index");
5545       return -99;
5546     }
5547
5548   /* Construct the API message */
5549   M (SW_INTERFACE_SET_TABLE, mp);
5550
5551   mp->sw_if_index = ntohl (sw_if_index);
5552   mp->is_ipv6 = is_ipv6;
5553   mp->vrf_id = ntohl (vrf_id);
5554
5555   /* send it... */
5556   S (mp);
5557
5558   /* Wait for a reply... */
5559   W (ret);
5560   return ret;
5561 }
5562
5563 static void vl_api_sw_interface_get_table_reply_t_handler
5564   (vl_api_sw_interface_get_table_reply_t * mp)
5565 {
5566   vat_main_t *vam = &vat_main;
5567
5568   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5569
5570   vam->retval = ntohl (mp->retval);
5571   vam->result_ready = 1;
5572
5573 }
5574
5575 static void vl_api_sw_interface_get_table_reply_t_handler_json
5576   (vl_api_sw_interface_get_table_reply_t * mp)
5577 {
5578   vat_main_t *vam = &vat_main;
5579   vat_json_node_t node;
5580
5581   vat_json_init_object (&node);
5582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5583   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5584
5585   vat_json_print (vam->ofp, &node);
5586   vat_json_free (&node);
5587
5588   vam->retval = ntohl (mp->retval);
5589   vam->result_ready = 1;
5590 }
5591
5592 static int
5593 api_sw_interface_get_table (vat_main_t * vam)
5594 {
5595   unformat_input_t *i = vam->input;
5596   vl_api_sw_interface_get_table_t *mp;
5597   u32 sw_if_index;
5598   u8 sw_if_index_set = 0;
5599   u8 is_ipv6 = 0;
5600   int ret;
5601
5602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5603     {
5604       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5605         sw_if_index_set = 1;
5606       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5607         sw_if_index_set = 1;
5608       else if (unformat (i, "ipv6"))
5609         is_ipv6 = 1;
5610       else
5611         break;
5612     }
5613
5614   if (sw_if_index_set == 0)
5615     {
5616       errmsg ("missing interface name or sw_if_index");
5617       return -99;
5618     }
5619
5620   M (SW_INTERFACE_GET_TABLE, mp);
5621   mp->sw_if_index = htonl (sw_if_index);
5622   mp->is_ipv6 = is_ipv6;
5623
5624   S (mp);
5625   W (ret);
5626   return ret;
5627 }
5628
5629 static int
5630 api_sw_interface_set_vpath (vat_main_t * vam)
5631 {
5632   unformat_input_t *i = vam->input;
5633   vl_api_sw_interface_set_vpath_t *mp;
5634   u32 sw_if_index = 0;
5635   u8 sw_if_index_set = 0;
5636   u8 is_enable = 0;
5637   int ret;
5638
5639   /* Parse args required to build the message */
5640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5641     {
5642       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5643         sw_if_index_set = 1;
5644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5645         sw_if_index_set = 1;
5646       else if (unformat (i, "enable"))
5647         is_enable = 1;
5648       else if (unformat (i, "disable"))
5649         is_enable = 0;
5650       else
5651         break;
5652     }
5653
5654   if (sw_if_index_set == 0)
5655     {
5656       errmsg ("missing interface name or sw_if_index");
5657       return -99;
5658     }
5659
5660   /* Construct the API message */
5661   M (SW_INTERFACE_SET_VPATH, mp);
5662
5663   mp->sw_if_index = ntohl (sw_if_index);
5664   mp->enable = is_enable;
5665
5666   /* send it... */
5667   S (mp);
5668
5669   /* Wait for a reply... */
5670   W (ret);
5671   return ret;
5672 }
5673
5674 static int
5675 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5676 {
5677   unformat_input_t *i = vam->input;
5678   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5679   u32 sw_if_index = 0;
5680   u8 sw_if_index_set = 0;
5681   u8 is_enable = 1;
5682   u8 is_ipv6 = 0;
5683   int ret;
5684
5685   /* Parse args required to build the message */
5686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5687     {
5688       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5689         sw_if_index_set = 1;
5690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5691         sw_if_index_set = 1;
5692       else if (unformat (i, "enable"))
5693         is_enable = 1;
5694       else if (unformat (i, "disable"))
5695         is_enable = 0;
5696       else if (unformat (i, "ip4"))
5697         is_ipv6 = 0;
5698       else if (unformat (i, "ip6"))
5699         is_ipv6 = 1;
5700       else
5701         break;
5702     }
5703
5704   if (sw_if_index_set == 0)
5705     {
5706       errmsg ("missing interface name or sw_if_index");
5707       return -99;
5708     }
5709
5710   /* Construct the API message */
5711   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5712
5713   mp->sw_if_index = ntohl (sw_if_index);
5714   mp->enable = is_enable;
5715   mp->is_ipv6 = is_ipv6;
5716
5717   /* send it... */
5718   S (mp);
5719
5720   /* Wait for a reply... */
5721   W (ret);
5722   return ret;
5723 }
5724
5725 static int
5726 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5727 {
5728   unformat_input_t *i = vam->input;
5729   vl_api_sw_interface_set_l2_xconnect_t *mp;
5730   u32 rx_sw_if_index;
5731   u8 rx_sw_if_index_set = 0;
5732   u32 tx_sw_if_index;
5733   u8 tx_sw_if_index_set = 0;
5734   u8 enable = 1;
5735   int ret;
5736
5737   /* Parse args required to build the message */
5738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5739     {
5740       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5741         rx_sw_if_index_set = 1;
5742       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5743         tx_sw_if_index_set = 1;
5744       else if (unformat (i, "rx"))
5745         {
5746           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5747             {
5748               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5749                             &rx_sw_if_index))
5750                 rx_sw_if_index_set = 1;
5751             }
5752           else
5753             break;
5754         }
5755       else if (unformat (i, "tx"))
5756         {
5757           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5758             {
5759               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5760                             &tx_sw_if_index))
5761                 tx_sw_if_index_set = 1;
5762             }
5763           else
5764             break;
5765         }
5766       else if (unformat (i, "enable"))
5767         enable = 1;
5768       else if (unformat (i, "disable"))
5769         enable = 0;
5770       else
5771         break;
5772     }
5773
5774   if (rx_sw_if_index_set == 0)
5775     {
5776       errmsg ("missing rx interface name or rx_sw_if_index");
5777       return -99;
5778     }
5779
5780   if (enable && (tx_sw_if_index_set == 0))
5781     {
5782       errmsg ("missing tx interface name or tx_sw_if_index");
5783       return -99;
5784     }
5785
5786   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5787
5788   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5789   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5790   mp->enable = enable;
5791
5792   S (mp);
5793   W (ret);
5794   return ret;
5795 }
5796
5797 static int
5798 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5799 {
5800   unformat_input_t *i = vam->input;
5801   vl_api_sw_interface_set_l2_bridge_t *mp;
5802   u32 rx_sw_if_index;
5803   u8 rx_sw_if_index_set = 0;
5804   u32 bd_id;
5805   u8 bd_id_set = 0;
5806   u8 bvi = 0;
5807   u32 shg = 0;
5808   u8 enable = 1;
5809   int ret;
5810
5811   /* Parse args required to build the message */
5812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5813     {
5814       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5815         rx_sw_if_index_set = 1;
5816       else if (unformat (i, "bd_id %d", &bd_id))
5817         bd_id_set = 1;
5818       else
5819         if (unformat
5820             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5821         rx_sw_if_index_set = 1;
5822       else if (unformat (i, "shg %d", &shg))
5823         ;
5824       else if (unformat (i, "bvi"))
5825         bvi = 1;
5826       else if (unformat (i, "enable"))
5827         enable = 1;
5828       else if (unformat (i, "disable"))
5829         enable = 0;
5830       else
5831         break;
5832     }
5833
5834   if (rx_sw_if_index_set == 0)
5835     {
5836       errmsg ("missing rx interface name or sw_if_index");
5837       return -99;
5838     }
5839
5840   if (enable && (bd_id_set == 0))
5841     {
5842       errmsg ("missing bridge domain");
5843       return -99;
5844     }
5845
5846   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5847
5848   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5849   mp->bd_id = ntohl (bd_id);
5850   mp->shg = (u8) shg;
5851   mp->bvi = bvi;
5852   mp->enable = enable;
5853
5854   S (mp);
5855   W (ret);
5856   return ret;
5857 }
5858
5859 static int
5860 api_bridge_domain_dump (vat_main_t * vam)
5861 {
5862   unformat_input_t *i = vam->input;
5863   vl_api_bridge_domain_dump_t *mp;
5864   vl_api_control_ping_t *mp_ping;
5865   u32 bd_id = ~0;
5866   int ret;
5867
5868   /* Parse args required to build the message */
5869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5870     {
5871       if (unformat (i, "bd_id %d", &bd_id))
5872         ;
5873       else
5874         break;
5875     }
5876
5877   M (BRIDGE_DOMAIN_DUMP, mp);
5878   mp->bd_id = ntohl (bd_id);
5879   S (mp);
5880
5881   /* Use a control ping for synchronization */
5882   M (CONTROL_PING, mp_ping);
5883   S (mp_ping);
5884
5885   W (ret);
5886   return ret;
5887 }
5888
5889 static int
5890 api_bridge_domain_add_del (vat_main_t * vam)
5891 {
5892   unformat_input_t *i = vam->input;
5893   vl_api_bridge_domain_add_del_t *mp;
5894   u32 bd_id = ~0;
5895   u8 is_add = 1;
5896   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5897   u32 mac_age = 0;
5898   int ret;
5899
5900   /* Parse args required to build the message */
5901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5902     {
5903       if (unformat (i, "bd_id %d", &bd_id))
5904         ;
5905       else if (unformat (i, "flood %d", &flood))
5906         ;
5907       else if (unformat (i, "uu-flood %d", &uu_flood))
5908         ;
5909       else if (unformat (i, "forward %d", &forward))
5910         ;
5911       else if (unformat (i, "learn %d", &learn))
5912         ;
5913       else if (unformat (i, "arp-term %d", &arp_term))
5914         ;
5915       else if (unformat (i, "mac-age %d", &mac_age))
5916         ;
5917       else if (unformat (i, "del"))
5918         {
5919           is_add = 0;
5920           flood = uu_flood = forward = learn = 0;
5921         }
5922       else
5923         break;
5924     }
5925
5926   if (bd_id == ~0)
5927     {
5928       errmsg ("missing bridge domain");
5929       return -99;
5930     }
5931
5932   if (mac_age > 255)
5933     {
5934       errmsg ("mac age must be less than 256 ");
5935       return -99;
5936     }
5937
5938   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5939
5940   mp->bd_id = ntohl (bd_id);
5941   mp->flood = flood;
5942   mp->uu_flood = uu_flood;
5943   mp->forward = forward;
5944   mp->learn = learn;
5945   mp->arp_term = arp_term;
5946   mp->is_add = is_add;
5947   mp->mac_age = (u8) mac_age;
5948
5949   S (mp);
5950   W (ret);
5951   return ret;
5952 }
5953
5954 static int
5955 api_l2fib_flush_bd (vat_main_t * vam)
5956 {
5957   unformat_input_t *i = vam->input;
5958   vl_api_l2fib_flush_bd_t *mp;
5959   u32 bd_id = ~0;
5960   int ret;
5961
5962   /* Parse args required to build the message */
5963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5964     {
5965       if (unformat (i, "bd_id %d", &bd_id));
5966       else
5967         break;
5968     }
5969
5970   if (bd_id == ~0)
5971     {
5972       errmsg ("missing bridge domain");
5973       return -99;
5974     }
5975
5976   M (L2FIB_FLUSH_BD, mp);
5977
5978   mp->bd_id = htonl (bd_id);
5979
5980   S (mp);
5981   W (ret);
5982   return ret;
5983 }
5984
5985 static int
5986 api_l2fib_flush_int (vat_main_t * vam)
5987 {
5988   unformat_input_t *i = vam->input;
5989   vl_api_l2fib_flush_int_t *mp;
5990   u32 sw_if_index = ~0;
5991   int ret;
5992
5993   /* Parse args required to build the message */
5994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5995     {
5996       if (unformat (i, "sw_if_index %d", &sw_if_index));
5997       else
5998         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
5999       else
6000         break;
6001     }
6002
6003   if (sw_if_index == ~0)
6004     {
6005       errmsg ("missing interface name or sw_if_index");
6006       return -99;
6007     }
6008
6009   M (L2FIB_FLUSH_INT, mp);
6010
6011   mp->sw_if_index = ntohl (sw_if_index);
6012
6013   S (mp);
6014   W (ret);
6015   return ret;
6016 }
6017
6018 static int
6019 api_l2fib_add_del (vat_main_t * vam)
6020 {
6021   unformat_input_t *i = vam->input;
6022   vl_api_l2fib_add_del_t *mp;
6023   f64 timeout;
6024   u64 mac = 0;
6025   u8 mac_set = 0;
6026   u32 bd_id;
6027   u8 bd_id_set = 0;
6028   u32 sw_if_index = ~0;
6029   u8 sw_if_index_set = 0;
6030   u8 is_add = 1;
6031   u8 static_mac = 0;
6032   u8 filter_mac = 0;
6033   u8 bvi_mac = 0;
6034   int count = 1;
6035   f64 before = 0;
6036   int j;
6037
6038   /* Parse args required to build the message */
6039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6040     {
6041       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6042         mac_set = 1;
6043       else if (unformat (i, "bd_id %d", &bd_id))
6044         bd_id_set = 1;
6045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6046         sw_if_index_set = 1;
6047       else if (unformat (i, "sw_if"))
6048         {
6049           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6050             {
6051               if (unformat
6052                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6053                 sw_if_index_set = 1;
6054             }
6055           else
6056             break;
6057         }
6058       else if (unformat (i, "static"))
6059         static_mac = 1;
6060       else if (unformat (i, "filter"))
6061         {
6062           filter_mac = 1;
6063           static_mac = 1;
6064         }
6065       else if (unformat (i, "bvi"))
6066         {
6067           bvi_mac = 1;
6068           static_mac = 1;
6069         }
6070       else if (unformat (i, "del"))
6071         is_add = 0;
6072       else if (unformat (i, "count %d", &count))
6073         ;
6074       else
6075         break;
6076     }
6077
6078   if (mac_set == 0)
6079     {
6080       errmsg ("missing mac address");
6081       return -99;
6082     }
6083
6084   if (bd_id_set == 0)
6085     {
6086       errmsg ("missing bridge domain");
6087       return -99;
6088     }
6089
6090   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6091     {
6092       errmsg ("missing interface name or sw_if_index");
6093       return -99;
6094     }
6095
6096   if (count > 1)
6097     {
6098       /* Turn on async mode */
6099       vam->async_mode = 1;
6100       vam->async_errors = 0;
6101       before = vat_time_now (vam);
6102     }
6103
6104   for (j = 0; j < count; j++)
6105     {
6106       M (L2FIB_ADD_DEL, mp);
6107
6108       mp->mac = mac;
6109       mp->bd_id = ntohl (bd_id);
6110       mp->is_add = is_add;
6111
6112       if (is_add)
6113         {
6114           mp->sw_if_index = ntohl (sw_if_index);
6115           mp->static_mac = static_mac;
6116           mp->filter_mac = filter_mac;
6117           mp->bvi_mac = bvi_mac;
6118         }
6119       increment_mac_address (&mac);
6120       /* send it... */
6121       S (mp);
6122     }
6123
6124   if (count > 1)
6125     {
6126       vl_api_control_ping_t *mp_ping;
6127       f64 after;
6128
6129       /* Shut off async mode */
6130       vam->async_mode = 0;
6131
6132       M (CONTROL_PING, mp_ping);
6133       S (mp_ping);
6134
6135       timeout = vat_time_now (vam) + 1.0;
6136       while (vat_time_now (vam) < timeout)
6137         if (vam->result_ready == 1)
6138           goto out;
6139       vam->retval = -99;
6140
6141     out:
6142       if (vam->retval == -99)
6143         errmsg ("timeout");
6144
6145       if (vam->async_errors > 0)
6146         {
6147           errmsg ("%d asynchronous errors", vam->async_errors);
6148           vam->retval = -98;
6149         }
6150       vam->async_errors = 0;
6151       after = vat_time_now (vam);
6152
6153       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6154              count, after - before, count / (after - before));
6155     }
6156   else
6157     {
6158       int ret;
6159
6160       /* Wait for a reply... */
6161       W (ret);
6162       return ret;
6163     }
6164   /* Return the good/bad news */
6165   return (vam->retval);
6166 }
6167
6168 static int
6169 api_bridge_domain_set_mac_age (vat_main_t * vam)
6170 {
6171   unformat_input_t *i = vam->input;
6172   vl_api_bridge_domain_set_mac_age_t *mp;
6173   u32 bd_id = ~0;
6174   u32 mac_age = 0;
6175   int ret;
6176
6177   /* Parse args required to build the message */
6178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6179     {
6180       if (unformat (i, "bd_id %d", &bd_id));
6181       else if (unformat (i, "mac-age %d", &mac_age));
6182       else
6183         break;
6184     }
6185
6186   if (bd_id == ~0)
6187     {
6188       errmsg ("missing bridge domain");
6189       return -99;
6190     }
6191
6192   if (mac_age > 255)
6193     {
6194       errmsg ("mac age must be less than 256 ");
6195       return -99;
6196     }
6197
6198   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6199
6200   mp->bd_id = htonl (bd_id);
6201   mp->mac_age = (u8) mac_age;
6202
6203   S (mp);
6204   W (ret);
6205   return ret;
6206 }
6207
6208 static int
6209 api_l2_flags (vat_main_t * vam)
6210 {
6211   unformat_input_t *i = vam->input;
6212   vl_api_l2_flags_t *mp;
6213   u32 sw_if_index;
6214   u32 feature_bitmap = 0;
6215   u8 sw_if_index_set = 0;
6216   int ret;
6217
6218   /* Parse args required to build the message */
6219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6220     {
6221       if (unformat (i, "sw_if_index %d", &sw_if_index))
6222         sw_if_index_set = 1;
6223       else if (unformat (i, "sw_if"))
6224         {
6225           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6226             {
6227               if (unformat
6228                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6229                 sw_if_index_set = 1;
6230             }
6231           else
6232             break;
6233         }
6234       else if (unformat (i, "learn"))
6235         feature_bitmap |= L2INPUT_FEAT_LEARN;
6236       else if (unformat (i, "forward"))
6237         feature_bitmap |= L2INPUT_FEAT_FWD;
6238       else if (unformat (i, "flood"))
6239         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6240       else if (unformat (i, "uu-flood"))
6241         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6242       else
6243         break;
6244     }
6245
6246   if (sw_if_index_set == 0)
6247     {
6248       errmsg ("missing interface name or sw_if_index");
6249       return -99;
6250     }
6251
6252   M (L2_FLAGS, mp);
6253
6254   mp->sw_if_index = ntohl (sw_if_index);
6255   mp->feature_bitmap = ntohl (feature_bitmap);
6256
6257   S (mp);
6258   W (ret);
6259   return ret;
6260 }
6261
6262 static int
6263 api_bridge_flags (vat_main_t * vam)
6264 {
6265   unformat_input_t *i = vam->input;
6266   vl_api_bridge_flags_t *mp;
6267   u32 bd_id;
6268   u8 bd_id_set = 0;
6269   u8 is_set = 1;
6270   u32 flags = 0;
6271   int ret;
6272
6273   /* Parse args required to build the message */
6274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6275     {
6276       if (unformat (i, "bd_id %d", &bd_id))
6277         bd_id_set = 1;
6278       else if (unformat (i, "learn"))
6279         flags |= L2_LEARN;
6280       else if (unformat (i, "forward"))
6281         flags |= L2_FWD;
6282       else if (unformat (i, "flood"))
6283         flags |= L2_FLOOD;
6284       else if (unformat (i, "uu-flood"))
6285         flags |= L2_UU_FLOOD;
6286       else if (unformat (i, "arp-term"))
6287         flags |= L2_ARP_TERM;
6288       else if (unformat (i, "off"))
6289         is_set = 0;
6290       else if (unformat (i, "disable"))
6291         is_set = 0;
6292       else
6293         break;
6294     }
6295
6296   if (bd_id_set == 0)
6297     {
6298       errmsg ("missing bridge domain");
6299       return -99;
6300     }
6301
6302   M (BRIDGE_FLAGS, mp);
6303
6304   mp->bd_id = ntohl (bd_id);
6305   mp->feature_bitmap = ntohl (flags);
6306   mp->is_set = is_set;
6307
6308   S (mp);
6309   W (ret);
6310   return ret;
6311 }
6312
6313 static int
6314 api_bd_ip_mac_add_del (vat_main_t * vam)
6315 {
6316   unformat_input_t *i = vam->input;
6317   vl_api_bd_ip_mac_add_del_t *mp;
6318   u32 bd_id;
6319   u8 is_ipv6 = 0;
6320   u8 is_add = 1;
6321   u8 bd_id_set = 0;
6322   u8 ip_set = 0;
6323   u8 mac_set = 0;
6324   ip4_address_t v4addr;
6325   ip6_address_t v6addr;
6326   u8 macaddr[6];
6327   int ret;
6328
6329
6330   /* Parse args required to build the message */
6331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332     {
6333       if (unformat (i, "bd_id %d", &bd_id))
6334         {
6335           bd_id_set++;
6336         }
6337       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6338         {
6339           ip_set++;
6340         }
6341       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6342         {
6343           ip_set++;
6344           is_ipv6++;
6345         }
6346       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6347         {
6348           mac_set++;
6349         }
6350       else if (unformat (i, "del"))
6351         is_add = 0;
6352       else
6353         break;
6354     }
6355
6356   if (bd_id_set == 0)
6357     {
6358       errmsg ("missing bridge domain");
6359       return -99;
6360     }
6361   else if (ip_set == 0)
6362     {
6363       errmsg ("missing IP address");
6364       return -99;
6365     }
6366   else if (mac_set == 0)
6367     {
6368       errmsg ("missing MAC address");
6369       return -99;
6370     }
6371
6372   M (BD_IP_MAC_ADD_DEL, mp);
6373
6374   mp->bd_id = ntohl (bd_id);
6375   mp->is_ipv6 = is_ipv6;
6376   mp->is_add = is_add;
6377   if (is_ipv6)
6378     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6379   else
6380     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6381   clib_memcpy (mp->mac_address, macaddr, 6);
6382   S (mp);
6383   W (ret);
6384   return ret;
6385 }
6386
6387 static int
6388 api_tap_connect (vat_main_t * vam)
6389 {
6390   unformat_input_t *i = vam->input;
6391   vl_api_tap_connect_t *mp;
6392   u8 mac_address[6];
6393   u8 random_mac = 1;
6394   u8 name_set = 0;
6395   u8 *tap_name;
6396   u8 *tag = 0;
6397   ip4_address_t ip4_address;
6398   u32 ip4_mask_width;
6399   int ip4_address_set = 0;
6400   ip6_address_t ip6_address;
6401   u32 ip6_mask_width;
6402   int ip6_address_set = 0;
6403   int ret;
6404
6405   memset (mac_address, 0, sizeof (mac_address));
6406
6407   /* Parse args required to build the message */
6408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6409     {
6410       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6411         {
6412           random_mac = 0;
6413         }
6414       else if (unformat (i, "random-mac"))
6415         random_mac = 1;
6416       else if (unformat (i, "tapname %s", &tap_name))
6417         name_set = 1;
6418       else if (unformat (i, "tag %s", &tag))
6419         ;
6420       else if (unformat (i, "address %U/%d",
6421                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6422         ip4_address_set = 1;
6423       else if (unformat (i, "address %U/%d",
6424                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6425         ip6_address_set = 1;
6426       else
6427         break;
6428     }
6429
6430   if (name_set == 0)
6431     {
6432       errmsg ("missing tap name");
6433       return -99;
6434     }
6435   if (vec_len (tap_name) > 63)
6436     {
6437       errmsg ("tap name too long");
6438       return -99;
6439     }
6440   vec_add1 (tap_name, 0);
6441
6442   if (vec_len (tag) > 63)
6443     {
6444       errmsg ("tag too long");
6445       return -99;
6446     }
6447
6448   /* Construct the API message */
6449   M (TAP_CONNECT, mp);
6450
6451   mp->use_random_mac = random_mac;
6452   clib_memcpy (mp->mac_address, mac_address, 6);
6453   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6454   if (tag)
6455     clib_memcpy (mp->tag, tag, vec_len (tag));
6456
6457   if (ip4_address_set)
6458     {
6459       mp->ip4_address_set = 1;
6460       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6461       mp->ip4_mask_width = ip4_mask_width;
6462     }
6463   if (ip6_address_set)
6464     {
6465       mp->ip6_address_set = 1;
6466       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6467       mp->ip6_mask_width = ip6_mask_width;
6468     }
6469
6470   vec_free (tap_name);
6471   vec_free (tag);
6472
6473   /* send it... */
6474   S (mp);
6475
6476   /* Wait for a reply... */
6477   W (ret);
6478   return ret;
6479 }
6480
6481 static int
6482 api_tap_modify (vat_main_t * vam)
6483 {
6484   unformat_input_t *i = vam->input;
6485   vl_api_tap_modify_t *mp;
6486   u8 mac_address[6];
6487   u8 random_mac = 1;
6488   u8 name_set = 0;
6489   u8 *tap_name;
6490   u32 sw_if_index = ~0;
6491   u8 sw_if_index_set = 0;
6492   int ret;
6493
6494   memset (mac_address, 0, sizeof (mac_address));
6495
6496   /* Parse args required to build the message */
6497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6498     {
6499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6500         sw_if_index_set = 1;
6501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6502         sw_if_index_set = 1;
6503       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6504         {
6505           random_mac = 0;
6506         }
6507       else if (unformat (i, "random-mac"))
6508         random_mac = 1;
6509       else if (unformat (i, "tapname %s", &tap_name))
6510         name_set = 1;
6511       else
6512         break;
6513     }
6514
6515   if (sw_if_index_set == 0)
6516     {
6517       errmsg ("missing vpp interface name");
6518       return -99;
6519     }
6520   if (name_set == 0)
6521     {
6522       errmsg ("missing tap name");
6523       return -99;
6524     }
6525   if (vec_len (tap_name) > 63)
6526     {
6527       errmsg ("tap name too long");
6528     }
6529   vec_add1 (tap_name, 0);
6530
6531   /* Construct the API message */
6532   M (TAP_MODIFY, mp);
6533
6534   mp->use_random_mac = random_mac;
6535   mp->sw_if_index = ntohl (sw_if_index);
6536   clib_memcpy (mp->mac_address, mac_address, 6);
6537   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6538   vec_free (tap_name);
6539
6540   /* send it... */
6541   S (mp);
6542
6543   /* Wait for a reply... */
6544   W (ret);
6545   return ret;
6546 }
6547
6548 static int
6549 api_tap_delete (vat_main_t * vam)
6550 {
6551   unformat_input_t *i = vam->input;
6552   vl_api_tap_delete_t *mp;
6553   u32 sw_if_index = ~0;
6554   u8 sw_if_index_set = 0;
6555   int ret;
6556
6557   /* Parse args required to build the message */
6558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6559     {
6560       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6563         sw_if_index_set = 1;
6564       else
6565         break;
6566     }
6567
6568   if (sw_if_index_set == 0)
6569     {
6570       errmsg ("missing vpp interface name");
6571       return -99;
6572     }
6573
6574   /* Construct the API message */
6575   M (TAP_DELETE, mp);
6576
6577   mp->sw_if_index = ntohl (sw_if_index);
6578
6579   /* send it... */
6580   S (mp);
6581
6582   /* Wait for a reply... */
6583   W (ret);
6584   return ret;
6585 }
6586
6587 static int
6588 api_ip_add_del_route (vat_main_t * vam)
6589 {
6590   unformat_input_t *i = vam->input;
6591   vl_api_ip_add_del_route_t *mp;
6592   u32 sw_if_index = ~0, vrf_id = 0;
6593   u8 is_ipv6 = 0;
6594   u8 is_local = 0, is_drop = 0;
6595   u8 is_unreach = 0, is_prohibit = 0;
6596   u8 create_vrf_if_needed = 0;
6597   u8 is_add = 1;
6598   u32 next_hop_weight = 1;
6599   u8 not_last = 0;
6600   u8 is_multipath = 0;
6601   u8 address_set = 0;
6602   u8 address_length_set = 0;
6603   u32 next_hop_table_id = 0;
6604   u32 resolve_attempts = 0;
6605   u32 dst_address_length = 0;
6606   u8 next_hop_set = 0;
6607   ip4_address_t v4_dst_address, v4_next_hop_address;
6608   ip6_address_t v6_dst_address, v6_next_hop_address;
6609   int count = 1;
6610   int j;
6611   f64 before = 0;
6612   u32 random_add_del = 0;
6613   u32 *random_vector = 0;
6614   uword *random_hash;
6615   u32 random_seed = 0xdeaddabe;
6616   u32 classify_table_index = ~0;
6617   u8 is_classify = 0;
6618   u8 resolve_host = 0, resolve_attached = 0;
6619   mpls_label_t *next_hop_out_label_stack = NULL;
6620   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6621   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6627         ;
6628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6629         ;
6630       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6631         {
6632           address_set = 1;
6633           is_ipv6 = 0;
6634         }
6635       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6636         {
6637           address_set = 1;
6638           is_ipv6 = 1;
6639         }
6640       else if (unformat (i, "/%d", &dst_address_length))
6641         {
6642           address_length_set = 1;
6643         }
6644
6645       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6646                                          &v4_next_hop_address))
6647         {
6648           next_hop_set = 1;
6649         }
6650       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6651                                          &v6_next_hop_address))
6652         {
6653           next_hop_set = 1;
6654         }
6655       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6656         ;
6657       else if (unformat (i, "weight %d", &next_hop_weight))
6658         ;
6659       else if (unformat (i, "drop"))
6660         {
6661           is_drop = 1;
6662         }
6663       else if (unformat (i, "null-send-unreach"))
6664         {
6665           is_unreach = 1;
6666         }
6667       else if (unformat (i, "null-send-prohibit"))
6668         {
6669           is_prohibit = 1;
6670         }
6671       else if (unformat (i, "local"))
6672         {
6673           is_local = 1;
6674         }
6675       else if (unformat (i, "classify %d", &classify_table_index))
6676         {
6677           is_classify = 1;
6678         }
6679       else if (unformat (i, "del"))
6680         is_add = 0;
6681       else if (unformat (i, "add"))
6682         is_add = 1;
6683       else if (unformat (i, "not-last"))
6684         not_last = 1;
6685       else if (unformat (i, "resolve-via-host"))
6686         resolve_host = 1;
6687       else if (unformat (i, "resolve-via-attached"))
6688         resolve_attached = 1;
6689       else if (unformat (i, "multipath"))
6690         is_multipath = 1;
6691       else if (unformat (i, "vrf %d", &vrf_id))
6692         ;
6693       else if (unformat (i, "create-vrf"))
6694         create_vrf_if_needed = 1;
6695       else if (unformat (i, "count %d", &count))
6696         ;
6697       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6698         ;
6699       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6700         ;
6701       else if (unformat (i, "out-label %d", &next_hop_out_label))
6702         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6703       else if (unformat (i, "via-label %d", &next_hop_via_label))
6704         ;
6705       else if (unformat (i, "random"))
6706         random_add_del = 1;
6707       else if (unformat (i, "seed %d", &random_seed))
6708         ;
6709       else
6710         {
6711           clib_warning ("parse error '%U'", format_unformat_error, i);
6712           return -99;
6713         }
6714     }
6715
6716   if (!next_hop_set && !is_drop && !is_local &&
6717       !is_classify && !is_unreach && !is_prohibit &&
6718       MPLS_LABEL_INVALID == next_hop_via_label)
6719     {
6720       errmsg
6721         ("next hop / local / drop / unreach / prohibit / classify not set");
6722       return -99;
6723     }
6724
6725   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6726     {
6727       errmsg ("next hop and next-hop via label set");
6728       return -99;
6729     }
6730   if (address_set == 0)
6731     {
6732       errmsg ("missing addresses");
6733       return -99;
6734     }
6735
6736   if (address_length_set == 0)
6737     {
6738       errmsg ("missing address length");
6739       return -99;
6740     }
6741
6742   /* Generate a pile of unique, random routes */
6743   if (random_add_del)
6744     {
6745       u32 this_random_address;
6746       random_hash = hash_create (count, sizeof (uword));
6747
6748       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6749       for (j = 0; j <= count; j++)
6750         {
6751           do
6752             {
6753               this_random_address = random_u32 (&random_seed);
6754               this_random_address =
6755                 clib_host_to_net_u32 (this_random_address);
6756             }
6757           while (hash_get (random_hash, this_random_address));
6758           vec_add1 (random_vector, this_random_address);
6759           hash_set (random_hash, this_random_address, 1);
6760         }
6761       hash_free (random_hash);
6762       v4_dst_address.as_u32 = random_vector[0];
6763     }
6764
6765   if (count > 1)
6766     {
6767       /* Turn on async mode */
6768       vam->async_mode = 1;
6769       vam->async_errors = 0;
6770       before = vat_time_now (vam);
6771     }
6772
6773   for (j = 0; j < count; j++)
6774     {
6775       /* Construct the API message */
6776       M2 (IP_ADD_DEL_ROUTE, mp,
6777           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6778
6779       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6780       mp->table_id = ntohl (vrf_id);
6781       mp->create_vrf_if_needed = create_vrf_if_needed;
6782
6783       mp->is_add = is_add;
6784       mp->is_drop = is_drop;
6785       mp->is_unreach = is_unreach;
6786       mp->is_prohibit = is_prohibit;
6787       mp->is_ipv6 = is_ipv6;
6788       mp->is_local = is_local;
6789       mp->is_classify = is_classify;
6790       mp->is_multipath = is_multipath;
6791       mp->is_resolve_host = resolve_host;
6792       mp->is_resolve_attached = resolve_attached;
6793       mp->not_last = not_last;
6794       mp->next_hop_weight = next_hop_weight;
6795       mp->dst_address_length = dst_address_length;
6796       mp->next_hop_table_id = ntohl (next_hop_table_id);
6797       mp->classify_table_index = ntohl (classify_table_index);
6798       mp->next_hop_via_label = ntohl (next_hop_via_label);
6799       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6800       if (0 != mp->next_hop_n_out_labels)
6801         {
6802           memcpy (mp->next_hop_out_label_stack,
6803                   next_hop_out_label_stack,
6804                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6805           vec_free (next_hop_out_label_stack);
6806         }
6807
6808       if (is_ipv6)
6809         {
6810           clib_memcpy (mp->dst_address, &v6_dst_address,
6811                        sizeof (v6_dst_address));
6812           if (next_hop_set)
6813             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6814                          sizeof (v6_next_hop_address));
6815           increment_v6_address (&v6_dst_address);
6816         }
6817       else
6818         {
6819           clib_memcpy (mp->dst_address, &v4_dst_address,
6820                        sizeof (v4_dst_address));
6821           if (next_hop_set)
6822             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6823                          sizeof (v4_next_hop_address));
6824           if (random_add_del)
6825             v4_dst_address.as_u32 = random_vector[j + 1];
6826           else
6827             increment_v4_address (&v4_dst_address);
6828         }
6829       /* send it... */
6830       S (mp);
6831       /* If we receive SIGTERM, stop now... */
6832       if (vam->do_exit)
6833         break;
6834     }
6835
6836   /* When testing multiple add/del ops, use a control-ping to sync */
6837   if (count > 1)
6838     {
6839       vl_api_control_ping_t *mp_ping;
6840       f64 after;
6841       f64 timeout;
6842
6843       /* Shut off async mode */
6844       vam->async_mode = 0;
6845
6846       M (CONTROL_PING, mp_ping);
6847       S (mp_ping);
6848
6849       timeout = vat_time_now (vam) + 1.0;
6850       while (vat_time_now (vam) < timeout)
6851         if (vam->result_ready == 1)
6852           goto out;
6853       vam->retval = -99;
6854
6855     out:
6856       if (vam->retval == -99)
6857         errmsg ("timeout");
6858
6859       if (vam->async_errors > 0)
6860         {
6861           errmsg ("%d asynchronous errors", vam->async_errors);
6862           vam->retval = -98;
6863         }
6864       vam->async_errors = 0;
6865       after = vat_time_now (vam);
6866
6867       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6868       if (j > 0)
6869         count = j;
6870
6871       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6872              count, after - before, count / (after - before));
6873     }
6874   else
6875     {
6876       int ret;
6877
6878       /* Wait for a reply... */
6879       W (ret);
6880       return ret;
6881     }
6882
6883   /* Return the good/bad news */
6884   return (vam->retval);
6885 }
6886
6887 static int
6888 api_ip_mroute_add_del (vat_main_t * vam)
6889 {
6890   unformat_input_t *i = vam->input;
6891   vl_api_ip_mroute_add_del_t *mp;
6892   u32 sw_if_index = ~0, vrf_id = 0;
6893   u8 is_ipv6 = 0;
6894   u8 is_local = 0;
6895   u8 create_vrf_if_needed = 0;
6896   u8 is_add = 1;
6897   u8 address_set = 0;
6898   u32 grp_address_length = 0;
6899   ip4_address_t v4_grp_address, v4_src_address;
6900   ip6_address_t v6_grp_address, v6_src_address;
6901   mfib_itf_flags_t iflags = 0;
6902   mfib_entry_flags_t eflags = 0;
6903   int ret;
6904
6905   /* Parse args required to build the message */
6906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6907     {
6908       if (unformat (i, "sw_if_index %d", &sw_if_index))
6909         ;
6910       else if (unformat (i, "%U %U",
6911                          unformat_ip4_address, &v4_src_address,
6912                          unformat_ip4_address, &v4_grp_address))
6913         {
6914           grp_address_length = 64;
6915           address_set = 1;
6916           is_ipv6 = 0;
6917         }
6918       else if (unformat (i, "%U %U",
6919                          unformat_ip6_address, &v6_src_address,
6920                          unformat_ip6_address, &v6_grp_address))
6921         {
6922           grp_address_length = 256;
6923           address_set = 1;
6924           is_ipv6 = 1;
6925         }
6926       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6927         {
6928           memset (&v4_src_address, 0, sizeof (v4_src_address));
6929           grp_address_length = 32;
6930           address_set = 1;
6931           is_ipv6 = 0;
6932         }
6933       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6934         {
6935           memset (&v6_src_address, 0, sizeof (v6_src_address));
6936           grp_address_length = 128;
6937           address_set = 1;
6938           is_ipv6 = 1;
6939         }
6940       else if (unformat (i, "/%d", &grp_address_length))
6941         ;
6942       else if (unformat (i, "local"))
6943         {
6944           is_local = 1;
6945         }
6946       else if (unformat (i, "del"))
6947         is_add = 0;
6948       else if (unformat (i, "add"))
6949         is_add = 1;
6950       else if (unformat (i, "vrf %d", &vrf_id))
6951         ;
6952       else if (unformat (i, "create-vrf"))
6953         create_vrf_if_needed = 1;
6954       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6955         ;
6956       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6957         ;
6958       else
6959         {
6960           clib_warning ("parse error '%U'", format_unformat_error, i);
6961           return -99;
6962         }
6963     }
6964
6965   if (address_set == 0)
6966     {
6967       errmsg ("missing addresses\n");
6968       return -99;
6969     }
6970
6971   /* Construct the API message */
6972   M (IP_MROUTE_ADD_DEL, mp);
6973
6974   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6975   mp->table_id = ntohl (vrf_id);
6976   mp->create_vrf_if_needed = create_vrf_if_needed;
6977
6978   mp->is_add = is_add;
6979   mp->is_ipv6 = is_ipv6;
6980   mp->is_local = is_local;
6981   mp->itf_flags = ntohl (iflags);
6982   mp->entry_flags = ntohl (eflags);
6983   mp->grp_address_length = grp_address_length;
6984   mp->grp_address_length = ntohs (mp->grp_address_length);
6985
6986   if (is_ipv6)
6987     {
6988       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6989       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6990     }
6991   else
6992     {
6993       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6994       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6995
6996     }
6997
6998   /* send it... */
6999   S (mp);
7000   /* Wait for a reply... */
7001   W (ret);
7002   return ret;
7003 }
7004
7005 static int
7006 api_mpls_route_add_del (vat_main_t * vam)
7007 {
7008   unformat_input_t *i = vam->input;
7009   vl_api_mpls_route_add_del_t *mp;
7010   u32 sw_if_index = ~0, table_id = 0;
7011   u8 create_table_if_needed = 0;
7012   u8 is_add = 1;
7013   u32 next_hop_weight = 1;
7014   u8 is_multipath = 0;
7015   u32 next_hop_table_id = 0;
7016   u8 next_hop_set = 0;
7017   ip4_address_t v4_next_hop_address = {
7018     .as_u32 = 0,
7019   };
7020   ip6_address_t v6_next_hop_address = { {0} };
7021   int count = 1;
7022   int j;
7023   f64 before = 0;
7024   u32 classify_table_index = ~0;
7025   u8 is_classify = 0;
7026   u8 resolve_host = 0, resolve_attached = 0;
7027   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7028   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7029   mpls_label_t *next_hop_out_label_stack = NULL;
7030   mpls_label_t local_label = MPLS_LABEL_INVALID;
7031   u8 is_eos = 0;
7032   u8 next_hop_proto_is_ip4 = 1;
7033
7034   /* Parse args required to build the message */
7035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7036     {
7037       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7038         ;
7039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7040         ;
7041       else if (unformat (i, "%d", &local_label))
7042         ;
7043       else if (unformat (i, "eos"))
7044         is_eos = 1;
7045       else if (unformat (i, "non-eos"))
7046         is_eos = 0;
7047       else if (unformat (i, "via %U", unformat_ip4_address,
7048                          &v4_next_hop_address))
7049         {
7050           next_hop_set = 1;
7051           next_hop_proto_is_ip4 = 1;
7052         }
7053       else if (unformat (i, "via %U", unformat_ip6_address,
7054                          &v6_next_hop_address))
7055         {
7056           next_hop_set = 1;
7057           next_hop_proto_is_ip4 = 0;
7058         }
7059       else if (unformat (i, "weight %d", &next_hop_weight))
7060         ;
7061       else if (unformat (i, "create-table"))
7062         create_table_if_needed = 1;
7063       else if (unformat (i, "classify %d", &classify_table_index))
7064         {
7065           is_classify = 1;
7066         }
7067       else if (unformat (i, "del"))
7068         is_add = 0;
7069       else if (unformat (i, "add"))
7070         is_add = 1;
7071       else if (unformat (i, "resolve-via-host"))
7072         resolve_host = 1;
7073       else if (unformat (i, "resolve-via-attached"))
7074         resolve_attached = 1;
7075       else if (unformat (i, "multipath"))
7076         is_multipath = 1;
7077       else if (unformat (i, "count %d", &count))
7078         ;
7079       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7080         {
7081           next_hop_set = 1;
7082           next_hop_proto_is_ip4 = 1;
7083         }
7084       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7085         {
7086           next_hop_set = 1;
7087           next_hop_proto_is_ip4 = 0;
7088         }
7089       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7090         ;
7091       else if (unformat (i, "via-label %d", &next_hop_via_label))
7092         ;
7093       else if (unformat (i, "out-label %d", &next_hop_out_label))
7094         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7095       else
7096         {
7097           clib_warning ("parse error '%U'", format_unformat_error, i);
7098           return -99;
7099         }
7100     }
7101
7102   if (!next_hop_set && !is_classify)
7103     {
7104       errmsg ("next hop / classify not set");
7105       return -99;
7106     }
7107
7108   if (MPLS_LABEL_INVALID == local_label)
7109     {
7110       errmsg ("missing label");
7111       return -99;
7112     }
7113
7114   if (count > 1)
7115     {
7116       /* Turn on async mode */
7117       vam->async_mode = 1;
7118       vam->async_errors = 0;
7119       before = vat_time_now (vam);
7120     }
7121
7122   for (j = 0; j < count; j++)
7123     {
7124       /* Construct the API message */
7125       M2 (MPLS_ROUTE_ADD_DEL, mp,
7126           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7127
7128       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7129       mp->mr_table_id = ntohl (table_id);
7130       mp->mr_create_table_if_needed = create_table_if_needed;
7131
7132       mp->mr_is_add = is_add;
7133       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7134       mp->mr_is_classify = is_classify;
7135       mp->mr_is_multipath = is_multipath;
7136       mp->mr_is_resolve_host = resolve_host;
7137       mp->mr_is_resolve_attached = resolve_attached;
7138       mp->mr_next_hop_weight = next_hop_weight;
7139       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7140       mp->mr_classify_table_index = ntohl (classify_table_index);
7141       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7142       mp->mr_label = ntohl (local_label);
7143       mp->mr_eos = is_eos;
7144
7145       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7146       if (0 != mp->mr_next_hop_n_out_labels)
7147         {
7148           memcpy (mp->mr_next_hop_out_label_stack,
7149                   next_hop_out_label_stack,
7150                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7151           vec_free (next_hop_out_label_stack);
7152         }
7153
7154       if (next_hop_set)
7155         {
7156           if (next_hop_proto_is_ip4)
7157             {
7158               clib_memcpy (mp->mr_next_hop,
7159                            &v4_next_hop_address,
7160                            sizeof (v4_next_hop_address));
7161             }
7162           else
7163             {
7164               clib_memcpy (mp->mr_next_hop,
7165                            &v6_next_hop_address,
7166                            sizeof (v6_next_hop_address));
7167             }
7168         }
7169       local_label++;
7170
7171       /* send it... */
7172       S (mp);
7173       /* If we receive SIGTERM, stop now... */
7174       if (vam->do_exit)
7175         break;
7176     }
7177
7178   /* When testing multiple add/del ops, use a control-ping to sync */
7179   if (count > 1)
7180     {
7181       vl_api_control_ping_t *mp_ping;
7182       f64 after;
7183       f64 timeout;
7184
7185       /* Shut off async mode */
7186       vam->async_mode = 0;
7187
7188       M (CONTROL_PING, mp_ping);
7189       S (mp_ping);
7190
7191       timeout = vat_time_now (vam) + 1.0;
7192       while (vat_time_now (vam) < timeout)
7193         if (vam->result_ready == 1)
7194           goto out;
7195       vam->retval = -99;
7196
7197     out:
7198       if (vam->retval == -99)
7199         errmsg ("timeout");
7200
7201       if (vam->async_errors > 0)
7202         {
7203           errmsg ("%d asynchronous errors", vam->async_errors);
7204           vam->retval = -98;
7205         }
7206       vam->async_errors = 0;
7207       after = vat_time_now (vam);
7208
7209       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7210       if (j > 0)
7211         count = j;
7212
7213       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7214              count, after - before, count / (after - before));
7215     }
7216   else
7217     {
7218       int ret;
7219
7220       /* Wait for a reply... */
7221       W (ret);
7222       return ret;
7223     }
7224
7225   /* Return the good/bad news */
7226   return (vam->retval);
7227 }
7228
7229 static int
7230 api_mpls_ip_bind_unbind (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_mpls_ip_bind_unbind_t *mp;
7234   u32 ip_table_id = 0;
7235   u8 create_table_if_needed = 0;
7236   u8 is_bind = 1;
7237   u8 is_ip4 = 1;
7238   ip4_address_t v4_address;
7239   ip6_address_t v6_address;
7240   u32 address_length;
7241   u8 address_set = 0;
7242   mpls_label_t local_label = MPLS_LABEL_INVALID;
7243   int ret;
7244
7245   /* Parse args required to build the message */
7246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7247     {
7248       if (unformat (i, "%U/%d", unformat_ip4_address,
7249                     &v4_address, &address_length))
7250         {
7251           is_ip4 = 1;
7252           address_set = 1;
7253         }
7254       else if (unformat (i, "%U/%d", unformat_ip6_address,
7255                          &v6_address, &address_length))
7256         {
7257           is_ip4 = 0;
7258           address_set = 1;
7259         }
7260       else if (unformat (i, "%d", &local_label))
7261         ;
7262       else if (unformat (i, "create-table"))
7263         create_table_if_needed = 1;
7264       else if (unformat (i, "table-id %d", &ip_table_id))
7265         ;
7266       else if (unformat (i, "unbind"))
7267         is_bind = 0;
7268       else if (unformat (i, "bind"))
7269         is_bind = 1;
7270       else
7271         {
7272           clib_warning ("parse error '%U'", format_unformat_error, i);
7273           return -99;
7274         }
7275     }
7276
7277   if (!address_set)
7278     {
7279       errmsg ("IP addres not set");
7280       return -99;
7281     }
7282
7283   if (MPLS_LABEL_INVALID == local_label)
7284     {
7285       errmsg ("missing label");
7286       return -99;
7287     }
7288
7289   /* Construct the API message */
7290   M (MPLS_IP_BIND_UNBIND, mp);
7291
7292   mp->mb_create_table_if_needed = create_table_if_needed;
7293   mp->mb_is_bind = is_bind;
7294   mp->mb_is_ip4 = is_ip4;
7295   mp->mb_ip_table_id = ntohl (ip_table_id);
7296   mp->mb_mpls_table_id = 0;
7297   mp->mb_label = ntohl (local_label);
7298   mp->mb_address_length = address_length;
7299
7300   if (is_ip4)
7301     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7302   else
7303     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7304
7305   /* send it... */
7306   S (mp);
7307
7308   /* Wait for a reply... */
7309   W (ret);
7310   return ret;
7311 }
7312
7313 static int
7314 api_proxy_arp_add_del (vat_main_t * vam)
7315 {
7316   unformat_input_t *i = vam->input;
7317   vl_api_proxy_arp_add_del_t *mp;
7318   u32 vrf_id = 0;
7319   u8 is_add = 1;
7320   ip4_address_t lo, hi;
7321   u8 range_set = 0;
7322   int ret;
7323
7324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7325     {
7326       if (unformat (i, "vrf %d", &vrf_id))
7327         ;
7328       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7329                          unformat_ip4_address, &hi))
7330         range_set = 1;
7331       else if (unformat (i, "del"))
7332         is_add = 0;
7333       else
7334         {
7335           clib_warning ("parse error '%U'", format_unformat_error, i);
7336           return -99;
7337         }
7338     }
7339
7340   if (range_set == 0)
7341     {
7342       errmsg ("address range not set");
7343       return -99;
7344     }
7345
7346   M (PROXY_ARP_ADD_DEL, mp);
7347
7348   mp->vrf_id = ntohl (vrf_id);
7349   mp->is_add = is_add;
7350   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7351   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7352
7353   S (mp);
7354   W (ret);
7355   return ret;
7356 }
7357
7358 static int
7359 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7360 {
7361   unformat_input_t *i = vam->input;
7362   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7363   u32 sw_if_index;
7364   u8 enable = 1;
7365   u8 sw_if_index_set = 0;
7366   int ret;
7367
7368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7369     {
7370       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7371         sw_if_index_set = 1;
7372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7373         sw_if_index_set = 1;
7374       else if (unformat (i, "enable"))
7375         enable = 1;
7376       else if (unformat (i, "disable"))
7377         enable = 0;
7378       else
7379         {
7380           clib_warning ("parse error '%U'", format_unformat_error, i);
7381           return -99;
7382         }
7383     }
7384
7385   if (sw_if_index_set == 0)
7386     {
7387       errmsg ("missing interface name or sw_if_index");
7388       return -99;
7389     }
7390
7391   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7392
7393   mp->sw_if_index = ntohl (sw_if_index);
7394   mp->enable_disable = enable;
7395
7396   S (mp);
7397   W (ret);
7398   return ret;
7399 }
7400
7401 static int
7402 api_mpls_tunnel_add_del (vat_main_t * vam)
7403 {
7404   unformat_input_t *i = vam->input;
7405   vl_api_mpls_tunnel_add_del_t *mp;
7406
7407   u8 is_add = 1;
7408   u8 l2_only = 0;
7409   u32 sw_if_index = ~0;
7410   u32 next_hop_sw_if_index = ~0;
7411   u32 next_hop_proto_is_ip4 = 1;
7412
7413   u32 next_hop_table_id = 0;
7414   ip4_address_t v4_next_hop_address = {
7415     .as_u32 = 0,
7416   };
7417   ip6_address_t v6_next_hop_address = { {0} };
7418   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7419   int ret;
7420
7421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7422     {
7423       if (unformat (i, "add"))
7424         is_add = 1;
7425       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7426         is_add = 0;
7427       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7428         ;
7429       else if (unformat (i, "via %U",
7430                          unformat_ip4_address, &v4_next_hop_address))
7431         {
7432           next_hop_proto_is_ip4 = 1;
7433         }
7434       else if (unformat (i, "via %U",
7435                          unformat_ip6_address, &v6_next_hop_address))
7436         {
7437           next_hop_proto_is_ip4 = 0;
7438         }
7439       else if (unformat (i, "l2-only"))
7440         l2_only = 1;
7441       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7442         ;
7443       else if (unformat (i, "out-label %d", &next_hop_out_label))
7444         vec_add1 (labels, ntohl (next_hop_out_label));
7445       else
7446         {
7447           clib_warning ("parse error '%U'", format_unformat_error, i);
7448           return -99;
7449         }
7450     }
7451
7452   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7453
7454   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7455   mp->mt_sw_if_index = ntohl (sw_if_index);
7456   mp->mt_is_add = is_add;
7457   mp->mt_l2_only = l2_only;
7458   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7459   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7460
7461   mp->mt_next_hop_n_out_labels = vec_len (labels);
7462
7463   if (0 != mp->mt_next_hop_n_out_labels)
7464     {
7465       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7466                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7467       vec_free (labels);
7468     }
7469
7470   if (next_hop_proto_is_ip4)
7471     {
7472       clib_memcpy (mp->mt_next_hop,
7473                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7474     }
7475   else
7476     {
7477       clib_memcpy (mp->mt_next_hop,
7478                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7479     }
7480
7481   S (mp);
7482   W (ret);
7483   return ret;
7484 }
7485
7486 static int
7487 api_sw_interface_set_unnumbered (vat_main_t * vam)
7488 {
7489   unformat_input_t *i = vam->input;
7490   vl_api_sw_interface_set_unnumbered_t *mp;
7491   u32 sw_if_index;
7492   u32 unnum_sw_index = ~0;
7493   u8 is_add = 1;
7494   u8 sw_if_index_set = 0;
7495   int ret;
7496
7497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7498     {
7499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7500         sw_if_index_set = 1;
7501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7502         sw_if_index_set = 1;
7503       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7504         ;
7505       else if (unformat (i, "del"))
7506         is_add = 0;
7507       else
7508         {
7509           clib_warning ("parse error '%U'", format_unformat_error, i);
7510           return -99;
7511         }
7512     }
7513
7514   if (sw_if_index_set == 0)
7515     {
7516       errmsg ("missing interface name or sw_if_index");
7517       return -99;
7518     }
7519
7520   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7521
7522   mp->sw_if_index = ntohl (sw_if_index);
7523   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7524   mp->is_add = is_add;
7525
7526   S (mp);
7527   W (ret);
7528   return ret;
7529 }
7530
7531 static int
7532 api_ip_neighbor_add_del (vat_main_t * vam)
7533 {
7534   unformat_input_t *i = vam->input;
7535   vl_api_ip_neighbor_add_del_t *mp;
7536   u32 sw_if_index;
7537   u8 sw_if_index_set = 0;
7538   u8 is_add = 1;
7539   u8 is_static = 0;
7540   u8 is_no_fib_entry = 0;
7541   u8 mac_address[6];
7542   u8 mac_set = 0;
7543   u8 v4_address_set = 0;
7544   u8 v6_address_set = 0;
7545   ip4_address_t v4address;
7546   ip6_address_t v6address;
7547   int ret;
7548
7549   memset (mac_address, 0, sizeof (mac_address));
7550
7551   /* Parse args required to build the message */
7552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7553     {
7554       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7555         {
7556           mac_set = 1;
7557         }
7558       else if (unformat (i, "del"))
7559         is_add = 0;
7560       else
7561         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7562         sw_if_index_set = 1;
7563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7564         sw_if_index_set = 1;
7565       else if (unformat (i, "is_static"))
7566         is_static = 1;
7567       else if (unformat (i, "no-fib-entry"))
7568         is_no_fib_entry = 1;
7569       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7570         v4_address_set = 1;
7571       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7572         v6_address_set = 1;
7573       else
7574         {
7575           clib_warning ("parse error '%U'", format_unformat_error, i);
7576           return -99;
7577         }
7578     }
7579
7580   if (sw_if_index_set == 0)
7581     {
7582       errmsg ("missing interface name or sw_if_index");
7583       return -99;
7584     }
7585   if (v4_address_set && v6_address_set)
7586     {
7587       errmsg ("both v4 and v6 addresses set");
7588       return -99;
7589     }
7590   if (!v4_address_set && !v6_address_set)
7591     {
7592       errmsg ("no address set");
7593       return -99;
7594     }
7595
7596   /* Construct the API message */
7597   M (IP_NEIGHBOR_ADD_DEL, mp);
7598
7599   mp->sw_if_index = ntohl (sw_if_index);
7600   mp->is_add = is_add;
7601   mp->is_static = is_static;
7602   mp->is_no_adj_fib = is_no_fib_entry;
7603   if (mac_set)
7604     clib_memcpy (mp->mac_address, mac_address, 6);
7605   if (v6_address_set)
7606     {
7607       mp->is_ipv6 = 1;
7608       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7609     }
7610   else
7611     {
7612       /* mp->is_ipv6 = 0; via memset in M macro above */
7613       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7614     }
7615
7616   /* send it... */
7617   S (mp);
7618
7619   /* Wait for a reply, return good/bad news  */
7620   W (ret);
7621   return ret;
7622 }
7623
7624 static int
7625 api_reset_vrf (vat_main_t * vam)
7626 {
7627   unformat_input_t *i = vam->input;
7628   vl_api_reset_vrf_t *mp;
7629   u32 vrf_id = 0;
7630   u8 is_ipv6 = 0;
7631   u8 vrf_id_set = 0;
7632   int ret;
7633
7634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7635     {
7636       if (unformat (i, "vrf %d", &vrf_id))
7637         vrf_id_set = 1;
7638       else if (unformat (i, "ipv6"))
7639         is_ipv6 = 1;
7640       else
7641         {
7642           clib_warning ("parse error '%U'", format_unformat_error, i);
7643           return -99;
7644         }
7645     }
7646
7647   if (vrf_id_set == 0)
7648     {
7649       errmsg ("missing vrf id");
7650       return -99;
7651     }
7652
7653   M (RESET_VRF, mp);
7654
7655   mp->vrf_id = ntohl (vrf_id);
7656   mp->is_ipv6 = is_ipv6;
7657
7658   S (mp);
7659   W (ret);
7660   return ret;
7661 }
7662
7663 static int
7664 api_create_vlan_subif (vat_main_t * vam)
7665 {
7666   unformat_input_t *i = vam->input;
7667   vl_api_create_vlan_subif_t *mp;
7668   u32 sw_if_index;
7669   u8 sw_if_index_set = 0;
7670   u32 vlan_id;
7671   u8 vlan_id_set = 0;
7672   int ret;
7673
7674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7675     {
7676       if (unformat (i, "sw_if_index %d", &sw_if_index))
7677         sw_if_index_set = 1;
7678       else
7679         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7680         sw_if_index_set = 1;
7681       else if (unformat (i, "vlan %d", &vlan_id))
7682         vlan_id_set = 1;
7683       else
7684         {
7685           clib_warning ("parse error '%U'", format_unformat_error, i);
7686           return -99;
7687         }
7688     }
7689
7690   if (sw_if_index_set == 0)
7691     {
7692       errmsg ("missing interface name or sw_if_index");
7693       return -99;
7694     }
7695
7696   if (vlan_id_set == 0)
7697     {
7698       errmsg ("missing vlan_id");
7699       return -99;
7700     }
7701   M (CREATE_VLAN_SUBIF, mp);
7702
7703   mp->sw_if_index = ntohl (sw_if_index);
7704   mp->vlan_id = ntohl (vlan_id);
7705
7706   S (mp);
7707   W (ret);
7708   return ret;
7709 }
7710
7711 #define foreach_create_subif_bit                \
7712 _(no_tags)                                      \
7713 _(one_tag)                                      \
7714 _(two_tags)                                     \
7715 _(dot1ad)                                       \
7716 _(exact_match)                                  \
7717 _(default_sub)                                  \
7718 _(outer_vlan_id_any)                            \
7719 _(inner_vlan_id_any)
7720
7721 static int
7722 api_create_subif (vat_main_t * vam)
7723 {
7724   unformat_input_t *i = vam->input;
7725   vl_api_create_subif_t *mp;
7726   u32 sw_if_index;
7727   u8 sw_if_index_set = 0;
7728   u32 sub_id;
7729   u8 sub_id_set = 0;
7730   u32 no_tags = 0;
7731   u32 one_tag = 0;
7732   u32 two_tags = 0;
7733   u32 dot1ad = 0;
7734   u32 exact_match = 0;
7735   u32 default_sub = 0;
7736   u32 outer_vlan_id_any = 0;
7737   u32 inner_vlan_id_any = 0;
7738   u32 tmp;
7739   u16 outer_vlan_id = 0;
7740   u16 inner_vlan_id = 0;
7741   int ret;
7742
7743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7744     {
7745       if (unformat (i, "sw_if_index %d", &sw_if_index))
7746         sw_if_index_set = 1;
7747       else
7748         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7749         sw_if_index_set = 1;
7750       else if (unformat (i, "sub_id %d", &sub_id))
7751         sub_id_set = 1;
7752       else if (unformat (i, "outer_vlan_id %d", &tmp))
7753         outer_vlan_id = tmp;
7754       else if (unformat (i, "inner_vlan_id %d", &tmp))
7755         inner_vlan_id = tmp;
7756
7757 #define _(a) else if (unformat (i, #a)) a = 1 ;
7758       foreach_create_subif_bit
7759 #undef _
7760         else
7761         {
7762           clib_warning ("parse error '%U'", format_unformat_error, i);
7763           return -99;
7764         }
7765     }
7766
7767   if (sw_if_index_set == 0)
7768     {
7769       errmsg ("missing interface name or sw_if_index");
7770       return -99;
7771     }
7772
7773   if (sub_id_set == 0)
7774     {
7775       errmsg ("missing sub_id");
7776       return -99;
7777     }
7778   M (CREATE_SUBIF, mp);
7779
7780   mp->sw_if_index = ntohl (sw_if_index);
7781   mp->sub_id = ntohl (sub_id);
7782
7783 #define _(a) mp->a = a;
7784   foreach_create_subif_bit;
7785 #undef _
7786
7787   mp->outer_vlan_id = ntohs (outer_vlan_id);
7788   mp->inner_vlan_id = ntohs (inner_vlan_id);
7789
7790   S (mp);
7791   W (ret);
7792   return ret;
7793 }
7794
7795 static int
7796 api_oam_add_del (vat_main_t * vam)
7797 {
7798   unformat_input_t *i = vam->input;
7799   vl_api_oam_add_del_t *mp;
7800   u32 vrf_id = 0;
7801   u8 is_add = 1;
7802   ip4_address_t src, dst;
7803   u8 src_set = 0;
7804   u8 dst_set = 0;
7805   int ret;
7806
7807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7808     {
7809       if (unformat (i, "vrf %d", &vrf_id))
7810         ;
7811       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7812         src_set = 1;
7813       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7814         dst_set = 1;
7815       else if (unformat (i, "del"))
7816         is_add = 0;
7817       else
7818         {
7819           clib_warning ("parse error '%U'", format_unformat_error, i);
7820           return -99;
7821         }
7822     }
7823
7824   if (src_set == 0)
7825     {
7826       errmsg ("missing src addr");
7827       return -99;
7828     }
7829
7830   if (dst_set == 0)
7831     {
7832       errmsg ("missing dst addr");
7833       return -99;
7834     }
7835
7836   M (OAM_ADD_DEL, mp);
7837
7838   mp->vrf_id = ntohl (vrf_id);
7839   mp->is_add = is_add;
7840   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7841   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7842
7843   S (mp);
7844   W (ret);
7845   return ret;
7846 }
7847
7848 static int
7849 api_reset_fib (vat_main_t * vam)
7850 {
7851   unformat_input_t *i = vam->input;
7852   vl_api_reset_fib_t *mp;
7853   u32 vrf_id = 0;
7854   u8 is_ipv6 = 0;
7855   u8 vrf_id_set = 0;
7856
7857   int ret;
7858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7859     {
7860       if (unformat (i, "vrf %d", &vrf_id))
7861         vrf_id_set = 1;
7862       else if (unformat (i, "ipv6"))
7863         is_ipv6 = 1;
7864       else
7865         {
7866           clib_warning ("parse error '%U'", format_unformat_error, i);
7867           return -99;
7868         }
7869     }
7870
7871   if (vrf_id_set == 0)
7872     {
7873       errmsg ("missing vrf id");
7874       return -99;
7875     }
7876
7877   M (RESET_FIB, mp);
7878
7879   mp->vrf_id = ntohl (vrf_id);
7880   mp->is_ipv6 = is_ipv6;
7881
7882   S (mp);
7883   W (ret);
7884   return ret;
7885 }
7886
7887 static int
7888 api_dhcp_proxy_config (vat_main_t * vam)
7889 {
7890   unformat_input_t *i = vam->input;
7891   vl_api_dhcp_proxy_config_t *mp;
7892   u32 rx_vrf_id = 0;
7893   u32 server_vrf_id = 0;
7894   u8 is_add = 1;
7895   u8 v4_address_set = 0;
7896   u8 v6_address_set = 0;
7897   ip4_address_t v4address;
7898   ip6_address_t v6address;
7899   u8 v4_src_address_set = 0;
7900   u8 v6_src_address_set = 0;
7901   ip4_address_t v4srcaddress;
7902   ip6_address_t v6srcaddress;
7903   int ret;
7904
7905   /* Parse args required to build the message */
7906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7907     {
7908       if (unformat (i, "del"))
7909         is_add = 0;
7910       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7911         ;
7912       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7913         ;
7914       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7915         v4_address_set = 1;
7916       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7917         v6_address_set = 1;
7918       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7919         v4_src_address_set = 1;
7920       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7921         v6_src_address_set = 1;
7922       else
7923         break;
7924     }
7925
7926   if (v4_address_set && v6_address_set)
7927     {
7928       errmsg ("both v4 and v6 server addresses set");
7929       return -99;
7930     }
7931   if (!v4_address_set && !v6_address_set)
7932     {
7933       errmsg ("no server addresses set");
7934       return -99;
7935     }
7936
7937   if (v4_src_address_set && v6_src_address_set)
7938     {
7939       errmsg ("both v4 and v6  src addresses set");
7940       return -99;
7941     }
7942   if (!v4_src_address_set && !v6_src_address_set)
7943     {
7944       errmsg ("no src addresses set");
7945       return -99;
7946     }
7947
7948   if (!(v4_src_address_set && v4_address_set) &&
7949       !(v6_src_address_set && v6_address_set))
7950     {
7951       errmsg ("no matching server and src addresses set");
7952       return -99;
7953     }
7954
7955   /* Construct the API message */
7956   M (DHCP_PROXY_CONFIG, mp);
7957
7958   mp->is_add = is_add;
7959   mp->rx_vrf_id = ntohl (rx_vrf_id);
7960   mp->server_vrf_id = ntohl (server_vrf_id);
7961   if (v6_address_set)
7962     {
7963       mp->is_ipv6 = 1;
7964       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7965       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7966     }
7967   else
7968     {
7969       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7970       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7971     }
7972
7973   /* send it... */
7974   S (mp);
7975
7976   /* Wait for a reply, return good/bad news  */
7977   W (ret);
7978   return ret;
7979 }
7980
7981 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7982 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7983
7984 static void
7985 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7986 {
7987   vat_main_t *vam = &vat_main;
7988   u32 i, count = mp->count;
7989   vl_api_dhcp_server_t *s;
7990
7991   if (mp->is_ipv6)
7992     print (vam->ofp,
7993            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7994            ntohl (mp->rx_vrf_id),
7995            format_ip6_address, mp->dhcp_src_address,
7996            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7997   else
7998     print (vam->ofp,
7999            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8000            ntohl (mp->rx_vrf_id),
8001            format_ip4_address, mp->dhcp_src_address,
8002            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8003
8004   for (i = 0; i < count; i++)
8005     {
8006       s = &mp->servers[i];
8007
8008       if (mp->is_ipv6)
8009         print (vam->ofp,
8010                " Server Table-ID %d, Server Address %U",
8011                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8012       else
8013         print (vam->ofp,
8014                " Server Table-ID %d, Server Address %U",
8015                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8016     }
8017 }
8018
8019 static void vl_api_dhcp_proxy_details_t_handler_json
8020   (vl_api_dhcp_proxy_details_t * mp)
8021 {
8022   vat_main_t *vam = &vat_main;
8023   vat_json_node_t *node = NULL;
8024   u32 i, count = mp->count;
8025   struct in_addr ip4;
8026   struct in6_addr ip6;
8027   vl_api_dhcp_server_t *s;
8028
8029   if (VAT_JSON_ARRAY != vam->json_tree.type)
8030     {
8031       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8032       vat_json_init_array (&vam->json_tree);
8033     }
8034   node = vat_json_array_add (&vam->json_tree);
8035
8036   vat_json_init_object (node);
8037   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8038   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8039   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8040
8041   if (mp->is_ipv6)
8042     {
8043       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8044       vat_json_object_add_ip6 (node, "src_address", ip6);
8045     }
8046   else
8047     {
8048       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8049       vat_json_object_add_ip4 (node, "src_address", ip4);
8050     }
8051
8052   for (i = 0; i < count; i++)
8053     {
8054       s = &mp->servers[i];
8055
8056       vat_json_object_add_uint (node, "server-table-id",
8057                                 ntohl (s->server_vrf_id));
8058
8059       if (mp->is_ipv6)
8060         {
8061           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8062           vat_json_object_add_ip4 (node, "src_address", ip4);
8063         }
8064       else
8065         {
8066           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8067           vat_json_object_add_ip6 (node, "server_address", ip6);
8068         }
8069     }
8070 }
8071
8072 static int
8073 api_dhcp_proxy_dump (vat_main_t * vam)
8074 {
8075   unformat_input_t *i = vam->input;
8076   vl_api_control_ping_t *mp_ping;
8077   vl_api_dhcp_proxy_dump_t *mp;
8078   u8 is_ipv6 = 0;
8079   int ret;
8080
8081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8082     {
8083       if (unformat (i, "ipv6"))
8084         is_ipv6 = 1;
8085       else
8086         {
8087           clib_warning ("parse error '%U'", format_unformat_error, i);
8088           return -99;
8089         }
8090     }
8091
8092   M (DHCP_PROXY_DUMP, mp);
8093
8094   mp->is_ip6 = is_ipv6;
8095   S (mp);
8096
8097   /* Use a control ping for synchronization */
8098   M (CONTROL_PING, mp_ping);
8099   S (mp_ping);
8100
8101   W (ret);
8102   return ret;
8103 }
8104
8105 static int
8106 api_dhcp_proxy_set_vss (vat_main_t * vam)
8107 {
8108   unformat_input_t *i = vam->input;
8109   vl_api_dhcp_proxy_set_vss_t *mp;
8110   u8 is_ipv6 = 0;
8111   u8 is_add = 1;
8112   u32 tbl_id;
8113   u8 tbl_id_set = 0;
8114   u32 oui;
8115   u8 oui_set = 0;
8116   u32 fib_id;
8117   u8 fib_id_set = 0;
8118   int ret;
8119
8120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8121     {
8122       if (unformat (i, "tbl_id %d", &tbl_id))
8123         tbl_id_set = 1;
8124       if (unformat (i, "fib_id %d", &fib_id))
8125         fib_id_set = 1;
8126       if (unformat (i, "oui %d", &oui))
8127         oui_set = 1;
8128       else if (unformat (i, "ipv6"))
8129         is_ipv6 = 1;
8130       else if (unformat (i, "del"))
8131         is_add = 0;
8132       else
8133         {
8134           clib_warning ("parse error '%U'", format_unformat_error, i);
8135           return -99;
8136         }
8137     }
8138
8139   if (tbl_id_set == 0)
8140     {
8141       errmsg ("missing tbl id");
8142       return -99;
8143     }
8144
8145   if (fib_id_set == 0)
8146     {
8147       errmsg ("missing fib id");
8148       return -99;
8149     }
8150   if (oui_set == 0)
8151     {
8152       errmsg ("missing oui");
8153       return -99;
8154     }
8155
8156   M (DHCP_PROXY_SET_VSS, mp);
8157   mp->tbl_id = ntohl (tbl_id);
8158   mp->fib_id = ntohl (fib_id);
8159   mp->oui = ntohl (oui);
8160   mp->is_ipv6 = is_ipv6;
8161   mp->is_add = is_add;
8162
8163   S (mp);
8164   W (ret);
8165   return ret;
8166 }
8167
8168 static int
8169 api_dhcp_client_config (vat_main_t * vam)
8170 {
8171   unformat_input_t *i = vam->input;
8172   vl_api_dhcp_client_config_t *mp;
8173   u32 sw_if_index;
8174   u8 sw_if_index_set = 0;
8175   u8 is_add = 1;
8176   u8 *hostname = 0;
8177   u8 disable_event = 0;
8178   int ret;
8179
8180   /* Parse args required to build the message */
8181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8182     {
8183       if (unformat (i, "del"))
8184         is_add = 0;
8185       else
8186         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8187         sw_if_index_set = 1;
8188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8189         sw_if_index_set = 1;
8190       else if (unformat (i, "hostname %s", &hostname))
8191         ;
8192       else if (unformat (i, "disable_event"))
8193         disable_event = 1;
8194       else
8195         break;
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 (vec_len (hostname) > 63)
8205     {
8206       errmsg ("hostname too long");
8207     }
8208   vec_add1 (hostname, 0);
8209
8210   /* Construct the API message */
8211   M (DHCP_CLIENT_CONFIG, mp);
8212
8213   mp->sw_if_index = htonl (sw_if_index);
8214   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8215   vec_free (hostname);
8216   mp->is_add = is_add;
8217   mp->want_dhcp_event = disable_event ? 0 : 1;
8218   mp->pid = htonl (getpid ());
8219
8220   /* send it... */
8221   S (mp);
8222
8223   /* Wait for a reply, return good/bad news  */
8224   W (ret);
8225   return ret;
8226 }
8227
8228 static int
8229 api_set_ip_flow_hash (vat_main_t * vam)
8230 {
8231   unformat_input_t *i = vam->input;
8232   vl_api_set_ip_flow_hash_t *mp;
8233   u32 vrf_id = 0;
8234   u8 is_ipv6 = 0;
8235   u8 vrf_id_set = 0;
8236   u8 src = 0;
8237   u8 dst = 0;
8238   u8 sport = 0;
8239   u8 dport = 0;
8240   u8 proto = 0;
8241   u8 reverse = 0;
8242   int ret;
8243
8244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8245     {
8246       if (unformat (i, "vrf %d", &vrf_id))
8247         vrf_id_set = 1;
8248       else if (unformat (i, "ipv6"))
8249         is_ipv6 = 1;
8250       else if (unformat (i, "src"))
8251         src = 1;
8252       else if (unformat (i, "dst"))
8253         dst = 1;
8254       else if (unformat (i, "sport"))
8255         sport = 1;
8256       else if (unformat (i, "dport"))
8257         dport = 1;
8258       else if (unformat (i, "proto"))
8259         proto = 1;
8260       else if (unformat (i, "reverse"))
8261         reverse = 1;
8262
8263       else
8264         {
8265           clib_warning ("parse error '%U'", format_unformat_error, i);
8266           return -99;
8267         }
8268     }
8269
8270   if (vrf_id_set == 0)
8271     {
8272       errmsg ("missing vrf id");
8273       return -99;
8274     }
8275
8276   M (SET_IP_FLOW_HASH, mp);
8277   mp->src = src;
8278   mp->dst = dst;
8279   mp->sport = sport;
8280   mp->dport = dport;
8281   mp->proto = proto;
8282   mp->reverse = reverse;
8283   mp->vrf_id = ntohl (vrf_id);
8284   mp->is_ipv6 = is_ipv6;
8285
8286   S (mp);
8287   W (ret);
8288   return ret;
8289 }
8290
8291 static int
8292 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8293 {
8294   unformat_input_t *i = vam->input;
8295   vl_api_sw_interface_ip6_enable_disable_t *mp;
8296   u32 sw_if_index;
8297   u8 sw_if_index_set = 0;
8298   u8 enable = 0;
8299   int ret;
8300
8301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8302     {
8303       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8304         sw_if_index_set = 1;
8305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8306         sw_if_index_set = 1;
8307       else if (unformat (i, "enable"))
8308         enable = 1;
8309       else if (unformat (i, "disable"))
8310         enable = 0;
8311       else
8312         {
8313           clib_warning ("parse error '%U'", format_unformat_error, i);
8314           return -99;
8315         }
8316     }
8317
8318   if (sw_if_index_set == 0)
8319     {
8320       errmsg ("missing interface name or sw_if_index");
8321       return -99;
8322     }
8323
8324   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8325
8326   mp->sw_if_index = ntohl (sw_if_index);
8327   mp->enable = enable;
8328
8329   S (mp);
8330   W (ret);
8331   return ret;
8332 }
8333
8334 static int
8335 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8336 {
8337   unformat_input_t *i = vam->input;
8338   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8339   u32 sw_if_index;
8340   u8 sw_if_index_set = 0;
8341   u8 v6_address_set = 0;
8342   ip6_address_t v6address;
8343   int ret;
8344
8345   /* Parse args required to build the message */
8346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8347     {
8348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8349         sw_if_index_set = 1;
8350       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8351         sw_if_index_set = 1;
8352       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8353         v6_address_set = 1;
8354       else
8355         break;
8356     }
8357
8358   if (sw_if_index_set == 0)
8359     {
8360       errmsg ("missing interface name or sw_if_index");
8361       return -99;
8362     }
8363   if (!v6_address_set)
8364     {
8365       errmsg ("no address set");
8366       return -99;
8367     }
8368
8369   /* Construct the API message */
8370   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8371
8372   mp->sw_if_index = ntohl (sw_if_index);
8373   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8374
8375   /* send it... */
8376   S (mp);
8377
8378   /* Wait for a reply, return good/bad news  */
8379   W (ret);
8380   return ret;
8381 }
8382
8383 static int
8384 api_ip6nd_proxy_add_del (vat_main_t * vam)
8385 {
8386   unformat_input_t *i = vam->input;
8387   vl_api_ip6nd_proxy_add_del_t *mp;
8388   u32 sw_if_index = ~0;
8389   u8 v6_address_set = 0;
8390   ip6_address_t v6address;
8391   u8 is_del = 0;
8392   int ret;
8393
8394   /* Parse args required to build the message */
8395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8396     {
8397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8398         ;
8399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8400         ;
8401       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8402         v6_address_set = 1;
8403       if (unformat (i, "del"))
8404         is_del = 1;
8405       else
8406         {
8407           clib_warning ("parse error '%U'", format_unformat_error, i);
8408           return -99;
8409         }
8410     }
8411
8412   if (sw_if_index == ~0)
8413     {
8414       errmsg ("missing interface name or sw_if_index");
8415       return -99;
8416     }
8417   if (!v6_address_set)
8418     {
8419       errmsg ("no address set");
8420       return -99;
8421     }
8422
8423   /* Construct the API message */
8424   M (IP6ND_PROXY_ADD_DEL, mp);
8425
8426   mp->is_del = is_del;
8427   mp->sw_if_index = ntohl (sw_if_index);
8428   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8429
8430   /* send it... */
8431   S (mp);
8432
8433   /* Wait for a reply, return good/bad news  */
8434   W (ret);
8435   return ret;
8436 }
8437
8438 static int
8439 api_ip6nd_proxy_dump (vat_main_t * vam)
8440 {
8441   vl_api_ip6nd_proxy_dump_t *mp;
8442   vl_api_control_ping_t *mp_ping;
8443   int ret;
8444
8445   M (IP6ND_PROXY_DUMP, mp);
8446
8447   S (mp);
8448
8449   /* Use a control ping for synchronization */
8450   M (CONTROL_PING, mp_ping);
8451   S (mp_ping);
8452
8453   W (ret);
8454   return ret;
8455 }
8456
8457 static void vl_api_ip6nd_proxy_details_t_handler
8458   (vl_api_ip6nd_proxy_details_t * mp)
8459 {
8460   vat_main_t *vam = &vat_main;
8461
8462   print (vam->ofp, "host %U sw_if_index %d",
8463          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8464 }
8465
8466 static void vl_api_ip6nd_proxy_details_t_handler_json
8467   (vl_api_ip6nd_proxy_details_t * mp)
8468 {
8469   vat_main_t *vam = &vat_main;
8470   struct in6_addr ip6;
8471   vat_json_node_t *node = NULL;
8472
8473   if (VAT_JSON_ARRAY != vam->json_tree.type)
8474     {
8475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8476       vat_json_init_array (&vam->json_tree);
8477     }
8478   node = vat_json_array_add (&vam->json_tree);
8479
8480   vat_json_init_object (node);
8481   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8482
8483   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8484   vat_json_object_add_ip6 (node, "host", ip6);
8485 }
8486
8487 static int
8488 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8489 {
8490   unformat_input_t *i = vam->input;
8491   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8492   u32 sw_if_index;
8493   u8 sw_if_index_set = 0;
8494   u32 address_length = 0;
8495   u8 v6_address_set = 0;
8496   ip6_address_t v6address;
8497   u8 use_default = 0;
8498   u8 no_advertise = 0;
8499   u8 off_link = 0;
8500   u8 no_autoconfig = 0;
8501   u8 no_onlink = 0;
8502   u8 is_no = 0;
8503   u32 val_lifetime = 0;
8504   u32 pref_lifetime = 0;
8505   int ret;
8506
8507   /* Parse args required to build the message */
8508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8509     {
8510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8511         sw_if_index_set = 1;
8512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8513         sw_if_index_set = 1;
8514       else if (unformat (i, "%U/%d",
8515                          unformat_ip6_address, &v6address, &address_length))
8516         v6_address_set = 1;
8517       else if (unformat (i, "val_life %d", &val_lifetime))
8518         ;
8519       else if (unformat (i, "pref_life %d", &pref_lifetime))
8520         ;
8521       else if (unformat (i, "def"))
8522         use_default = 1;
8523       else if (unformat (i, "noadv"))
8524         no_advertise = 1;
8525       else if (unformat (i, "offl"))
8526         off_link = 1;
8527       else if (unformat (i, "noauto"))
8528         no_autoconfig = 1;
8529       else if (unformat (i, "nolink"))
8530         no_onlink = 1;
8531       else if (unformat (i, "isno"))
8532         is_no = 1;
8533       else
8534         {
8535           clib_warning ("parse error '%U'", format_unformat_error, i);
8536           return -99;
8537         }
8538     }
8539
8540   if (sw_if_index_set == 0)
8541     {
8542       errmsg ("missing interface name or sw_if_index");
8543       return -99;
8544     }
8545   if (!v6_address_set)
8546     {
8547       errmsg ("no address set");
8548       return -99;
8549     }
8550
8551   /* Construct the API message */
8552   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8553
8554   mp->sw_if_index = ntohl (sw_if_index);
8555   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8556   mp->address_length = address_length;
8557   mp->use_default = use_default;
8558   mp->no_advertise = no_advertise;
8559   mp->off_link = off_link;
8560   mp->no_autoconfig = no_autoconfig;
8561   mp->no_onlink = no_onlink;
8562   mp->is_no = is_no;
8563   mp->val_lifetime = ntohl (val_lifetime);
8564   mp->pref_lifetime = ntohl (pref_lifetime);
8565
8566   /* send it... */
8567   S (mp);
8568
8569   /* Wait for a reply, return good/bad news  */
8570   W (ret);
8571   return ret;
8572 }
8573
8574 static int
8575 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8576 {
8577   unformat_input_t *i = vam->input;
8578   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8579   u32 sw_if_index;
8580   u8 sw_if_index_set = 0;
8581   u8 suppress = 0;
8582   u8 managed = 0;
8583   u8 other = 0;
8584   u8 ll_option = 0;
8585   u8 send_unicast = 0;
8586   u8 cease = 0;
8587   u8 is_no = 0;
8588   u8 default_router = 0;
8589   u32 max_interval = 0;
8590   u32 min_interval = 0;
8591   u32 lifetime = 0;
8592   u32 initial_count = 0;
8593   u32 initial_interval = 0;
8594   int ret;
8595
8596
8597   /* Parse args required to build the message */
8598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8599     {
8600       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8601         sw_if_index_set = 1;
8602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8603         sw_if_index_set = 1;
8604       else if (unformat (i, "maxint %d", &max_interval))
8605         ;
8606       else if (unformat (i, "minint %d", &min_interval))
8607         ;
8608       else if (unformat (i, "life %d", &lifetime))
8609         ;
8610       else if (unformat (i, "count %d", &initial_count))
8611         ;
8612       else if (unformat (i, "interval %d", &initial_interval))
8613         ;
8614       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8615         suppress = 1;
8616       else if (unformat (i, "managed"))
8617         managed = 1;
8618       else if (unformat (i, "other"))
8619         other = 1;
8620       else if (unformat (i, "ll"))
8621         ll_option = 1;
8622       else if (unformat (i, "send"))
8623         send_unicast = 1;
8624       else if (unformat (i, "cease"))
8625         cease = 1;
8626       else if (unformat (i, "isno"))
8627         is_no = 1;
8628       else if (unformat (i, "def"))
8629         default_router = 1;
8630       else
8631         {
8632           clib_warning ("parse error '%U'", format_unformat_error, i);
8633           return -99;
8634         }
8635     }
8636
8637   if (sw_if_index_set == 0)
8638     {
8639       errmsg ("missing interface name or sw_if_index");
8640       return -99;
8641     }
8642
8643   /* Construct the API message */
8644   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8645
8646   mp->sw_if_index = ntohl (sw_if_index);
8647   mp->max_interval = ntohl (max_interval);
8648   mp->min_interval = ntohl (min_interval);
8649   mp->lifetime = ntohl (lifetime);
8650   mp->initial_count = ntohl (initial_count);
8651   mp->initial_interval = ntohl (initial_interval);
8652   mp->suppress = suppress;
8653   mp->managed = managed;
8654   mp->other = other;
8655   mp->ll_option = ll_option;
8656   mp->send_unicast = send_unicast;
8657   mp->cease = cease;
8658   mp->is_no = is_no;
8659   mp->default_router = default_router;
8660
8661   /* send it... */
8662   S (mp);
8663
8664   /* Wait for a reply, return good/bad news  */
8665   W (ret);
8666   return ret;
8667 }
8668
8669 static int
8670 api_set_arp_neighbor_limit (vat_main_t * vam)
8671 {
8672   unformat_input_t *i = vam->input;
8673   vl_api_set_arp_neighbor_limit_t *mp;
8674   u32 arp_nbr_limit;
8675   u8 limit_set = 0;
8676   u8 is_ipv6 = 0;
8677   int ret;
8678
8679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8680     {
8681       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8682         limit_set = 1;
8683       else if (unformat (i, "ipv6"))
8684         is_ipv6 = 1;
8685       else
8686         {
8687           clib_warning ("parse error '%U'", format_unformat_error, i);
8688           return -99;
8689         }
8690     }
8691
8692   if (limit_set == 0)
8693     {
8694       errmsg ("missing limit value");
8695       return -99;
8696     }
8697
8698   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8699
8700   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8701   mp->is_ipv6 = is_ipv6;
8702
8703   S (mp);
8704   W (ret);
8705   return ret;
8706 }
8707
8708 static int
8709 api_l2_patch_add_del (vat_main_t * vam)
8710 {
8711   unformat_input_t *i = vam->input;
8712   vl_api_l2_patch_add_del_t *mp;
8713   u32 rx_sw_if_index;
8714   u8 rx_sw_if_index_set = 0;
8715   u32 tx_sw_if_index;
8716   u8 tx_sw_if_index_set = 0;
8717   u8 is_add = 1;
8718   int ret;
8719
8720   /* Parse args required to build the message */
8721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8722     {
8723       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8724         rx_sw_if_index_set = 1;
8725       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8726         tx_sw_if_index_set = 1;
8727       else if (unformat (i, "rx"))
8728         {
8729           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8730             {
8731               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8732                             &rx_sw_if_index))
8733                 rx_sw_if_index_set = 1;
8734             }
8735           else
8736             break;
8737         }
8738       else if (unformat (i, "tx"))
8739         {
8740           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8741             {
8742               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8743                             &tx_sw_if_index))
8744                 tx_sw_if_index_set = 1;
8745             }
8746           else
8747             break;
8748         }
8749       else if (unformat (i, "del"))
8750         is_add = 0;
8751       else
8752         break;
8753     }
8754
8755   if (rx_sw_if_index_set == 0)
8756     {
8757       errmsg ("missing rx interface name or rx_sw_if_index");
8758       return -99;
8759     }
8760
8761   if (tx_sw_if_index_set == 0)
8762     {
8763       errmsg ("missing tx interface name or tx_sw_if_index");
8764       return -99;
8765     }
8766
8767   M (L2_PATCH_ADD_DEL, mp);
8768
8769   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8770   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8771   mp->is_add = is_add;
8772
8773   S (mp);
8774   W (ret);
8775   return ret;
8776 }
8777
8778 u8 is_del;
8779 u8 localsid_addr[16];
8780 u8 end_psp;
8781 u8 behavior;
8782 u32 sw_if_index;
8783 u32 vlan_index;
8784 u32 fib_table;
8785 u8 nh_addr[16];
8786
8787 static int
8788 api_sr_localsid_add_del (vat_main_t * vam)
8789 {
8790   unformat_input_t *i = vam->input;
8791   vl_api_sr_localsid_add_del_t *mp;
8792
8793   u8 is_del;
8794   ip6_address_t localsid;
8795   u8 end_psp = 0;
8796   u8 behavior = ~0;
8797   u32 sw_if_index;
8798   u32 fib_table = ~(u32) 0;
8799   ip6_address_t next_hop;
8800
8801   bool nexthop_set = 0;
8802
8803   int ret;
8804
8805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8806     {
8807       if (unformat (i, "del"))
8808         is_del = 1;
8809       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8810       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8811         nexthop_set = 1;
8812       else if (unformat (i, "behavior %u", &behavior));
8813       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8814       else if (unformat (i, "fib-table %u", &fib_table));
8815       else if (unformat (i, "end.psp %u", &behavior));
8816       else
8817         break;
8818     }
8819
8820   M (SR_LOCALSID_ADD_DEL, mp);
8821
8822   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8823   if (nexthop_set)
8824     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8825   mp->behavior = behavior;
8826   mp->sw_if_index = ntohl (sw_if_index);
8827   mp->fib_table = ntohl (fib_table);
8828   mp->end_psp = end_psp;
8829   mp->is_del = is_del;
8830
8831   S (mp);
8832   W (ret);
8833   return ret;
8834 }
8835
8836 static int
8837 api_ioam_enable (vat_main_t * vam)
8838 {
8839   unformat_input_t *input = vam->input;
8840   vl_api_ioam_enable_t *mp;
8841   u32 id = 0;
8842   int has_trace_option = 0;
8843   int has_pot_option = 0;
8844   int has_seqno_option = 0;
8845   int has_analyse_option = 0;
8846   int ret;
8847
8848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8849     {
8850       if (unformat (input, "trace"))
8851         has_trace_option = 1;
8852       else if (unformat (input, "pot"))
8853         has_pot_option = 1;
8854       else if (unformat (input, "seqno"))
8855         has_seqno_option = 1;
8856       else if (unformat (input, "analyse"))
8857         has_analyse_option = 1;
8858       else
8859         break;
8860     }
8861   M (IOAM_ENABLE, mp);
8862   mp->id = htons (id);
8863   mp->seqno = has_seqno_option;
8864   mp->analyse = has_analyse_option;
8865   mp->pot_enable = has_pot_option;
8866   mp->trace_enable = has_trace_option;
8867
8868   S (mp);
8869   W (ret);
8870   return ret;
8871 }
8872
8873
8874 static int
8875 api_ioam_disable (vat_main_t * vam)
8876 {
8877   vl_api_ioam_disable_t *mp;
8878   int ret;
8879
8880   M (IOAM_DISABLE, mp);
8881   S (mp);
8882   W (ret);
8883   return ret;
8884 }
8885
8886 #define foreach_tcp_proto_field                 \
8887 _(src_port)                                     \
8888 _(dst_port)
8889
8890 #define foreach_udp_proto_field                 \
8891 _(src_port)                                     \
8892 _(dst_port)
8893
8894 #define foreach_ip4_proto_field                 \
8895 _(src_address)                                  \
8896 _(dst_address)                                  \
8897 _(tos)                                          \
8898 _(length)                                       \
8899 _(fragment_id)                                  \
8900 _(ttl)                                          \
8901 _(protocol)                                     \
8902 _(checksum)
8903
8904 typedef struct
8905 {
8906   u16 src_port, dst_port;
8907 } tcpudp_header_t;
8908
8909 #if VPP_API_TEST_BUILTIN == 0
8910 uword
8911 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8912 {
8913   u8 **maskp = va_arg (*args, u8 **);
8914   u8 *mask = 0;
8915   u8 found_something = 0;
8916   tcp_header_t *tcp;
8917
8918 #define _(a) u8 a=0;
8919   foreach_tcp_proto_field;
8920 #undef _
8921
8922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8923     {
8924       if (0);
8925 #define _(a) else if (unformat (input, #a)) a=1;
8926       foreach_tcp_proto_field
8927 #undef _
8928         else
8929         break;
8930     }
8931
8932 #define _(a) found_something += a;
8933   foreach_tcp_proto_field;
8934 #undef _
8935
8936   if (found_something == 0)
8937     return 0;
8938
8939   vec_validate (mask, sizeof (*tcp) - 1);
8940
8941   tcp = (tcp_header_t *) mask;
8942
8943 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8944   foreach_tcp_proto_field;
8945 #undef _
8946
8947   *maskp = mask;
8948   return 1;
8949 }
8950
8951 uword
8952 unformat_udp_mask (unformat_input_t * input, va_list * args)
8953 {
8954   u8 **maskp = va_arg (*args, u8 **);
8955   u8 *mask = 0;
8956   u8 found_something = 0;
8957   udp_header_t *udp;
8958
8959 #define _(a) u8 a=0;
8960   foreach_udp_proto_field;
8961 #undef _
8962
8963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8964     {
8965       if (0);
8966 #define _(a) else if (unformat (input, #a)) a=1;
8967       foreach_udp_proto_field
8968 #undef _
8969         else
8970         break;
8971     }
8972
8973 #define _(a) found_something += a;
8974   foreach_udp_proto_field;
8975 #undef _
8976
8977   if (found_something == 0)
8978     return 0;
8979
8980   vec_validate (mask, sizeof (*udp) - 1);
8981
8982   udp = (udp_header_t *) mask;
8983
8984 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8985   foreach_udp_proto_field;
8986 #undef _
8987
8988   *maskp = mask;
8989   return 1;
8990 }
8991
8992 uword
8993 unformat_l4_mask (unformat_input_t * input, va_list * args)
8994 {
8995   u8 **maskp = va_arg (*args, u8 **);
8996   u16 src_port = 0, dst_port = 0;
8997   tcpudp_header_t *tcpudp;
8998
8999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9000     {
9001       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9002         return 1;
9003       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9004         return 1;
9005       else if (unformat (input, "src_port"))
9006         src_port = 0xFFFF;
9007       else if (unformat (input, "dst_port"))
9008         dst_port = 0xFFFF;
9009       else
9010         return 0;
9011     }
9012
9013   if (!src_port && !dst_port)
9014     return 0;
9015
9016   u8 *mask = 0;
9017   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9018
9019   tcpudp = (tcpudp_header_t *) mask;
9020   tcpudp->src_port = src_port;
9021   tcpudp->dst_port = dst_port;
9022
9023   *maskp = mask;
9024
9025   return 1;
9026 }
9027
9028 uword
9029 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9030 {
9031   u8 **maskp = va_arg (*args, u8 **);
9032   u8 *mask = 0;
9033   u8 found_something = 0;
9034   ip4_header_t *ip;
9035
9036 #define _(a) u8 a=0;
9037   foreach_ip4_proto_field;
9038 #undef _
9039   u8 version = 0;
9040   u8 hdr_length = 0;
9041
9042
9043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9044     {
9045       if (unformat (input, "version"))
9046         version = 1;
9047       else if (unformat (input, "hdr_length"))
9048         hdr_length = 1;
9049       else if (unformat (input, "src"))
9050         src_address = 1;
9051       else if (unformat (input, "dst"))
9052         dst_address = 1;
9053       else if (unformat (input, "proto"))
9054         protocol = 1;
9055
9056 #define _(a) else if (unformat (input, #a)) a=1;
9057       foreach_ip4_proto_field
9058 #undef _
9059         else
9060         break;
9061     }
9062
9063 #define _(a) found_something += a;
9064   foreach_ip4_proto_field;
9065 #undef _
9066
9067   if (found_something == 0)
9068     return 0;
9069
9070   vec_validate (mask, sizeof (*ip) - 1);
9071
9072   ip = (ip4_header_t *) mask;
9073
9074 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9075   foreach_ip4_proto_field;
9076 #undef _
9077
9078   ip->ip_version_and_header_length = 0;
9079
9080   if (version)
9081     ip->ip_version_and_header_length |= 0xF0;
9082
9083   if (hdr_length)
9084     ip->ip_version_and_header_length |= 0x0F;
9085
9086   *maskp = mask;
9087   return 1;
9088 }
9089
9090 #define foreach_ip6_proto_field                 \
9091 _(src_address)                                  \
9092 _(dst_address)                                  \
9093 _(payload_length)                               \
9094 _(hop_limit)                                    \
9095 _(protocol)
9096
9097 uword
9098 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9099 {
9100   u8 **maskp = va_arg (*args, u8 **);
9101   u8 *mask = 0;
9102   u8 found_something = 0;
9103   ip6_header_t *ip;
9104   u32 ip_version_traffic_class_and_flow_label;
9105
9106 #define _(a) u8 a=0;
9107   foreach_ip6_proto_field;
9108 #undef _
9109   u8 version = 0;
9110   u8 traffic_class = 0;
9111   u8 flow_label = 0;
9112
9113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9114     {
9115       if (unformat (input, "version"))
9116         version = 1;
9117       else if (unformat (input, "traffic-class"))
9118         traffic_class = 1;
9119       else if (unformat (input, "flow-label"))
9120         flow_label = 1;
9121       else if (unformat (input, "src"))
9122         src_address = 1;
9123       else if (unformat (input, "dst"))
9124         dst_address = 1;
9125       else if (unformat (input, "proto"))
9126         protocol = 1;
9127
9128 #define _(a) else if (unformat (input, #a)) a=1;
9129       foreach_ip6_proto_field
9130 #undef _
9131         else
9132         break;
9133     }
9134
9135 #define _(a) found_something += a;
9136   foreach_ip6_proto_field;
9137 #undef _
9138
9139   if (found_something == 0)
9140     return 0;
9141
9142   vec_validate (mask, sizeof (*ip) - 1);
9143
9144   ip = (ip6_header_t *) mask;
9145
9146 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9147   foreach_ip6_proto_field;
9148 #undef _
9149
9150   ip_version_traffic_class_and_flow_label = 0;
9151
9152   if (version)
9153     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9154
9155   if (traffic_class)
9156     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9157
9158   if (flow_label)
9159     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9160
9161   ip->ip_version_traffic_class_and_flow_label =
9162     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9163
9164   *maskp = mask;
9165   return 1;
9166 }
9167
9168 uword
9169 unformat_l3_mask (unformat_input_t * input, va_list * args)
9170 {
9171   u8 **maskp = va_arg (*args, u8 **);
9172
9173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9174     {
9175       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9176         return 1;
9177       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9178         return 1;
9179       else
9180         break;
9181     }
9182   return 0;
9183 }
9184
9185 uword
9186 unformat_l2_mask (unformat_input_t * input, va_list * args)
9187 {
9188   u8 **maskp = va_arg (*args, u8 **);
9189   u8 *mask = 0;
9190   u8 src = 0;
9191   u8 dst = 0;
9192   u8 proto = 0;
9193   u8 tag1 = 0;
9194   u8 tag2 = 0;
9195   u8 ignore_tag1 = 0;
9196   u8 ignore_tag2 = 0;
9197   u8 cos1 = 0;
9198   u8 cos2 = 0;
9199   u8 dot1q = 0;
9200   u8 dot1ad = 0;
9201   int len = 14;
9202
9203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9204     {
9205       if (unformat (input, "src"))
9206         src = 1;
9207       else if (unformat (input, "dst"))
9208         dst = 1;
9209       else if (unformat (input, "proto"))
9210         proto = 1;
9211       else if (unformat (input, "tag1"))
9212         tag1 = 1;
9213       else if (unformat (input, "tag2"))
9214         tag2 = 1;
9215       else if (unformat (input, "ignore-tag1"))
9216         ignore_tag1 = 1;
9217       else if (unformat (input, "ignore-tag2"))
9218         ignore_tag2 = 1;
9219       else if (unformat (input, "cos1"))
9220         cos1 = 1;
9221       else if (unformat (input, "cos2"))
9222         cos2 = 1;
9223       else if (unformat (input, "dot1q"))
9224         dot1q = 1;
9225       else if (unformat (input, "dot1ad"))
9226         dot1ad = 1;
9227       else
9228         break;
9229     }
9230   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9231        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9232     return 0;
9233
9234   if (tag1 || ignore_tag1 || cos1 || dot1q)
9235     len = 18;
9236   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9237     len = 22;
9238
9239   vec_validate (mask, len - 1);
9240
9241   if (dst)
9242     memset (mask, 0xff, 6);
9243
9244   if (src)
9245     memset (mask + 6, 0xff, 6);
9246
9247   if (tag2 || dot1ad)
9248     {
9249       /* inner vlan tag */
9250       if (tag2)
9251         {
9252           mask[19] = 0xff;
9253           mask[18] = 0x0f;
9254         }
9255       if (cos2)
9256         mask[18] |= 0xe0;
9257       if (proto)
9258         mask[21] = mask[20] = 0xff;
9259       if (tag1)
9260         {
9261           mask[15] = 0xff;
9262           mask[14] = 0x0f;
9263         }
9264       if (cos1)
9265         mask[14] |= 0xe0;
9266       *maskp = mask;
9267       return 1;
9268     }
9269   if (tag1 | dot1q)
9270     {
9271       if (tag1)
9272         {
9273           mask[15] = 0xff;
9274           mask[14] = 0x0f;
9275         }
9276       if (cos1)
9277         mask[14] |= 0xe0;
9278       if (proto)
9279         mask[16] = mask[17] = 0xff;
9280
9281       *maskp = mask;
9282       return 1;
9283     }
9284   if (cos2)
9285     mask[18] |= 0xe0;
9286   if (cos1)
9287     mask[14] |= 0xe0;
9288   if (proto)
9289     mask[12] = mask[13] = 0xff;
9290
9291   *maskp = mask;
9292   return 1;
9293 }
9294
9295 uword
9296 unformat_classify_mask (unformat_input_t * input, va_list * args)
9297 {
9298   u8 **maskp = va_arg (*args, u8 **);
9299   u32 *skipp = va_arg (*args, u32 *);
9300   u32 *matchp = va_arg (*args, u32 *);
9301   u32 match;
9302   u8 *mask = 0;
9303   u8 *l2 = 0;
9304   u8 *l3 = 0;
9305   u8 *l4 = 0;
9306   int i;
9307
9308   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9309     {
9310       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9311         ;
9312       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9313         ;
9314       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9315         ;
9316       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9317         ;
9318       else
9319         break;
9320     }
9321
9322   if (l4 && !l3)
9323     {
9324       vec_free (mask);
9325       vec_free (l2);
9326       vec_free (l4);
9327       return 0;
9328     }
9329
9330   if (mask || l2 || l3 || l4)
9331     {
9332       if (l2 || l3 || l4)
9333         {
9334           /* "With a free Ethernet header in every package" */
9335           if (l2 == 0)
9336             vec_validate (l2, 13);
9337           mask = l2;
9338           if (vec_len (l3))
9339             {
9340               vec_append (mask, l3);
9341               vec_free (l3);
9342             }
9343           if (vec_len (l4))
9344             {
9345               vec_append (mask, l4);
9346               vec_free (l4);
9347             }
9348         }
9349
9350       /* Scan forward looking for the first significant mask octet */
9351       for (i = 0; i < vec_len (mask); i++)
9352         if (mask[i])
9353           break;
9354
9355       /* compute (skip, match) params */
9356       *skipp = i / sizeof (u32x4);
9357       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9358
9359       /* Pad mask to an even multiple of the vector size */
9360       while (vec_len (mask) % sizeof (u32x4))
9361         vec_add1 (mask, 0);
9362
9363       match = vec_len (mask) / sizeof (u32x4);
9364
9365       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9366         {
9367           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9368           if (*tmp || *(tmp + 1))
9369             break;
9370           match--;
9371         }
9372       if (match == 0)
9373         clib_warning ("BUG: match 0");
9374
9375       _vec_len (mask) = match * sizeof (u32x4);
9376
9377       *matchp = match;
9378       *maskp = mask;
9379
9380       return 1;
9381     }
9382
9383   return 0;
9384 }
9385 #endif /* VPP_API_TEST_BUILTIN */
9386
9387 #define foreach_l2_next                         \
9388 _(drop, DROP)                                   \
9389 _(ethernet, ETHERNET_INPUT)                     \
9390 _(ip4, IP4_INPUT)                               \
9391 _(ip6, IP6_INPUT)
9392
9393 uword
9394 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9395 {
9396   u32 *miss_next_indexp = va_arg (*args, u32 *);
9397   u32 next_index = 0;
9398   u32 tmp;
9399
9400 #define _(n,N) \
9401   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9402   foreach_l2_next;
9403 #undef _
9404
9405   if (unformat (input, "%d", &tmp))
9406     {
9407       next_index = tmp;
9408       goto out;
9409     }
9410
9411   return 0;
9412
9413 out:
9414   *miss_next_indexp = next_index;
9415   return 1;
9416 }
9417
9418 #define foreach_ip_next                         \
9419 _(drop, DROP)                                   \
9420 _(local, LOCAL)                                 \
9421 _(rewrite, REWRITE)
9422
9423 uword
9424 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9425 {
9426   u32 *miss_next_indexp = va_arg (*args, u32 *);
9427   u32 next_index = 0;
9428   u32 tmp;
9429
9430 #define _(n,N) \
9431   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9432   foreach_ip_next;
9433 #undef _
9434
9435   if (unformat (input, "%d", &tmp))
9436     {
9437       next_index = tmp;
9438       goto out;
9439     }
9440
9441   return 0;
9442
9443 out:
9444   *miss_next_indexp = next_index;
9445   return 1;
9446 }
9447
9448 #define foreach_acl_next                        \
9449 _(deny, DENY)
9450
9451 uword
9452 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9453 {
9454   u32 *miss_next_indexp = va_arg (*args, u32 *);
9455   u32 next_index = 0;
9456   u32 tmp;
9457
9458 #define _(n,N) \
9459   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9460   foreach_acl_next;
9461 #undef _
9462
9463   if (unformat (input, "permit"))
9464     {
9465       next_index = ~0;
9466       goto out;
9467     }
9468   else if (unformat (input, "%d", &tmp))
9469     {
9470       next_index = tmp;
9471       goto out;
9472     }
9473
9474   return 0;
9475
9476 out:
9477   *miss_next_indexp = next_index;
9478   return 1;
9479 }
9480
9481 uword
9482 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9483 {
9484   u32 *r = va_arg (*args, u32 *);
9485
9486   if (unformat (input, "conform-color"))
9487     *r = POLICE_CONFORM;
9488   else if (unformat (input, "exceed-color"))
9489     *r = POLICE_EXCEED;
9490   else
9491     return 0;
9492
9493   return 1;
9494 }
9495
9496 static int
9497 api_classify_add_del_table (vat_main_t * vam)
9498 {
9499   unformat_input_t *i = vam->input;
9500   vl_api_classify_add_del_table_t *mp;
9501
9502   u32 nbuckets = 2;
9503   u32 skip = ~0;
9504   u32 match = ~0;
9505   int is_add = 1;
9506   int del_chain = 0;
9507   u32 table_index = ~0;
9508   u32 next_table_index = ~0;
9509   u32 miss_next_index = ~0;
9510   u32 memory_size = 32 << 20;
9511   u8 *mask = 0;
9512   u32 current_data_flag = 0;
9513   int current_data_offset = 0;
9514   int ret;
9515
9516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9517     {
9518       if (unformat (i, "del"))
9519         is_add = 0;
9520       else if (unformat (i, "del-chain"))
9521         {
9522           is_add = 0;
9523           del_chain = 1;
9524         }
9525       else if (unformat (i, "buckets %d", &nbuckets))
9526         ;
9527       else if (unformat (i, "memory_size %d", &memory_size))
9528         ;
9529       else if (unformat (i, "skip %d", &skip))
9530         ;
9531       else if (unformat (i, "match %d", &match))
9532         ;
9533       else if (unformat (i, "table %d", &table_index))
9534         ;
9535       else if (unformat (i, "mask %U", unformat_classify_mask,
9536                          &mask, &skip, &match))
9537         ;
9538       else if (unformat (i, "next-table %d", &next_table_index))
9539         ;
9540       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9541                          &miss_next_index))
9542         ;
9543       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9544                          &miss_next_index))
9545         ;
9546       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9547                          &miss_next_index))
9548         ;
9549       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9550         ;
9551       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9552         ;
9553       else
9554         break;
9555     }
9556
9557   if (is_add && mask == 0)
9558     {
9559       errmsg ("Mask required");
9560       return -99;
9561     }
9562
9563   if (is_add && skip == ~0)
9564     {
9565       errmsg ("skip count required");
9566       return -99;
9567     }
9568
9569   if (is_add && match == ~0)
9570     {
9571       errmsg ("match count required");
9572       return -99;
9573     }
9574
9575   if (!is_add && table_index == ~0)
9576     {
9577       errmsg ("table index required for delete");
9578       return -99;
9579     }
9580
9581   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9582
9583   mp->is_add = is_add;
9584   mp->del_chain = del_chain;
9585   mp->table_index = ntohl (table_index);
9586   mp->nbuckets = ntohl (nbuckets);
9587   mp->memory_size = ntohl (memory_size);
9588   mp->skip_n_vectors = ntohl (skip);
9589   mp->match_n_vectors = ntohl (match);
9590   mp->next_table_index = ntohl (next_table_index);
9591   mp->miss_next_index = ntohl (miss_next_index);
9592   mp->current_data_flag = ntohl (current_data_flag);
9593   mp->current_data_offset = ntohl (current_data_offset);
9594   clib_memcpy (mp->mask, mask, vec_len (mask));
9595
9596   vec_free (mask);
9597
9598   S (mp);
9599   W (ret);
9600   return ret;
9601 }
9602
9603 #if VPP_API_TEST_BUILTIN == 0
9604 uword
9605 unformat_l4_match (unformat_input_t * input, va_list * args)
9606 {
9607   u8 **matchp = va_arg (*args, u8 **);
9608
9609   u8 *proto_header = 0;
9610   int src_port = 0;
9611   int dst_port = 0;
9612
9613   tcpudp_header_t h;
9614
9615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9616     {
9617       if (unformat (input, "src_port %d", &src_port))
9618         ;
9619       else if (unformat (input, "dst_port %d", &dst_port))
9620         ;
9621       else
9622         return 0;
9623     }
9624
9625   h.src_port = clib_host_to_net_u16 (src_port);
9626   h.dst_port = clib_host_to_net_u16 (dst_port);
9627   vec_validate (proto_header, sizeof (h) - 1);
9628   memcpy (proto_header, &h, sizeof (h));
9629
9630   *matchp = proto_header;
9631
9632   return 1;
9633 }
9634
9635 uword
9636 unformat_ip4_match (unformat_input_t * input, va_list * args)
9637 {
9638   u8 **matchp = va_arg (*args, u8 **);
9639   u8 *match = 0;
9640   ip4_header_t *ip;
9641   int version = 0;
9642   u32 version_val;
9643   int hdr_length = 0;
9644   u32 hdr_length_val;
9645   int src = 0, dst = 0;
9646   ip4_address_t src_val, dst_val;
9647   int proto = 0;
9648   u32 proto_val;
9649   int tos = 0;
9650   u32 tos_val;
9651   int length = 0;
9652   u32 length_val;
9653   int fragment_id = 0;
9654   u32 fragment_id_val;
9655   int ttl = 0;
9656   int ttl_val;
9657   int checksum = 0;
9658   u32 checksum_val;
9659
9660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9661     {
9662       if (unformat (input, "version %d", &version_val))
9663         version = 1;
9664       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9665         hdr_length = 1;
9666       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9667         src = 1;
9668       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9669         dst = 1;
9670       else if (unformat (input, "proto %d", &proto_val))
9671         proto = 1;
9672       else if (unformat (input, "tos %d", &tos_val))
9673         tos = 1;
9674       else if (unformat (input, "length %d", &length_val))
9675         length = 1;
9676       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9677         fragment_id = 1;
9678       else if (unformat (input, "ttl %d", &ttl_val))
9679         ttl = 1;
9680       else if (unformat (input, "checksum %d", &checksum_val))
9681         checksum = 1;
9682       else
9683         break;
9684     }
9685
9686   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9687       + ttl + checksum == 0)
9688     return 0;
9689
9690   /*
9691    * Aligned because we use the real comparison functions
9692    */
9693   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9694
9695   ip = (ip4_header_t *) match;
9696
9697   /* These are realistically matched in practice */
9698   if (src)
9699     ip->src_address.as_u32 = src_val.as_u32;
9700
9701   if (dst)
9702     ip->dst_address.as_u32 = dst_val.as_u32;
9703
9704   if (proto)
9705     ip->protocol = proto_val;
9706
9707
9708   /* These are not, but they're included for completeness */
9709   if (version)
9710     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9711
9712   if (hdr_length)
9713     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9714
9715   if (tos)
9716     ip->tos = tos_val;
9717
9718   if (length)
9719     ip->length = clib_host_to_net_u16 (length_val);
9720
9721   if (ttl)
9722     ip->ttl = ttl_val;
9723
9724   if (checksum)
9725     ip->checksum = clib_host_to_net_u16 (checksum_val);
9726
9727   *matchp = match;
9728   return 1;
9729 }
9730
9731 uword
9732 unformat_ip6_match (unformat_input_t * input, va_list * args)
9733 {
9734   u8 **matchp = va_arg (*args, u8 **);
9735   u8 *match = 0;
9736   ip6_header_t *ip;
9737   int version = 0;
9738   u32 version_val;
9739   u8 traffic_class = 0;
9740   u32 traffic_class_val = 0;
9741   u8 flow_label = 0;
9742   u8 flow_label_val;
9743   int src = 0, dst = 0;
9744   ip6_address_t src_val, dst_val;
9745   int proto = 0;
9746   u32 proto_val;
9747   int payload_length = 0;
9748   u32 payload_length_val;
9749   int hop_limit = 0;
9750   int hop_limit_val;
9751   u32 ip_version_traffic_class_and_flow_label;
9752
9753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9754     {
9755       if (unformat (input, "version %d", &version_val))
9756         version = 1;
9757       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9758         traffic_class = 1;
9759       else if (unformat (input, "flow_label %d", &flow_label_val))
9760         flow_label = 1;
9761       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9762         src = 1;
9763       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9764         dst = 1;
9765       else if (unformat (input, "proto %d", &proto_val))
9766         proto = 1;
9767       else if (unformat (input, "payload_length %d", &payload_length_val))
9768         payload_length = 1;
9769       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9770         hop_limit = 1;
9771       else
9772         break;
9773     }
9774
9775   if (version + traffic_class + flow_label + src + dst + proto +
9776       payload_length + hop_limit == 0)
9777     return 0;
9778
9779   /*
9780    * Aligned because we use the real comparison functions
9781    */
9782   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9783
9784   ip = (ip6_header_t *) match;
9785
9786   if (src)
9787     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9788
9789   if (dst)
9790     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9791
9792   if (proto)
9793     ip->protocol = proto_val;
9794
9795   ip_version_traffic_class_and_flow_label = 0;
9796
9797   if (version)
9798     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9799
9800   if (traffic_class)
9801     ip_version_traffic_class_and_flow_label |=
9802       (traffic_class_val & 0xFF) << 20;
9803
9804   if (flow_label)
9805     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9806
9807   ip->ip_version_traffic_class_and_flow_label =
9808     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9809
9810   if (payload_length)
9811     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9812
9813   if (hop_limit)
9814     ip->hop_limit = hop_limit_val;
9815
9816   *matchp = match;
9817   return 1;
9818 }
9819
9820 uword
9821 unformat_l3_match (unformat_input_t * input, va_list * args)
9822 {
9823   u8 **matchp = va_arg (*args, u8 **);
9824
9825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9826     {
9827       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9828         return 1;
9829       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9830         return 1;
9831       else
9832         break;
9833     }
9834   return 0;
9835 }
9836
9837 uword
9838 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9839 {
9840   u8 *tagp = va_arg (*args, u8 *);
9841   u32 tag;
9842
9843   if (unformat (input, "%d", &tag))
9844     {
9845       tagp[0] = (tag >> 8) & 0x0F;
9846       tagp[1] = tag & 0xFF;
9847       return 1;
9848     }
9849
9850   return 0;
9851 }
9852
9853 uword
9854 unformat_l2_match (unformat_input_t * input, va_list * args)
9855 {
9856   u8 **matchp = va_arg (*args, u8 **);
9857   u8 *match = 0;
9858   u8 src = 0;
9859   u8 src_val[6];
9860   u8 dst = 0;
9861   u8 dst_val[6];
9862   u8 proto = 0;
9863   u16 proto_val;
9864   u8 tag1 = 0;
9865   u8 tag1_val[2];
9866   u8 tag2 = 0;
9867   u8 tag2_val[2];
9868   int len = 14;
9869   u8 ignore_tag1 = 0;
9870   u8 ignore_tag2 = 0;
9871   u8 cos1 = 0;
9872   u8 cos2 = 0;
9873   u32 cos1_val = 0;
9874   u32 cos2_val = 0;
9875
9876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9877     {
9878       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9879         src = 1;
9880       else
9881         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9882         dst = 1;
9883       else if (unformat (input, "proto %U",
9884                          unformat_ethernet_type_host_byte_order, &proto_val))
9885         proto = 1;
9886       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9887         tag1 = 1;
9888       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9889         tag2 = 1;
9890       else if (unformat (input, "ignore-tag1"))
9891         ignore_tag1 = 1;
9892       else if (unformat (input, "ignore-tag2"))
9893         ignore_tag2 = 1;
9894       else if (unformat (input, "cos1 %d", &cos1_val))
9895         cos1 = 1;
9896       else if (unformat (input, "cos2 %d", &cos2_val))
9897         cos2 = 1;
9898       else
9899         break;
9900     }
9901   if ((src + dst + proto + tag1 + tag2 +
9902        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9903     return 0;
9904
9905   if (tag1 || ignore_tag1 || cos1)
9906     len = 18;
9907   if (tag2 || ignore_tag2 || cos2)
9908     len = 22;
9909
9910   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9911
9912   if (dst)
9913     clib_memcpy (match, dst_val, 6);
9914
9915   if (src)
9916     clib_memcpy (match + 6, src_val, 6);
9917
9918   if (tag2)
9919     {
9920       /* inner vlan tag */
9921       match[19] = tag2_val[1];
9922       match[18] = tag2_val[0];
9923       if (cos2)
9924         match[18] |= (cos2_val & 0x7) << 5;
9925       if (proto)
9926         {
9927           match[21] = proto_val & 0xff;
9928           match[20] = proto_val >> 8;
9929         }
9930       if (tag1)
9931         {
9932           match[15] = tag1_val[1];
9933           match[14] = tag1_val[0];
9934         }
9935       if (cos1)
9936         match[14] |= (cos1_val & 0x7) << 5;
9937       *matchp = match;
9938       return 1;
9939     }
9940   if (tag1)
9941     {
9942       match[15] = tag1_val[1];
9943       match[14] = tag1_val[0];
9944       if (proto)
9945         {
9946           match[17] = proto_val & 0xff;
9947           match[16] = proto_val >> 8;
9948         }
9949       if (cos1)
9950         match[14] |= (cos1_val & 0x7) << 5;
9951
9952       *matchp = match;
9953       return 1;
9954     }
9955   if (cos2)
9956     match[18] |= (cos2_val & 0x7) << 5;
9957   if (cos1)
9958     match[14] |= (cos1_val & 0x7) << 5;
9959   if (proto)
9960     {
9961       match[13] = proto_val & 0xff;
9962       match[12] = proto_val >> 8;
9963     }
9964
9965   *matchp = match;
9966   return 1;
9967 }
9968 #endif
9969
9970 uword
9971 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9972 {
9973   u8 **matchp = va_arg (*args, u8 **);
9974   u32 skip_n_vectors = va_arg (*args, u32);
9975   u32 match_n_vectors = va_arg (*args, u32);
9976
9977   u8 *match = 0;
9978   u8 *l2 = 0;
9979   u8 *l3 = 0;
9980   u8 *l4 = 0;
9981
9982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9983     {
9984       if (unformat (input, "hex %U", unformat_hex_string, &match))
9985         ;
9986       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9987         ;
9988       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9989         ;
9990       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9991         ;
9992       else
9993         break;
9994     }
9995
9996   if (l4 && !l3)
9997     {
9998       vec_free (match);
9999       vec_free (l2);
10000       vec_free (l4);
10001       return 0;
10002     }
10003
10004   if (match || l2 || l3 || l4)
10005     {
10006       if (l2 || l3 || l4)
10007         {
10008           /* "Win a free Ethernet header in every packet" */
10009           if (l2 == 0)
10010             vec_validate_aligned (l2, 13, sizeof (u32x4));
10011           match = l2;
10012           if (vec_len (l3))
10013             {
10014               vec_append_aligned (match, l3, sizeof (u32x4));
10015               vec_free (l3);
10016             }
10017           if (vec_len (l4))
10018             {
10019               vec_append_aligned (match, l4, sizeof (u32x4));
10020               vec_free (l4);
10021             }
10022         }
10023
10024       /* Make sure the vector is big enough even if key is all 0's */
10025       vec_validate_aligned
10026         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10027          sizeof (u32x4));
10028
10029       /* Set size, include skipped vectors */
10030       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10031
10032       *matchp = match;
10033
10034       return 1;
10035     }
10036
10037   return 0;
10038 }
10039
10040 static int
10041 api_classify_add_del_session (vat_main_t * vam)
10042 {
10043   unformat_input_t *i = vam->input;
10044   vl_api_classify_add_del_session_t *mp;
10045   int is_add = 1;
10046   u32 table_index = ~0;
10047   u32 hit_next_index = ~0;
10048   u32 opaque_index = ~0;
10049   u8 *match = 0;
10050   i32 advance = 0;
10051   u32 skip_n_vectors = 0;
10052   u32 match_n_vectors = 0;
10053   u32 action = 0;
10054   u32 metadata = 0;
10055   int ret;
10056
10057   /*
10058    * Warning: you have to supply skip_n and match_n
10059    * because the API client cant simply look at the classify
10060    * table object.
10061    */
10062
10063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10064     {
10065       if (unformat (i, "del"))
10066         is_add = 0;
10067       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10068                          &hit_next_index))
10069         ;
10070       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10071                          &hit_next_index))
10072         ;
10073       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10074                          &hit_next_index))
10075         ;
10076       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10077         ;
10078       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10079         ;
10080       else if (unformat (i, "opaque-index %d", &opaque_index))
10081         ;
10082       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10083         ;
10084       else if (unformat (i, "match_n %d", &match_n_vectors))
10085         ;
10086       else if (unformat (i, "match %U", api_unformat_classify_match,
10087                          &match, skip_n_vectors, match_n_vectors))
10088         ;
10089       else if (unformat (i, "advance %d", &advance))
10090         ;
10091       else if (unformat (i, "table-index %d", &table_index))
10092         ;
10093       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10094         action = 1;
10095       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10096         action = 2;
10097       else if (unformat (i, "action %d", &action))
10098         ;
10099       else if (unformat (i, "metadata %d", &metadata))
10100         ;
10101       else
10102         break;
10103     }
10104
10105   if (table_index == ~0)
10106     {
10107       errmsg ("Table index required");
10108       return -99;
10109     }
10110
10111   if (is_add && match == 0)
10112     {
10113       errmsg ("Match value required");
10114       return -99;
10115     }
10116
10117   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10118
10119   mp->is_add = is_add;
10120   mp->table_index = ntohl (table_index);
10121   mp->hit_next_index = ntohl (hit_next_index);
10122   mp->opaque_index = ntohl (opaque_index);
10123   mp->advance = ntohl (advance);
10124   mp->action = action;
10125   mp->metadata = ntohl (metadata);
10126   clib_memcpy (mp->match, match, vec_len (match));
10127   vec_free (match);
10128
10129   S (mp);
10130   W (ret);
10131   return ret;
10132 }
10133
10134 static int
10135 api_classify_set_interface_ip_table (vat_main_t * vam)
10136 {
10137   unformat_input_t *i = vam->input;
10138   vl_api_classify_set_interface_ip_table_t *mp;
10139   u32 sw_if_index;
10140   int sw_if_index_set;
10141   u32 table_index = ~0;
10142   u8 is_ipv6 = 0;
10143   int ret;
10144
10145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10146     {
10147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10148         sw_if_index_set = 1;
10149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10150         sw_if_index_set = 1;
10151       else if (unformat (i, "table %d", &table_index))
10152         ;
10153       else
10154         {
10155           clib_warning ("parse error '%U'", format_unformat_error, i);
10156           return -99;
10157         }
10158     }
10159
10160   if (sw_if_index_set == 0)
10161     {
10162       errmsg ("missing interface name or sw_if_index");
10163       return -99;
10164     }
10165
10166
10167   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10168
10169   mp->sw_if_index = ntohl (sw_if_index);
10170   mp->table_index = ntohl (table_index);
10171   mp->is_ipv6 = is_ipv6;
10172
10173   S (mp);
10174   W (ret);
10175   return ret;
10176 }
10177
10178 static int
10179 api_classify_set_interface_l2_tables (vat_main_t * vam)
10180 {
10181   unformat_input_t *i = vam->input;
10182   vl_api_classify_set_interface_l2_tables_t *mp;
10183   u32 sw_if_index;
10184   int sw_if_index_set;
10185   u32 ip4_table_index = ~0;
10186   u32 ip6_table_index = ~0;
10187   u32 other_table_index = ~0;
10188   u32 is_input = 1;
10189   int ret;
10190
10191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10192     {
10193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10194         sw_if_index_set = 1;
10195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10196         sw_if_index_set = 1;
10197       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10198         ;
10199       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10200         ;
10201       else if (unformat (i, "other-table %d", &other_table_index))
10202         ;
10203       else if (unformat (i, "is-input %d", &is_input))
10204         ;
10205       else
10206         {
10207           clib_warning ("parse error '%U'", format_unformat_error, i);
10208           return -99;
10209         }
10210     }
10211
10212   if (sw_if_index_set == 0)
10213     {
10214       errmsg ("missing interface name or sw_if_index");
10215       return -99;
10216     }
10217
10218
10219   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10220
10221   mp->sw_if_index = ntohl (sw_if_index);
10222   mp->ip4_table_index = ntohl (ip4_table_index);
10223   mp->ip6_table_index = ntohl (ip6_table_index);
10224   mp->other_table_index = ntohl (other_table_index);
10225   mp->is_input = (u8) is_input;
10226
10227   S (mp);
10228   W (ret);
10229   return ret;
10230 }
10231
10232 static int
10233 api_set_ipfix_exporter (vat_main_t * vam)
10234 {
10235   unformat_input_t *i = vam->input;
10236   vl_api_set_ipfix_exporter_t *mp;
10237   ip4_address_t collector_address;
10238   u8 collector_address_set = 0;
10239   u32 collector_port = ~0;
10240   ip4_address_t src_address;
10241   u8 src_address_set = 0;
10242   u32 vrf_id = ~0;
10243   u32 path_mtu = ~0;
10244   u32 template_interval = ~0;
10245   u8 udp_checksum = 0;
10246   int ret;
10247
10248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10249     {
10250       if (unformat (i, "collector_address %U", unformat_ip4_address,
10251                     &collector_address))
10252         collector_address_set = 1;
10253       else if (unformat (i, "collector_port %d", &collector_port))
10254         ;
10255       else if (unformat (i, "src_address %U", unformat_ip4_address,
10256                          &src_address))
10257         src_address_set = 1;
10258       else if (unformat (i, "vrf_id %d", &vrf_id))
10259         ;
10260       else if (unformat (i, "path_mtu %d", &path_mtu))
10261         ;
10262       else if (unformat (i, "template_interval %d", &template_interval))
10263         ;
10264       else if (unformat (i, "udp_checksum"))
10265         udp_checksum = 1;
10266       else
10267         break;
10268     }
10269
10270   if (collector_address_set == 0)
10271     {
10272       errmsg ("collector_address required");
10273       return -99;
10274     }
10275
10276   if (src_address_set == 0)
10277     {
10278       errmsg ("src_address required");
10279       return -99;
10280     }
10281
10282   M (SET_IPFIX_EXPORTER, mp);
10283
10284   memcpy (mp->collector_address, collector_address.data,
10285           sizeof (collector_address.data));
10286   mp->collector_port = htons ((u16) collector_port);
10287   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10288   mp->vrf_id = htonl (vrf_id);
10289   mp->path_mtu = htonl (path_mtu);
10290   mp->template_interval = htonl (template_interval);
10291   mp->udp_checksum = udp_checksum;
10292
10293   S (mp);
10294   W (ret);
10295   return ret;
10296 }
10297
10298 static int
10299 api_set_ipfix_classify_stream (vat_main_t * vam)
10300 {
10301   unformat_input_t *i = vam->input;
10302   vl_api_set_ipfix_classify_stream_t *mp;
10303   u32 domain_id = 0;
10304   u32 src_port = UDP_DST_PORT_ipfix;
10305   int ret;
10306
10307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10308     {
10309       if (unformat (i, "domain %d", &domain_id))
10310         ;
10311       else if (unformat (i, "src_port %d", &src_port))
10312         ;
10313       else
10314         {
10315           errmsg ("unknown input `%U'", format_unformat_error, i);
10316           return -99;
10317         }
10318     }
10319
10320   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10321
10322   mp->domain_id = htonl (domain_id);
10323   mp->src_port = htons ((u16) src_port);
10324
10325   S (mp);
10326   W (ret);
10327   return ret;
10328 }
10329
10330 static int
10331 api_ipfix_classify_table_add_del (vat_main_t * vam)
10332 {
10333   unformat_input_t *i = vam->input;
10334   vl_api_ipfix_classify_table_add_del_t *mp;
10335   int is_add = -1;
10336   u32 classify_table_index = ~0;
10337   u8 ip_version = 0;
10338   u8 transport_protocol = 255;
10339   int ret;
10340
10341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10342     {
10343       if (unformat (i, "add"))
10344         is_add = 1;
10345       else if (unformat (i, "del"))
10346         is_add = 0;
10347       else if (unformat (i, "table %d", &classify_table_index))
10348         ;
10349       else if (unformat (i, "ip4"))
10350         ip_version = 4;
10351       else if (unformat (i, "ip6"))
10352         ip_version = 6;
10353       else if (unformat (i, "tcp"))
10354         transport_protocol = 6;
10355       else if (unformat (i, "udp"))
10356         transport_protocol = 17;
10357       else
10358         {
10359           errmsg ("unknown input `%U'", format_unformat_error, i);
10360           return -99;
10361         }
10362     }
10363
10364   if (is_add == -1)
10365     {
10366       errmsg ("expecting: add|del");
10367       return -99;
10368     }
10369   if (classify_table_index == ~0)
10370     {
10371       errmsg ("classifier table not specified");
10372       return -99;
10373     }
10374   if (ip_version == 0)
10375     {
10376       errmsg ("IP version not specified");
10377       return -99;
10378     }
10379
10380   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10381
10382   mp->is_add = is_add;
10383   mp->table_id = htonl (classify_table_index);
10384   mp->ip_version = ip_version;
10385   mp->transport_protocol = transport_protocol;
10386
10387   S (mp);
10388   W (ret);
10389   return ret;
10390 }
10391
10392 static int
10393 api_get_node_index (vat_main_t * vam)
10394 {
10395   unformat_input_t *i = vam->input;
10396   vl_api_get_node_index_t *mp;
10397   u8 *name = 0;
10398   int ret;
10399
10400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10401     {
10402       if (unformat (i, "node %s", &name))
10403         ;
10404       else
10405         break;
10406     }
10407   if (name == 0)
10408     {
10409       errmsg ("node name required");
10410       return -99;
10411     }
10412   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10413     {
10414       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10415       return -99;
10416     }
10417
10418   M (GET_NODE_INDEX, mp);
10419   clib_memcpy (mp->node_name, name, vec_len (name));
10420   vec_free (name);
10421
10422   S (mp);
10423   W (ret);
10424   return ret;
10425 }
10426
10427 static int
10428 api_get_next_index (vat_main_t * vam)
10429 {
10430   unformat_input_t *i = vam->input;
10431   vl_api_get_next_index_t *mp;
10432   u8 *node_name = 0, *next_node_name = 0;
10433   int ret;
10434
10435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10436     {
10437       if (unformat (i, "node-name %s", &node_name))
10438         ;
10439       else if (unformat (i, "next-node-name %s", &next_node_name))
10440         break;
10441     }
10442
10443   if (node_name == 0)
10444     {
10445       errmsg ("node name required");
10446       return -99;
10447     }
10448   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10449     {
10450       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10451       return -99;
10452     }
10453
10454   if (next_node_name == 0)
10455     {
10456       errmsg ("next node name required");
10457       return -99;
10458     }
10459   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10460     {
10461       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10462       return -99;
10463     }
10464
10465   M (GET_NEXT_INDEX, mp);
10466   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10467   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10468   vec_free (node_name);
10469   vec_free (next_node_name);
10470
10471   S (mp);
10472   W (ret);
10473   return ret;
10474 }
10475
10476 static int
10477 api_add_node_next (vat_main_t * vam)
10478 {
10479   unformat_input_t *i = vam->input;
10480   vl_api_add_node_next_t *mp;
10481   u8 *name = 0;
10482   u8 *next = 0;
10483   int ret;
10484
10485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10486     {
10487       if (unformat (i, "node %s", &name))
10488         ;
10489       else if (unformat (i, "next %s", &next))
10490         ;
10491       else
10492         break;
10493     }
10494   if (name == 0)
10495     {
10496       errmsg ("node name required");
10497       return -99;
10498     }
10499   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10500     {
10501       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10502       return -99;
10503     }
10504   if (next == 0)
10505     {
10506       errmsg ("next node required");
10507       return -99;
10508     }
10509   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10510     {
10511       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10512       return -99;
10513     }
10514
10515   M (ADD_NODE_NEXT, mp);
10516   clib_memcpy (mp->node_name, name, vec_len (name));
10517   clib_memcpy (mp->next_name, next, vec_len (next));
10518   vec_free (name);
10519   vec_free (next);
10520
10521   S (mp);
10522   W (ret);
10523   return ret;
10524 }
10525
10526 static int
10527 api_l2tpv3_create_tunnel (vat_main_t * vam)
10528 {
10529   unformat_input_t *i = vam->input;
10530   ip6_address_t client_address, our_address;
10531   int client_address_set = 0;
10532   int our_address_set = 0;
10533   u32 local_session_id = 0;
10534   u32 remote_session_id = 0;
10535   u64 local_cookie = 0;
10536   u64 remote_cookie = 0;
10537   u8 l2_sublayer_present = 0;
10538   vl_api_l2tpv3_create_tunnel_t *mp;
10539   int ret;
10540
10541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10542     {
10543       if (unformat (i, "client_address %U", unformat_ip6_address,
10544                     &client_address))
10545         client_address_set = 1;
10546       else if (unformat (i, "our_address %U", unformat_ip6_address,
10547                          &our_address))
10548         our_address_set = 1;
10549       else if (unformat (i, "local_session_id %d", &local_session_id))
10550         ;
10551       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10552         ;
10553       else if (unformat (i, "local_cookie %lld", &local_cookie))
10554         ;
10555       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10556         ;
10557       else if (unformat (i, "l2-sublayer-present"))
10558         l2_sublayer_present = 1;
10559       else
10560         break;
10561     }
10562
10563   if (client_address_set == 0)
10564     {
10565       errmsg ("client_address required");
10566       return -99;
10567     }
10568
10569   if (our_address_set == 0)
10570     {
10571       errmsg ("our_address required");
10572       return -99;
10573     }
10574
10575   M (L2TPV3_CREATE_TUNNEL, mp);
10576
10577   clib_memcpy (mp->client_address, client_address.as_u8,
10578                sizeof (mp->client_address));
10579
10580   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10581
10582   mp->local_session_id = ntohl (local_session_id);
10583   mp->remote_session_id = ntohl (remote_session_id);
10584   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10585   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10586   mp->l2_sublayer_present = l2_sublayer_present;
10587   mp->is_ipv6 = 1;
10588
10589   S (mp);
10590   W (ret);
10591   return ret;
10592 }
10593
10594 static int
10595 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10596 {
10597   unformat_input_t *i = vam->input;
10598   u32 sw_if_index;
10599   u8 sw_if_index_set = 0;
10600   u64 new_local_cookie = 0;
10601   u64 new_remote_cookie = 0;
10602   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10603   int ret;
10604
10605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10606     {
10607       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10608         sw_if_index_set = 1;
10609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10610         sw_if_index_set = 1;
10611       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10612         ;
10613       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10614         ;
10615       else
10616         break;
10617     }
10618
10619   if (sw_if_index_set == 0)
10620     {
10621       errmsg ("missing interface name or sw_if_index");
10622       return -99;
10623     }
10624
10625   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10626
10627   mp->sw_if_index = ntohl (sw_if_index);
10628   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10629   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10630
10631   S (mp);
10632   W (ret);
10633   return ret;
10634 }
10635
10636 static int
10637 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10638 {
10639   unformat_input_t *i = vam->input;
10640   vl_api_l2tpv3_interface_enable_disable_t *mp;
10641   u32 sw_if_index;
10642   u8 sw_if_index_set = 0;
10643   u8 enable_disable = 1;
10644   int ret;
10645
10646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10647     {
10648       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10649         sw_if_index_set = 1;
10650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10651         sw_if_index_set = 1;
10652       else if (unformat (i, "enable"))
10653         enable_disable = 1;
10654       else if (unformat (i, "disable"))
10655         enable_disable = 0;
10656       else
10657         break;
10658     }
10659
10660   if (sw_if_index_set == 0)
10661     {
10662       errmsg ("missing interface name or sw_if_index");
10663       return -99;
10664     }
10665
10666   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10667
10668   mp->sw_if_index = ntohl (sw_if_index);
10669   mp->enable_disable = enable_disable;
10670
10671   S (mp);
10672   W (ret);
10673   return ret;
10674 }
10675
10676 static int
10677 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10678 {
10679   unformat_input_t *i = vam->input;
10680   vl_api_l2tpv3_set_lookup_key_t *mp;
10681   u8 key = ~0;
10682   int ret;
10683
10684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10685     {
10686       if (unformat (i, "lookup_v6_src"))
10687         key = L2T_LOOKUP_SRC_ADDRESS;
10688       else if (unformat (i, "lookup_v6_dst"))
10689         key = L2T_LOOKUP_DST_ADDRESS;
10690       else if (unformat (i, "lookup_session_id"))
10691         key = L2T_LOOKUP_SESSION_ID;
10692       else
10693         break;
10694     }
10695
10696   if (key == (u8) ~ 0)
10697     {
10698       errmsg ("l2tp session lookup key unset");
10699       return -99;
10700     }
10701
10702   M (L2TPV3_SET_LOOKUP_KEY, mp);
10703
10704   mp->key = key;
10705
10706   S (mp);
10707   W (ret);
10708   return ret;
10709 }
10710
10711 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10712   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10713 {
10714   vat_main_t *vam = &vat_main;
10715
10716   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10717          format_ip6_address, mp->our_address,
10718          format_ip6_address, mp->client_address,
10719          clib_net_to_host_u32 (mp->sw_if_index));
10720
10721   print (vam->ofp,
10722          "   local cookies %016llx %016llx remote cookie %016llx",
10723          clib_net_to_host_u64 (mp->local_cookie[0]),
10724          clib_net_to_host_u64 (mp->local_cookie[1]),
10725          clib_net_to_host_u64 (mp->remote_cookie));
10726
10727   print (vam->ofp, "   local session-id %d remote session-id %d",
10728          clib_net_to_host_u32 (mp->local_session_id),
10729          clib_net_to_host_u32 (mp->remote_session_id));
10730
10731   print (vam->ofp, "   l2 specific sublayer %s\n",
10732          mp->l2_sublayer_present ? "preset" : "absent");
10733
10734 }
10735
10736 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10737   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10738 {
10739   vat_main_t *vam = &vat_main;
10740   vat_json_node_t *node = NULL;
10741   struct in6_addr addr;
10742
10743   if (VAT_JSON_ARRAY != vam->json_tree.type)
10744     {
10745       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10746       vat_json_init_array (&vam->json_tree);
10747     }
10748   node = vat_json_array_add (&vam->json_tree);
10749
10750   vat_json_init_object (node);
10751
10752   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10753   vat_json_object_add_ip6 (node, "our_address", addr);
10754   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10755   vat_json_object_add_ip6 (node, "client_address", addr);
10756
10757   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10758   vat_json_init_array (lc);
10759   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10760   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10761   vat_json_object_add_uint (node, "remote_cookie",
10762                             clib_net_to_host_u64 (mp->remote_cookie));
10763
10764   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10765   vat_json_object_add_uint (node, "local_session_id",
10766                             clib_net_to_host_u32 (mp->local_session_id));
10767   vat_json_object_add_uint (node, "remote_session_id",
10768                             clib_net_to_host_u32 (mp->remote_session_id));
10769   vat_json_object_add_string_copy (node, "l2_sublayer",
10770                                    mp->l2_sublayer_present ? (u8 *) "present"
10771                                    : (u8 *) "absent");
10772 }
10773
10774 static int
10775 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10776 {
10777   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10778   vl_api_control_ping_t *mp_ping;
10779   int ret;
10780
10781   /* Get list of l2tpv3-tunnel interfaces */
10782   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10783   S (mp);
10784
10785   /* Use a control ping for synchronization */
10786   M (CONTROL_PING, mp_ping);
10787   S (mp_ping);
10788
10789   W (ret);
10790   return ret;
10791 }
10792
10793
10794 static void vl_api_sw_interface_tap_details_t_handler
10795   (vl_api_sw_interface_tap_details_t * mp)
10796 {
10797   vat_main_t *vam = &vat_main;
10798
10799   print (vam->ofp, "%-16s %d",
10800          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10801 }
10802
10803 static void vl_api_sw_interface_tap_details_t_handler_json
10804   (vl_api_sw_interface_tap_details_t * mp)
10805 {
10806   vat_main_t *vam = &vat_main;
10807   vat_json_node_t *node = NULL;
10808
10809   if (VAT_JSON_ARRAY != vam->json_tree.type)
10810     {
10811       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10812       vat_json_init_array (&vam->json_tree);
10813     }
10814   node = vat_json_array_add (&vam->json_tree);
10815
10816   vat_json_init_object (node);
10817   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10818   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10819 }
10820
10821 static int
10822 api_sw_interface_tap_dump (vat_main_t * vam)
10823 {
10824   vl_api_sw_interface_tap_dump_t *mp;
10825   vl_api_control_ping_t *mp_ping;
10826   int ret;
10827
10828   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10829   /* Get list of tap interfaces */
10830   M (SW_INTERFACE_TAP_DUMP, mp);
10831   S (mp);
10832
10833   /* Use a control ping for synchronization */
10834   M (CONTROL_PING, mp_ping);
10835   S (mp_ping);
10836
10837   W (ret);
10838   return ret;
10839 }
10840
10841 static uword unformat_vxlan_decap_next
10842   (unformat_input_t * input, va_list * args)
10843 {
10844   u32 *result = va_arg (*args, u32 *);
10845   u32 tmp;
10846
10847   if (unformat (input, "l2"))
10848     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10849   else if (unformat (input, "%d", &tmp))
10850     *result = tmp;
10851   else
10852     return 0;
10853   return 1;
10854 }
10855
10856 static int
10857 api_vxlan_add_del_tunnel (vat_main_t * vam)
10858 {
10859   unformat_input_t *line_input = vam->input;
10860   vl_api_vxlan_add_del_tunnel_t *mp;
10861   ip46_address_t src, dst;
10862   u8 is_add = 1;
10863   u8 ipv4_set = 0, ipv6_set = 0;
10864   u8 src_set = 0;
10865   u8 dst_set = 0;
10866   u8 grp_set = 0;
10867   u32 mcast_sw_if_index = ~0;
10868   u32 encap_vrf_id = 0;
10869   u32 decap_next_index = ~0;
10870   u32 vni = 0;
10871   int ret;
10872
10873   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10874   memset (&src, 0, sizeof src);
10875   memset (&dst, 0, sizeof dst);
10876
10877   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10878     {
10879       if (unformat (line_input, "del"))
10880         is_add = 0;
10881       else
10882         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10883         {
10884           ipv4_set = 1;
10885           src_set = 1;
10886         }
10887       else
10888         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10889         {
10890           ipv4_set = 1;
10891           dst_set = 1;
10892         }
10893       else
10894         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10895         {
10896           ipv6_set = 1;
10897           src_set = 1;
10898         }
10899       else
10900         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10901         {
10902           ipv6_set = 1;
10903           dst_set = 1;
10904         }
10905       else if (unformat (line_input, "group %U %U",
10906                          unformat_ip4_address, &dst.ip4,
10907                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10908         {
10909           grp_set = dst_set = 1;
10910           ipv4_set = 1;
10911         }
10912       else if (unformat (line_input, "group %U",
10913                          unformat_ip4_address, &dst.ip4))
10914         {
10915           grp_set = dst_set = 1;
10916           ipv4_set = 1;
10917         }
10918       else if (unformat (line_input, "group %U %U",
10919                          unformat_ip6_address, &dst.ip6,
10920                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10921         {
10922           grp_set = dst_set = 1;
10923           ipv6_set = 1;
10924         }
10925       else if (unformat (line_input, "group %U",
10926                          unformat_ip6_address, &dst.ip6))
10927         {
10928           grp_set = dst_set = 1;
10929           ipv6_set = 1;
10930         }
10931       else
10932         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10933         ;
10934       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10935         ;
10936       else if (unformat (line_input, "decap-next %U",
10937                          unformat_vxlan_decap_next, &decap_next_index))
10938         ;
10939       else if (unformat (line_input, "vni %d", &vni))
10940         ;
10941       else
10942         {
10943           errmsg ("parse error '%U'", format_unformat_error, line_input);
10944           return -99;
10945         }
10946     }
10947
10948   if (src_set == 0)
10949     {
10950       errmsg ("tunnel src address not specified");
10951       return -99;
10952     }
10953   if (dst_set == 0)
10954     {
10955       errmsg ("tunnel dst address not specified");
10956       return -99;
10957     }
10958
10959   if (grp_set && !ip46_address_is_multicast (&dst))
10960     {
10961       errmsg ("tunnel group address not multicast");
10962       return -99;
10963     }
10964   if (grp_set && mcast_sw_if_index == ~0)
10965     {
10966       errmsg ("tunnel nonexistent multicast device");
10967       return -99;
10968     }
10969   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10970     {
10971       errmsg ("tunnel dst address must be unicast");
10972       return -99;
10973     }
10974
10975
10976   if (ipv4_set && ipv6_set)
10977     {
10978       errmsg ("both IPv4 and IPv6 addresses specified");
10979       return -99;
10980     }
10981
10982   if ((vni == 0) || (vni >> 24))
10983     {
10984       errmsg ("vni not specified or out of range");
10985       return -99;
10986     }
10987
10988   M (VXLAN_ADD_DEL_TUNNEL, mp);
10989
10990   if (ipv6_set)
10991     {
10992       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10993       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10994     }
10995   else
10996     {
10997       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10998       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10999     }
11000   mp->encap_vrf_id = ntohl (encap_vrf_id);
11001   mp->decap_next_index = ntohl (decap_next_index);
11002   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11003   mp->vni = ntohl (vni);
11004   mp->is_add = is_add;
11005   mp->is_ipv6 = ipv6_set;
11006
11007   S (mp);
11008   W (ret);
11009   return ret;
11010 }
11011
11012 static void vl_api_vxlan_tunnel_details_t_handler
11013   (vl_api_vxlan_tunnel_details_t * mp)
11014 {
11015   vat_main_t *vam = &vat_main;
11016   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11017   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11018
11019   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11020          ntohl (mp->sw_if_index),
11021          format_ip46_address, &src, IP46_TYPE_ANY,
11022          format_ip46_address, &dst, IP46_TYPE_ANY,
11023          ntohl (mp->encap_vrf_id),
11024          ntohl (mp->decap_next_index), ntohl (mp->vni),
11025          ntohl (mp->mcast_sw_if_index));
11026 }
11027
11028 static void vl_api_vxlan_tunnel_details_t_handler_json
11029   (vl_api_vxlan_tunnel_details_t * mp)
11030 {
11031   vat_main_t *vam = &vat_main;
11032   vat_json_node_t *node = NULL;
11033
11034   if (VAT_JSON_ARRAY != vam->json_tree.type)
11035     {
11036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11037       vat_json_init_array (&vam->json_tree);
11038     }
11039   node = vat_json_array_add (&vam->json_tree);
11040
11041   vat_json_init_object (node);
11042   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11043   if (mp->is_ipv6)
11044     {
11045       struct in6_addr ip6;
11046
11047       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11048       vat_json_object_add_ip6 (node, "src_address", ip6);
11049       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11050       vat_json_object_add_ip6 (node, "dst_address", ip6);
11051     }
11052   else
11053     {
11054       struct in_addr ip4;
11055
11056       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11057       vat_json_object_add_ip4 (node, "src_address", ip4);
11058       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11059       vat_json_object_add_ip4 (node, "dst_address", ip4);
11060     }
11061   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11062   vat_json_object_add_uint (node, "decap_next_index",
11063                             ntohl (mp->decap_next_index));
11064   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11065   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11066   vat_json_object_add_uint (node, "mcast_sw_if_index",
11067                             ntohl (mp->mcast_sw_if_index));
11068 }
11069
11070 static int
11071 api_vxlan_tunnel_dump (vat_main_t * vam)
11072 {
11073   unformat_input_t *i = vam->input;
11074   vl_api_vxlan_tunnel_dump_t *mp;
11075   vl_api_control_ping_t *mp_ping;
11076   u32 sw_if_index;
11077   u8 sw_if_index_set = 0;
11078   int ret;
11079
11080   /* Parse args required to build the message */
11081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11082     {
11083       if (unformat (i, "sw_if_index %d", &sw_if_index))
11084         sw_if_index_set = 1;
11085       else
11086         break;
11087     }
11088
11089   if (sw_if_index_set == 0)
11090     {
11091       sw_if_index = ~0;
11092     }
11093
11094   if (!vam->json_output)
11095     {
11096       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11097              "sw_if_index", "src_address", "dst_address",
11098              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11099     }
11100
11101   /* Get list of vxlan-tunnel interfaces */
11102   M (VXLAN_TUNNEL_DUMP, mp);
11103
11104   mp->sw_if_index = htonl (sw_if_index);
11105
11106   S (mp);
11107
11108   /* Use a control ping for synchronization */
11109   M (CONTROL_PING, mp_ping);
11110   S (mp_ping);
11111
11112   W (ret);
11113   return ret;
11114 }
11115
11116 static int
11117 api_gre_add_del_tunnel (vat_main_t * vam)
11118 {
11119   unformat_input_t *line_input = vam->input;
11120   vl_api_gre_add_del_tunnel_t *mp;
11121   ip4_address_t src4, dst4;
11122   ip6_address_t src6, dst6;
11123   u8 is_add = 1;
11124   u8 ipv4_set = 0;
11125   u8 ipv6_set = 0;
11126   u8 teb = 0;
11127   u8 src_set = 0;
11128   u8 dst_set = 0;
11129   u32 outer_fib_id = 0;
11130   int ret;
11131
11132   memset (&src4, 0, sizeof src4);
11133   memset (&dst4, 0, sizeof dst4);
11134   memset (&src6, 0, sizeof src6);
11135   memset (&dst6, 0, sizeof dst6);
11136
11137   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11138     {
11139       if (unformat (line_input, "del"))
11140         is_add = 0;
11141       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11142         {
11143           src_set = 1;
11144           ipv4_set = 1;
11145         }
11146       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11147         {
11148           dst_set = 1;
11149           ipv4_set = 1;
11150         }
11151       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11152         {
11153           src_set = 1;
11154           ipv6_set = 1;
11155         }
11156       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11157         {
11158           dst_set = 1;
11159           ipv6_set = 1;
11160         }
11161       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11162         ;
11163       else if (unformat (line_input, "teb"))
11164         teb = 1;
11165       else
11166         {
11167           errmsg ("parse error '%U'", format_unformat_error, line_input);
11168           return -99;
11169         }
11170     }
11171
11172   if (src_set == 0)
11173     {
11174       errmsg ("tunnel src address not specified");
11175       return -99;
11176     }
11177   if (dst_set == 0)
11178     {
11179       errmsg ("tunnel dst address not specified");
11180       return -99;
11181     }
11182   if (ipv4_set && ipv6_set)
11183     {
11184       errmsg ("both IPv4 and IPv6 addresses specified");
11185       return -99;
11186     }
11187
11188
11189   M (GRE_ADD_DEL_TUNNEL, mp);
11190
11191   if (ipv4_set)
11192     {
11193       clib_memcpy (&mp->src_address, &src4, 4);
11194       clib_memcpy (&mp->dst_address, &dst4, 4);
11195     }
11196   else
11197     {
11198       clib_memcpy (&mp->src_address, &src6, 16);
11199       clib_memcpy (&mp->dst_address, &dst6, 16);
11200     }
11201   mp->outer_fib_id = ntohl (outer_fib_id);
11202   mp->is_add = is_add;
11203   mp->teb = teb;
11204   mp->is_ipv6 = ipv6_set;
11205
11206   S (mp);
11207   W (ret);
11208   return ret;
11209 }
11210
11211 static void vl_api_gre_tunnel_details_t_handler
11212   (vl_api_gre_tunnel_details_t * mp)
11213 {
11214   vat_main_t *vam = &vat_main;
11215   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11216   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11217
11218   print (vam->ofp, "%11d%24U%24U%6d%14d",
11219          ntohl (mp->sw_if_index),
11220          format_ip46_address, &src, IP46_TYPE_ANY,
11221          format_ip46_address, &dst, IP46_TYPE_ANY,
11222          mp->teb, ntohl (mp->outer_fib_id));
11223 }
11224
11225 static void vl_api_gre_tunnel_details_t_handler_json
11226   (vl_api_gre_tunnel_details_t * mp)
11227 {
11228   vat_main_t *vam = &vat_main;
11229   vat_json_node_t *node = NULL;
11230   struct in_addr ip4;
11231   struct in6_addr ip6;
11232
11233   if (VAT_JSON_ARRAY != vam->json_tree.type)
11234     {
11235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11236       vat_json_init_array (&vam->json_tree);
11237     }
11238   node = vat_json_array_add (&vam->json_tree);
11239
11240   vat_json_init_object (node);
11241   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11242   if (!mp->is_ipv6)
11243     {
11244       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11245       vat_json_object_add_ip4 (node, "src_address", ip4);
11246       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11247       vat_json_object_add_ip4 (node, "dst_address", ip4);
11248     }
11249   else
11250     {
11251       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11252       vat_json_object_add_ip6 (node, "src_address", ip6);
11253       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11254       vat_json_object_add_ip6 (node, "dst_address", ip6);
11255     }
11256   vat_json_object_add_uint (node, "teb", mp->teb);
11257   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11258   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11259 }
11260
11261 static int
11262 api_gre_tunnel_dump (vat_main_t * vam)
11263 {
11264   unformat_input_t *i = vam->input;
11265   vl_api_gre_tunnel_dump_t *mp;
11266   vl_api_control_ping_t *mp_ping;
11267   u32 sw_if_index;
11268   u8 sw_if_index_set = 0;
11269   int ret;
11270
11271   /* Parse args required to build the message */
11272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11273     {
11274       if (unformat (i, "sw_if_index %d", &sw_if_index))
11275         sw_if_index_set = 1;
11276       else
11277         break;
11278     }
11279
11280   if (sw_if_index_set == 0)
11281     {
11282       sw_if_index = ~0;
11283     }
11284
11285   if (!vam->json_output)
11286     {
11287       print (vam->ofp, "%11s%24s%24s%6s%14s",
11288              "sw_if_index", "src_address", "dst_address", "teb",
11289              "outer_fib_id");
11290     }
11291
11292   /* Get list of gre-tunnel interfaces */
11293   M (GRE_TUNNEL_DUMP, mp);
11294
11295   mp->sw_if_index = htonl (sw_if_index);
11296
11297   S (mp);
11298
11299   /* Use a control ping for synchronization */
11300   M (CONTROL_PING, mp_ping);
11301   S (mp_ping);
11302
11303   W (ret);
11304   return ret;
11305 }
11306
11307 static int
11308 api_l2_fib_clear_table (vat_main_t * vam)
11309 {
11310 //  unformat_input_t * i = vam->input;
11311   vl_api_l2_fib_clear_table_t *mp;
11312   int ret;
11313
11314   M (L2_FIB_CLEAR_TABLE, mp);
11315
11316   S (mp);
11317   W (ret);
11318   return ret;
11319 }
11320
11321 static int
11322 api_l2_interface_efp_filter (vat_main_t * vam)
11323 {
11324   unformat_input_t *i = vam->input;
11325   vl_api_l2_interface_efp_filter_t *mp;
11326   u32 sw_if_index;
11327   u8 enable = 1;
11328   u8 sw_if_index_set = 0;
11329   int ret;
11330
11331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11332     {
11333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11334         sw_if_index_set = 1;
11335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11336         sw_if_index_set = 1;
11337       else if (unformat (i, "enable"))
11338         enable = 1;
11339       else if (unformat (i, "disable"))
11340         enable = 0;
11341       else
11342         {
11343           clib_warning ("parse error '%U'", format_unformat_error, i);
11344           return -99;
11345         }
11346     }
11347
11348   if (sw_if_index_set == 0)
11349     {
11350       errmsg ("missing sw_if_index");
11351       return -99;
11352     }
11353
11354   M (L2_INTERFACE_EFP_FILTER, mp);
11355
11356   mp->sw_if_index = ntohl (sw_if_index);
11357   mp->enable_disable = enable;
11358
11359   S (mp);
11360   W (ret);
11361   return ret;
11362 }
11363
11364 #define foreach_vtr_op                          \
11365 _("disable",  L2_VTR_DISABLED)                  \
11366 _("push-1",  L2_VTR_PUSH_1)                     \
11367 _("push-2",  L2_VTR_PUSH_2)                     \
11368 _("pop-1",  L2_VTR_POP_1)                       \
11369 _("pop-2",  L2_VTR_POP_2)                       \
11370 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11371 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11372 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11373 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11374
11375 static int
11376 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11377 {
11378   unformat_input_t *i = vam->input;
11379   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11380   u32 sw_if_index;
11381   u8 sw_if_index_set = 0;
11382   u8 vtr_op_set = 0;
11383   u32 vtr_op = 0;
11384   u32 push_dot1q = 1;
11385   u32 tag1 = ~0;
11386   u32 tag2 = ~0;
11387   int ret;
11388
11389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11390     {
11391       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11392         sw_if_index_set = 1;
11393       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11394         sw_if_index_set = 1;
11395       else if (unformat (i, "vtr_op %d", &vtr_op))
11396         vtr_op_set = 1;
11397 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11398       foreach_vtr_op
11399 #undef _
11400         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11401         ;
11402       else if (unformat (i, "tag1 %d", &tag1))
11403         ;
11404       else if (unformat (i, "tag2 %d", &tag2))
11405         ;
11406       else
11407         {
11408           clib_warning ("parse error '%U'", format_unformat_error, i);
11409           return -99;
11410         }
11411     }
11412
11413   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11414     {
11415       errmsg ("missing vtr operation or sw_if_index");
11416       return -99;
11417     }
11418
11419   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11420   mp->sw_if_index = ntohl (sw_if_index);
11421   mp->vtr_op = ntohl (vtr_op);
11422   mp->push_dot1q = ntohl (push_dot1q);
11423   mp->tag1 = ntohl (tag1);
11424   mp->tag2 = ntohl (tag2);
11425
11426   S (mp);
11427   W (ret);
11428   return ret;
11429 }
11430
11431 static int
11432 api_create_vhost_user_if (vat_main_t * vam)
11433 {
11434   unformat_input_t *i = vam->input;
11435   vl_api_create_vhost_user_if_t *mp;
11436   u8 *file_name;
11437   u8 is_server = 0;
11438   u8 file_name_set = 0;
11439   u32 custom_dev_instance = ~0;
11440   u8 hwaddr[6];
11441   u8 use_custom_mac = 0;
11442   u8 *tag = 0;
11443   int ret;
11444
11445   /* Shut up coverity */
11446   memset (hwaddr, 0, sizeof (hwaddr));
11447
11448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11449     {
11450       if (unformat (i, "socket %s", &file_name))
11451         {
11452           file_name_set = 1;
11453         }
11454       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11455         ;
11456       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11457         use_custom_mac = 1;
11458       else if (unformat (i, "server"))
11459         is_server = 1;
11460       else if (unformat (i, "tag %s", &tag))
11461         ;
11462       else
11463         break;
11464     }
11465
11466   if (file_name_set == 0)
11467     {
11468       errmsg ("missing socket file name");
11469       return -99;
11470     }
11471
11472   if (vec_len (file_name) > 255)
11473     {
11474       errmsg ("socket file name too long");
11475       return -99;
11476     }
11477   vec_add1 (file_name, 0);
11478
11479   M (CREATE_VHOST_USER_IF, mp);
11480
11481   mp->is_server = is_server;
11482   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11483   vec_free (file_name);
11484   if (custom_dev_instance != ~0)
11485     {
11486       mp->renumber = 1;
11487       mp->custom_dev_instance = ntohl (custom_dev_instance);
11488     }
11489   mp->use_custom_mac = use_custom_mac;
11490   clib_memcpy (mp->mac_address, hwaddr, 6);
11491   if (tag)
11492     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11493   vec_free (tag);
11494
11495   S (mp);
11496   W (ret);
11497   return ret;
11498 }
11499
11500 static int
11501 api_modify_vhost_user_if (vat_main_t * vam)
11502 {
11503   unformat_input_t *i = vam->input;
11504   vl_api_modify_vhost_user_if_t *mp;
11505   u8 *file_name;
11506   u8 is_server = 0;
11507   u8 file_name_set = 0;
11508   u32 custom_dev_instance = ~0;
11509   u8 sw_if_index_set = 0;
11510   u32 sw_if_index = (u32) ~ 0;
11511   int ret;
11512
11513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11514     {
11515       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11516         sw_if_index_set = 1;
11517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11518         sw_if_index_set = 1;
11519       else if (unformat (i, "socket %s", &file_name))
11520         {
11521           file_name_set = 1;
11522         }
11523       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11524         ;
11525       else if (unformat (i, "server"))
11526         is_server = 1;
11527       else
11528         break;
11529     }
11530
11531   if (sw_if_index_set == 0)
11532     {
11533       errmsg ("missing sw_if_index or interface name");
11534       return -99;
11535     }
11536
11537   if (file_name_set == 0)
11538     {
11539       errmsg ("missing socket file name");
11540       return -99;
11541     }
11542
11543   if (vec_len (file_name) > 255)
11544     {
11545       errmsg ("socket file name too long");
11546       return -99;
11547     }
11548   vec_add1 (file_name, 0);
11549
11550   M (MODIFY_VHOST_USER_IF, mp);
11551
11552   mp->sw_if_index = ntohl (sw_if_index);
11553   mp->is_server = is_server;
11554   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11555   vec_free (file_name);
11556   if (custom_dev_instance != ~0)
11557     {
11558       mp->renumber = 1;
11559       mp->custom_dev_instance = ntohl (custom_dev_instance);
11560     }
11561
11562   S (mp);
11563   W (ret);
11564   return ret;
11565 }
11566
11567 static int
11568 api_delete_vhost_user_if (vat_main_t * vam)
11569 {
11570   unformat_input_t *i = vam->input;
11571   vl_api_delete_vhost_user_if_t *mp;
11572   u32 sw_if_index = ~0;
11573   u8 sw_if_index_set = 0;
11574   int ret;
11575
11576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11577     {
11578       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11579         sw_if_index_set = 1;
11580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11581         sw_if_index_set = 1;
11582       else
11583         break;
11584     }
11585
11586   if (sw_if_index_set == 0)
11587     {
11588       errmsg ("missing sw_if_index or interface name");
11589       return -99;
11590     }
11591
11592
11593   M (DELETE_VHOST_USER_IF, mp);
11594
11595   mp->sw_if_index = ntohl (sw_if_index);
11596
11597   S (mp);
11598   W (ret);
11599   return ret;
11600 }
11601
11602 static void vl_api_sw_interface_vhost_user_details_t_handler
11603   (vl_api_sw_interface_vhost_user_details_t * mp)
11604 {
11605   vat_main_t *vam = &vat_main;
11606
11607   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11608          (char *) mp->interface_name,
11609          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11610          clib_net_to_host_u64 (mp->features), mp->is_server,
11611          ntohl (mp->num_regions), (char *) mp->sock_filename);
11612   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11613 }
11614
11615 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11616   (vl_api_sw_interface_vhost_user_details_t * mp)
11617 {
11618   vat_main_t *vam = &vat_main;
11619   vat_json_node_t *node = NULL;
11620
11621   if (VAT_JSON_ARRAY != vam->json_tree.type)
11622     {
11623       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11624       vat_json_init_array (&vam->json_tree);
11625     }
11626   node = vat_json_array_add (&vam->json_tree);
11627
11628   vat_json_init_object (node);
11629   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11630   vat_json_object_add_string_copy (node, "interface_name",
11631                                    mp->interface_name);
11632   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11633                             ntohl (mp->virtio_net_hdr_sz));
11634   vat_json_object_add_uint (node, "features",
11635                             clib_net_to_host_u64 (mp->features));
11636   vat_json_object_add_uint (node, "is_server", mp->is_server);
11637   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11638   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11639   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11640 }
11641
11642 static int
11643 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11644 {
11645   vl_api_sw_interface_vhost_user_dump_t *mp;
11646   vl_api_control_ping_t *mp_ping;
11647   int ret;
11648   print (vam->ofp,
11649          "Interface name            idx hdr_sz features server regions filename");
11650
11651   /* Get list of vhost-user interfaces */
11652   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11653   S (mp);
11654
11655   /* Use a control ping for synchronization */
11656   M (CONTROL_PING, mp_ping);
11657   S (mp_ping);
11658
11659   W (ret);
11660   return ret;
11661 }
11662
11663 static int
11664 api_show_version (vat_main_t * vam)
11665 {
11666   vl_api_show_version_t *mp;
11667   int ret;
11668
11669   M (SHOW_VERSION, mp);
11670
11671   S (mp);
11672   W (ret);
11673   return ret;
11674 }
11675
11676
11677 static int
11678 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11679 {
11680   unformat_input_t *line_input = vam->input;
11681   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11682   ip4_address_t local4, remote4;
11683   ip6_address_t local6, remote6;
11684   u8 is_add = 1;
11685   u8 ipv4_set = 0, ipv6_set = 0;
11686   u8 local_set = 0;
11687   u8 remote_set = 0;
11688   u32 encap_vrf_id = 0;
11689   u32 decap_vrf_id = 0;
11690   u8 protocol = ~0;
11691   u32 vni;
11692   u8 vni_set = 0;
11693   int ret;
11694
11695   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11696     {
11697       if (unformat (line_input, "del"))
11698         is_add = 0;
11699       else if (unformat (line_input, "local %U",
11700                          unformat_ip4_address, &local4))
11701         {
11702           local_set = 1;
11703           ipv4_set = 1;
11704         }
11705       else if (unformat (line_input, "remote %U",
11706                          unformat_ip4_address, &remote4))
11707         {
11708           remote_set = 1;
11709           ipv4_set = 1;
11710         }
11711       else if (unformat (line_input, "local %U",
11712                          unformat_ip6_address, &local6))
11713         {
11714           local_set = 1;
11715           ipv6_set = 1;
11716         }
11717       else if (unformat (line_input, "remote %U",
11718                          unformat_ip6_address, &remote6))
11719         {
11720           remote_set = 1;
11721           ipv6_set = 1;
11722         }
11723       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11724         ;
11725       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11726         ;
11727       else if (unformat (line_input, "vni %d", &vni))
11728         vni_set = 1;
11729       else if (unformat (line_input, "next-ip4"))
11730         protocol = 1;
11731       else if (unformat (line_input, "next-ip6"))
11732         protocol = 2;
11733       else if (unformat (line_input, "next-ethernet"))
11734         protocol = 3;
11735       else if (unformat (line_input, "next-nsh"))
11736         protocol = 4;
11737       else
11738         {
11739           errmsg ("parse error '%U'", format_unformat_error, line_input);
11740           return -99;
11741         }
11742     }
11743
11744   if (local_set == 0)
11745     {
11746       errmsg ("tunnel local address not specified");
11747       return -99;
11748     }
11749   if (remote_set == 0)
11750     {
11751       errmsg ("tunnel remote address not specified");
11752       return -99;
11753     }
11754   if (ipv4_set && ipv6_set)
11755     {
11756       errmsg ("both IPv4 and IPv6 addresses specified");
11757       return -99;
11758     }
11759
11760   if (vni_set == 0)
11761     {
11762       errmsg ("vni not specified");
11763       return -99;
11764     }
11765
11766   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11767
11768
11769   if (ipv6_set)
11770     {
11771       clib_memcpy (&mp->local, &local6, sizeof (local6));
11772       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11773     }
11774   else
11775     {
11776       clib_memcpy (&mp->local, &local4, sizeof (local4));
11777       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11778     }
11779
11780   mp->encap_vrf_id = ntohl (encap_vrf_id);
11781   mp->decap_vrf_id = ntohl (decap_vrf_id);
11782   mp->protocol = protocol;
11783   mp->vni = ntohl (vni);
11784   mp->is_add = is_add;
11785   mp->is_ipv6 = ipv6_set;
11786
11787   S (mp);
11788   W (ret);
11789   return ret;
11790 }
11791
11792 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11793   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11794 {
11795   vat_main_t *vam = &vat_main;
11796
11797   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11798          ntohl (mp->sw_if_index),
11799          format_ip46_address, &(mp->local[0]),
11800          format_ip46_address, &(mp->remote[0]),
11801          ntohl (mp->vni),
11802          ntohl (mp->protocol),
11803          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11804 }
11805
11806 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11807   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11808 {
11809   vat_main_t *vam = &vat_main;
11810   vat_json_node_t *node = NULL;
11811   struct in_addr ip4;
11812   struct in6_addr ip6;
11813
11814   if (VAT_JSON_ARRAY != vam->json_tree.type)
11815     {
11816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11817       vat_json_init_array (&vam->json_tree);
11818     }
11819   node = vat_json_array_add (&vam->json_tree);
11820
11821   vat_json_init_object (node);
11822   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11823   if (mp->is_ipv6)
11824     {
11825       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11826       vat_json_object_add_ip6 (node, "local", ip6);
11827       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11828       vat_json_object_add_ip6 (node, "remote", ip6);
11829     }
11830   else
11831     {
11832       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11833       vat_json_object_add_ip4 (node, "local", ip4);
11834       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11835       vat_json_object_add_ip4 (node, "remote", ip4);
11836     }
11837   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11838   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11839   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11840   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11841   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11842 }
11843
11844 static int
11845 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11846 {
11847   unformat_input_t *i = vam->input;
11848   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11849   vl_api_control_ping_t *mp_ping;
11850   u32 sw_if_index;
11851   u8 sw_if_index_set = 0;
11852   int ret;
11853
11854   /* Parse args required to build the message */
11855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11856     {
11857       if (unformat (i, "sw_if_index %d", &sw_if_index))
11858         sw_if_index_set = 1;
11859       else
11860         break;
11861     }
11862
11863   if (sw_if_index_set == 0)
11864     {
11865       sw_if_index = ~0;
11866     }
11867
11868   if (!vam->json_output)
11869     {
11870       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11871              "sw_if_index", "local", "remote", "vni",
11872              "protocol", "encap_vrf_id", "decap_vrf_id");
11873     }
11874
11875   /* Get list of vxlan-tunnel interfaces */
11876   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11877
11878   mp->sw_if_index = htonl (sw_if_index);
11879
11880   S (mp);
11881
11882   /* Use a control ping for synchronization */
11883   M (CONTROL_PING, mp_ping);
11884   S (mp_ping);
11885
11886   W (ret);
11887   return ret;
11888 }
11889
11890 u8 *
11891 format_l2_fib_mac_address (u8 * s, va_list * args)
11892 {
11893   u8 *a = va_arg (*args, u8 *);
11894
11895   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11896                  a[2], a[3], a[4], a[5], a[6], a[7]);
11897 }
11898
11899 static void vl_api_l2_fib_table_details_t_handler
11900   (vl_api_l2_fib_table_details_t * mp)
11901 {
11902   vat_main_t *vam = &vat_main;
11903
11904   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11905          "       %d       %d     %d",
11906          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11907          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11908          mp->bvi_mac);
11909 }
11910
11911 static void vl_api_l2_fib_table_details_t_handler_json
11912   (vl_api_l2_fib_table_details_t * mp)
11913 {
11914   vat_main_t *vam = &vat_main;
11915   vat_json_node_t *node = NULL;
11916
11917   if (VAT_JSON_ARRAY != vam->json_tree.type)
11918     {
11919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11920       vat_json_init_array (&vam->json_tree);
11921     }
11922   node = vat_json_array_add (&vam->json_tree);
11923
11924   vat_json_init_object (node);
11925   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11926   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11927   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11928   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11929   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11930   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11931 }
11932
11933 static int
11934 api_l2_fib_table_dump (vat_main_t * vam)
11935 {
11936   unformat_input_t *i = vam->input;
11937   vl_api_l2_fib_table_dump_t *mp;
11938   vl_api_control_ping_t *mp_ping;
11939   u32 bd_id;
11940   u8 bd_id_set = 0;
11941   int ret;
11942
11943   /* Parse args required to build the message */
11944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11945     {
11946       if (unformat (i, "bd_id %d", &bd_id))
11947         bd_id_set = 1;
11948       else
11949         break;
11950     }
11951
11952   if (bd_id_set == 0)
11953     {
11954       errmsg ("missing bridge domain");
11955       return -99;
11956     }
11957
11958   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11959
11960   /* Get list of l2 fib entries */
11961   M (L2_FIB_TABLE_DUMP, mp);
11962
11963   mp->bd_id = ntohl (bd_id);
11964   S (mp);
11965
11966   /* Use a control ping for synchronization */
11967   M (CONTROL_PING, mp_ping);
11968   S (mp_ping);
11969
11970   W (ret);
11971   return ret;
11972 }
11973
11974
11975 static int
11976 api_interface_name_renumber (vat_main_t * vam)
11977 {
11978   unformat_input_t *line_input = vam->input;
11979   vl_api_interface_name_renumber_t *mp;
11980   u32 sw_if_index = ~0;
11981   u32 new_show_dev_instance = ~0;
11982   int ret;
11983
11984   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11985     {
11986       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11987                     &sw_if_index))
11988         ;
11989       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11990         ;
11991       else if (unformat (line_input, "new_show_dev_instance %d",
11992                          &new_show_dev_instance))
11993         ;
11994       else
11995         break;
11996     }
11997
11998   if (sw_if_index == ~0)
11999     {
12000       errmsg ("missing interface name or sw_if_index");
12001       return -99;
12002     }
12003
12004   if (new_show_dev_instance == ~0)
12005     {
12006       errmsg ("missing new_show_dev_instance");
12007       return -99;
12008     }
12009
12010   M (INTERFACE_NAME_RENUMBER, mp);
12011
12012   mp->sw_if_index = ntohl (sw_if_index);
12013   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12014
12015   S (mp);
12016   W (ret);
12017   return ret;
12018 }
12019
12020 static int
12021 api_want_ip4_arp_events (vat_main_t * vam)
12022 {
12023   unformat_input_t *line_input = vam->input;
12024   vl_api_want_ip4_arp_events_t *mp;
12025   ip4_address_t address;
12026   int address_set = 0;
12027   u32 enable_disable = 1;
12028   int ret;
12029
12030   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12031     {
12032       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12033         address_set = 1;
12034       else if (unformat (line_input, "del"))
12035         enable_disable = 0;
12036       else
12037         break;
12038     }
12039
12040   if (address_set == 0)
12041     {
12042       errmsg ("missing addresses");
12043       return -99;
12044     }
12045
12046   M (WANT_IP4_ARP_EVENTS, mp);
12047   mp->enable_disable = enable_disable;
12048   mp->pid = htonl (getpid ());
12049   mp->address = address.as_u32;
12050
12051   S (mp);
12052   W (ret);
12053   return ret;
12054 }
12055
12056 static int
12057 api_want_ip6_nd_events (vat_main_t * vam)
12058 {
12059   unformat_input_t *line_input = vam->input;
12060   vl_api_want_ip6_nd_events_t *mp;
12061   ip6_address_t address;
12062   int address_set = 0;
12063   u32 enable_disable = 1;
12064   int ret;
12065
12066   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12067     {
12068       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12069         address_set = 1;
12070       else if (unformat (line_input, "del"))
12071         enable_disable = 0;
12072       else
12073         break;
12074     }
12075
12076   if (address_set == 0)
12077     {
12078       errmsg ("missing addresses");
12079       return -99;
12080     }
12081
12082   M (WANT_IP6_ND_EVENTS, mp);
12083   mp->enable_disable = enable_disable;
12084   mp->pid = htonl (getpid ());
12085   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12086
12087   S (mp);
12088   W (ret);
12089   return ret;
12090 }
12091
12092 static int
12093 api_input_acl_set_interface (vat_main_t * vam)
12094 {
12095   unformat_input_t *i = vam->input;
12096   vl_api_input_acl_set_interface_t *mp;
12097   u32 sw_if_index;
12098   int sw_if_index_set;
12099   u32 ip4_table_index = ~0;
12100   u32 ip6_table_index = ~0;
12101   u32 l2_table_index = ~0;
12102   u8 is_add = 1;
12103   int ret;
12104
12105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12106     {
12107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12108         sw_if_index_set = 1;
12109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12110         sw_if_index_set = 1;
12111       else if (unformat (i, "del"))
12112         is_add = 0;
12113       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12114         ;
12115       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12116         ;
12117       else if (unformat (i, "l2-table %d", &l2_table_index))
12118         ;
12119       else
12120         {
12121           clib_warning ("parse error '%U'", format_unformat_error, i);
12122           return -99;
12123         }
12124     }
12125
12126   if (sw_if_index_set == 0)
12127     {
12128       errmsg ("missing interface name or sw_if_index");
12129       return -99;
12130     }
12131
12132   M (INPUT_ACL_SET_INTERFACE, mp);
12133
12134   mp->sw_if_index = ntohl (sw_if_index);
12135   mp->ip4_table_index = ntohl (ip4_table_index);
12136   mp->ip6_table_index = ntohl (ip6_table_index);
12137   mp->l2_table_index = ntohl (l2_table_index);
12138   mp->is_add = is_add;
12139
12140   S (mp);
12141   W (ret);
12142   return ret;
12143 }
12144
12145 static int
12146 api_ip_address_dump (vat_main_t * vam)
12147 {
12148   unformat_input_t *i = vam->input;
12149   vl_api_ip_address_dump_t *mp;
12150   vl_api_control_ping_t *mp_ping;
12151   u32 sw_if_index = ~0;
12152   u8 sw_if_index_set = 0;
12153   u8 ipv4_set = 0;
12154   u8 ipv6_set = 0;
12155   int ret;
12156
12157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12158     {
12159       if (unformat (i, "sw_if_index %d", &sw_if_index))
12160         sw_if_index_set = 1;
12161       else
12162         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12163         sw_if_index_set = 1;
12164       else if (unformat (i, "ipv4"))
12165         ipv4_set = 1;
12166       else if (unformat (i, "ipv6"))
12167         ipv6_set = 1;
12168       else
12169         break;
12170     }
12171
12172   if (ipv4_set && ipv6_set)
12173     {
12174       errmsg ("ipv4 and ipv6 flags cannot be both set");
12175       return -99;
12176     }
12177
12178   if ((!ipv4_set) && (!ipv6_set))
12179     {
12180       errmsg ("no ipv4 nor ipv6 flag set");
12181       return -99;
12182     }
12183
12184   if (sw_if_index_set == 0)
12185     {
12186       errmsg ("missing interface name or sw_if_index");
12187       return -99;
12188     }
12189
12190   vam->current_sw_if_index = sw_if_index;
12191   vam->is_ipv6 = ipv6_set;
12192
12193   M (IP_ADDRESS_DUMP, mp);
12194   mp->sw_if_index = ntohl (sw_if_index);
12195   mp->is_ipv6 = ipv6_set;
12196   S (mp);
12197
12198   /* Use a control ping for synchronization */
12199   M (CONTROL_PING, mp_ping);
12200   S (mp_ping);
12201
12202   W (ret);
12203   return ret;
12204 }
12205
12206 static int
12207 api_ip_dump (vat_main_t * vam)
12208 {
12209   vl_api_ip_dump_t *mp;
12210   vl_api_control_ping_t *mp_ping;
12211   unformat_input_t *in = vam->input;
12212   int ipv4_set = 0;
12213   int ipv6_set = 0;
12214   int is_ipv6;
12215   int i;
12216   int ret;
12217
12218   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12219     {
12220       if (unformat (in, "ipv4"))
12221         ipv4_set = 1;
12222       else if (unformat (in, "ipv6"))
12223         ipv6_set = 1;
12224       else
12225         break;
12226     }
12227
12228   if (ipv4_set && ipv6_set)
12229     {
12230       errmsg ("ipv4 and ipv6 flags cannot be both set");
12231       return -99;
12232     }
12233
12234   if ((!ipv4_set) && (!ipv6_set))
12235     {
12236       errmsg ("no ipv4 nor ipv6 flag set");
12237       return -99;
12238     }
12239
12240   is_ipv6 = ipv6_set;
12241   vam->is_ipv6 = is_ipv6;
12242
12243   /* free old data */
12244   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12245     {
12246       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12247     }
12248   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12249
12250   M (IP_DUMP, mp);
12251   mp->is_ipv6 = ipv6_set;
12252   S (mp);
12253
12254   /* Use a control ping for synchronization */
12255   M (CONTROL_PING, mp_ping);
12256   S (mp_ping);
12257
12258   W (ret);
12259   return ret;
12260 }
12261
12262 static int
12263 api_ipsec_spd_add_del (vat_main_t * vam)
12264 {
12265   unformat_input_t *i = vam->input;
12266   vl_api_ipsec_spd_add_del_t *mp;
12267   u32 spd_id = ~0;
12268   u8 is_add = 1;
12269   int ret;
12270
12271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12272     {
12273       if (unformat (i, "spd_id %d", &spd_id))
12274         ;
12275       else if (unformat (i, "del"))
12276         is_add = 0;
12277       else
12278         {
12279           clib_warning ("parse error '%U'", format_unformat_error, i);
12280           return -99;
12281         }
12282     }
12283   if (spd_id == ~0)
12284     {
12285       errmsg ("spd_id must be set");
12286       return -99;
12287     }
12288
12289   M (IPSEC_SPD_ADD_DEL, mp);
12290
12291   mp->spd_id = ntohl (spd_id);
12292   mp->is_add = is_add;
12293
12294   S (mp);
12295   W (ret);
12296   return ret;
12297 }
12298
12299 static int
12300 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12301 {
12302   unformat_input_t *i = vam->input;
12303   vl_api_ipsec_interface_add_del_spd_t *mp;
12304   u32 sw_if_index;
12305   u8 sw_if_index_set = 0;
12306   u32 spd_id = (u32) ~ 0;
12307   u8 is_add = 1;
12308   int ret;
12309
12310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12311     {
12312       if (unformat (i, "del"))
12313         is_add = 0;
12314       else if (unformat (i, "spd_id %d", &spd_id))
12315         ;
12316       else
12317         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12318         sw_if_index_set = 1;
12319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12320         sw_if_index_set = 1;
12321       else
12322         {
12323           clib_warning ("parse error '%U'", format_unformat_error, i);
12324           return -99;
12325         }
12326
12327     }
12328
12329   if (spd_id == (u32) ~ 0)
12330     {
12331       errmsg ("spd_id must be set");
12332       return -99;
12333     }
12334
12335   if (sw_if_index_set == 0)
12336     {
12337       errmsg ("missing interface name or sw_if_index");
12338       return -99;
12339     }
12340
12341   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12342
12343   mp->spd_id = ntohl (spd_id);
12344   mp->sw_if_index = ntohl (sw_if_index);
12345   mp->is_add = is_add;
12346
12347   S (mp);
12348   W (ret);
12349   return ret;
12350 }
12351
12352 static int
12353 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12354 {
12355   unformat_input_t *i = vam->input;
12356   vl_api_ipsec_spd_add_del_entry_t *mp;
12357   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12358   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12359   i32 priority = 0;
12360   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12361   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12362   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12363   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12364   int ret;
12365
12366   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12367   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12368   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12369   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12370   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12371   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12372
12373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12374     {
12375       if (unformat (i, "del"))
12376         is_add = 0;
12377       if (unformat (i, "outbound"))
12378         is_outbound = 1;
12379       if (unformat (i, "inbound"))
12380         is_outbound = 0;
12381       else if (unformat (i, "spd_id %d", &spd_id))
12382         ;
12383       else if (unformat (i, "sa_id %d", &sa_id))
12384         ;
12385       else if (unformat (i, "priority %d", &priority))
12386         ;
12387       else if (unformat (i, "protocol %d", &protocol))
12388         ;
12389       else if (unformat (i, "lport_start %d", &lport_start))
12390         ;
12391       else if (unformat (i, "lport_stop %d", &lport_stop))
12392         ;
12393       else if (unformat (i, "rport_start %d", &rport_start))
12394         ;
12395       else if (unformat (i, "rport_stop %d", &rport_stop))
12396         ;
12397       else
12398         if (unformat
12399             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12400         {
12401           is_ipv6 = 0;
12402           is_ip_any = 0;
12403         }
12404       else
12405         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12406         {
12407           is_ipv6 = 0;
12408           is_ip_any = 0;
12409         }
12410       else
12411         if (unformat
12412             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12413         {
12414           is_ipv6 = 0;
12415           is_ip_any = 0;
12416         }
12417       else
12418         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12419         {
12420           is_ipv6 = 0;
12421           is_ip_any = 0;
12422         }
12423       else
12424         if (unformat
12425             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12426         {
12427           is_ipv6 = 1;
12428           is_ip_any = 0;
12429         }
12430       else
12431         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12432         {
12433           is_ipv6 = 1;
12434           is_ip_any = 0;
12435         }
12436       else
12437         if (unformat
12438             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12439         {
12440           is_ipv6 = 1;
12441           is_ip_any = 0;
12442         }
12443       else
12444         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12445         {
12446           is_ipv6 = 1;
12447           is_ip_any = 0;
12448         }
12449       else
12450         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12451         {
12452           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12453             {
12454               clib_warning ("unsupported action: 'resolve'");
12455               return -99;
12456             }
12457         }
12458       else
12459         {
12460           clib_warning ("parse error '%U'", format_unformat_error, i);
12461           return -99;
12462         }
12463
12464     }
12465
12466   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12467
12468   mp->spd_id = ntohl (spd_id);
12469   mp->priority = ntohl (priority);
12470   mp->is_outbound = is_outbound;
12471
12472   mp->is_ipv6 = is_ipv6;
12473   if (is_ipv6 || is_ip_any)
12474     {
12475       clib_memcpy (mp->remote_address_start, &raddr6_start,
12476                    sizeof (ip6_address_t));
12477       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12478                    sizeof (ip6_address_t));
12479       clib_memcpy (mp->local_address_start, &laddr6_start,
12480                    sizeof (ip6_address_t));
12481       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12482                    sizeof (ip6_address_t));
12483     }
12484   else
12485     {
12486       clib_memcpy (mp->remote_address_start, &raddr4_start,
12487                    sizeof (ip4_address_t));
12488       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12489                    sizeof (ip4_address_t));
12490       clib_memcpy (mp->local_address_start, &laddr4_start,
12491                    sizeof (ip4_address_t));
12492       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12493                    sizeof (ip4_address_t));
12494     }
12495   mp->protocol = (u8) protocol;
12496   mp->local_port_start = ntohs ((u16) lport_start);
12497   mp->local_port_stop = ntohs ((u16) lport_stop);
12498   mp->remote_port_start = ntohs ((u16) rport_start);
12499   mp->remote_port_stop = ntohs ((u16) rport_stop);
12500   mp->policy = (u8) policy;
12501   mp->sa_id = ntohl (sa_id);
12502   mp->is_add = is_add;
12503   mp->is_ip_any = is_ip_any;
12504   S (mp);
12505   W (ret);
12506   return ret;
12507 }
12508
12509 static int
12510 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12511 {
12512   unformat_input_t *i = vam->input;
12513   vl_api_ipsec_sad_add_del_entry_t *mp;
12514   u32 sad_id = 0, spi = 0;
12515   u8 *ck = 0, *ik = 0;
12516   u8 is_add = 1;
12517
12518   u8 protocol = IPSEC_PROTOCOL_AH;
12519   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12520   u32 crypto_alg = 0, integ_alg = 0;
12521   ip4_address_t tun_src4;
12522   ip4_address_t tun_dst4;
12523   ip6_address_t tun_src6;
12524   ip6_address_t tun_dst6;
12525   int ret;
12526
12527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12528     {
12529       if (unformat (i, "del"))
12530         is_add = 0;
12531       else if (unformat (i, "sad_id %d", &sad_id))
12532         ;
12533       else if (unformat (i, "spi %d", &spi))
12534         ;
12535       else if (unformat (i, "esp"))
12536         protocol = IPSEC_PROTOCOL_ESP;
12537       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12538         {
12539           is_tunnel = 1;
12540           is_tunnel_ipv6 = 0;
12541         }
12542       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12543         {
12544           is_tunnel = 1;
12545           is_tunnel_ipv6 = 0;
12546         }
12547       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12548         {
12549           is_tunnel = 1;
12550           is_tunnel_ipv6 = 1;
12551         }
12552       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12553         {
12554           is_tunnel = 1;
12555           is_tunnel_ipv6 = 1;
12556         }
12557       else
12558         if (unformat
12559             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12560         {
12561           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12562               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12563             {
12564               clib_warning ("unsupported crypto-alg: '%U'",
12565                             format_ipsec_crypto_alg, crypto_alg);
12566               return -99;
12567             }
12568         }
12569       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12570         ;
12571       else
12572         if (unformat
12573             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12574         {
12575           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12576               integ_alg >= IPSEC_INTEG_N_ALG)
12577             {
12578               clib_warning ("unsupported integ-alg: '%U'",
12579                             format_ipsec_integ_alg, integ_alg);
12580               return -99;
12581             }
12582         }
12583       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12584         ;
12585       else
12586         {
12587           clib_warning ("parse error '%U'", format_unformat_error, i);
12588           return -99;
12589         }
12590
12591     }
12592
12593   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12594
12595   mp->sad_id = ntohl (sad_id);
12596   mp->is_add = is_add;
12597   mp->protocol = protocol;
12598   mp->spi = ntohl (spi);
12599   mp->is_tunnel = is_tunnel;
12600   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12601   mp->crypto_algorithm = crypto_alg;
12602   mp->integrity_algorithm = integ_alg;
12603   mp->crypto_key_length = vec_len (ck);
12604   mp->integrity_key_length = vec_len (ik);
12605
12606   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12607     mp->crypto_key_length = sizeof (mp->crypto_key);
12608
12609   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12610     mp->integrity_key_length = sizeof (mp->integrity_key);
12611
12612   if (ck)
12613     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12614   if (ik)
12615     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12616
12617   if (is_tunnel)
12618     {
12619       if (is_tunnel_ipv6)
12620         {
12621           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12622                        sizeof (ip6_address_t));
12623           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12624                        sizeof (ip6_address_t));
12625         }
12626       else
12627         {
12628           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12629                        sizeof (ip4_address_t));
12630           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12631                        sizeof (ip4_address_t));
12632         }
12633     }
12634
12635   S (mp);
12636   W (ret);
12637   return ret;
12638 }
12639
12640 static int
12641 api_ipsec_sa_set_key (vat_main_t * vam)
12642 {
12643   unformat_input_t *i = vam->input;
12644   vl_api_ipsec_sa_set_key_t *mp;
12645   u32 sa_id;
12646   u8 *ck = 0, *ik = 0;
12647   int ret;
12648
12649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12650     {
12651       if (unformat (i, "sa_id %d", &sa_id))
12652         ;
12653       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12654         ;
12655       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12656         ;
12657       else
12658         {
12659           clib_warning ("parse error '%U'", format_unformat_error, i);
12660           return -99;
12661         }
12662     }
12663
12664   M (IPSEC_SA_SET_KEY, mp);
12665
12666   mp->sa_id = ntohl (sa_id);
12667   mp->crypto_key_length = vec_len (ck);
12668   mp->integrity_key_length = vec_len (ik);
12669
12670   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12671     mp->crypto_key_length = sizeof (mp->crypto_key);
12672
12673   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12674     mp->integrity_key_length = sizeof (mp->integrity_key);
12675
12676   if (ck)
12677     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12678   if (ik)
12679     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12680
12681   S (mp);
12682   W (ret);
12683   return ret;
12684 }
12685
12686 static int
12687 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12688 {
12689   unformat_input_t *i = vam->input;
12690   vl_api_ipsec_tunnel_if_add_del_t *mp;
12691   u32 local_spi = 0, remote_spi = 0;
12692   u32 crypto_alg = 0, integ_alg = 0;
12693   u8 *lck = NULL, *rck = NULL;
12694   u8 *lik = NULL, *rik = NULL;
12695   ip4_address_t local_ip = { {0} };
12696   ip4_address_t remote_ip = { {0} };
12697   u8 is_add = 1;
12698   u8 esn = 0;
12699   u8 anti_replay = 0;
12700   int ret;
12701
12702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12703     {
12704       if (unformat (i, "del"))
12705         is_add = 0;
12706       else if (unformat (i, "esn"))
12707         esn = 1;
12708       else if (unformat (i, "anti_replay"))
12709         anti_replay = 1;
12710       else if (unformat (i, "local_spi %d", &local_spi))
12711         ;
12712       else if (unformat (i, "remote_spi %d", &remote_spi))
12713         ;
12714       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12715         ;
12716       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12717         ;
12718       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12719         ;
12720       else
12721         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12722         ;
12723       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12724         ;
12725       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12726         ;
12727       else
12728         if (unformat
12729             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12730         {
12731           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12732               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12733             {
12734               errmsg ("unsupported crypto-alg: '%U'\n",
12735                       format_ipsec_crypto_alg, crypto_alg);
12736               return -99;
12737             }
12738         }
12739       else
12740         if (unformat
12741             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12742         {
12743           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12744               integ_alg >= IPSEC_INTEG_N_ALG)
12745             {
12746               errmsg ("unsupported integ-alg: '%U'\n",
12747                       format_ipsec_integ_alg, integ_alg);
12748               return -99;
12749             }
12750         }
12751       else
12752         {
12753           errmsg ("parse error '%U'\n", format_unformat_error, i);
12754           return -99;
12755         }
12756     }
12757
12758   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12759
12760   mp->is_add = is_add;
12761   mp->esn = esn;
12762   mp->anti_replay = anti_replay;
12763
12764   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12765   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12766
12767   mp->local_spi = htonl (local_spi);
12768   mp->remote_spi = htonl (remote_spi);
12769   mp->crypto_alg = (u8) crypto_alg;
12770
12771   mp->local_crypto_key_len = 0;
12772   if (lck)
12773     {
12774       mp->local_crypto_key_len = vec_len (lck);
12775       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12776         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12777       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12778     }
12779
12780   mp->remote_crypto_key_len = 0;
12781   if (rck)
12782     {
12783       mp->remote_crypto_key_len = vec_len (rck);
12784       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12785         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12786       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12787     }
12788
12789   mp->integ_alg = (u8) integ_alg;
12790
12791   mp->local_integ_key_len = 0;
12792   if (lik)
12793     {
12794       mp->local_integ_key_len = vec_len (lik);
12795       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12796         mp->local_integ_key_len = sizeof (mp->local_integ_key);
12797       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12798     }
12799
12800   mp->remote_integ_key_len = 0;
12801   if (rik)
12802     {
12803       mp->remote_integ_key_len = vec_len (rik);
12804       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12805         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12806       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12807     }
12808
12809   S (mp);
12810   W (ret);
12811   return ret;
12812 }
12813
12814 static int
12815 api_ikev2_profile_add_del (vat_main_t * vam)
12816 {
12817   unformat_input_t *i = vam->input;
12818   vl_api_ikev2_profile_add_del_t *mp;
12819   u8 is_add = 1;
12820   u8 *name = 0;
12821   int ret;
12822
12823   const char *valid_chars = "a-zA-Z0-9_";
12824
12825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12826     {
12827       if (unformat (i, "del"))
12828         is_add = 0;
12829       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12830         vec_add1 (name, 0);
12831       else
12832         {
12833           errmsg ("parse error '%U'", format_unformat_error, i);
12834           return -99;
12835         }
12836     }
12837
12838   if (!vec_len (name))
12839     {
12840       errmsg ("profile name must be specified");
12841       return -99;
12842     }
12843
12844   if (vec_len (name) > 64)
12845     {
12846       errmsg ("profile name too long");
12847       return -99;
12848     }
12849
12850   M (IKEV2_PROFILE_ADD_DEL, mp);
12851
12852   clib_memcpy (mp->name, name, vec_len (name));
12853   mp->is_add = is_add;
12854   vec_free (name);
12855
12856   S (mp);
12857   W (ret);
12858   return ret;
12859 }
12860
12861 static int
12862 api_ikev2_profile_set_auth (vat_main_t * vam)
12863 {
12864   unformat_input_t *i = vam->input;
12865   vl_api_ikev2_profile_set_auth_t *mp;
12866   u8 *name = 0;
12867   u8 *data = 0;
12868   u32 auth_method = 0;
12869   u8 is_hex = 0;
12870   int ret;
12871
12872   const char *valid_chars = "a-zA-Z0-9_";
12873
12874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12875     {
12876       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12877         vec_add1 (name, 0);
12878       else if (unformat (i, "auth_method %U",
12879                          unformat_ikev2_auth_method, &auth_method))
12880         ;
12881       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12882         is_hex = 1;
12883       else if (unformat (i, "auth_data %v", &data))
12884         ;
12885       else
12886         {
12887           errmsg ("parse error '%U'", format_unformat_error, i);
12888           return -99;
12889         }
12890     }
12891
12892   if (!vec_len (name))
12893     {
12894       errmsg ("profile name must be specified");
12895       return -99;
12896     }
12897
12898   if (vec_len (name) > 64)
12899     {
12900       errmsg ("profile name too long");
12901       return -99;
12902     }
12903
12904   if (!vec_len (data))
12905     {
12906       errmsg ("auth_data must be specified");
12907       return -99;
12908     }
12909
12910   if (!auth_method)
12911     {
12912       errmsg ("auth_method must be specified");
12913       return -99;
12914     }
12915
12916   M (IKEV2_PROFILE_SET_AUTH, mp);
12917
12918   mp->is_hex = is_hex;
12919   mp->auth_method = (u8) auth_method;
12920   mp->data_len = vec_len (data);
12921   clib_memcpy (mp->name, name, vec_len (name));
12922   clib_memcpy (mp->data, data, vec_len (data));
12923   vec_free (name);
12924   vec_free (data);
12925
12926   S (mp);
12927   W (ret);
12928   return ret;
12929 }
12930
12931 static int
12932 api_ikev2_profile_set_id (vat_main_t * vam)
12933 {
12934   unformat_input_t *i = vam->input;
12935   vl_api_ikev2_profile_set_id_t *mp;
12936   u8 *name = 0;
12937   u8 *data = 0;
12938   u8 is_local = 0;
12939   u32 id_type = 0;
12940   ip4_address_t ip4;
12941   int ret;
12942
12943   const char *valid_chars = "a-zA-Z0-9_";
12944
12945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12946     {
12947       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12948         vec_add1 (name, 0);
12949       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12950         ;
12951       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12952         {
12953           data = vec_new (u8, 4);
12954           clib_memcpy (data, ip4.as_u8, 4);
12955         }
12956       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12957         ;
12958       else if (unformat (i, "id_data %v", &data))
12959         ;
12960       else if (unformat (i, "local"))
12961         is_local = 1;
12962       else if (unformat (i, "remote"))
12963         is_local = 0;
12964       else
12965         {
12966           errmsg ("parse error '%U'", format_unformat_error, i);
12967           return -99;
12968         }
12969     }
12970
12971   if (!vec_len (name))
12972     {
12973       errmsg ("profile name must be specified");
12974       return -99;
12975     }
12976
12977   if (vec_len (name) > 64)
12978     {
12979       errmsg ("profile name too long");
12980       return -99;
12981     }
12982
12983   if (!vec_len (data))
12984     {
12985       errmsg ("id_data must be specified");
12986       return -99;
12987     }
12988
12989   if (!id_type)
12990     {
12991       errmsg ("id_type must be specified");
12992       return -99;
12993     }
12994
12995   M (IKEV2_PROFILE_SET_ID, mp);
12996
12997   mp->is_local = is_local;
12998   mp->id_type = (u8) id_type;
12999   mp->data_len = vec_len (data);
13000   clib_memcpy (mp->name, name, vec_len (name));
13001   clib_memcpy (mp->data, data, vec_len (data));
13002   vec_free (name);
13003   vec_free (data);
13004
13005   S (mp);
13006   W (ret);
13007   return ret;
13008 }
13009
13010 static int
13011 api_ikev2_profile_set_ts (vat_main_t * vam)
13012 {
13013   unformat_input_t *i = vam->input;
13014   vl_api_ikev2_profile_set_ts_t *mp;
13015   u8 *name = 0;
13016   u8 is_local = 0;
13017   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13018   ip4_address_t start_addr, end_addr;
13019
13020   const char *valid_chars = "a-zA-Z0-9_";
13021   int ret;
13022
13023   start_addr.as_u32 = 0;
13024   end_addr.as_u32 = (u32) ~ 0;
13025
13026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13027     {
13028       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13029         vec_add1 (name, 0);
13030       else if (unformat (i, "protocol %d", &proto))
13031         ;
13032       else if (unformat (i, "start_port %d", &start_port))
13033         ;
13034       else if (unformat (i, "end_port %d", &end_port))
13035         ;
13036       else
13037         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13038         ;
13039       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13040         ;
13041       else if (unformat (i, "local"))
13042         is_local = 1;
13043       else if (unformat (i, "remote"))
13044         is_local = 0;
13045       else
13046         {
13047           errmsg ("parse error '%U'", format_unformat_error, i);
13048           return -99;
13049         }
13050     }
13051
13052   if (!vec_len (name))
13053     {
13054       errmsg ("profile name must be specified");
13055       return -99;
13056     }
13057
13058   if (vec_len (name) > 64)
13059     {
13060       errmsg ("profile name too long");
13061       return -99;
13062     }
13063
13064   M (IKEV2_PROFILE_SET_TS, mp);
13065
13066   mp->is_local = is_local;
13067   mp->proto = (u8) proto;
13068   mp->start_port = (u16) start_port;
13069   mp->end_port = (u16) end_port;
13070   mp->start_addr = start_addr.as_u32;
13071   mp->end_addr = end_addr.as_u32;
13072   clib_memcpy (mp->name, name, vec_len (name));
13073   vec_free (name);
13074
13075   S (mp);
13076   W (ret);
13077   return ret;
13078 }
13079
13080 static int
13081 api_ikev2_set_local_key (vat_main_t * vam)
13082 {
13083   unformat_input_t *i = vam->input;
13084   vl_api_ikev2_set_local_key_t *mp;
13085   u8 *file = 0;
13086   int ret;
13087
13088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13089     {
13090       if (unformat (i, "file %v", &file))
13091         vec_add1 (file, 0);
13092       else
13093         {
13094           errmsg ("parse error '%U'", format_unformat_error, i);
13095           return -99;
13096         }
13097     }
13098
13099   if (!vec_len (file))
13100     {
13101       errmsg ("RSA key file must be specified");
13102       return -99;
13103     }
13104
13105   if (vec_len (file) > 256)
13106     {
13107       errmsg ("file name too long");
13108       return -99;
13109     }
13110
13111   M (IKEV2_SET_LOCAL_KEY, mp);
13112
13113   clib_memcpy (mp->key_file, file, vec_len (file));
13114   vec_free (file);
13115
13116   S (mp);
13117   W (ret);
13118   return ret;
13119 }
13120
13121 static int
13122 api_ikev2_set_responder (vat_main_t * vam)
13123 {
13124   unformat_input_t *i = vam->input;
13125   vl_api_ikev2_set_responder_t *mp;
13126   int ret;
13127   u8 *name = 0;
13128   u32 sw_if_index = ~0;
13129   ip4_address_t address;
13130
13131   const char *valid_chars = "a-zA-Z0-9_";
13132
13133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13134     {
13135       if (unformat
13136           (i, "%U interface %d address %U", unformat_token, valid_chars,
13137            &name, &sw_if_index, unformat_ip4_address, &address))
13138         vec_add1 (name, 0);
13139       else
13140         {
13141           errmsg ("parse error '%U'", format_unformat_error, i);
13142           return -99;
13143         }
13144     }
13145
13146   if (!vec_len (name))
13147     {
13148       errmsg ("profile name must be specified");
13149       return -99;
13150     }
13151
13152   if (vec_len (name) > 64)
13153     {
13154       errmsg ("profile name too long");
13155       return -99;
13156     }
13157
13158   M (IKEV2_SET_RESPONDER, mp);
13159
13160   clib_memcpy (mp->name, name, vec_len (name));
13161   vec_free (name);
13162
13163   mp->sw_if_index = sw_if_index;
13164   clib_memcpy (mp->address, &address, sizeof (address));
13165
13166   S (mp);
13167   W (ret);
13168   return ret;
13169 }
13170
13171 static int
13172 api_ikev2_set_ike_transforms (vat_main_t * vam)
13173 {
13174   unformat_input_t *i = vam->input;
13175   vl_api_ikev2_set_ike_transforms_t *mp;
13176   int ret;
13177   u8 *name = 0;
13178   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13179
13180   const char *valid_chars = "a-zA-Z0-9_";
13181
13182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13183     {
13184       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13185                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13186         vec_add1 (name, 0);
13187       else
13188         {
13189           errmsg ("parse error '%U'", format_unformat_error, i);
13190           return -99;
13191         }
13192     }
13193
13194   if (!vec_len (name))
13195     {
13196       errmsg ("profile name must be specified");
13197       return -99;
13198     }
13199
13200   if (vec_len (name) > 64)
13201     {
13202       errmsg ("profile name too long");
13203       return -99;
13204     }
13205
13206   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13207
13208   clib_memcpy (mp->name, name, vec_len (name));
13209   vec_free (name);
13210   mp->crypto_alg = crypto_alg;
13211   mp->crypto_key_size = crypto_key_size;
13212   mp->integ_alg = integ_alg;
13213   mp->dh_group = dh_group;
13214
13215   S (mp);
13216   W (ret);
13217   return ret;
13218 }
13219
13220
13221 static int
13222 api_ikev2_set_esp_transforms (vat_main_t * vam)
13223 {
13224   unformat_input_t *i = vam->input;
13225   vl_api_ikev2_set_esp_transforms_t *mp;
13226   int ret;
13227   u8 *name = 0;
13228   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13229
13230   const char *valid_chars = "a-zA-Z0-9_";
13231
13232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13233     {
13234       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13235                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13236         vec_add1 (name, 0);
13237       else
13238         {
13239           errmsg ("parse error '%U'", format_unformat_error, i);
13240           return -99;
13241         }
13242     }
13243
13244   if (!vec_len (name))
13245     {
13246       errmsg ("profile name must be specified");
13247       return -99;
13248     }
13249
13250   if (vec_len (name) > 64)
13251     {
13252       errmsg ("profile name too long");
13253       return -99;
13254     }
13255
13256   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13257
13258   clib_memcpy (mp->name, name, vec_len (name));
13259   vec_free (name);
13260   mp->crypto_alg = crypto_alg;
13261   mp->crypto_key_size = crypto_key_size;
13262   mp->integ_alg = integ_alg;
13263   mp->dh_group = dh_group;
13264
13265   S (mp);
13266   W (ret);
13267   return ret;
13268 }
13269
13270 static int
13271 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13272 {
13273   unformat_input_t *i = vam->input;
13274   vl_api_ikev2_set_sa_lifetime_t *mp;
13275   int ret;
13276   u8 *name = 0;
13277   u64 lifetime, lifetime_maxdata;
13278   u32 lifetime_jitter, handover;
13279
13280   const char *valid_chars = "a-zA-Z0-9_";
13281
13282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13283     {
13284       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13285                     &lifetime, &lifetime_jitter, &handover,
13286                     &lifetime_maxdata))
13287         vec_add1 (name, 0);
13288       else
13289         {
13290           errmsg ("parse error '%U'", format_unformat_error, i);
13291           return -99;
13292         }
13293     }
13294
13295   if (!vec_len (name))
13296     {
13297       errmsg ("profile name must be specified");
13298       return -99;
13299     }
13300
13301   if (vec_len (name) > 64)
13302     {
13303       errmsg ("profile name too long");
13304       return -99;
13305     }
13306
13307   M (IKEV2_SET_SA_LIFETIME, mp);
13308
13309   clib_memcpy (mp->name, name, vec_len (name));
13310   vec_free (name);
13311   mp->lifetime = lifetime;
13312   mp->lifetime_jitter = lifetime_jitter;
13313   mp->handover = handover;
13314   mp->lifetime_maxdata = lifetime_maxdata;
13315
13316   S (mp);
13317   W (ret);
13318   return ret;
13319 }
13320
13321 static int
13322 api_ikev2_initiate_sa_init (vat_main_t * vam)
13323 {
13324   unformat_input_t *i = vam->input;
13325   vl_api_ikev2_initiate_sa_init_t *mp;
13326   int ret;
13327   u8 *name = 0;
13328
13329   const char *valid_chars = "a-zA-Z0-9_";
13330
13331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13332     {
13333       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13334         vec_add1 (name, 0);
13335       else
13336         {
13337           errmsg ("parse error '%U'", format_unformat_error, i);
13338           return -99;
13339         }
13340     }
13341
13342   if (!vec_len (name))
13343     {
13344       errmsg ("profile name must be specified");
13345       return -99;
13346     }
13347
13348   if (vec_len (name) > 64)
13349     {
13350       errmsg ("profile name too long");
13351       return -99;
13352     }
13353
13354   M (IKEV2_INITIATE_SA_INIT, mp);
13355
13356   clib_memcpy (mp->name, name, vec_len (name));
13357   vec_free (name);
13358
13359   S (mp);
13360   W (ret);
13361   return ret;
13362 }
13363
13364 static int
13365 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13366 {
13367   unformat_input_t *i = vam->input;
13368   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13369   int ret;
13370   u64 ispi;
13371
13372
13373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13374     {
13375       if (unformat (i, "%lx", &ispi))
13376         ;
13377       else
13378         {
13379           errmsg ("parse error '%U'", format_unformat_error, i);
13380           return -99;
13381         }
13382     }
13383
13384   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13385
13386   mp->ispi = ispi;
13387
13388   S (mp);
13389   W (ret);
13390   return ret;
13391 }
13392
13393 static int
13394 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13395 {
13396   unformat_input_t *i = vam->input;
13397   vl_api_ikev2_initiate_del_child_sa_t *mp;
13398   int ret;
13399   u32 ispi;
13400
13401
13402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13403     {
13404       if (unformat (i, "%x", &ispi))
13405         ;
13406       else
13407         {
13408           errmsg ("parse error '%U'", format_unformat_error, i);
13409           return -99;
13410         }
13411     }
13412
13413   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13414
13415   mp->ispi = ispi;
13416
13417   S (mp);
13418   W (ret);
13419   return ret;
13420 }
13421
13422 static int
13423 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13424 {
13425   unformat_input_t *i = vam->input;
13426   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13427   int ret;
13428   u32 ispi;
13429
13430
13431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13432     {
13433       if (unformat (i, "%x", &ispi))
13434         ;
13435       else
13436         {
13437           errmsg ("parse error '%U'", format_unformat_error, i);
13438           return -99;
13439         }
13440     }
13441
13442   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13443
13444   mp->ispi = ispi;
13445
13446   S (mp);
13447   W (ret);
13448   return ret;
13449 }
13450
13451 /*
13452  * MAP
13453  */
13454 static int
13455 api_map_add_domain (vat_main_t * vam)
13456 {
13457   unformat_input_t *i = vam->input;
13458   vl_api_map_add_domain_t *mp;
13459
13460   ip4_address_t ip4_prefix;
13461   ip6_address_t ip6_prefix;
13462   ip6_address_t ip6_src;
13463   u32 num_m_args = 0;
13464   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13465     0, psid_length = 0;
13466   u8 is_translation = 0;
13467   u32 mtu = 0;
13468   u32 ip6_src_len = 128;
13469   int ret;
13470
13471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13472     {
13473       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13474                     &ip4_prefix, &ip4_prefix_len))
13475         num_m_args++;
13476       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13477                          &ip6_prefix, &ip6_prefix_len))
13478         num_m_args++;
13479       else
13480         if (unformat
13481             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13482              &ip6_src_len))
13483         num_m_args++;
13484       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13485         num_m_args++;
13486       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13487         num_m_args++;
13488       else if (unformat (i, "psid-offset %d", &psid_offset))
13489         num_m_args++;
13490       else if (unformat (i, "psid-len %d", &psid_length))
13491         num_m_args++;
13492       else if (unformat (i, "mtu %d", &mtu))
13493         num_m_args++;
13494       else if (unformat (i, "map-t"))
13495         is_translation = 1;
13496       else
13497         {
13498           clib_warning ("parse error '%U'", format_unformat_error, i);
13499           return -99;
13500         }
13501     }
13502
13503   if (num_m_args < 3)
13504     {
13505       errmsg ("mandatory argument(s) missing");
13506       return -99;
13507     }
13508
13509   /* Construct the API message */
13510   M (MAP_ADD_DOMAIN, mp);
13511
13512   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13513   mp->ip4_prefix_len = ip4_prefix_len;
13514
13515   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13516   mp->ip6_prefix_len = ip6_prefix_len;
13517
13518   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13519   mp->ip6_src_prefix_len = ip6_src_len;
13520
13521   mp->ea_bits_len = ea_bits_len;
13522   mp->psid_offset = psid_offset;
13523   mp->psid_length = psid_length;
13524   mp->is_translation = is_translation;
13525   mp->mtu = htons (mtu);
13526
13527   /* send it... */
13528   S (mp);
13529
13530   /* Wait for a reply, return good/bad news  */
13531   W (ret);
13532   return ret;
13533 }
13534
13535 static int
13536 api_map_del_domain (vat_main_t * vam)
13537 {
13538   unformat_input_t *i = vam->input;
13539   vl_api_map_del_domain_t *mp;
13540
13541   u32 num_m_args = 0;
13542   u32 index;
13543   int ret;
13544
13545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13546     {
13547       if (unformat (i, "index %d", &index))
13548         num_m_args++;
13549       else
13550         {
13551           clib_warning ("parse error '%U'", format_unformat_error, i);
13552           return -99;
13553         }
13554     }
13555
13556   if (num_m_args != 1)
13557     {
13558       errmsg ("mandatory argument(s) missing");
13559       return -99;
13560     }
13561
13562   /* Construct the API message */
13563   M (MAP_DEL_DOMAIN, mp);
13564
13565   mp->index = ntohl (index);
13566
13567   /* send it... */
13568   S (mp);
13569
13570   /* Wait for a reply, return good/bad news  */
13571   W (ret);
13572   return ret;
13573 }
13574
13575 static int
13576 api_map_add_del_rule (vat_main_t * vam)
13577 {
13578   unformat_input_t *i = vam->input;
13579   vl_api_map_add_del_rule_t *mp;
13580   u8 is_add = 1;
13581   ip6_address_t ip6_dst;
13582   u32 num_m_args = 0, index, psid = 0;
13583   int ret;
13584
13585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13586     {
13587       if (unformat (i, "index %d", &index))
13588         num_m_args++;
13589       else if (unformat (i, "psid %d", &psid))
13590         num_m_args++;
13591       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13592         num_m_args++;
13593       else if (unformat (i, "del"))
13594         {
13595           is_add = 0;
13596         }
13597       else
13598         {
13599           clib_warning ("parse error '%U'", format_unformat_error, i);
13600           return -99;
13601         }
13602     }
13603
13604   /* Construct the API message */
13605   M (MAP_ADD_DEL_RULE, mp);
13606
13607   mp->index = ntohl (index);
13608   mp->is_add = is_add;
13609   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13610   mp->psid = ntohs (psid);
13611
13612   /* send it... */
13613   S (mp);
13614
13615   /* Wait for a reply, return good/bad news  */
13616   W (ret);
13617   return ret;
13618 }
13619
13620 static int
13621 api_map_domain_dump (vat_main_t * vam)
13622 {
13623   vl_api_map_domain_dump_t *mp;
13624   vl_api_control_ping_t *mp_ping;
13625   int ret;
13626
13627   /* Construct the API message */
13628   M (MAP_DOMAIN_DUMP, mp);
13629
13630   /* send it... */
13631   S (mp);
13632
13633   /* Use a control ping for synchronization */
13634   M (CONTROL_PING, mp_ping);
13635   S (mp_ping);
13636
13637   W (ret);
13638   return ret;
13639 }
13640
13641 static int
13642 api_map_rule_dump (vat_main_t * vam)
13643 {
13644   unformat_input_t *i = vam->input;
13645   vl_api_map_rule_dump_t *mp;
13646   vl_api_control_ping_t *mp_ping;
13647   u32 domain_index = ~0;
13648   int ret;
13649
13650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13651     {
13652       if (unformat (i, "index %u", &domain_index))
13653         ;
13654       else
13655         break;
13656     }
13657
13658   if (domain_index == ~0)
13659     {
13660       clib_warning ("parse error: domain index expected");
13661       return -99;
13662     }
13663
13664   /* Construct the API message */
13665   M (MAP_RULE_DUMP, mp);
13666
13667   mp->domain_index = htonl (domain_index);
13668
13669   /* send it... */
13670   S (mp);
13671
13672   /* Use a control ping for synchronization */
13673   M (CONTROL_PING, mp_ping);
13674   S (mp_ping);
13675
13676   W (ret);
13677   return ret;
13678 }
13679
13680 static void vl_api_map_add_domain_reply_t_handler
13681   (vl_api_map_add_domain_reply_t * mp)
13682 {
13683   vat_main_t *vam = &vat_main;
13684   i32 retval = ntohl (mp->retval);
13685
13686   if (vam->async_mode)
13687     {
13688       vam->async_errors += (retval < 0);
13689     }
13690   else
13691     {
13692       vam->retval = retval;
13693       vam->result_ready = 1;
13694     }
13695 }
13696
13697 static void vl_api_map_add_domain_reply_t_handler_json
13698   (vl_api_map_add_domain_reply_t * mp)
13699 {
13700   vat_main_t *vam = &vat_main;
13701   vat_json_node_t node;
13702
13703   vat_json_init_object (&node);
13704   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13705   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13706
13707   vat_json_print (vam->ofp, &node);
13708   vat_json_free (&node);
13709
13710   vam->retval = ntohl (mp->retval);
13711   vam->result_ready = 1;
13712 }
13713
13714 static int
13715 api_get_first_msg_id (vat_main_t * vam)
13716 {
13717   vl_api_get_first_msg_id_t *mp;
13718   unformat_input_t *i = vam->input;
13719   u8 *name;
13720   u8 name_set = 0;
13721   int ret;
13722
13723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13724     {
13725       if (unformat (i, "client %s", &name))
13726         name_set = 1;
13727       else
13728         break;
13729     }
13730
13731   if (name_set == 0)
13732     {
13733       errmsg ("missing client name");
13734       return -99;
13735     }
13736   vec_add1 (name, 0);
13737
13738   if (vec_len (name) > 63)
13739     {
13740       errmsg ("client name too long");
13741       return -99;
13742     }
13743
13744   M (GET_FIRST_MSG_ID, mp);
13745   clib_memcpy (mp->name, name, vec_len (name));
13746   S (mp);
13747   W (ret);
13748   return ret;
13749 }
13750
13751 static int
13752 api_cop_interface_enable_disable (vat_main_t * vam)
13753 {
13754   unformat_input_t *line_input = vam->input;
13755   vl_api_cop_interface_enable_disable_t *mp;
13756   u32 sw_if_index = ~0;
13757   u8 enable_disable = 1;
13758   int ret;
13759
13760   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13761     {
13762       if (unformat (line_input, "disable"))
13763         enable_disable = 0;
13764       if (unformat (line_input, "enable"))
13765         enable_disable = 1;
13766       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13767                          vam, &sw_if_index))
13768         ;
13769       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13770         ;
13771       else
13772         break;
13773     }
13774
13775   if (sw_if_index == ~0)
13776     {
13777       errmsg ("missing interface name or sw_if_index");
13778       return -99;
13779     }
13780
13781   /* Construct the API message */
13782   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13783   mp->sw_if_index = ntohl (sw_if_index);
13784   mp->enable_disable = enable_disable;
13785
13786   /* send it... */
13787   S (mp);
13788   /* Wait for the reply */
13789   W (ret);
13790   return ret;
13791 }
13792
13793 static int
13794 api_cop_whitelist_enable_disable (vat_main_t * vam)
13795 {
13796   unformat_input_t *line_input = vam->input;
13797   vl_api_cop_whitelist_enable_disable_t *mp;
13798   u32 sw_if_index = ~0;
13799   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13800   u32 fib_id = 0;
13801   int ret;
13802
13803   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13804     {
13805       if (unformat (line_input, "ip4"))
13806         ip4 = 1;
13807       else if (unformat (line_input, "ip6"))
13808         ip6 = 1;
13809       else if (unformat (line_input, "default"))
13810         default_cop = 1;
13811       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13812                          vam, &sw_if_index))
13813         ;
13814       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13815         ;
13816       else if (unformat (line_input, "fib-id %d", &fib_id))
13817         ;
13818       else
13819         break;
13820     }
13821
13822   if (sw_if_index == ~0)
13823     {
13824       errmsg ("missing interface name or sw_if_index");
13825       return -99;
13826     }
13827
13828   /* Construct the API message */
13829   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13830   mp->sw_if_index = ntohl (sw_if_index);
13831   mp->fib_id = ntohl (fib_id);
13832   mp->ip4 = ip4;
13833   mp->ip6 = ip6;
13834   mp->default_cop = default_cop;
13835
13836   /* send it... */
13837   S (mp);
13838   /* Wait for the reply */
13839   W (ret);
13840   return ret;
13841 }
13842
13843 static int
13844 api_get_node_graph (vat_main_t * vam)
13845 {
13846   vl_api_get_node_graph_t *mp;
13847   int ret;
13848
13849   M (GET_NODE_GRAPH, mp);
13850
13851   /* send it... */
13852   S (mp);
13853   /* Wait for the reply */
13854   W (ret);
13855   return ret;
13856 }
13857
13858 /* *INDENT-OFF* */
13859 /** Used for parsing LISP eids */
13860 typedef CLIB_PACKED(struct{
13861   u8 addr[16];   /**< eid address */
13862   u32 len;       /**< prefix length if IP */
13863   u8 type;      /**< type of eid */
13864 }) lisp_eid_vat_t;
13865 /* *INDENT-ON* */
13866
13867 static uword
13868 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13869 {
13870   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13871
13872   memset (a, 0, sizeof (a[0]));
13873
13874   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13875     {
13876       a->type = 0;              /* ipv4 type */
13877     }
13878   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13879     {
13880       a->type = 1;              /* ipv6 type */
13881     }
13882   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13883     {
13884       a->type = 2;              /* mac type */
13885     }
13886   else
13887     {
13888       return 0;
13889     }
13890
13891   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13892     {
13893       return 0;
13894     }
13895
13896   return 1;
13897 }
13898
13899 static int
13900 lisp_eid_size_vat (u8 type)
13901 {
13902   switch (type)
13903     {
13904     case 0:
13905       return 4;
13906     case 1:
13907       return 16;
13908     case 2:
13909       return 6;
13910     }
13911   return 0;
13912 }
13913
13914 static void
13915 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13916 {
13917   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13918 }
13919
13920 static int
13921 api_one_add_del_locator_set (vat_main_t * vam)
13922 {
13923   unformat_input_t *input = vam->input;
13924   vl_api_one_add_del_locator_set_t *mp;
13925   u8 is_add = 1;
13926   u8 *locator_set_name = NULL;
13927   u8 locator_set_name_set = 0;
13928   vl_api_local_locator_t locator, *locators = 0;
13929   u32 sw_if_index, priority, weight;
13930   u32 data_len = 0;
13931
13932   int ret;
13933   /* Parse args required to build the message */
13934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13935     {
13936       if (unformat (input, "del"))
13937         {
13938           is_add = 0;
13939         }
13940       else if (unformat (input, "locator-set %s", &locator_set_name))
13941         {
13942           locator_set_name_set = 1;
13943         }
13944       else if (unformat (input, "sw_if_index %u p %u w %u",
13945                          &sw_if_index, &priority, &weight))
13946         {
13947           locator.sw_if_index = htonl (sw_if_index);
13948           locator.priority = priority;
13949           locator.weight = weight;
13950           vec_add1 (locators, locator);
13951         }
13952       else
13953         if (unformat
13954             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13955              &sw_if_index, &priority, &weight))
13956         {
13957           locator.sw_if_index = htonl (sw_if_index);
13958           locator.priority = priority;
13959           locator.weight = weight;
13960           vec_add1 (locators, locator);
13961         }
13962       else
13963         break;
13964     }
13965
13966   if (locator_set_name_set == 0)
13967     {
13968       errmsg ("missing locator-set name");
13969       vec_free (locators);
13970       return -99;
13971     }
13972
13973   if (vec_len (locator_set_name) > 64)
13974     {
13975       errmsg ("locator-set name too long");
13976       vec_free (locator_set_name);
13977       vec_free (locators);
13978       return -99;
13979     }
13980   vec_add1 (locator_set_name, 0);
13981
13982   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13983
13984   /* Construct the API message */
13985   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13986
13987   mp->is_add = is_add;
13988   clib_memcpy (mp->locator_set_name, locator_set_name,
13989                vec_len (locator_set_name));
13990   vec_free (locator_set_name);
13991
13992   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13993   if (locators)
13994     clib_memcpy (mp->locators, locators, data_len);
13995   vec_free (locators);
13996
13997   /* send it... */
13998   S (mp);
13999
14000   /* Wait for a reply... */
14001   W (ret);
14002   return ret;
14003 }
14004
14005 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14006
14007 static int
14008 api_one_add_del_locator (vat_main_t * vam)
14009 {
14010   unformat_input_t *input = vam->input;
14011   vl_api_one_add_del_locator_t *mp;
14012   u32 tmp_if_index = ~0;
14013   u32 sw_if_index = ~0;
14014   u8 sw_if_index_set = 0;
14015   u8 sw_if_index_if_name_set = 0;
14016   u32 priority = ~0;
14017   u8 priority_set = 0;
14018   u32 weight = ~0;
14019   u8 weight_set = 0;
14020   u8 is_add = 1;
14021   u8 *locator_set_name = NULL;
14022   u8 locator_set_name_set = 0;
14023   int ret;
14024
14025   /* Parse args required to build the message */
14026   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14027     {
14028       if (unformat (input, "del"))
14029         {
14030           is_add = 0;
14031         }
14032       else if (unformat (input, "locator-set %s", &locator_set_name))
14033         {
14034           locator_set_name_set = 1;
14035         }
14036       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14037                          &tmp_if_index))
14038         {
14039           sw_if_index_if_name_set = 1;
14040           sw_if_index = tmp_if_index;
14041         }
14042       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14043         {
14044           sw_if_index_set = 1;
14045           sw_if_index = tmp_if_index;
14046         }
14047       else if (unformat (input, "p %d", &priority))
14048         {
14049           priority_set = 1;
14050         }
14051       else if (unformat (input, "w %d", &weight))
14052         {
14053           weight_set = 1;
14054         }
14055       else
14056         break;
14057     }
14058
14059   if (locator_set_name_set == 0)
14060     {
14061       errmsg ("missing locator-set name");
14062       return -99;
14063     }
14064
14065   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14066     {
14067       errmsg ("missing sw_if_index");
14068       vec_free (locator_set_name);
14069       return -99;
14070     }
14071
14072   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14073     {
14074       errmsg ("cannot use both params interface name and sw_if_index");
14075       vec_free (locator_set_name);
14076       return -99;
14077     }
14078
14079   if (priority_set == 0)
14080     {
14081       errmsg ("missing locator-set priority");
14082       vec_free (locator_set_name);
14083       return -99;
14084     }
14085
14086   if (weight_set == 0)
14087     {
14088       errmsg ("missing locator-set weight");
14089       vec_free (locator_set_name);
14090       return -99;
14091     }
14092
14093   if (vec_len (locator_set_name) > 64)
14094     {
14095       errmsg ("locator-set name too long");
14096       vec_free (locator_set_name);
14097       return -99;
14098     }
14099   vec_add1 (locator_set_name, 0);
14100
14101   /* Construct the API message */
14102   M (ONE_ADD_DEL_LOCATOR, mp);
14103
14104   mp->is_add = is_add;
14105   mp->sw_if_index = ntohl (sw_if_index);
14106   mp->priority = priority;
14107   mp->weight = weight;
14108   clib_memcpy (mp->locator_set_name, locator_set_name,
14109                vec_len (locator_set_name));
14110   vec_free (locator_set_name);
14111
14112   /* send it... */
14113   S (mp);
14114
14115   /* Wait for a reply... */
14116   W (ret);
14117   return ret;
14118 }
14119
14120 #define api_lisp_add_del_locator api_one_add_del_locator
14121
14122 uword
14123 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14124 {
14125   u32 *key_id = va_arg (*args, u32 *);
14126   u8 *s = 0;
14127
14128   if (unformat (input, "%s", &s))
14129     {
14130       if (!strcmp ((char *) s, "sha1"))
14131         key_id[0] = HMAC_SHA_1_96;
14132       else if (!strcmp ((char *) s, "sha256"))
14133         key_id[0] = HMAC_SHA_256_128;
14134       else
14135         {
14136           clib_warning ("invalid key_id: '%s'", s);
14137           key_id[0] = HMAC_NO_KEY;
14138         }
14139     }
14140   else
14141     return 0;
14142
14143   vec_free (s);
14144   return 1;
14145 }
14146
14147 static int
14148 api_one_add_del_local_eid (vat_main_t * vam)
14149 {
14150   unformat_input_t *input = vam->input;
14151   vl_api_one_add_del_local_eid_t *mp;
14152   u8 is_add = 1;
14153   u8 eid_set = 0;
14154   lisp_eid_vat_t _eid, *eid = &_eid;
14155   u8 *locator_set_name = 0;
14156   u8 locator_set_name_set = 0;
14157   u32 vni = 0;
14158   u16 key_id = 0;
14159   u8 *key = 0;
14160   int ret;
14161
14162   /* Parse args required to build the message */
14163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14164     {
14165       if (unformat (input, "del"))
14166         {
14167           is_add = 0;
14168         }
14169       else if (unformat (input, "vni %d", &vni))
14170         {
14171           ;
14172         }
14173       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14174         {
14175           eid_set = 1;
14176         }
14177       else if (unformat (input, "locator-set %s", &locator_set_name))
14178         {
14179           locator_set_name_set = 1;
14180         }
14181       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14182         ;
14183       else if (unformat (input, "secret-key %_%v%_", &key))
14184         ;
14185       else
14186         break;
14187     }
14188
14189   if (locator_set_name_set == 0)
14190     {
14191       errmsg ("missing locator-set name");
14192       return -99;
14193     }
14194
14195   if (0 == eid_set)
14196     {
14197       errmsg ("EID address not set!");
14198       vec_free (locator_set_name);
14199       return -99;
14200     }
14201
14202   if (key && (0 == key_id))
14203     {
14204       errmsg ("invalid key_id!");
14205       return -99;
14206     }
14207
14208   if (vec_len (key) > 64)
14209     {
14210       errmsg ("key too long");
14211       vec_free (key);
14212       return -99;
14213     }
14214
14215   if (vec_len (locator_set_name) > 64)
14216     {
14217       errmsg ("locator-set name too long");
14218       vec_free (locator_set_name);
14219       return -99;
14220     }
14221   vec_add1 (locator_set_name, 0);
14222
14223   /* Construct the API message */
14224   M (ONE_ADD_DEL_LOCAL_EID, mp);
14225
14226   mp->is_add = is_add;
14227   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14228   mp->eid_type = eid->type;
14229   mp->prefix_len = eid->len;
14230   mp->vni = clib_host_to_net_u32 (vni);
14231   mp->key_id = clib_host_to_net_u16 (key_id);
14232   clib_memcpy (mp->locator_set_name, locator_set_name,
14233                vec_len (locator_set_name));
14234   clib_memcpy (mp->key, key, vec_len (key));
14235
14236   vec_free (locator_set_name);
14237   vec_free (key);
14238
14239   /* send it... */
14240   S (mp);
14241
14242   /* Wait for a reply... */
14243   W (ret);
14244   return ret;
14245 }
14246
14247 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14248
14249 static int
14250 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14251 {
14252   u32 dp_table = 0, vni = 0;;
14253   unformat_input_t *input = vam->input;
14254   vl_api_gpe_add_del_fwd_entry_t *mp;
14255   u8 is_add = 1;
14256   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14257   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14258   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14259   u32 action = ~0, w;
14260   ip4_address_t rmt_rloc4, lcl_rloc4;
14261   ip6_address_t rmt_rloc6, lcl_rloc6;
14262   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14263   int ret;
14264
14265   memset (&rloc, 0, sizeof (rloc));
14266
14267   /* Parse args required to build the message */
14268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14269     {
14270       if (unformat (input, "del"))
14271         is_add = 0;
14272       else if (unformat (input, "add"))
14273         is_add = 1;
14274       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14275         {
14276           rmt_eid_set = 1;
14277         }
14278       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14279         {
14280           lcl_eid_set = 1;
14281         }
14282       else if (unformat (input, "vrf %d", &dp_table))
14283         ;
14284       else if (unformat (input, "bd %d", &dp_table))
14285         ;
14286       else if (unformat (input, "vni %d", &vni))
14287         ;
14288       else if (unformat (input, "w %d", &w))
14289         {
14290           if (!curr_rloc)
14291             {
14292               errmsg ("No RLOC configured for setting priority/weight!");
14293               return -99;
14294             }
14295           curr_rloc->weight = w;
14296         }
14297       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14298                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14299         {
14300           rloc.is_ip4 = 1;
14301
14302           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14303           rloc.weight = 0;
14304           vec_add1 (lcl_locs, rloc);
14305
14306           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14307           vec_add1 (rmt_locs, rloc);
14308           /* weight saved in rmt loc */
14309           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14310         }
14311       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14312                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14313         {
14314           rloc.is_ip4 = 0;
14315           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14316           rloc.weight = 0;
14317           vec_add1 (lcl_locs, rloc);
14318
14319           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14320           vec_add1 (rmt_locs, rloc);
14321           /* weight saved in rmt loc */
14322           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14323         }
14324       else if (unformat (input, "action %d", &action))
14325         {
14326           ;
14327         }
14328       else
14329         {
14330           clib_warning ("parse error '%U'", format_unformat_error, input);
14331           return -99;
14332         }
14333     }
14334
14335   if (!rmt_eid_set)
14336     {
14337       errmsg ("remote eid addresses not set");
14338       return -99;
14339     }
14340
14341   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14342     {
14343       errmsg ("eid types don't match");
14344       return -99;
14345     }
14346
14347   if (0 == rmt_locs && (u32) ~ 0 == action)
14348     {
14349       errmsg ("action not set for negative mapping");
14350       return -99;
14351     }
14352
14353   /* Construct the API message */
14354   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14355       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14356
14357   mp->is_add = is_add;
14358   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14359   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14360   mp->eid_type = rmt_eid->type;
14361   mp->dp_table = clib_host_to_net_u32 (dp_table);
14362   mp->vni = clib_host_to_net_u32 (vni);
14363   mp->rmt_len = rmt_eid->len;
14364   mp->lcl_len = lcl_eid->len;
14365   mp->action = action;
14366
14367   if (0 != rmt_locs && 0 != lcl_locs)
14368     {
14369       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14370       clib_memcpy (mp->locs, lcl_locs,
14371                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14372
14373       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14374       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14375                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14376     }
14377   vec_free (lcl_locs);
14378   vec_free (rmt_locs);
14379
14380   /* send it... */
14381   S (mp);
14382
14383   /* Wait for a reply... */
14384   W (ret);
14385   return ret;
14386 }
14387
14388 static int
14389 api_one_add_del_map_server (vat_main_t * vam)
14390 {
14391   unformat_input_t *input = vam->input;
14392   vl_api_one_add_del_map_server_t *mp;
14393   u8 is_add = 1;
14394   u8 ipv4_set = 0;
14395   u8 ipv6_set = 0;
14396   ip4_address_t ipv4;
14397   ip6_address_t ipv6;
14398   int ret;
14399
14400   /* Parse args required to build the message */
14401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14402     {
14403       if (unformat (input, "del"))
14404         {
14405           is_add = 0;
14406         }
14407       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14408         {
14409           ipv4_set = 1;
14410         }
14411       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14412         {
14413           ipv6_set = 1;
14414         }
14415       else
14416         break;
14417     }
14418
14419   if (ipv4_set && ipv6_set)
14420     {
14421       errmsg ("both eid v4 and v6 addresses set");
14422       return -99;
14423     }
14424
14425   if (!ipv4_set && !ipv6_set)
14426     {
14427       errmsg ("eid addresses not set");
14428       return -99;
14429     }
14430
14431   /* Construct the API message */
14432   M (ONE_ADD_DEL_MAP_SERVER, mp);
14433
14434   mp->is_add = is_add;
14435   if (ipv6_set)
14436     {
14437       mp->is_ipv6 = 1;
14438       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14439     }
14440   else
14441     {
14442       mp->is_ipv6 = 0;
14443       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14444     }
14445
14446   /* send it... */
14447   S (mp);
14448
14449   /* Wait for a reply... */
14450   W (ret);
14451   return ret;
14452 }
14453
14454 #define api_lisp_add_del_map_server api_one_add_del_map_server
14455
14456 static int
14457 api_one_add_del_map_resolver (vat_main_t * vam)
14458 {
14459   unformat_input_t *input = vam->input;
14460   vl_api_one_add_del_map_resolver_t *mp;
14461   u8 is_add = 1;
14462   u8 ipv4_set = 0;
14463   u8 ipv6_set = 0;
14464   ip4_address_t ipv4;
14465   ip6_address_t ipv6;
14466   int ret;
14467
14468   /* Parse args required to build the message */
14469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14470     {
14471       if (unformat (input, "del"))
14472         {
14473           is_add = 0;
14474         }
14475       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14476         {
14477           ipv4_set = 1;
14478         }
14479       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14480         {
14481           ipv6_set = 1;
14482         }
14483       else
14484         break;
14485     }
14486
14487   if (ipv4_set && ipv6_set)
14488     {
14489       errmsg ("both eid v4 and v6 addresses set");
14490       return -99;
14491     }
14492
14493   if (!ipv4_set && !ipv6_set)
14494     {
14495       errmsg ("eid addresses not set");
14496       return -99;
14497     }
14498
14499   /* Construct the API message */
14500   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14501
14502   mp->is_add = is_add;
14503   if (ipv6_set)
14504     {
14505       mp->is_ipv6 = 1;
14506       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14507     }
14508   else
14509     {
14510       mp->is_ipv6 = 0;
14511       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14512     }
14513
14514   /* send it... */
14515   S (mp);
14516
14517   /* Wait for a reply... */
14518   W (ret);
14519   return ret;
14520 }
14521
14522 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14523
14524 static int
14525 api_lisp_gpe_enable_disable (vat_main_t * vam)
14526 {
14527   unformat_input_t *input = vam->input;
14528   vl_api_gpe_enable_disable_t *mp;
14529   u8 is_set = 0;
14530   u8 is_en = 1;
14531   int ret;
14532
14533   /* Parse args required to build the message */
14534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14535     {
14536       if (unformat (input, "enable"))
14537         {
14538           is_set = 1;
14539           is_en = 1;
14540         }
14541       else if (unformat (input, "disable"))
14542         {
14543           is_set = 1;
14544           is_en = 0;
14545         }
14546       else
14547         break;
14548     }
14549
14550   if (is_set == 0)
14551     {
14552       errmsg ("Value not set");
14553       return -99;
14554     }
14555
14556   /* Construct the API message */
14557   M (GPE_ENABLE_DISABLE, mp);
14558
14559   mp->is_en = is_en;
14560
14561   /* send it... */
14562   S (mp);
14563
14564   /* Wait for a reply... */
14565   W (ret);
14566   return ret;
14567 }
14568
14569 static int
14570 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14571 {
14572   unformat_input_t *input = vam->input;
14573   vl_api_one_rloc_probe_enable_disable_t *mp;
14574   u8 is_set = 0;
14575   u8 is_en = 0;
14576   int ret;
14577
14578   /* Parse args required to build the message */
14579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14580     {
14581       if (unformat (input, "enable"))
14582         {
14583           is_set = 1;
14584           is_en = 1;
14585         }
14586       else if (unformat (input, "disable"))
14587         is_set = 1;
14588       else
14589         break;
14590     }
14591
14592   if (!is_set)
14593     {
14594       errmsg ("Value not set");
14595       return -99;
14596     }
14597
14598   /* Construct the API message */
14599   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14600
14601   mp->is_enabled = is_en;
14602
14603   /* send it... */
14604   S (mp);
14605
14606   /* Wait for a reply... */
14607   W (ret);
14608   return ret;
14609 }
14610
14611 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14612
14613 static int
14614 api_one_map_register_enable_disable (vat_main_t * vam)
14615 {
14616   unformat_input_t *input = vam->input;
14617   vl_api_one_map_register_enable_disable_t *mp;
14618   u8 is_set = 0;
14619   u8 is_en = 0;
14620   int ret;
14621
14622   /* Parse args required to build the message */
14623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14624     {
14625       if (unformat (input, "enable"))
14626         {
14627           is_set = 1;
14628           is_en = 1;
14629         }
14630       else if (unformat (input, "disable"))
14631         is_set = 1;
14632       else
14633         break;
14634     }
14635
14636   if (!is_set)
14637     {
14638       errmsg ("Value not set");
14639       return -99;
14640     }
14641
14642   /* Construct the API message */
14643   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14644
14645   mp->is_enabled = is_en;
14646
14647   /* send it... */
14648   S (mp);
14649
14650   /* Wait for a reply... */
14651   W (ret);
14652   return ret;
14653 }
14654
14655 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14656
14657 static int
14658 api_one_enable_disable (vat_main_t * vam)
14659 {
14660   unformat_input_t *input = vam->input;
14661   vl_api_one_enable_disable_t *mp;
14662   u8 is_set = 0;
14663   u8 is_en = 0;
14664   int ret;
14665
14666   /* Parse args required to build the message */
14667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14668     {
14669       if (unformat (input, "enable"))
14670         {
14671           is_set = 1;
14672           is_en = 1;
14673         }
14674       else if (unformat (input, "disable"))
14675         {
14676           is_set = 1;
14677         }
14678       else
14679         break;
14680     }
14681
14682   if (!is_set)
14683     {
14684       errmsg ("Value not set");
14685       return -99;
14686     }
14687
14688   /* Construct the API message */
14689   M (ONE_ENABLE_DISABLE, mp);
14690
14691   mp->is_en = is_en;
14692
14693   /* send it... */
14694   S (mp);
14695
14696   /* Wait for a reply... */
14697   W (ret);
14698   return ret;
14699 }
14700
14701 #define api_lisp_enable_disable api_one_enable_disable
14702
14703 static int
14704 api_show_one_map_register_state (vat_main_t * vam)
14705 {
14706   vl_api_show_one_map_register_state_t *mp;
14707   int ret;
14708
14709   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14710
14711   /* send */
14712   S (mp);
14713
14714   /* wait for reply */
14715   W (ret);
14716   return ret;
14717 }
14718
14719 #define api_show_lisp_map_register_state api_show_one_map_register_state
14720
14721 static int
14722 api_show_one_rloc_probe_state (vat_main_t * vam)
14723 {
14724   vl_api_show_one_rloc_probe_state_t *mp;
14725   int ret;
14726
14727   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14728
14729   /* send */
14730   S (mp);
14731
14732   /* wait for reply */
14733   W (ret);
14734   return ret;
14735 }
14736
14737 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14738
14739 static int
14740 api_one_stats_enable_disable (vat_main_t * vam)
14741 {
14742   vl_api_one_stats_enable_disable_t *mp;
14743   unformat_input_t *input = vam->input;
14744   u8 is_set = 0;
14745   u8 is_en = 0;
14746   int ret;
14747
14748   /* Parse args required to build the message */
14749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14750     {
14751       if (unformat (input, "enable"))
14752         {
14753           is_set = 1;
14754           is_en = 1;
14755         }
14756       else if (unformat (input, "disable"))
14757         {
14758           is_set = 1;
14759         }
14760       else
14761         break;
14762     }
14763
14764   if (!is_set)
14765     {
14766       errmsg ("Value not set");
14767       return -99;
14768     }
14769
14770   M (ONE_STATS_ENABLE_DISABLE, mp);
14771   mp->is_en = is_en;
14772
14773   /* send */
14774   S (mp);
14775
14776   /* wait for reply */
14777   W (ret);
14778   return ret;
14779 }
14780
14781 static int
14782 api_show_one_stats_enable_disable (vat_main_t * vam)
14783 {
14784   vl_api_show_one_stats_enable_disable_t *mp;
14785   int ret;
14786
14787   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14788
14789   /* send */
14790   S (mp);
14791
14792   /* wait for reply */
14793   W (ret);
14794   return ret;
14795 }
14796
14797 static int
14798 api_show_one_map_request_mode (vat_main_t * vam)
14799 {
14800   vl_api_show_one_map_request_mode_t *mp;
14801   int ret;
14802
14803   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14804
14805   /* send */
14806   S (mp);
14807
14808   /* wait for reply */
14809   W (ret);
14810   return ret;
14811 }
14812
14813 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14814
14815 static int
14816 api_one_map_request_mode (vat_main_t * vam)
14817 {
14818   unformat_input_t *input = vam->input;
14819   vl_api_one_map_request_mode_t *mp;
14820   u8 mode = 0;
14821   int ret;
14822
14823   /* Parse args required to build the message */
14824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14825     {
14826       if (unformat (input, "dst-only"))
14827         mode = 0;
14828       else if (unformat (input, "src-dst"))
14829         mode = 1;
14830       else
14831         {
14832           errmsg ("parse error '%U'", format_unformat_error, input);
14833           return -99;
14834         }
14835     }
14836
14837   M (ONE_MAP_REQUEST_MODE, mp);
14838
14839   mp->mode = mode;
14840
14841   /* send */
14842   S (mp);
14843
14844   /* wait for reply */
14845   W (ret);
14846   return ret;
14847 }
14848
14849 #define api_lisp_map_request_mode api_one_map_request_mode
14850
14851 /**
14852  * Enable/disable ONE proxy ITR.
14853  *
14854  * @param vam vpp API test context
14855  * @return return code
14856  */
14857 static int
14858 api_one_pitr_set_locator_set (vat_main_t * vam)
14859 {
14860   u8 ls_name_set = 0;
14861   unformat_input_t *input = vam->input;
14862   vl_api_one_pitr_set_locator_set_t *mp;
14863   u8 is_add = 1;
14864   u8 *ls_name = 0;
14865   int ret;
14866
14867   /* Parse args required to build the message */
14868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14869     {
14870       if (unformat (input, "del"))
14871         is_add = 0;
14872       else if (unformat (input, "locator-set %s", &ls_name))
14873         ls_name_set = 1;
14874       else
14875         {
14876           errmsg ("parse error '%U'", format_unformat_error, input);
14877           return -99;
14878         }
14879     }
14880
14881   if (!ls_name_set)
14882     {
14883       errmsg ("locator-set name not set!");
14884       return -99;
14885     }
14886
14887   M (ONE_PITR_SET_LOCATOR_SET, mp);
14888
14889   mp->is_add = is_add;
14890   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14891   vec_free (ls_name);
14892
14893   /* send */
14894   S (mp);
14895
14896   /* wait for reply */
14897   W (ret);
14898   return ret;
14899 }
14900
14901 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14902
14903 static int
14904 api_show_one_pitr (vat_main_t * vam)
14905 {
14906   vl_api_show_one_pitr_t *mp;
14907   int ret;
14908
14909   if (!vam->json_output)
14910     {
14911       print (vam->ofp, "%=20s", "lisp status:");
14912     }
14913
14914   M (SHOW_ONE_PITR, mp);
14915   /* send it... */
14916   S (mp);
14917
14918   /* Wait for a reply... */
14919   W (ret);
14920   return ret;
14921 }
14922
14923 #define api_show_lisp_pitr api_show_one_pitr
14924
14925 static int
14926 api_one_use_petr (vat_main_t * vam)
14927 {
14928   unformat_input_t *input = vam->input;
14929   vl_api_one_use_petr_t *mp;
14930   u8 is_add = 0;
14931   ip_address_t ip;
14932   int ret;
14933
14934   memset (&ip, 0, sizeof (ip));
14935
14936   /* Parse args required to build the message */
14937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14938     {
14939       if (unformat (input, "disable"))
14940         is_add = 0;
14941       else
14942         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14943         {
14944           is_add = 1;
14945           ip_addr_version (&ip) = IP4;
14946         }
14947       else
14948         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14949         {
14950           is_add = 1;
14951           ip_addr_version (&ip) = IP6;
14952         }
14953       else
14954         {
14955           errmsg ("parse error '%U'", format_unformat_error, input);
14956           return -99;
14957         }
14958     }
14959
14960   M (ONE_USE_PETR, mp);
14961
14962   mp->is_add = is_add;
14963   if (is_add)
14964     {
14965       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14966       if (mp->is_ip4)
14967         clib_memcpy (mp->address, &ip, 4);
14968       else
14969         clib_memcpy (mp->address, &ip, 16);
14970     }
14971
14972   /* send */
14973   S (mp);
14974
14975   /* wait for reply */
14976   W (ret);
14977   return ret;
14978 }
14979
14980 #define api_lisp_use_petr api_one_use_petr
14981
14982 static int
14983 api_show_one_use_petr (vat_main_t * vam)
14984 {
14985   vl_api_show_one_use_petr_t *mp;
14986   int ret;
14987
14988   if (!vam->json_output)
14989     {
14990       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14991     }
14992
14993   M (SHOW_ONE_USE_PETR, mp);
14994   /* send it... */
14995   S (mp);
14996
14997   /* Wait for a reply... */
14998   W (ret);
14999   return ret;
15000 }
15001
15002 #define api_show_lisp_use_petr api_show_one_use_petr
15003
15004 /**
15005  * Add/delete mapping between vni and vrf
15006  */
15007 static int
15008 api_one_eid_table_add_del_map (vat_main_t * vam)
15009 {
15010   unformat_input_t *input = vam->input;
15011   vl_api_one_eid_table_add_del_map_t *mp;
15012   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15013   u32 vni, vrf, bd_index;
15014   int ret;
15015
15016   /* Parse args required to build the message */
15017   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15018     {
15019       if (unformat (input, "del"))
15020         is_add = 0;
15021       else if (unformat (input, "vrf %d", &vrf))
15022         vrf_set = 1;
15023       else if (unformat (input, "bd_index %d", &bd_index))
15024         bd_index_set = 1;
15025       else if (unformat (input, "vni %d", &vni))
15026         vni_set = 1;
15027       else
15028         break;
15029     }
15030
15031   if (!vni_set || (!vrf_set && !bd_index_set))
15032     {
15033       errmsg ("missing arguments!");
15034       return -99;
15035     }
15036
15037   if (vrf_set && bd_index_set)
15038     {
15039       errmsg ("error: both vrf and bd entered!");
15040       return -99;
15041     }
15042
15043   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15044
15045   mp->is_add = is_add;
15046   mp->vni = htonl (vni);
15047   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15048   mp->is_l2 = bd_index_set;
15049
15050   /* send */
15051   S (mp);
15052
15053   /* wait for reply */
15054   W (ret);
15055   return ret;
15056 }
15057
15058 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15059
15060 uword
15061 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15062 {
15063   u32 *action = va_arg (*args, u32 *);
15064   u8 *s = 0;
15065
15066   if (unformat (input, "%s", &s))
15067     {
15068       if (!strcmp ((char *) s, "no-action"))
15069         action[0] = 0;
15070       else if (!strcmp ((char *) s, "natively-forward"))
15071         action[0] = 1;
15072       else if (!strcmp ((char *) s, "send-map-request"))
15073         action[0] = 2;
15074       else if (!strcmp ((char *) s, "drop"))
15075         action[0] = 3;
15076       else
15077         {
15078           clib_warning ("invalid action: '%s'", s);
15079           action[0] = 3;
15080         }
15081     }
15082   else
15083     return 0;
15084
15085   vec_free (s);
15086   return 1;
15087 }
15088
15089 /**
15090  * Add/del remote mapping to/from ONE control plane
15091  *
15092  * @param vam vpp API test context
15093  * @return return code
15094  */
15095 static int
15096 api_one_add_del_remote_mapping (vat_main_t * vam)
15097 {
15098   unformat_input_t *input = vam->input;
15099   vl_api_one_add_del_remote_mapping_t *mp;
15100   u32 vni = 0;
15101   lisp_eid_vat_t _eid, *eid = &_eid;
15102   lisp_eid_vat_t _seid, *seid = &_seid;
15103   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15104   u32 action = ~0, p, w, data_len;
15105   ip4_address_t rloc4;
15106   ip6_address_t rloc6;
15107   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15108   int ret;
15109
15110   memset (&rloc, 0, sizeof (rloc));
15111
15112   /* Parse args required to build the message */
15113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15114     {
15115       if (unformat (input, "del-all"))
15116         {
15117           del_all = 1;
15118         }
15119       else if (unformat (input, "del"))
15120         {
15121           is_add = 0;
15122         }
15123       else if (unformat (input, "add"))
15124         {
15125           is_add = 1;
15126         }
15127       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15128         {
15129           eid_set = 1;
15130         }
15131       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15132         {
15133           seid_set = 1;
15134         }
15135       else if (unformat (input, "vni %d", &vni))
15136         {
15137           ;
15138         }
15139       else if (unformat (input, "p %d w %d", &p, &w))
15140         {
15141           if (!curr_rloc)
15142             {
15143               errmsg ("No RLOC configured for setting priority/weight!");
15144               return -99;
15145             }
15146           curr_rloc->priority = p;
15147           curr_rloc->weight = w;
15148         }
15149       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15150         {
15151           rloc.is_ip4 = 1;
15152           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15153           vec_add1 (rlocs, rloc);
15154           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15155         }
15156       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15157         {
15158           rloc.is_ip4 = 0;
15159           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15160           vec_add1 (rlocs, rloc);
15161           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15162         }
15163       else if (unformat (input, "action %U",
15164                          unformat_negative_mapping_action, &action))
15165         {
15166           ;
15167         }
15168       else
15169         {
15170           clib_warning ("parse error '%U'", format_unformat_error, input);
15171           return -99;
15172         }
15173     }
15174
15175   if (0 == eid_set)
15176     {
15177       errmsg ("missing params!");
15178       return -99;
15179     }
15180
15181   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15182     {
15183       errmsg ("no action set for negative map-reply!");
15184       return -99;
15185     }
15186
15187   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15188
15189   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15190   mp->is_add = is_add;
15191   mp->vni = htonl (vni);
15192   mp->action = (u8) action;
15193   mp->is_src_dst = seid_set;
15194   mp->eid_len = eid->len;
15195   mp->seid_len = seid->len;
15196   mp->del_all = del_all;
15197   mp->eid_type = eid->type;
15198   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15199   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15200
15201   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15202   clib_memcpy (mp->rlocs, rlocs, data_len);
15203   vec_free (rlocs);
15204
15205   /* send it... */
15206   S (mp);
15207
15208   /* Wait for a reply... */
15209   W (ret);
15210   return ret;
15211 }
15212
15213 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15214
15215 /**
15216  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15217  * forwarding entries in data-plane accordingly.
15218  *
15219  * @param vam vpp API test context
15220  * @return return code
15221  */
15222 static int
15223 api_one_add_del_adjacency (vat_main_t * vam)
15224 {
15225   unformat_input_t *input = vam->input;
15226   vl_api_one_add_del_adjacency_t *mp;
15227   u32 vni = 0;
15228   ip4_address_t leid4, reid4;
15229   ip6_address_t leid6, reid6;
15230   u8 reid_mac[6] = { 0 };
15231   u8 leid_mac[6] = { 0 };
15232   u8 reid_type, leid_type;
15233   u32 leid_len = 0, reid_len = 0, len;
15234   u8 is_add = 1;
15235   int ret;
15236
15237   leid_type = reid_type = (u8) ~ 0;
15238
15239   /* Parse args required to build the message */
15240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15241     {
15242       if (unformat (input, "del"))
15243         {
15244           is_add = 0;
15245         }
15246       else if (unformat (input, "add"))
15247         {
15248           is_add = 1;
15249         }
15250       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15251                          &reid4, &len))
15252         {
15253           reid_type = 0;        /* ipv4 */
15254           reid_len = len;
15255         }
15256       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15257                          &reid6, &len))
15258         {
15259           reid_type = 1;        /* ipv6 */
15260           reid_len = len;
15261         }
15262       else if (unformat (input, "reid %U", unformat_ethernet_address,
15263                          reid_mac))
15264         {
15265           reid_type = 2;        /* mac */
15266         }
15267       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15268                          &leid4, &len))
15269         {
15270           leid_type = 0;        /* ipv4 */
15271           leid_len = len;
15272         }
15273       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15274                          &leid6, &len))
15275         {
15276           leid_type = 1;        /* ipv6 */
15277           leid_len = len;
15278         }
15279       else if (unformat (input, "leid %U", unformat_ethernet_address,
15280                          leid_mac))
15281         {
15282           leid_type = 2;        /* mac */
15283         }
15284       else if (unformat (input, "vni %d", &vni))
15285         {
15286           ;
15287         }
15288       else
15289         {
15290           errmsg ("parse error '%U'", format_unformat_error, input);
15291           return -99;
15292         }
15293     }
15294
15295   if ((u8) ~ 0 == reid_type)
15296     {
15297       errmsg ("missing params!");
15298       return -99;
15299     }
15300
15301   if (leid_type != reid_type)
15302     {
15303       errmsg ("remote and local EIDs are of different types!");
15304       return -99;
15305     }
15306
15307   M (ONE_ADD_DEL_ADJACENCY, mp);
15308   mp->is_add = is_add;
15309   mp->vni = htonl (vni);
15310   mp->leid_len = leid_len;
15311   mp->reid_len = reid_len;
15312   mp->eid_type = reid_type;
15313
15314   switch (mp->eid_type)
15315     {
15316     case 0:
15317       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15318       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15319       break;
15320     case 1:
15321       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15322       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15323       break;
15324     case 2:
15325       clib_memcpy (mp->leid, leid_mac, 6);
15326       clib_memcpy (mp->reid, reid_mac, 6);
15327       break;
15328     default:
15329       errmsg ("unknown EID type %d!", mp->eid_type);
15330       return 0;
15331     }
15332
15333   /* send it... */
15334   S (mp);
15335
15336   /* Wait for a reply... */
15337   W (ret);
15338   return ret;
15339 }
15340
15341 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15342
15343 uword
15344 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15345 {
15346   u32 *mode = va_arg (*args, u32 *);
15347
15348   if (unformat (input, "lisp"))
15349     *mode = 0;
15350   else if (unformat (input, "vxlan"))
15351     *mode = 1;
15352   else
15353     return 0;
15354
15355   return 1;
15356 }
15357
15358 static int
15359 api_gpe_get_encap_mode (vat_main_t * vam)
15360 {
15361   vl_api_gpe_get_encap_mode_t *mp;
15362   int ret;
15363
15364   /* Construct the API message */
15365   M (GPE_GET_ENCAP_MODE, mp);
15366
15367   /* send it... */
15368   S (mp);
15369
15370   /* Wait for a reply... */
15371   W (ret);
15372   return ret;
15373 }
15374
15375 static int
15376 api_gpe_set_encap_mode (vat_main_t * vam)
15377 {
15378   unformat_input_t *input = vam->input;
15379   vl_api_gpe_set_encap_mode_t *mp;
15380   int ret;
15381   u32 mode = 0;
15382
15383   /* Parse args required to build the message */
15384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15385     {
15386       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15387         ;
15388       else
15389         break;
15390     }
15391
15392   /* Construct the API message */
15393   M (GPE_SET_ENCAP_MODE, mp);
15394
15395   mp->mode = mode;
15396
15397   /* send it... */
15398   S (mp);
15399
15400   /* Wait for a reply... */
15401   W (ret);
15402   return ret;
15403 }
15404
15405 static int
15406 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15407 {
15408   unformat_input_t *input = vam->input;
15409   vl_api_gpe_add_del_iface_t *mp;
15410   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15411   u32 dp_table = 0, vni = 0;
15412   int ret;
15413
15414   /* Parse args required to build the message */
15415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15416     {
15417       if (unformat (input, "up"))
15418         {
15419           action_set = 1;
15420           is_add = 1;
15421         }
15422       else if (unformat (input, "down"))
15423         {
15424           action_set = 1;
15425           is_add = 0;
15426         }
15427       else if (unformat (input, "table_id %d", &dp_table))
15428         {
15429           dp_table_set = 1;
15430         }
15431       else if (unformat (input, "bd_id %d", &dp_table))
15432         {
15433           dp_table_set = 1;
15434           is_l2 = 1;
15435         }
15436       else if (unformat (input, "vni %d", &vni))
15437         {
15438           vni_set = 1;
15439         }
15440       else
15441         break;
15442     }
15443
15444   if (action_set == 0)
15445     {
15446       errmsg ("Action not set");
15447       return -99;
15448     }
15449   if (dp_table_set == 0 || vni_set == 0)
15450     {
15451       errmsg ("vni and dp_table must be set");
15452       return -99;
15453     }
15454
15455   /* Construct the API message */
15456   M (GPE_ADD_DEL_IFACE, mp);
15457
15458   mp->is_add = is_add;
15459   mp->dp_table = dp_table;
15460   mp->is_l2 = is_l2;
15461   mp->vni = vni;
15462
15463   /* send it... */
15464   S (mp);
15465
15466   /* Wait for a reply... */
15467   W (ret);
15468   return ret;
15469 }
15470
15471 /**
15472  * Add/del map request itr rlocs from ONE control plane and updates
15473  *
15474  * @param vam vpp API test context
15475  * @return return code
15476  */
15477 static int
15478 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15479 {
15480   unformat_input_t *input = vam->input;
15481   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15482   u8 *locator_set_name = 0;
15483   u8 locator_set_name_set = 0;
15484   u8 is_add = 1;
15485   int ret;
15486
15487   /* Parse args required to build the message */
15488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15489     {
15490       if (unformat (input, "del"))
15491         {
15492           is_add = 0;
15493         }
15494       else if (unformat (input, "%_%v%_", &locator_set_name))
15495         {
15496           locator_set_name_set = 1;
15497         }
15498       else
15499         {
15500           clib_warning ("parse error '%U'", format_unformat_error, input);
15501           return -99;
15502         }
15503     }
15504
15505   if (is_add && !locator_set_name_set)
15506     {
15507       errmsg ("itr-rloc is not set!");
15508       return -99;
15509     }
15510
15511   if (is_add && vec_len (locator_set_name) > 64)
15512     {
15513       errmsg ("itr-rloc locator-set name too long");
15514       vec_free (locator_set_name);
15515       return -99;
15516     }
15517
15518   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15519   mp->is_add = is_add;
15520   if (is_add)
15521     {
15522       clib_memcpy (mp->locator_set_name, locator_set_name,
15523                    vec_len (locator_set_name));
15524     }
15525   else
15526     {
15527       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15528     }
15529   vec_free (locator_set_name);
15530
15531   /* send it... */
15532   S (mp);
15533
15534   /* Wait for a reply... */
15535   W (ret);
15536   return ret;
15537 }
15538
15539 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15540
15541 static int
15542 api_one_locator_dump (vat_main_t * vam)
15543 {
15544   unformat_input_t *input = vam->input;
15545   vl_api_one_locator_dump_t *mp;
15546   vl_api_control_ping_t *mp_ping;
15547   u8 is_index_set = 0, is_name_set = 0;
15548   u8 *ls_name = 0;
15549   u32 ls_index = ~0;
15550   int ret;
15551
15552   /* Parse args required to build the message */
15553   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15554     {
15555       if (unformat (input, "ls_name %_%v%_", &ls_name))
15556         {
15557           is_name_set = 1;
15558         }
15559       else if (unformat (input, "ls_index %d", &ls_index))
15560         {
15561           is_index_set = 1;
15562         }
15563       else
15564         {
15565           errmsg ("parse error '%U'", format_unformat_error, input);
15566           return -99;
15567         }
15568     }
15569
15570   if (!is_index_set && !is_name_set)
15571     {
15572       errmsg ("error: expected one of index or name!");
15573       return -99;
15574     }
15575
15576   if (is_index_set && is_name_set)
15577     {
15578       errmsg ("error: only one param expected!");
15579       return -99;
15580     }
15581
15582   if (vec_len (ls_name) > 62)
15583     {
15584       errmsg ("error: locator set name too long!");
15585       return -99;
15586     }
15587
15588   if (!vam->json_output)
15589     {
15590       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15591     }
15592
15593   M (ONE_LOCATOR_DUMP, mp);
15594   mp->is_index_set = is_index_set;
15595
15596   if (is_index_set)
15597     mp->ls_index = clib_host_to_net_u32 (ls_index);
15598   else
15599     {
15600       vec_add1 (ls_name, 0);
15601       strncpy ((char *) mp->ls_name, (char *) ls_name,
15602                sizeof (mp->ls_name) - 1);
15603     }
15604
15605   /* send it... */
15606   S (mp);
15607
15608   /* Use a control ping for synchronization */
15609   M (CONTROL_PING, mp_ping);
15610   S (mp_ping);
15611
15612   /* Wait for a reply... */
15613   W (ret);
15614   return ret;
15615 }
15616
15617 #define api_lisp_locator_dump api_one_locator_dump
15618
15619 static int
15620 api_one_locator_set_dump (vat_main_t * vam)
15621 {
15622   vl_api_one_locator_set_dump_t *mp;
15623   vl_api_control_ping_t *mp_ping;
15624   unformat_input_t *input = vam->input;
15625   u8 filter = 0;
15626   int ret;
15627
15628   /* Parse args required to build the message */
15629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15630     {
15631       if (unformat (input, "local"))
15632         {
15633           filter = 1;
15634         }
15635       else if (unformat (input, "remote"))
15636         {
15637           filter = 2;
15638         }
15639       else
15640         {
15641           errmsg ("parse error '%U'", format_unformat_error, input);
15642           return -99;
15643         }
15644     }
15645
15646   if (!vam->json_output)
15647     {
15648       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15649     }
15650
15651   M (ONE_LOCATOR_SET_DUMP, mp);
15652
15653   mp->filter = filter;
15654
15655   /* send it... */
15656   S (mp);
15657
15658   /* Use a control ping for synchronization */
15659   M (CONTROL_PING, mp_ping);
15660   S (mp_ping);
15661
15662   /* Wait for a reply... */
15663   W (ret);
15664   return ret;
15665 }
15666
15667 #define api_lisp_locator_set_dump api_one_locator_set_dump
15668
15669 static int
15670 api_one_eid_table_map_dump (vat_main_t * vam)
15671 {
15672   u8 is_l2 = 0;
15673   u8 mode_set = 0;
15674   unformat_input_t *input = vam->input;
15675   vl_api_one_eid_table_map_dump_t *mp;
15676   vl_api_control_ping_t *mp_ping;
15677   int ret;
15678
15679   /* Parse args required to build the message */
15680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15681     {
15682       if (unformat (input, "l2"))
15683         {
15684           is_l2 = 1;
15685           mode_set = 1;
15686         }
15687       else if (unformat (input, "l3"))
15688         {
15689           is_l2 = 0;
15690           mode_set = 1;
15691         }
15692       else
15693         {
15694           errmsg ("parse error '%U'", format_unformat_error, input);
15695           return -99;
15696         }
15697     }
15698
15699   if (!mode_set)
15700     {
15701       errmsg ("expected one of 'l2' or 'l3' parameter!");
15702       return -99;
15703     }
15704
15705   if (!vam->json_output)
15706     {
15707       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15708     }
15709
15710   M (ONE_EID_TABLE_MAP_DUMP, mp);
15711   mp->is_l2 = is_l2;
15712
15713   /* send it... */
15714   S (mp);
15715
15716   /* Use a control ping for synchronization */
15717   M (CONTROL_PING, mp_ping);
15718   S (mp_ping);
15719
15720   /* Wait for a reply... */
15721   W (ret);
15722   return ret;
15723 }
15724
15725 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15726
15727 static int
15728 api_one_eid_table_vni_dump (vat_main_t * vam)
15729 {
15730   vl_api_one_eid_table_vni_dump_t *mp;
15731   vl_api_control_ping_t *mp_ping;
15732   int ret;
15733
15734   if (!vam->json_output)
15735     {
15736       print (vam->ofp, "VNI");
15737     }
15738
15739   M (ONE_EID_TABLE_VNI_DUMP, mp);
15740
15741   /* send it... */
15742   S (mp);
15743
15744   /* Use a control ping for synchronization */
15745   M (CONTROL_PING, mp_ping);
15746   S (mp_ping);
15747
15748   /* Wait for a reply... */
15749   W (ret);
15750   return ret;
15751 }
15752
15753 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15754
15755 static int
15756 api_one_eid_table_dump (vat_main_t * vam)
15757 {
15758   unformat_input_t *i = vam->input;
15759   vl_api_one_eid_table_dump_t *mp;
15760   vl_api_control_ping_t *mp_ping;
15761   struct in_addr ip4;
15762   struct in6_addr ip6;
15763   u8 mac[6];
15764   u8 eid_type = ~0, eid_set = 0;
15765   u32 prefix_length = ~0, t, vni = 0;
15766   u8 filter = 0;
15767   int ret;
15768
15769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15770     {
15771       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15772         {
15773           eid_set = 1;
15774           eid_type = 0;
15775           prefix_length = t;
15776         }
15777       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15778         {
15779           eid_set = 1;
15780           eid_type = 1;
15781           prefix_length = t;
15782         }
15783       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15784         {
15785           eid_set = 1;
15786           eid_type = 2;
15787         }
15788       else if (unformat (i, "vni %d", &t))
15789         {
15790           vni = t;
15791         }
15792       else if (unformat (i, "local"))
15793         {
15794           filter = 1;
15795         }
15796       else if (unformat (i, "remote"))
15797         {
15798           filter = 2;
15799         }
15800       else
15801         {
15802           errmsg ("parse error '%U'", format_unformat_error, i);
15803           return -99;
15804         }
15805     }
15806
15807   if (!vam->json_output)
15808     {
15809       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15810              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15811     }
15812
15813   M (ONE_EID_TABLE_DUMP, mp);
15814
15815   mp->filter = filter;
15816   if (eid_set)
15817     {
15818       mp->eid_set = 1;
15819       mp->vni = htonl (vni);
15820       mp->eid_type = eid_type;
15821       switch (eid_type)
15822         {
15823         case 0:
15824           mp->prefix_length = prefix_length;
15825           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15826           break;
15827         case 1:
15828           mp->prefix_length = prefix_length;
15829           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15830           break;
15831         case 2:
15832           clib_memcpy (mp->eid, mac, sizeof (mac));
15833           break;
15834         default:
15835           errmsg ("unknown EID type %d!", eid_type);
15836           return -99;
15837         }
15838     }
15839
15840   /* send it... */
15841   S (mp);
15842
15843   /* Use a control ping for synchronization */
15844   M (CONTROL_PING, mp_ping);
15845   S (mp_ping);
15846
15847   /* Wait for a reply... */
15848   W (ret);
15849   return ret;
15850 }
15851
15852 #define api_lisp_eid_table_dump api_one_eid_table_dump
15853
15854 static int
15855 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15856 {
15857   unformat_input_t *i = vam->input;
15858   vl_api_gpe_fwd_entries_get_t *mp;
15859   u8 vni_set = 0;
15860   u32 vni = ~0;
15861   int ret;
15862
15863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15864     {
15865       if (unformat (i, "vni %d", &vni))
15866         {
15867           vni_set = 1;
15868         }
15869       else
15870         {
15871           errmsg ("parse error '%U'", format_unformat_error, i);
15872           return -99;
15873         }
15874     }
15875
15876   if (!vni_set)
15877     {
15878       errmsg ("vni not set!");
15879       return -99;
15880     }
15881
15882   if (!vam->json_output)
15883     {
15884       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15885              "leid", "reid");
15886     }
15887
15888   M (GPE_FWD_ENTRIES_GET, mp);
15889   mp->vni = clib_host_to_net_u32 (vni);
15890
15891   /* send it... */
15892   S (mp);
15893
15894   /* Wait for a reply... */
15895   W (ret);
15896   return ret;
15897 }
15898
15899 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
15900 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
15901 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15902 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15903 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15904 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15905
15906 static int
15907 api_one_adjacencies_get (vat_main_t * vam)
15908 {
15909   unformat_input_t *i = vam->input;
15910   vl_api_one_adjacencies_get_t *mp;
15911   u8 vni_set = 0;
15912   u32 vni = ~0;
15913   int ret;
15914
15915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15916     {
15917       if (unformat (i, "vni %d", &vni))
15918         {
15919           vni_set = 1;
15920         }
15921       else
15922         {
15923           errmsg ("parse error '%U'", format_unformat_error, i);
15924           return -99;
15925         }
15926     }
15927
15928   if (!vni_set)
15929     {
15930       errmsg ("vni not set!");
15931       return -99;
15932     }
15933
15934   if (!vam->json_output)
15935     {
15936       print (vam->ofp, "%s %40s", "leid", "reid");
15937     }
15938
15939   M (ONE_ADJACENCIES_GET, mp);
15940   mp->vni = clib_host_to_net_u32 (vni);
15941
15942   /* send it... */
15943   S (mp);
15944
15945   /* Wait for a reply... */
15946   W (ret);
15947   return ret;
15948 }
15949
15950 #define api_lisp_adjacencies_get api_one_adjacencies_get
15951
15952 static int
15953 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
15954 {
15955   vl_api_gpe_fwd_entry_vnis_get_t *mp;
15956   int ret;
15957
15958   if (!vam->json_output)
15959     {
15960       print (vam->ofp, "VNIs");
15961     }
15962
15963   M (GPE_FWD_ENTRY_VNIS_GET, mp);
15964
15965   /* send it... */
15966   S (mp);
15967
15968   /* Wait for a reply... */
15969   W (ret);
15970   return ret;
15971 }
15972
15973 static int
15974 api_one_map_server_dump (vat_main_t * vam)
15975 {
15976   vl_api_one_map_server_dump_t *mp;
15977   vl_api_control_ping_t *mp_ping;
15978   int ret;
15979
15980   if (!vam->json_output)
15981     {
15982       print (vam->ofp, "%=20s", "Map server");
15983     }
15984
15985   M (ONE_MAP_SERVER_DUMP, mp);
15986   /* send it... */
15987   S (mp);
15988
15989   /* Use a control ping for synchronization */
15990   M (CONTROL_PING, mp_ping);
15991   S (mp_ping);
15992
15993   /* Wait for a reply... */
15994   W (ret);
15995   return ret;
15996 }
15997
15998 #define api_lisp_map_server_dump api_one_map_server_dump
15999
16000 static int
16001 api_one_map_resolver_dump (vat_main_t * vam)
16002 {
16003   vl_api_one_map_resolver_dump_t *mp;
16004   vl_api_control_ping_t *mp_ping;
16005   int ret;
16006
16007   if (!vam->json_output)
16008     {
16009       print (vam->ofp, "%=20s", "Map resolver");
16010     }
16011
16012   M (ONE_MAP_RESOLVER_DUMP, mp);
16013   /* send it... */
16014   S (mp);
16015
16016   /* Use a control ping for synchronization */
16017   M (CONTROL_PING, mp_ping);
16018   S (mp_ping);
16019
16020   /* Wait for a reply... */
16021   W (ret);
16022   return ret;
16023 }
16024
16025 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16026
16027 static int
16028 api_one_stats_flush (vat_main_t * vam)
16029 {
16030   vl_api_one_stats_flush_t *mp;
16031   int ret = 0;
16032
16033   M (ONE_STATS_FLUSH, mp);
16034   S (mp);
16035   W (ret);
16036   return ret;
16037 }
16038
16039 static int
16040 api_one_stats_dump (vat_main_t * vam)
16041 {
16042   vl_api_one_stats_dump_t *mp;
16043   vl_api_control_ping_t *mp_ping;
16044   int ret;
16045
16046   M (ONE_STATS_DUMP, mp);
16047   /* send it... */
16048   S (mp);
16049
16050   /* Use a control ping for synchronization */
16051   M (CONTROL_PING, mp_ping);
16052   S (mp_ping);
16053
16054   /* Wait for a reply... */
16055   W (ret);
16056   return ret;
16057 }
16058
16059 static int
16060 api_show_one_status (vat_main_t * vam)
16061 {
16062   vl_api_show_one_status_t *mp;
16063   int ret;
16064
16065   if (!vam->json_output)
16066     {
16067       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16068     }
16069
16070   M (SHOW_ONE_STATUS, mp);
16071   /* send it... */
16072   S (mp);
16073   /* Wait for a reply... */
16074   W (ret);
16075   return ret;
16076 }
16077
16078 #define api_show_lisp_status api_show_one_status
16079
16080 static int
16081 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16082 {
16083   vl_api_gpe_fwd_entry_path_dump_t *mp;
16084   vl_api_control_ping_t *mp_ping;
16085   unformat_input_t *i = vam->input;
16086   u32 fwd_entry_index = ~0;
16087   int ret;
16088
16089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16090     {
16091       if (unformat (i, "index %d", &fwd_entry_index))
16092         ;
16093       else
16094         break;
16095     }
16096
16097   if (~0 == fwd_entry_index)
16098     {
16099       errmsg ("no index specified!");
16100       return -99;
16101     }
16102
16103   if (!vam->json_output)
16104     {
16105       print (vam->ofp, "first line");
16106     }
16107
16108   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16109
16110   /* send it... */
16111   S (mp);
16112   /* Use a control ping for synchronization */
16113   M (CONTROL_PING, mp_ping);
16114   S (mp_ping);
16115
16116   /* Wait for a reply... */
16117   W (ret);
16118   return ret;
16119 }
16120
16121 static int
16122 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16123 {
16124   vl_api_one_get_map_request_itr_rlocs_t *mp;
16125   int ret;
16126
16127   if (!vam->json_output)
16128     {
16129       print (vam->ofp, "%=20s", "itr-rlocs:");
16130     }
16131
16132   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16133   /* send it... */
16134   S (mp);
16135   /* Wait for a reply... */
16136   W (ret);
16137   return ret;
16138 }
16139
16140 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16141
16142 static int
16143 api_af_packet_create (vat_main_t * vam)
16144 {
16145   unformat_input_t *i = vam->input;
16146   vl_api_af_packet_create_t *mp;
16147   u8 *host_if_name = 0;
16148   u8 hw_addr[6];
16149   u8 random_hw_addr = 1;
16150   int ret;
16151
16152   memset (hw_addr, 0, sizeof (hw_addr));
16153
16154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16155     {
16156       if (unformat (i, "name %s", &host_if_name))
16157         vec_add1 (host_if_name, 0);
16158       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16159         random_hw_addr = 0;
16160       else
16161         break;
16162     }
16163
16164   if (!vec_len (host_if_name))
16165     {
16166       errmsg ("host-interface name must be specified");
16167       return -99;
16168     }
16169
16170   if (vec_len (host_if_name) > 64)
16171     {
16172       errmsg ("host-interface name too long");
16173       return -99;
16174     }
16175
16176   M (AF_PACKET_CREATE, mp);
16177
16178   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16179   clib_memcpy (mp->hw_addr, hw_addr, 6);
16180   mp->use_random_hw_addr = random_hw_addr;
16181   vec_free (host_if_name);
16182
16183   S (mp);
16184
16185   /* *INDENT-OFF* */
16186   W2 (ret,
16187       ({
16188         if (ret == 0)
16189           fprintf (vam->ofp ? vam->ofp : stderr,
16190                    " new sw_if_index = %d\n", vam->sw_if_index);
16191       }));
16192   /* *INDENT-ON* */
16193   return ret;
16194 }
16195
16196 static int
16197 api_af_packet_delete (vat_main_t * vam)
16198 {
16199   unformat_input_t *i = vam->input;
16200   vl_api_af_packet_delete_t *mp;
16201   u8 *host_if_name = 0;
16202   int ret;
16203
16204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16205     {
16206       if (unformat (i, "name %s", &host_if_name))
16207         vec_add1 (host_if_name, 0);
16208       else
16209         break;
16210     }
16211
16212   if (!vec_len (host_if_name))
16213     {
16214       errmsg ("host-interface name must be specified");
16215       return -99;
16216     }
16217
16218   if (vec_len (host_if_name) > 64)
16219     {
16220       errmsg ("host-interface name too long");
16221       return -99;
16222     }
16223
16224   M (AF_PACKET_DELETE, mp);
16225
16226   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16227   vec_free (host_if_name);
16228
16229   S (mp);
16230   W (ret);
16231   return ret;
16232 }
16233
16234 static int
16235 api_policer_add_del (vat_main_t * vam)
16236 {
16237   unformat_input_t *i = vam->input;
16238   vl_api_policer_add_del_t *mp;
16239   u8 is_add = 1;
16240   u8 *name = 0;
16241   u32 cir = 0;
16242   u32 eir = 0;
16243   u64 cb = 0;
16244   u64 eb = 0;
16245   u8 rate_type = 0;
16246   u8 round_type = 0;
16247   u8 type = 0;
16248   u8 color_aware = 0;
16249   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16250   int ret;
16251
16252   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16253   conform_action.dscp = 0;
16254   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16255   exceed_action.dscp = 0;
16256   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16257   violate_action.dscp = 0;
16258
16259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16260     {
16261       if (unformat (i, "del"))
16262         is_add = 0;
16263       else if (unformat (i, "name %s", &name))
16264         vec_add1 (name, 0);
16265       else if (unformat (i, "cir %u", &cir))
16266         ;
16267       else if (unformat (i, "eir %u", &eir))
16268         ;
16269       else if (unformat (i, "cb %u", &cb))
16270         ;
16271       else if (unformat (i, "eb %u", &eb))
16272         ;
16273       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16274                          &rate_type))
16275         ;
16276       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16277                          &round_type))
16278         ;
16279       else if (unformat (i, "type %U", unformat_policer_type, &type))
16280         ;
16281       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16282                          &conform_action))
16283         ;
16284       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16285                          &exceed_action))
16286         ;
16287       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16288                          &violate_action))
16289         ;
16290       else if (unformat (i, "color-aware"))
16291         color_aware = 1;
16292       else
16293         break;
16294     }
16295
16296   if (!vec_len (name))
16297     {
16298       errmsg ("policer name must be specified");
16299       return -99;
16300     }
16301
16302   if (vec_len (name) > 64)
16303     {
16304       errmsg ("policer name too long");
16305       return -99;
16306     }
16307
16308   M (POLICER_ADD_DEL, mp);
16309
16310   clib_memcpy (mp->name, name, vec_len (name));
16311   vec_free (name);
16312   mp->is_add = is_add;
16313   mp->cir = cir;
16314   mp->eir = eir;
16315   mp->cb = cb;
16316   mp->eb = eb;
16317   mp->rate_type = rate_type;
16318   mp->round_type = round_type;
16319   mp->type = type;
16320   mp->conform_action_type = conform_action.action_type;
16321   mp->conform_dscp = conform_action.dscp;
16322   mp->exceed_action_type = exceed_action.action_type;
16323   mp->exceed_dscp = exceed_action.dscp;
16324   mp->violate_action_type = violate_action.action_type;
16325   mp->violate_dscp = violate_action.dscp;
16326   mp->color_aware = color_aware;
16327
16328   S (mp);
16329   W (ret);
16330   return ret;
16331 }
16332
16333 static int
16334 api_policer_dump (vat_main_t * vam)
16335 {
16336   unformat_input_t *i = vam->input;
16337   vl_api_policer_dump_t *mp;
16338   vl_api_control_ping_t *mp_ping;
16339   u8 *match_name = 0;
16340   u8 match_name_valid = 0;
16341   int ret;
16342
16343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16344     {
16345       if (unformat (i, "name %s", &match_name))
16346         {
16347           vec_add1 (match_name, 0);
16348           match_name_valid = 1;
16349         }
16350       else
16351         break;
16352     }
16353
16354   M (POLICER_DUMP, mp);
16355   mp->match_name_valid = match_name_valid;
16356   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16357   vec_free (match_name);
16358   /* send it... */
16359   S (mp);
16360
16361   /* Use a control ping for synchronization */
16362   M (CONTROL_PING, mp_ping);
16363   S (mp_ping);
16364
16365   /* Wait for a reply... */
16366   W (ret);
16367   return ret;
16368 }
16369
16370 static int
16371 api_policer_classify_set_interface (vat_main_t * vam)
16372 {
16373   unformat_input_t *i = vam->input;
16374   vl_api_policer_classify_set_interface_t *mp;
16375   u32 sw_if_index;
16376   int sw_if_index_set;
16377   u32 ip4_table_index = ~0;
16378   u32 ip6_table_index = ~0;
16379   u32 l2_table_index = ~0;
16380   u8 is_add = 1;
16381   int ret;
16382
16383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16384     {
16385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16386         sw_if_index_set = 1;
16387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16388         sw_if_index_set = 1;
16389       else if (unformat (i, "del"))
16390         is_add = 0;
16391       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16392         ;
16393       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16394         ;
16395       else if (unformat (i, "l2-table %d", &l2_table_index))
16396         ;
16397       else
16398         {
16399           clib_warning ("parse error '%U'", format_unformat_error, i);
16400           return -99;
16401         }
16402     }
16403
16404   if (sw_if_index_set == 0)
16405     {
16406       errmsg ("missing interface name or sw_if_index");
16407       return -99;
16408     }
16409
16410   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16411
16412   mp->sw_if_index = ntohl (sw_if_index);
16413   mp->ip4_table_index = ntohl (ip4_table_index);
16414   mp->ip6_table_index = ntohl (ip6_table_index);
16415   mp->l2_table_index = ntohl (l2_table_index);
16416   mp->is_add = is_add;
16417
16418   S (mp);
16419   W (ret);
16420   return ret;
16421 }
16422
16423 static int
16424 api_policer_classify_dump (vat_main_t * vam)
16425 {
16426   unformat_input_t *i = vam->input;
16427   vl_api_policer_classify_dump_t *mp;
16428   vl_api_control_ping_t *mp_ping;
16429   u8 type = POLICER_CLASSIFY_N_TABLES;
16430   int ret;
16431
16432   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16433     ;
16434   else
16435     {
16436       errmsg ("classify table type must be specified");
16437       return -99;
16438     }
16439
16440   if (!vam->json_output)
16441     {
16442       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16443     }
16444
16445   M (POLICER_CLASSIFY_DUMP, mp);
16446   mp->type = type;
16447   /* send it... */
16448   S (mp);
16449
16450   /* Use a control ping for synchronization */
16451   M (CONTROL_PING, mp_ping);
16452   S (mp_ping);
16453
16454   /* Wait for a reply... */
16455   W (ret);
16456   return ret;
16457 }
16458
16459 static int
16460 api_netmap_create (vat_main_t * vam)
16461 {
16462   unformat_input_t *i = vam->input;
16463   vl_api_netmap_create_t *mp;
16464   u8 *if_name = 0;
16465   u8 hw_addr[6];
16466   u8 random_hw_addr = 1;
16467   u8 is_pipe = 0;
16468   u8 is_master = 0;
16469   int ret;
16470
16471   memset (hw_addr, 0, sizeof (hw_addr));
16472
16473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16474     {
16475       if (unformat (i, "name %s", &if_name))
16476         vec_add1 (if_name, 0);
16477       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16478         random_hw_addr = 0;
16479       else if (unformat (i, "pipe"))
16480         is_pipe = 1;
16481       else if (unformat (i, "master"))
16482         is_master = 1;
16483       else if (unformat (i, "slave"))
16484         is_master = 0;
16485       else
16486         break;
16487     }
16488
16489   if (!vec_len (if_name))
16490     {
16491       errmsg ("interface name must be specified");
16492       return -99;
16493     }
16494
16495   if (vec_len (if_name) > 64)
16496     {
16497       errmsg ("interface name too long");
16498       return -99;
16499     }
16500
16501   M (NETMAP_CREATE, mp);
16502
16503   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16504   clib_memcpy (mp->hw_addr, hw_addr, 6);
16505   mp->use_random_hw_addr = random_hw_addr;
16506   mp->is_pipe = is_pipe;
16507   mp->is_master = is_master;
16508   vec_free (if_name);
16509
16510   S (mp);
16511   W (ret);
16512   return ret;
16513 }
16514
16515 static int
16516 api_netmap_delete (vat_main_t * vam)
16517 {
16518   unformat_input_t *i = vam->input;
16519   vl_api_netmap_delete_t *mp;
16520   u8 *if_name = 0;
16521   int ret;
16522
16523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16524     {
16525       if (unformat (i, "name %s", &if_name))
16526         vec_add1 (if_name, 0);
16527       else
16528         break;
16529     }
16530
16531   if (!vec_len (if_name))
16532     {
16533       errmsg ("interface name must be specified");
16534       return -99;
16535     }
16536
16537   if (vec_len (if_name) > 64)
16538     {
16539       errmsg ("interface name too long");
16540       return -99;
16541     }
16542
16543   M (NETMAP_DELETE, mp);
16544
16545   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16546   vec_free (if_name);
16547
16548   S (mp);
16549   W (ret);
16550   return ret;
16551 }
16552
16553 static void
16554 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16555 {
16556   if (fp->afi == IP46_TYPE_IP6)
16557     print (vam->ofp,
16558            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16559            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16560            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16561            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16562            format_ip6_address, fp->next_hop);
16563   else if (fp->afi == IP46_TYPE_IP4)
16564     print (vam->ofp,
16565            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16566            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16567            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16568            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16569            format_ip4_address, fp->next_hop);
16570 }
16571
16572 static void
16573 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16574                                  vl_api_fib_path2_t * fp)
16575 {
16576   struct in_addr ip4;
16577   struct in6_addr ip6;
16578
16579   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16580   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16581   vat_json_object_add_uint (node, "is_local", fp->is_local);
16582   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16583   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16584   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16585   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16586   if (fp->afi == IP46_TYPE_IP4)
16587     {
16588       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16589       vat_json_object_add_ip4 (node, "next_hop", ip4);
16590     }
16591   else if (fp->afi == IP46_TYPE_IP6)
16592     {
16593       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16594       vat_json_object_add_ip6 (node, "next_hop", ip6);
16595     }
16596 }
16597
16598 static void
16599 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16600 {
16601   vat_main_t *vam = &vat_main;
16602   int count = ntohl (mp->mt_count);
16603   vl_api_fib_path2_t *fp;
16604   i32 i;
16605
16606   print (vam->ofp, "[%d]: sw_if_index %d via:",
16607          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16608   fp = mp->mt_paths;
16609   for (i = 0; i < count; i++)
16610     {
16611       vl_api_mpls_fib_path_print (vam, fp);
16612       fp++;
16613     }
16614
16615   print (vam->ofp, "");
16616 }
16617
16618 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16619 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16620
16621 static void
16622 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16623 {
16624   vat_main_t *vam = &vat_main;
16625   vat_json_node_t *node = NULL;
16626   int count = ntohl (mp->mt_count);
16627   vl_api_fib_path2_t *fp;
16628   i32 i;
16629
16630   if (VAT_JSON_ARRAY != vam->json_tree.type)
16631     {
16632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16633       vat_json_init_array (&vam->json_tree);
16634     }
16635   node = vat_json_array_add (&vam->json_tree);
16636
16637   vat_json_init_object (node);
16638   vat_json_object_add_uint (node, "tunnel_index",
16639                             ntohl (mp->mt_tunnel_index));
16640   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16641
16642   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16643
16644   fp = mp->mt_paths;
16645   for (i = 0; i < count; i++)
16646     {
16647       vl_api_mpls_fib_path_json_print (node, fp);
16648       fp++;
16649     }
16650 }
16651
16652 static int
16653 api_mpls_tunnel_dump (vat_main_t * vam)
16654 {
16655   vl_api_mpls_tunnel_dump_t *mp;
16656   vl_api_control_ping_t *mp_ping;
16657   i32 index = -1;
16658   int ret;
16659
16660   /* Parse args required to build the message */
16661   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16662     {
16663       if (!unformat (vam->input, "tunnel_index %d", &index))
16664         {
16665           index = -1;
16666           break;
16667         }
16668     }
16669
16670   print (vam->ofp, "  tunnel_index %d", index);
16671
16672   M (MPLS_TUNNEL_DUMP, mp);
16673   mp->tunnel_index = htonl (index);
16674   S (mp);
16675
16676   /* Use a control ping for synchronization */
16677   M (CONTROL_PING, mp_ping);
16678   S (mp_ping);
16679
16680   W (ret);
16681   return ret;
16682 }
16683
16684 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16685 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16686
16687
16688 static void
16689 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16690 {
16691   vat_main_t *vam = &vat_main;
16692   int count = ntohl (mp->count);
16693   vl_api_fib_path2_t *fp;
16694   int i;
16695
16696   print (vam->ofp,
16697          "table-id %d, label %u, ess_bit %u",
16698          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16699   fp = mp->path;
16700   for (i = 0; i < count; i++)
16701     {
16702       vl_api_mpls_fib_path_print (vam, fp);
16703       fp++;
16704     }
16705 }
16706
16707 static void vl_api_mpls_fib_details_t_handler_json
16708   (vl_api_mpls_fib_details_t * mp)
16709 {
16710   vat_main_t *vam = &vat_main;
16711   int count = ntohl (mp->count);
16712   vat_json_node_t *node = NULL;
16713   vl_api_fib_path2_t *fp;
16714   int i;
16715
16716   if (VAT_JSON_ARRAY != vam->json_tree.type)
16717     {
16718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16719       vat_json_init_array (&vam->json_tree);
16720     }
16721   node = vat_json_array_add (&vam->json_tree);
16722
16723   vat_json_init_object (node);
16724   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16725   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16726   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16727   vat_json_object_add_uint (node, "path_count", count);
16728   fp = mp->path;
16729   for (i = 0; i < count; i++)
16730     {
16731       vl_api_mpls_fib_path_json_print (node, fp);
16732       fp++;
16733     }
16734 }
16735
16736 static int
16737 api_mpls_fib_dump (vat_main_t * vam)
16738 {
16739   vl_api_mpls_fib_dump_t *mp;
16740   vl_api_control_ping_t *mp_ping;
16741   int ret;
16742
16743   M (MPLS_FIB_DUMP, mp);
16744   S (mp);
16745
16746   /* Use a control ping for synchronization */
16747   M (CONTROL_PING, mp_ping);
16748   S (mp_ping);
16749
16750   W (ret);
16751   return ret;
16752 }
16753
16754 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16755 #define vl_api_ip_fib_details_t_print vl_noop_handler
16756
16757 static void
16758 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16759 {
16760   vat_main_t *vam = &vat_main;
16761   int count = ntohl (mp->count);
16762   vl_api_fib_path_t *fp;
16763   int i;
16764
16765   print (vam->ofp,
16766          "table-id %d, prefix %U/%d",
16767          ntohl (mp->table_id), format_ip4_address, mp->address,
16768          mp->address_length);
16769   fp = mp->path;
16770   for (i = 0; i < count; i++)
16771     {
16772       if (fp->afi == IP46_TYPE_IP6)
16773         print (vam->ofp,
16774                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16775                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16776                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16777                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16778                format_ip6_address, fp->next_hop);
16779       else if (fp->afi == IP46_TYPE_IP4)
16780         print (vam->ofp,
16781                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16782                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16783                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16784                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16785                format_ip4_address, fp->next_hop);
16786       fp++;
16787     }
16788 }
16789
16790 static void vl_api_ip_fib_details_t_handler_json
16791   (vl_api_ip_fib_details_t * mp)
16792 {
16793   vat_main_t *vam = &vat_main;
16794   int count = ntohl (mp->count);
16795   vat_json_node_t *node = NULL;
16796   struct in_addr ip4;
16797   struct in6_addr ip6;
16798   vl_api_fib_path_t *fp;
16799   int i;
16800
16801   if (VAT_JSON_ARRAY != vam->json_tree.type)
16802     {
16803       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16804       vat_json_init_array (&vam->json_tree);
16805     }
16806   node = vat_json_array_add (&vam->json_tree);
16807
16808   vat_json_init_object (node);
16809   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16810   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16811   vat_json_object_add_ip4 (node, "prefix", ip4);
16812   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16813   vat_json_object_add_uint (node, "path_count", count);
16814   fp = mp->path;
16815   for (i = 0; i < count; i++)
16816     {
16817       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16818       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16819       vat_json_object_add_uint (node, "is_local", fp->is_local);
16820       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16821       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16822       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16823       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16824       if (fp->afi == IP46_TYPE_IP4)
16825         {
16826           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16827           vat_json_object_add_ip4 (node, "next_hop", ip4);
16828         }
16829       else if (fp->afi == IP46_TYPE_IP6)
16830         {
16831           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16832           vat_json_object_add_ip6 (node, "next_hop", ip6);
16833         }
16834     }
16835 }
16836
16837 static int
16838 api_ip_fib_dump (vat_main_t * vam)
16839 {
16840   vl_api_ip_fib_dump_t *mp;
16841   vl_api_control_ping_t *mp_ping;
16842   int ret;
16843
16844   M (IP_FIB_DUMP, mp);
16845   S (mp);
16846
16847   /* Use a control ping for synchronization */
16848   M (CONTROL_PING, mp_ping);
16849   S (mp_ping);
16850
16851   W (ret);
16852   return ret;
16853 }
16854
16855 static int
16856 api_ip_mfib_dump (vat_main_t * vam)
16857 {
16858   vl_api_ip_mfib_dump_t *mp;
16859   vl_api_control_ping_t *mp_ping;
16860   int ret;
16861
16862   M (IP_MFIB_DUMP, mp);
16863   S (mp);
16864
16865   /* Use a control ping for synchronization */
16866   M (CONTROL_PING, mp_ping);
16867   S (mp_ping);
16868
16869   W (ret);
16870   return ret;
16871 }
16872
16873 static void vl_api_ip_neighbor_details_t_handler
16874   (vl_api_ip_neighbor_details_t * mp)
16875 {
16876   vat_main_t *vam = &vat_main;
16877
16878   print (vam->ofp, "%c %U %U",
16879          (mp->is_static) ? 'S' : 'D',
16880          format_ethernet_address, &mp->mac_address,
16881          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16882          &mp->ip_address);
16883 }
16884
16885 static void vl_api_ip_neighbor_details_t_handler_json
16886   (vl_api_ip_neighbor_details_t * mp)
16887 {
16888
16889   vat_main_t *vam = &vat_main;
16890   vat_json_node_t *node;
16891   struct in_addr ip4;
16892   struct in6_addr ip6;
16893
16894   if (VAT_JSON_ARRAY != vam->json_tree.type)
16895     {
16896       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16897       vat_json_init_array (&vam->json_tree);
16898     }
16899   node = vat_json_array_add (&vam->json_tree);
16900
16901   vat_json_init_object (node);
16902   vat_json_object_add_string_copy (node, "flag",
16903                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16904                                    "dynamic");
16905
16906   vat_json_object_add_string_copy (node, "link_layer",
16907                                    format (0, "%U", format_ethernet_address,
16908                                            &mp->mac_address));
16909
16910   if (mp->is_ipv6)
16911     {
16912       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16913       vat_json_object_add_ip6 (node, "ip_address", ip6);
16914     }
16915   else
16916     {
16917       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16918       vat_json_object_add_ip4 (node, "ip_address", ip4);
16919     }
16920 }
16921
16922 static int
16923 api_ip_neighbor_dump (vat_main_t * vam)
16924 {
16925   unformat_input_t *i = vam->input;
16926   vl_api_ip_neighbor_dump_t *mp;
16927   vl_api_control_ping_t *mp_ping;
16928   u8 is_ipv6 = 0;
16929   u32 sw_if_index = ~0;
16930   int ret;
16931
16932   /* Parse args required to build the message */
16933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16934     {
16935       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16936         ;
16937       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16938         ;
16939       else if (unformat (i, "ip6"))
16940         is_ipv6 = 1;
16941       else
16942         break;
16943     }
16944
16945   if (sw_if_index == ~0)
16946     {
16947       errmsg ("missing interface name or sw_if_index");
16948       return -99;
16949     }
16950
16951   M (IP_NEIGHBOR_DUMP, mp);
16952   mp->is_ipv6 = (u8) is_ipv6;
16953   mp->sw_if_index = ntohl (sw_if_index);
16954   S (mp);
16955
16956   /* Use a control ping for synchronization */
16957   M (CONTROL_PING, mp_ping);
16958   S (mp_ping);
16959
16960   W (ret);
16961   return ret;
16962 }
16963
16964 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16965 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16966
16967 static void
16968 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16969 {
16970   vat_main_t *vam = &vat_main;
16971   int count = ntohl (mp->count);
16972   vl_api_fib_path_t *fp;
16973   int i;
16974
16975   print (vam->ofp,
16976          "table-id %d, prefix %U/%d",
16977          ntohl (mp->table_id), format_ip6_address, mp->address,
16978          mp->address_length);
16979   fp = mp->path;
16980   for (i = 0; i < count; i++)
16981     {
16982       if (fp->afi == IP46_TYPE_IP6)
16983         print (vam->ofp,
16984                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16985                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16986                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16987                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16988                format_ip6_address, fp->next_hop);
16989       else if (fp->afi == IP46_TYPE_IP4)
16990         print (vam->ofp,
16991                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16992                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16993                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16994                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16995                format_ip4_address, fp->next_hop);
16996       fp++;
16997     }
16998 }
16999
17000 static void vl_api_ip6_fib_details_t_handler_json
17001   (vl_api_ip6_fib_details_t * mp)
17002 {
17003   vat_main_t *vam = &vat_main;
17004   int count = ntohl (mp->count);
17005   vat_json_node_t *node = NULL;
17006   struct in_addr ip4;
17007   struct in6_addr ip6;
17008   vl_api_fib_path_t *fp;
17009   int i;
17010
17011   if (VAT_JSON_ARRAY != vam->json_tree.type)
17012     {
17013       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17014       vat_json_init_array (&vam->json_tree);
17015     }
17016   node = vat_json_array_add (&vam->json_tree);
17017
17018   vat_json_init_object (node);
17019   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17020   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17021   vat_json_object_add_ip6 (node, "prefix", ip6);
17022   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17023   vat_json_object_add_uint (node, "path_count", count);
17024   fp = mp->path;
17025   for (i = 0; i < count; i++)
17026     {
17027       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17028       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17029       vat_json_object_add_uint (node, "is_local", fp->is_local);
17030       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17031       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17032       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17033       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17034       if (fp->afi == IP46_TYPE_IP4)
17035         {
17036           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17037           vat_json_object_add_ip4 (node, "next_hop", ip4);
17038         }
17039       else if (fp->afi == IP46_TYPE_IP6)
17040         {
17041           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17042           vat_json_object_add_ip6 (node, "next_hop", ip6);
17043         }
17044     }
17045 }
17046
17047 static int
17048 api_ip6_fib_dump (vat_main_t * vam)
17049 {
17050   vl_api_ip6_fib_dump_t *mp;
17051   vl_api_control_ping_t *mp_ping;
17052   int ret;
17053
17054   M (IP6_FIB_DUMP, mp);
17055   S (mp);
17056
17057   /* Use a control ping for synchronization */
17058   M (CONTROL_PING, mp_ping);
17059   S (mp_ping);
17060
17061   W (ret);
17062   return ret;
17063 }
17064
17065 static int
17066 api_ip6_mfib_dump (vat_main_t * vam)
17067 {
17068   vl_api_ip6_mfib_dump_t *mp;
17069   vl_api_control_ping_t *mp_ping;
17070   int ret;
17071
17072   M (IP6_MFIB_DUMP, mp);
17073   S (mp);
17074
17075   /* Use a control ping for synchronization */
17076   M (CONTROL_PING, mp_ping);
17077   S (mp_ping);
17078
17079   W (ret);
17080   return ret;
17081 }
17082
17083 int
17084 api_classify_table_ids (vat_main_t * vam)
17085 {
17086   vl_api_classify_table_ids_t *mp;
17087   int ret;
17088
17089   /* Construct the API message */
17090   M (CLASSIFY_TABLE_IDS, mp);
17091   mp->context = 0;
17092
17093   S (mp);
17094   W (ret);
17095   return ret;
17096 }
17097
17098 int
17099 api_classify_table_by_interface (vat_main_t * vam)
17100 {
17101   unformat_input_t *input = vam->input;
17102   vl_api_classify_table_by_interface_t *mp;
17103
17104   u32 sw_if_index = ~0;
17105   int ret;
17106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17107     {
17108       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17109         ;
17110       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17111         ;
17112       else
17113         break;
17114     }
17115   if (sw_if_index == ~0)
17116     {
17117       errmsg ("missing interface name or sw_if_index");
17118       return -99;
17119     }
17120
17121   /* Construct the API message */
17122   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17123   mp->context = 0;
17124   mp->sw_if_index = ntohl (sw_if_index);
17125
17126   S (mp);
17127   W (ret);
17128   return ret;
17129 }
17130
17131 int
17132 api_classify_table_info (vat_main_t * vam)
17133 {
17134   unformat_input_t *input = vam->input;
17135   vl_api_classify_table_info_t *mp;
17136
17137   u32 table_id = ~0;
17138   int ret;
17139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17140     {
17141       if (unformat (input, "table_id %d", &table_id))
17142         ;
17143       else
17144         break;
17145     }
17146   if (table_id == ~0)
17147     {
17148       errmsg ("missing table id");
17149       return -99;
17150     }
17151
17152   /* Construct the API message */
17153   M (CLASSIFY_TABLE_INFO, mp);
17154   mp->context = 0;
17155   mp->table_id = ntohl (table_id);
17156
17157   S (mp);
17158   W (ret);
17159   return ret;
17160 }
17161
17162 int
17163 api_classify_session_dump (vat_main_t * vam)
17164 {
17165   unformat_input_t *input = vam->input;
17166   vl_api_classify_session_dump_t *mp;
17167   vl_api_control_ping_t *mp_ping;
17168
17169   u32 table_id = ~0;
17170   int ret;
17171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17172     {
17173       if (unformat (input, "table_id %d", &table_id))
17174         ;
17175       else
17176         break;
17177     }
17178   if (table_id == ~0)
17179     {
17180       errmsg ("missing table id");
17181       return -99;
17182     }
17183
17184   /* Construct the API message */
17185   M (CLASSIFY_SESSION_DUMP, mp);
17186   mp->context = 0;
17187   mp->table_id = ntohl (table_id);
17188   S (mp);
17189
17190   /* Use a control ping for synchronization */
17191   M (CONTROL_PING, mp_ping);
17192   S (mp_ping);
17193
17194   W (ret);
17195   return ret;
17196 }
17197
17198 static void
17199 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17200 {
17201   vat_main_t *vam = &vat_main;
17202
17203   print (vam->ofp, "collector_address %U, collector_port %d, "
17204          "src_address %U, vrf_id %d, path_mtu %u, "
17205          "template_interval %u, udp_checksum %d",
17206          format_ip4_address, mp->collector_address,
17207          ntohs (mp->collector_port),
17208          format_ip4_address, mp->src_address,
17209          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17210          ntohl (mp->template_interval), mp->udp_checksum);
17211
17212   vam->retval = 0;
17213   vam->result_ready = 1;
17214 }
17215
17216 static void
17217   vl_api_ipfix_exporter_details_t_handler_json
17218   (vl_api_ipfix_exporter_details_t * mp)
17219 {
17220   vat_main_t *vam = &vat_main;
17221   vat_json_node_t node;
17222   struct in_addr collector_address;
17223   struct in_addr src_address;
17224
17225   vat_json_init_object (&node);
17226   clib_memcpy (&collector_address, &mp->collector_address,
17227                sizeof (collector_address));
17228   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17229   vat_json_object_add_uint (&node, "collector_port",
17230                             ntohs (mp->collector_port));
17231   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17232   vat_json_object_add_ip4 (&node, "src_address", src_address);
17233   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17234   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17235   vat_json_object_add_uint (&node, "template_interval",
17236                             ntohl (mp->template_interval));
17237   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17238
17239   vat_json_print (vam->ofp, &node);
17240   vat_json_free (&node);
17241   vam->retval = 0;
17242   vam->result_ready = 1;
17243 }
17244
17245 int
17246 api_ipfix_exporter_dump (vat_main_t * vam)
17247 {
17248   vl_api_ipfix_exporter_dump_t *mp;
17249   int ret;
17250
17251   /* Construct the API message */
17252   M (IPFIX_EXPORTER_DUMP, mp);
17253   mp->context = 0;
17254
17255   S (mp);
17256   W (ret);
17257   return ret;
17258 }
17259
17260 static int
17261 api_ipfix_classify_stream_dump (vat_main_t * vam)
17262 {
17263   vl_api_ipfix_classify_stream_dump_t *mp;
17264   int ret;
17265
17266   /* Construct the API message */
17267   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17268   mp->context = 0;
17269
17270   S (mp);
17271   W (ret);
17272   return ret;
17273   /* NOTREACHED */
17274   return 0;
17275 }
17276
17277 static void
17278   vl_api_ipfix_classify_stream_details_t_handler
17279   (vl_api_ipfix_classify_stream_details_t * mp)
17280 {
17281   vat_main_t *vam = &vat_main;
17282   print (vam->ofp, "domain_id %d, src_port %d",
17283          ntohl (mp->domain_id), ntohs (mp->src_port));
17284   vam->retval = 0;
17285   vam->result_ready = 1;
17286 }
17287
17288 static void
17289   vl_api_ipfix_classify_stream_details_t_handler_json
17290   (vl_api_ipfix_classify_stream_details_t * mp)
17291 {
17292   vat_main_t *vam = &vat_main;
17293   vat_json_node_t node;
17294
17295   vat_json_init_object (&node);
17296   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17297   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17298
17299   vat_json_print (vam->ofp, &node);
17300   vat_json_free (&node);
17301   vam->retval = 0;
17302   vam->result_ready = 1;
17303 }
17304
17305 static int
17306 api_ipfix_classify_table_dump (vat_main_t * vam)
17307 {
17308   vl_api_ipfix_classify_table_dump_t *mp;
17309   vl_api_control_ping_t *mp_ping;
17310   int ret;
17311
17312   if (!vam->json_output)
17313     {
17314       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17315              "transport_protocol");
17316     }
17317
17318   /* Construct the API message */
17319   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17320
17321   /* send it... */
17322   S (mp);
17323
17324   /* Use a control ping for synchronization */
17325   M (CONTROL_PING, mp_ping);
17326   S (mp_ping);
17327
17328   W (ret);
17329   return ret;
17330 }
17331
17332 static void
17333   vl_api_ipfix_classify_table_details_t_handler
17334   (vl_api_ipfix_classify_table_details_t * mp)
17335 {
17336   vat_main_t *vam = &vat_main;
17337   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17338          mp->transport_protocol);
17339 }
17340
17341 static void
17342   vl_api_ipfix_classify_table_details_t_handler_json
17343   (vl_api_ipfix_classify_table_details_t * mp)
17344 {
17345   vat_json_node_t *node = NULL;
17346   vat_main_t *vam = &vat_main;
17347
17348   if (VAT_JSON_ARRAY != vam->json_tree.type)
17349     {
17350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17351       vat_json_init_array (&vam->json_tree);
17352     }
17353
17354   node = vat_json_array_add (&vam->json_tree);
17355   vat_json_init_object (node);
17356
17357   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17358   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17359   vat_json_object_add_uint (node, "transport_protocol",
17360                             mp->transport_protocol);
17361 }
17362
17363 static int
17364 api_sw_interface_span_enable_disable (vat_main_t * vam)
17365 {
17366   unformat_input_t *i = vam->input;
17367   vl_api_sw_interface_span_enable_disable_t *mp;
17368   u32 src_sw_if_index = ~0;
17369   u32 dst_sw_if_index = ~0;
17370   u8 state = 3;
17371   int ret;
17372
17373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17374     {
17375       if (unformat
17376           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17377         ;
17378       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17379         ;
17380       else
17381         if (unformat
17382             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17383         ;
17384       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17385         ;
17386       else if (unformat (i, "disable"))
17387         state = 0;
17388       else if (unformat (i, "rx"))
17389         state = 1;
17390       else if (unformat (i, "tx"))
17391         state = 2;
17392       else if (unformat (i, "both"))
17393         state = 3;
17394       else
17395         break;
17396     }
17397
17398   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17399
17400   mp->sw_if_index_from = htonl (src_sw_if_index);
17401   mp->sw_if_index_to = htonl (dst_sw_if_index);
17402   mp->state = state;
17403
17404   S (mp);
17405   W (ret);
17406   return ret;
17407 }
17408
17409 static void
17410 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17411                                             * mp)
17412 {
17413   vat_main_t *vam = &vat_main;
17414   u8 *sw_if_from_name = 0;
17415   u8 *sw_if_to_name = 0;
17416   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17417   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17418   char *states[] = { "none", "rx", "tx", "both" };
17419   hash_pair_t *p;
17420
17421   /* *INDENT-OFF* */
17422   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17423   ({
17424     if ((u32) p->value[0] == sw_if_index_from)
17425       {
17426         sw_if_from_name = (u8 *)(p->key);
17427         if (sw_if_to_name)
17428           break;
17429       }
17430     if ((u32) p->value[0] == sw_if_index_to)
17431       {
17432         sw_if_to_name = (u8 *)(p->key);
17433         if (sw_if_from_name)
17434           break;
17435       }
17436   }));
17437   /* *INDENT-ON* */
17438   print (vam->ofp, "%20s => %20s (%s)",
17439          sw_if_from_name, sw_if_to_name, states[mp->state]);
17440 }
17441
17442 static void
17443   vl_api_sw_interface_span_details_t_handler_json
17444   (vl_api_sw_interface_span_details_t * mp)
17445 {
17446   vat_main_t *vam = &vat_main;
17447   vat_json_node_t *node = NULL;
17448   u8 *sw_if_from_name = 0;
17449   u8 *sw_if_to_name = 0;
17450   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17451   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17452   hash_pair_t *p;
17453
17454   /* *INDENT-OFF* */
17455   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17456   ({
17457     if ((u32) p->value[0] == sw_if_index_from)
17458       {
17459         sw_if_from_name = (u8 *)(p->key);
17460         if (sw_if_to_name)
17461           break;
17462       }
17463     if ((u32) p->value[0] == sw_if_index_to)
17464       {
17465         sw_if_to_name = (u8 *)(p->key);
17466         if (sw_if_from_name)
17467           break;
17468       }
17469   }));
17470   /* *INDENT-ON* */
17471
17472   if (VAT_JSON_ARRAY != vam->json_tree.type)
17473     {
17474       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17475       vat_json_init_array (&vam->json_tree);
17476     }
17477   node = vat_json_array_add (&vam->json_tree);
17478
17479   vat_json_init_object (node);
17480   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17481   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17482   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17483   if (0 != sw_if_to_name)
17484     {
17485       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17486     }
17487   vat_json_object_add_uint (node, "state", mp->state);
17488 }
17489
17490 static int
17491 api_sw_interface_span_dump (vat_main_t * vam)
17492 {
17493   vl_api_sw_interface_span_dump_t *mp;
17494   vl_api_control_ping_t *mp_ping;
17495   int ret;
17496
17497   M (SW_INTERFACE_SPAN_DUMP, mp);
17498   S (mp);
17499
17500   /* Use a control ping for synchronization */
17501   M (CONTROL_PING, mp_ping);
17502   S (mp_ping);
17503
17504   W (ret);
17505   return ret;
17506 }
17507
17508 int
17509 api_pg_create_interface (vat_main_t * vam)
17510 {
17511   unformat_input_t *input = vam->input;
17512   vl_api_pg_create_interface_t *mp;
17513
17514   u32 if_id = ~0;
17515   int ret;
17516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17517     {
17518       if (unformat (input, "if_id %d", &if_id))
17519         ;
17520       else
17521         break;
17522     }
17523   if (if_id == ~0)
17524     {
17525       errmsg ("missing pg interface index");
17526       return -99;
17527     }
17528
17529   /* Construct the API message */
17530   M (PG_CREATE_INTERFACE, mp);
17531   mp->context = 0;
17532   mp->interface_id = ntohl (if_id);
17533
17534   S (mp);
17535   W (ret);
17536   return ret;
17537 }
17538
17539 int
17540 api_pg_capture (vat_main_t * vam)
17541 {
17542   unformat_input_t *input = vam->input;
17543   vl_api_pg_capture_t *mp;
17544
17545   u32 if_id = ~0;
17546   u8 enable = 1;
17547   u32 count = 1;
17548   u8 pcap_file_set = 0;
17549   u8 *pcap_file = 0;
17550   int ret;
17551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17552     {
17553       if (unformat (input, "if_id %d", &if_id))
17554         ;
17555       else if (unformat (input, "pcap %s", &pcap_file))
17556         pcap_file_set = 1;
17557       else if (unformat (input, "count %d", &count))
17558         ;
17559       else if (unformat (input, "disable"))
17560         enable = 0;
17561       else
17562         break;
17563     }
17564   if (if_id == ~0)
17565     {
17566       errmsg ("missing pg interface index");
17567       return -99;
17568     }
17569   if (pcap_file_set > 0)
17570     {
17571       if (vec_len (pcap_file) > 255)
17572         {
17573           errmsg ("pcap file name is too long");
17574           return -99;
17575         }
17576     }
17577
17578   u32 name_len = vec_len (pcap_file);
17579   /* Construct the API message */
17580   M (PG_CAPTURE, mp);
17581   mp->context = 0;
17582   mp->interface_id = ntohl (if_id);
17583   mp->is_enabled = enable;
17584   mp->count = ntohl (count);
17585   mp->pcap_name_length = ntohl (name_len);
17586   if (pcap_file_set != 0)
17587     {
17588       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17589     }
17590   vec_free (pcap_file);
17591
17592   S (mp);
17593   W (ret);
17594   return ret;
17595 }
17596
17597 int
17598 api_pg_enable_disable (vat_main_t * vam)
17599 {
17600   unformat_input_t *input = vam->input;
17601   vl_api_pg_enable_disable_t *mp;
17602
17603   u8 enable = 1;
17604   u8 stream_name_set = 0;
17605   u8 *stream_name = 0;
17606   int ret;
17607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17608     {
17609       if (unformat (input, "stream %s", &stream_name))
17610         stream_name_set = 1;
17611       else if (unformat (input, "disable"))
17612         enable = 0;
17613       else
17614         break;
17615     }
17616
17617   if (stream_name_set > 0)
17618     {
17619       if (vec_len (stream_name) > 255)
17620         {
17621           errmsg ("stream name too long");
17622           return -99;
17623         }
17624     }
17625
17626   u32 name_len = vec_len (stream_name);
17627   /* Construct the API message */
17628   M (PG_ENABLE_DISABLE, mp);
17629   mp->context = 0;
17630   mp->is_enabled = enable;
17631   if (stream_name_set != 0)
17632     {
17633       mp->stream_name_length = ntohl (name_len);
17634       clib_memcpy (mp->stream_name, stream_name, name_len);
17635     }
17636   vec_free (stream_name);
17637
17638   S (mp);
17639   W (ret);
17640   return ret;
17641 }
17642
17643 int
17644 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17645 {
17646   unformat_input_t *input = vam->input;
17647   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17648
17649   u16 *low_ports = 0;
17650   u16 *high_ports = 0;
17651   u16 this_low;
17652   u16 this_hi;
17653   ip4_address_t ip4_addr;
17654   ip6_address_t ip6_addr;
17655   u32 length;
17656   u32 tmp, tmp2;
17657   u8 prefix_set = 0;
17658   u32 vrf_id = ~0;
17659   u8 is_add = 1;
17660   u8 is_ipv6 = 0;
17661   int ret;
17662
17663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17664     {
17665       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17666         {
17667           prefix_set = 1;
17668         }
17669       else
17670         if (unformat
17671             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17672         {
17673           prefix_set = 1;
17674           is_ipv6 = 1;
17675         }
17676       else if (unformat (input, "vrf %d", &vrf_id))
17677         ;
17678       else if (unformat (input, "del"))
17679         is_add = 0;
17680       else if (unformat (input, "port %d", &tmp))
17681         {
17682           if (tmp == 0 || tmp > 65535)
17683             {
17684               errmsg ("port %d out of range", tmp);
17685               return -99;
17686             }
17687           this_low = tmp;
17688           this_hi = this_low + 1;
17689           vec_add1 (low_ports, this_low);
17690           vec_add1 (high_ports, this_hi);
17691         }
17692       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17693         {
17694           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17695             {
17696               errmsg ("incorrect range parameters");
17697               return -99;
17698             }
17699           this_low = tmp;
17700           /* Note: in debug CLI +1 is added to high before
17701              passing to real fn that does "the work"
17702              (ip_source_and_port_range_check_add_del).
17703              This fn is a wrapper around the binary API fn a
17704              control plane will call, which expects this increment
17705              to have occurred. Hence letting the binary API control
17706              plane fn do the increment for consistency between VAT
17707              and other control planes.
17708            */
17709           this_hi = tmp2;
17710           vec_add1 (low_ports, this_low);
17711           vec_add1 (high_ports, this_hi);
17712         }
17713       else
17714         break;
17715     }
17716
17717   if (prefix_set == 0)
17718     {
17719       errmsg ("<address>/<mask> not specified");
17720       return -99;
17721     }
17722
17723   if (vrf_id == ~0)
17724     {
17725       errmsg ("VRF ID required, not specified");
17726       return -99;
17727     }
17728
17729   if (vrf_id == 0)
17730     {
17731       errmsg
17732         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17733       return -99;
17734     }
17735
17736   if (vec_len (low_ports) == 0)
17737     {
17738       errmsg ("At least one port or port range required");
17739       return -99;
17740     }
17741
17742   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17743
17744   mp->is_add = is_add;
17745
17746   if (is_ipv6)
17747     {
17748       mp->is_ipv6 = 1;
17749       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17750     }
17751   else
17752     {
17753       mp->is_ipv6 = 0;
17754       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17755     }
17756
17757   mp->mask_length = length;
17758   mp->number_of_ranges = vec_len (low_ports);
17759
17760   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17761   vec_free (low_ports);
17762
17763   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17764   vec_free (high_ports);
17765
17766   mp->vrf_id = ntohl (vrf_id);
17767
17768   S (mp);
17769   W (ret);
17770   return ret;
17771 }
17772
17773 int
17774 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17775 {
17776   unformat_input_t *input = vam->input;
17777   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17778   u32 sw_if_index = ~0;
17779   int vrf_set = 0;
17780   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17781   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17782   u8 is_add = 1;
17783   int ret;
17784
17785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17786     {
17787       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17788         ;
17789       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17790         ;
17791       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17792         vrf_set = 1;
17793       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17794         vrf_set = 1;
17795       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17796         vrf_set = 1;
17797       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17798         vrf_set = 1;
17799       else if (unformat (input, "del"))
17800         is_add = 0;
17801       else
17802         break;
17803     }
17804
17805   if (sw_if_index == ~0)
17806     {
17807       errmsg ("Interface required but not specified");
17808       return -99;
17809     }
17810
17811   if (vrf_set == 0)
17812     {
17813       errmsg ("VRF ID required but not specified");
17814       return -99;
17815     }
17816
17817   if (tcp_out_vrf_id == 0
17818       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17819     {
17820       errmsg
17821         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17822       return -99;
17823     }
17824
17825   /* Construct the API message */
17826   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17827
17828   mp->sw_if_index = ntohl (sw_if_index);
17829   mp->is_add = is_add;
17830   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17831   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17832   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17833   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17834
17835   /* send it... */
17836   S (mp);
17837
17838   /* Wait for a reply... */
17839   W (ret);
17840   return ret;
17841 }
17842
17843 static int
17844 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17845 {
17846   unformat_input_t *i = vam->input;
17847   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17848   u32 local_sa_id = 0;
17849   u32 remote_sa_id = 0;
17850   ip4_address_t src_address;
17851   ip4_address_t dst_address;
17852   u8 is_add = 1;
17853   int ret;
17854
17855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17856     {
17857       if (unformat (i, "local_sa %d", &local_sa_id))
17858         ;
17859       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17860         ;
17861       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17862         ;
17863       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17864         ;
17865       else if (unformat (i, "del"))
17866         is_add = 0;
17867       else
17868         {
17869           clib_warning ("parse error '%U'", format_unformat_error, i);
17870           return -99;
17871         }
17872     }
17873
17874   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17875
17876   mp->local_sa_id = ntohl (local_sa_id);
17877   mp->remote_sa_id = ntohl (remote_sa_id);
17878   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17879   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17880   mp->is_add = is_add;
17881
17882   S (mp);
17883   W (ret);
17884   return ret;
17885 }
17886
17887 static int
17888 api_punt (vat_main_t * vam)
17889 {
17890   unformat_input_t *i = vam->input;
17891   vl_api_punt_t *mp;
17892   u32 ipv = ~0;
17893   u32 protocol = ~0;
17894   u32 port = ~0;
17895   int is_add = 1;
17896   int ret;
17897
17898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17899     {
17900       if (unformat (i, "ip %d", &ipv))
17901         ;
17902       else if (unformat (i, "protocol %d", &protocol))
17903         ;
17904       else if (unformat (i, "port %d", &port))
17905         ;
17906       else if (unformat (i, "del"))
17907         is_add = 0;
17908       else
17909         {
17910           clib_warning ("parse error '%U'", format_unformat_error, i);
17911           return -99;
17912         }
17913     }
17914
17915   M (PUNT, mp);
17916
17917   mp->is_add = (u8) is_add;
17918   mp->ipv = (u8) ipv;
17919   mp->l4_protocol = (u8) protocol;
17920   mp->l4_port = htons ((u16) port);
17921
17922   S (mp);
17923   W (ret);
17924   return ret;
17925 }
17926
17927 static void vl_api_ipsec_gre_tunnel_details_t_handler
17928   (vl_api_ipsec_gre_tunnel_details_t * mp)
17929 {
17930   vat_main_t *vam = &vat_main;
17931
17932   print (vam->ofp, "%11d%15U%15U%14d%14d",
17933          ntohl (mp->sw_if_index),
17934          format_ip4_address, &mp->src_address,
17935          format_ip4_address, &mp->dst_address,
17936          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17937 }
17938
17939 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17940   (vl_api_ipsec_gre_tunnel_details_t * mp)
17941 {
17942   vat_main_t *vam = &vat_main;
17943   vat_json_node_t *node = NULL;
17944   struct in_addr ip4;
17945
17946   if (VAT_JSON_ARRAY != vam->json_tree.type)
17947     {
17948       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17949       vat_json_init_array (&vam->json_tree);
17950     }
17951   node = vat_json_array_add (&vam->json_tree);
17952
17953   vat_json_init_object (node);
17954   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17955   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17956   vat_json_object_add_ip4 (node, "src_address", ip4);
17957   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17958   vat_json_object_add_ip4 (node, "dst_address", ip4);
17959   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17960   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17961 }
17962
17963 static int
17964 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17965 {
17966   unformat_input_t *i = vam->input;
17967   vl_api_ipsec_gre_tunnel_dump_t *mp;
17968   vl_api_control_ping_t *mp_ping;
17969   u32 sw_if_index;
17970   u8 sw_if_index_set = 0;
17971   int ret;
17972
17973   /* Parse args required to build the message */
17974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17975     {
17976       if (unformat (i, "sw_if_index %d", &sw_if_index))
17977         sw_if_index_set = 1;
17978       else
17979         break;
17980     }
17981
17982   if (sw_if_index_set == 0)
17983     {
17984       sw_if_index = ~0;
17985     }
17986
17987   if (!vam->json_output)
17988     {
17989       print (vam->ofp, "%11s%15s%15s%14s%14s",
17990              "sw_if_index", "src_address", "dst_address",
17991              "local_sa_id", "remote_sa_id");
17992     }
17993
17994   /* Get list of gre-tunnel interfaces */
17995   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17996
17997   mp->sw_if_index = htonl (sw_if_index);
17998
17999   S (mp);
18000
18001   /* Use a control ping for synchronization */
18002   M (CONTROL_PING, mp_ping);
18003   S (mp_ping);
18004
18005   W (ret);
18006   return ret;
18007 }
18008
18009 static int
18010 api_delete_subif (vat_main_t * vam)
18011 {
18012   unformat_input_t *i = vam->input;
18013   vl_api_delete_subif_t *mp;
18014   u32 sw_if_index = ~0;
18015   int ret;
18016
18017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18018     {
18019       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18020         ;
18021       if (unformat (i, "sw_if_index %d", &sw_if_index))
18022         ;
18023       else
18024         break;
18025     }
18026
18027   if (sw_if_index == ~0)
18028     {
18029       errmsg ("missing sw_if_index");
18030       return -99;
18031     }
18032
18033   /* Construct the API message */
18034   M (DELETE_SUBIF, mp);
18035   mp->sw_if_index = ntohl (sw_if_index);
18036
18037   S (mp);
18038   W (ret);
18039   return ret;
18040 }
18041
18042 #define foreach_pbb_vtr_op      \
18043 _("disable",  L2_VTR_DISABLED)  \
18044 _("pop",  L2_VTR_POP_2)         \
18045 _("push",  L2_VTR_PUSH_2)
18046
18047 static int
18048 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18049 {
18050   unformat_input_t *i = vam->input;
18051   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18052   u32 sw_if_index = ~0, vtr_op = ~0;
18053   u16 outer_tag = ~0;
18054   u8 dmac[6], smac[6];
18055   u8 dmac_set = 0, smac_set = 0;
18056   u16 vlanid = 0;
18057   u32 sid = ~0;
18058   u32 tmp;
18059   int ret;
18060
18061   /* Shut up coverity */
18062   memset (dmac, 0, sizeof (dmac));
18063   memset (smac, 0, sizeof (smac));
18064
18065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18066     {
18067       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18068         ;
18069       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18070         ;
18071       else if (unformat (i, "vtr_op %d", &vtr_op))
18072         ;
18073 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18074       foreach_pbb_vtr_op
18075 #undef _
18076         else if (unformat (i, "translate_pbb_stag"))
18077         {
18078           if (unformat (i, "%d", &tmp))
18079             {
18080               vtr_op = L2_VTR_TRANSLATE_2_1;
18081               outer_tag = tmp;
18082             }
18083           else
18084             {
18085               errmsg
18086                 ("translate_pbb_stag operation requires outer tag definition");
18087               return -99;
18088             }
18089         }
18090       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18091         dmac_set++;
18092       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18093         smac_set++;
18094       else if (unformat (i, "sid %d", &sid))
18095         ;
18096       else if (unformat (i, "vlanid %d", &tmp))
18097         vlanid = tmp;
18098       else
18099         {
18100           clib_warning ("parse error '%U'", format_unformat_error, i);
18101           return -99;
18102         }
18103     }
18104
18105   if ((sw_if_index == ~0) || (vtr_op == ~0))
18106     {
18107       errmsg ("missing sw_if_index or vtr operation");
18108       return -99;
18109     }
18110   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18111       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18112     {
18113       errmsg
18114         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18115       return -99;
18116     }
18117
18118   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18119   mp->sw_if_index = ntohl (sw_if_index);
18120   mp->vtr_op = ntohl (vtr_op);
18121   mp->outer_tag = ntohs (outer_tag);
18122   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18123   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18124   mp->b_vlanid = ntohs (vlanid);
18125   mp->i_sid = ntohl (sid);
18126
18127   S (mp);
18128   W (ret);
18129   return ret;
18130 }
18131
18132 static int
18133 api_flow_classify_set_interface (vat_main_t * vam)
18134 {
18135   unformat_input_t *i = vam->input;
18136   vl_api_flow_classify_set_interface_t *mp;
18137   u32 sw_if_index;
18138   int sw_if_index_set;
18139   u32 ip4_table_index = ~0;
18140   u32 ip6_table_index = ~0;
18141   u8 is_add = 1;
18142   int ret;
18143
18144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18145     {
18146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18147         sw_if_index_set = 1;
18148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18149         sw_if_index_set = 1;
18150       else if (unformat (i, "del"))
18151         is_add = 0;
18152       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18153         ;
18154       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18155         ;
18156       else
18157         {
18158           clib_warning ("parse error '%U'", format_unformat_error, i);
18159           return -99;
18160         }
18161     }
18162
18163   if (sw_if_index_set == 0)
18164     {
18165       errmsg ("missing interface name or sw_if_index");
18166       return -99;
18167     }
18168
18169   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18170
18171   mp->sw_if_index = ntohl (sw_if_index);
18172   mp->ip4_table_index = ntohl (ip4_table_index);
18173   mp->ip6_table_index = ntohl (ip6_table_index);
18174   mp->is_add = is_add;
18175
18176   S (mp);
18177   W (ret);
18178   return ret;
18179 }
18180
18181 static int
18182 api_flow_classify_dump (vat_main_t * vam)
18183 {
18184   unformat_input_t *i = vam->input;
18185   vl_api_flow_classify_dump_t *mp;
18186   vl_api_control_ping_t *mp_ping;
18187   u8 type = FLOW_CLASSIFY_N_TABLES;
18188   int ret;
18189
18190   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18191     ;
18192   else
18193     {
18194       errmsg ("classify table type must be specified");
18195       return -99;
18196     }
18197
18198   if (!vam->json_output)
18199     {
18200       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18201     }
18202
18203   M (FLOW_CLASSIFY_DUMP, mp);
18204   mp->type = type;
18205   /* send it... */
18206   S (mp);
18207
18208   /* Use a control ping for synchronization */
18209   M (CONTROL_PING, mp_ping);
18210   S (mp_ping);
18211
18212   /* Wait for a reply... */
18213   W (ret);
18214   return ret;
18215 }
18216
18217 static int
18218 api_feature_enable_disable (vat_main_t * vam)
18219 {
18220   unformat_input_t *i = vam->input;
18221   vl_api_feature_enable_disable_t *mp;
18222   u8 *arc_name = 0;
18223   u8 *feature_name = 0;
18224   u32 sw_if_index = ~0;
18225   u8 enable = 1;
18226   int ret;
18227
18228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18229     {
18230       if (unformat (i, "arc_name %s", &arc_name))
18231         ;
18232       else if (unformat (i, "feature_name %s", &feature_name))
18233         ;
18234       else
18235         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18236         ;
18237       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18238         ;
18239       else if (unformat (i, "disable"))
18240         enable = 0;
18241       else
18242         break;
18243     }
18244
18245   if (arc_name == 0)
18246     {
18247       errmsg ("missing arc name");
18248       return -99;
18249     }
18250   if (vec_len (arc_name) > 63)
18251     {
18252       errmsg ("arc name too long");
18253     }
18254
18255   if (feature_name == 0)
18256     {
18257       errmsg ("missing feature name");
18258       return -99;
18259     }
18260   if (vec_len (feature_name) > 63)
18261     {
18262       errmsg ("feature name too long");
18263     }
18264
18265   if (sw_if_index == ~0)
18266     {
18267       errmsg ("missing interface name or sw_if_index");
18268       return -99;
18269     }
18270
18271   /* Construct the API message */
18272   M (FEATURE_ENABLE_DISABLE, mp);
18273   mp->sw_if_index = ntohl (sw_if_index);
18274   mp->enable = enable;
18275   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18276   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18277   vec_free (arc_name);
18278   vec_free (feature_name);
18279
18280   S (mp);
18281   W (ret);
18282   return ret;
18283 }
18284
18285 static int
18286 api_sw_interface_tag_add_del (vat_main_t * vam)
18287 {
18288   unformat_input_t *i = vam->input;
18289   vl_api_sw_interface_tag_add_del_t *mp;
18290   u32 sw_if_index = ~0;
18291   u8 *tag = 0;
18292   u8 enable = 1;
18293   int ret;
18294
18295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18296     {
18297       if (unformat (i, "tag %s", &tag))
18298         ;
18299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18300         ;
18301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18302         ;
18303       else if (unformat (i, "del"))
18304         enable = 0;
18305       else
18306         break;
18307     }
18308
18309   if (sw_if_index == ~0)
18310     {
18311       errmsg ("missing interface name or sw_if_index");
18312       return -99;
18313     }
18314
18315   if (enable && (tag == 0))
18316     {
18317       errmsg ("no tag specified");
18318       return -99;
18319     }
18320
18321   /* Construct the API message */
18322   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18323   mp->sw_if_index = ntohl (sw_if_index);
18324   mp->is_add = enable;
18325   if (enable)
18326     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18327   vec_free (tag);
18328
18329   S (mp);
18330   W (ret);
18331   return ret;
18332 }
18333
18334 static void vl_api_l2_xconnect_details_t_handler
18335   (vl_api_l2_xconnect_details_t * mp)
18336 {
18337   vat_main_t *vam = &vat_main;
18338
18339   print (vam->ofp, "%15d%15d",
18340          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18341 }
18342
18343 static void vl_api_l2_xconnect_details_t_handler_json
18344   (vl_api_l2_xconnect_details_t * mp)
18345 {
18346   vat_main_t *vam = &vat_main;
18347   vat_json_node_t *node = NULL;
18348
18349   if (VAT_JSON_ARRAY != vam->json_tree.type)
18350     {
18351       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18352       vat_json_init_array (&vam->json_tree);
18353     }
18354   node = vat_json_array_add (&vam->json_tree);
18355
18356   vat_json_init_object (node);
18357   vat_json_object_add_uint (node, "rx_sw_if_index",
18358                             ntohl (mp->rx_sw_if_index));
18359   vat_json_object_add_uint (node, "tx_sw_if_index",
18360                             ntohl (mp->tx_sw_if_index));
18361 }
18362
18363 static int
18364 api_l2_xconnect_dump (vat_main_t * vam)
18365 {
18366   vl_api_l2_xconnect_dump_t *mp;
18367   vl_api_control_ping_t *mp_ping;
18368   int ret;
18369
18370   if (!vam->json_output)
18371     {
18372       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18373     }
18374
18375   M (L2_XCONNECT_DUMP, mp);
18376
18377   S (mp);
18378
18379   /* Use a control ping for synchronization */
18380   M (CONTROL_PING, mp_ping);
18381   S (mp_ping);
18382
18383   W (ret);
18384   return ret;
18385 }
18386
18387 static int
18388 api_sw_interface_set_mtu (vat_main_t * vam)
18389 {
18390   unformat_input_t *i = vam->input;
18391   vl_api_sw_interface_set_mtu_t *mp;
18392   u32 sw_if_index = ~0;
18393   u32 mtu = 0;
18394   int ret;
18395
18396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18397     {
18398       if (unformat (i, "mtu %d", &mtu))
18399         ;
18400       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18401         ;
18402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18403         ;
18404       else
18405         break;
18406     }
18407
18408   if (sw_if_index == ~0)
18409     {
18410       errmsg ("missing interface name or sw_if_index");
18411       return -99;
18412     }
18413
18414   if (mtu == 0)
18415     {
18416       errmsg ("no mtu specified");
18417       return -99;
18418     }
18419
18420   /* Construct the API message */
18421   M (SW_INTERFACE_SET_MTU, mp);
18422   mp->sw_if_index = ntohl (sw_if_index);
18423   mp->mtu = ntohs ((u16) mtu);
18424
18425   S (mp);
18426   W (ret);
18427   return ret;
18428 }
18429
18430
18431 static int
18432 q_or_quit (vat_main_t * vam)
18433 {
18434 #if VPP_API_TEST_BUILTIN == 0
18435   longjmp (vam->jump_buf, 1);
18436 #endif
18437   return 0;                     /* not so much */
18438 }
18439
18440 static int
18441 q (vat_main_t * vam)
18442 {
18443   return q_or_quit (vam);
18444 }
18445
18446 static int
18447 quit (vat_main_t * vam)
18448 {
18449   return q_or_quit (vam);
18450 }
18451
18452 static int
18453 comment (vat_main_t * vam)
18454 {
18455   return 0;
18456 }
18457
18458 static int
18459 cmd_cmp (void *a1, void *a2)
18460 {
18461   u8 **c1 = a1;
18462   u8 **c2 = a2;
18463
18464   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18465 }
18466
18467 static int
18468 help (vat_main_t * vam)
18469 {
18470   u8 **cmds = 0;
18471   u8 *name = 0;
18472   hash_pair_t *p;
18473   unformat_input_t *i = vam->input;
18474   int j;
18475
18476   if (unformat (i, "%s", &name))
18477     {
18478       uword *hs;
18479
18480       vec_add1 (name, 0);
18481
18482       hs = hash_get_mem (vam->help_by_name, name);
18483       if (hs)
18484         print (vam->ofp, "usage: %s %s", name, hs[0]);
18485       else
18486         print (vam->ofp, "No such msg / command '%s'", name);
18487       vec_free (name);
18488       return 0;
18489     }
18490
18491   print (vam->ofp, "Help is available for the following:");
18492
18493     /* *INDENT-OFF* */
18494     hash_foreach_pair (p, vam->function_by_name,
18495     ({
18496       vec_add1 (cmds, (u8 *)(p->key));
18497     }));
18498     /* *INDENT-ON* */
18499
18500   vec_sort_with_function (cmds, cmd_cmp);
18501
18502   for (j = 0; j < vec_len (cmds); j++)
18503     print (vam->ofp, "%s", cmds[j]);
18504
18505   vec_free (cmds);
18506   return 0;
18507 }
18508
18509 static int
18510 set (vat_main_t * vam)
18511 {
18512   u8 *name = 0, *value = 0;
18513   unformat_input_t *i = vam->input;
18514
18515   if (unformat (i, "%s", &name))
18516     {
18517       /* The input buffer is a vector, not a string. */
18518       value = vec_dup (i->buffer);
18519       vec_delete (value, i->index, 0);
18520       /* Almost certainly has a trailing newline */
18521       if (value[vec_len (value) - 1] == '\n')
18522         value[vec_len (value) - 1] = 0;
18523       /* Make sure it's a proper string, one way or the other */
18524       vec_add1 (value, 0);
18525       (void) clib_macro_set_value (&vam->macro_main,
18526                                    (char *) name, (char *) value);
18527     }
18528   else
18529     errmsg ("usage: set <name> <value>");
18530
18531   vec_free (name);
18532   vec_free (value);
18533   return 0;
18534 }
18535
18536 static int
18537 unset (vat_main_t * vam)
18538 {
18539   u8 *name = 0;
18540
18541   if (unformat (vam->input, "%s", &name))
18542     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18543       errmsg ("unset: %s wasn't set", name);
18544   vec_free (name);
18545   return 0;
18546 }
18547
18548 typedef struct
18549 {
18550   u8 *name;
18551   u8 *value;
18552 } macro_sort_t;
18553
18554
18555 static int
18556 macro_sort_cmp (void *a1, void *a2)
18557 {
18558   macro_sort_t *s1 = a1;
18559   macro_sort_t *s2 = a2;
18560
18561   return strcmp ((char *) (s1->name), (char *) (s2->name));
18562 }
18563
18564 static int
18565 dump_macro_table (vat_main_t * vam)
18566 {
18567   macro_sort_t *sort_me = 0, *sm;
18568   int i;
18569   hash_pair_t *p;
18570
18571     /* *INDENT-OFF* */
18572     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18573     ({
18574       vec_add2 (sort_me, sm, 1);
18575       sm->name = (u8 *)(p->key);
18576       sm->value = (u8 *) (p->value[0]);
18577     }));
18578     /* *INDENT-ON* */
18579
18580   vec_sort_with_function (sort_me, macro_sort_cmp);
18581
18582   if (vec_len (sort_me))
18583     print (vam->ofp, "%-15s%s", "Name", "Value");
18584   else
18585     print (vam->ofp, "The macro table is empty...");
18586
18587   for (i = 0; i < vec_len (sort_me); i++)
18588     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18589   return 0;
18590 }
18591
18592 static int
18593 dump_node_table (vat_main_t * vam)
18594 {
18595   int i, j;
18596   vlib_node_t *node, *next_node;
18597
18598   if (vec_len (vam->graph_nodes) == 0)
18599     {
18600       print (vam->ofp, "Node table empty, issue get_node_graph...");
18601       return 0;
18602     }
18603
18604   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18605     {
18606       node = vam->graph_nodes[i];
18607       print (vam->ofp, "[%d] %s", i, node->name);
18608       for (j = 0; j < vec_len (node->next_nodes); j++)
18609         {
18610           if (node->next_nodes[j] != ~0)
18611             {
18612               next_node = vam->graph_nodes[node->next_nodes[j]];
18613               print (vam->ofp, "  [%d] %s", j, next_node->name);
18614             }
18615         }
18616     }
18617   return 0;
18618 }
18619
18620 static int
18621 value_sort_cmp (void *a1, void *a2)
18622 {
18623   name_sort_t *n1 = a1;
18624   name_sort_t *n2 = a2;
18625
18626   if (n1->value < n2->value)
18627     return -1;
18628   if (n1->value > n2->value)
18629     return 1;
18630   return 0;
18631 }
18632
18633
18634 static int
18635 dump_msg_api_table (vat_main_t * vam)
18636 {
18637   api_main_t *am = &api_main;
18638   name_sort_t *nses = 0, *ns;
18639   hash_pair_t *hp;
18640   int i;
18641
18642   /* *INDENT-OFF* */
18643   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18644   ({
18645     vec_add2 (nses, ns, 1);
18646     ns->name = (u8 *)(hp->key);
18647     ns->value = (u32) hp->value[0];
18648   }));
18649   /* *INDENT-ON* */
18650
18651   vec_sort_with_function (nses, value_sort_cmp);
18652
18653   for (i = 0; i < vec_len (nses); i++)
18654     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18655   vec_free (nses);
18656   return 0;
18657 }
18658
18659 static int
18660 get_msg_id (vat_main_t * vam)
18661 {
18662   u8 *name_and_crc;
18663   u32 message_index;
18664
18665   if (unformat (vam->input, "%s", &name_and_crc))
18666     {
18667       message_index = vl_api_get_msg_index (name_and_crc);
18668       if (message_index == ~0)
18669         {
18670           print (vam->ofp, " '%s' not found", name_and_crc);
18671           return 0;
18672         }
18673       print (vam->ofp, " '%s' has message index %d",
18674              name_and_crc, message_index);
18675       return 0;
18676     }
18677   errmsg ("name_and_crc required...");
18678   return 0;
18679 }
18680
18681 static int
18682 search_node_table (vat_main_t * vam)
18683 {
18684   unformat_input_t *line_input = vam->input;
18685   u8 *node_to_find;
18686   int j;
18687   vlib_node_t *node, *next_node;
18688   uword *p;
18689
18690   if (vam->graph_node_index_by_name == 0)
18691     {
18692       print (vam->ofp, "Node table empty, issue get_node_graph...");
18693       return 0;
18694     }
18695
18696   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18697     {
18698       if (unformat (line_input, "%s", &node_to_find))
18699         {
18700           vec_add1 (node_to_find, 0);
18701           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18702           if (p == 0)
18703             {
18704               print (vam->ofp, "%s not found...", node_to_find);
18705               goto out;
18706             }
18707           node = vam->graph_nodes[p[0]];
18708           print (vam->ofp, "[%d] %s", p[0], node->name);
18709           for (j = 0; j < vec_len (node->next_nodes); j++)
18710             {
18711               if (node->next_nodes[j] != ~0)
18712                 {
18713                   next_node = vam->graph_nodes[node->next_nodes[j]];
18714                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18715                 }
18716             }
18717         }
18718
18719       else
18720         {
18721           clib_warning ("parse error '%U'", format_unformat_error,
18722                         line_input);
18723           return -99;
18724         }
18725
18726     out:
18727       vec_free (node_to_find);
18728
18729     }
18730
18731   return 0;
18732 }
18733
18734
18735 static int
18736 script (vat_main_t * vam)
18737 {
18738 #if (VPP_API_TEST_BUILTIN==0)
18739   u8 *s = 0;
18740   char *save_current_file;
18741   unformat_input_t save_input;
18742   jmp_buf save_jump_buf;
18743   u32 save_line_number;
18744
18745   FILE *new_fp, *save_ifp;
18746
18747   if (unformat (vam->input, "%s", &s))
18748     {
18749       new_fp = fopen ((char *) s, "r");
18750       if (new_fp == 0)
18751         {
18752           errmsg ("Couldn't open script file %s", s);
18753           vec_free (s);
18754           return -99;
18755         }
18756     }
18757   else
18758     {
18759       errmsg ("Missing script name");
18760       return -99;
18761     }
18762
18763   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18764   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18765   save_ifp = vam->ifp;
18766   save_line_number = vam->input_line_number;
18767   save_current_file = (char *) vam->current_file;
18768
18769   vam->input_line_number = 0;
18770   vam->ifp = new_fp;
18771   vam->current_file = s;
18772   do_one_file (vam);
18773
18774   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18775   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18776   vam->ifp = save_ifp;
18777   vam->input_line_number = save_line_number;
18778   vam->current_file = (u8 *) save_current_file;
18779   vec_free (s);
18780
18781   return 0;
18782 #else
18783   clib_warning ("use the exec command...");
18784   return -99;
18785 #endif
18786 }
18787
18788 static int
18789 echo (vat_main_t * vam)
18790 {
18791   print (vam->ofp, "%v", vam->input->buffer);
18792   return 0;
18793 }
18794
18795 /* List of API message constructors, CLI names map to api_xxx */
18796 #define foreach_vpe_api_msg                                             \
18797 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18798 _(sw_interface_dump,"")                                                 \
18799 _(sw_interface_set_flags,                                               \
18800   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18801 _(sw_interface_add_del_address,                                         \
18802   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18803 _(sw_interface_set_table,                                               \
18804   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18805 _(sw_interface_set_mpls_enable,                                         \
18806   "<intfc> | sw_if_index [disable | dis]")                              \
18807 _(sw_interface_set_vpath,                                               \
18808   "<intfc> | sw_if_index <id> enable | disable")                        \
18809 _(sw_interface_set_vxlan_bypass,                                        \
18810   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18811 _(sw_interface_set_l2_xconnect,                                         \
18812   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18813   "enable | disable")                                                   \
18814 _(sw_interface_set_l2_bridge,                                           \
18815   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
18816   "[shg <split-horizon-group>] [bvi]\n"                                 \
18817   "enable | disable")                                                   \
18818 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
18819 _(bridge_domain_add_del,                                                \
18820   "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") \
18821 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18822 _(l2fib_add_del,                                                        \
18823   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18824 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
18825 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
18826 _(l2_flags,                                                             \
18827   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18828 _(bridge_flags,                                                         \
18829   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18830 _(tap_connect,                                                          \
18831   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18832 _(tap_modify,                                                           \
18833   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18834 _(tap_delete,                                                           \
18835   "<vpp-if-name> | sw_if_index <id>")                                   \
18836 _(sw_interface_tap_dump, "")                                            \
18837 _(ip_add_del_route,                                                     \
18838   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18839   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18840   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18841   "[multipath] [count <n>]")                                            \
18842 _(ip_mroute_add_del,                                                    \
18843   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18844   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18845 _(mpls_route_add_del,                                                   \
18846   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18847   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18848   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18849   "[multipath] [count <n>]")                                            \
18850 _(mpls_ip_bind_unbind,                                                  \
18851   "<label> <addr/len>")                                                 \
18852 _(mpls_tunnel_add_del,                                                  \
18853   " via <addr> [table-id <n>]\n"                                        \
18854   "sw_if_index <id>] [l2]  [del]")                                      \
18855 _(proxy_arp_add_del,                                                    \
18856   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18857 _(proxy_arp_intfc_enable_disable,                                       \
18858   "<intfc> | sw_if_index <id> enable | disable")                        \
18859 _(sw_interface_set_unnumbered,                                          \
18860   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18861 _(ip_neighbor_add_del,                                                  \
18862   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18863   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18864 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18865 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18866 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18867   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18868   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18869   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18870 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18871 _(reset_fib, "vrf <n> [ipv6]")                                          \
18872 _(dhcp_proxy_config,                                                    \
18873   "svr <v46-address> src <v46-address>\n"                               \
18874    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18875 _(dhcp_proxy_set_vss,                                                   \
18876   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18877 _(dhcp_proxy_dump, "ip6")                                               \
18878 _(dhcp_client_config,                                                   \
18879   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18880 _(set_ip_flow_hash,                                                     \
18881   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18882 _(sw_interface_ip6_enable_disable,                                      \
18883   "<intfc> | sw_if_index <id> enable | disable")                        \
18884 _(sw_interface_ip6_set_link_local_address,                              \
18885   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18886 _(ip6nd_proxy_add_del,                                                  \
18887   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18888 _(ip6nd_proxy_dump, "")                                                 \
18889 _(sw_interface_ip6nd_ra_prefix,                                         \
18890   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18891   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18892   "[nolink] [isno]")                                                    \
18893 _(sw_interface_ip6nd_ra_config,                                         \
18894   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18895   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18896   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18897 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18898 _(l2_patch_add_del,                                                     \
18899   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18900   "enable | disable")                                                   \
18901 _(sr_localsid_add_del,                                                  \
18902   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18903   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18904 _(classify_add_del_table,                                               \
18905   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18906   " [del] [del-chain] mask <mask-value>\n"                              \
18907   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18908   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18909 _(classify_add_del_session,                                             \
18910   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18911   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18912   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18913   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18914 _(classify_set_interface_ip_table,                                      \
18915   "<intfc> | sw_if_index <nn> table <nn>")                              \
18916 _(classify_set_interface_l2_tables,                                     \
18917   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18918   "  [other-table <nn>]")                                               \
18919 _(get_node_index, "node <node-name")                                    \
18920 _(add_node_next, "node <node-name> next <next-node-name>")              \
18921 _(l2tpv3_create_tunnel,                                                 \
18922   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18923   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18924   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18925 _(l2tpv3_set_tunnel_cookies,                                            \
18926   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18927   "[new_remote_cookie <nn>]\n")                                         \
18928 _(l2tpv3_interface_enable_disable,                                      \
18929   "<intfc> | sw_if_index <nn> enable | disable")                        \
18930 _(l2tpv3_set_lookup_key,                                                \
18931   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18932 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18933 _(vxlan_add_del_tunnel,                                                 \
18934   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18935   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18936   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18937 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18938 _(gre_add_del_tunnel,                                                   \
18939   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18940 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18941 _(l2_fib_clear_table, "")                                               \
18942 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18943 _(l2_interface_vlan_tag_rewrite,                                        \
18944   "<intfc> | sw_if_index <nn> \n"                                       \
18945   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18946   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18947 _(create_vhost_user_if,                                                 \
18948         "socket <filename> [server] [renumber <dev_instance>] "         \
18949         "[mac <mac_address>]")                                          \
18950 _(modify_vhost_user_if,                                                 \
18951         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18952         "[server] [renumber <dev_instance>]")                           \
18953 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18954 _(sw_interface_vhost_user_dump, "")                                     \
18955 _(show_version, "")                                                     \
18956 _(vxlan_gpe_add_del_tunnel,                                             \
18957   "local <addr> remote <addr> vni <nn>\n"                               \
18958     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18959   "[next-ethernet] [next-nsh]\n")                                       \
18960 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18961 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18962 _(interface_name_renumber,                                              \
18963   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18964 _(input_acl_set_interface,                                              \
18965   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18966   "  [l2-table <nn>] [del]")                                            \
18967 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18968 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18969 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18970 _(ip_dump, "ipv4 | ipv6")                                               \
18971 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18972 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18973   "  spid_id <n> ")                                                     \
18974 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18975   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18976   "  integ_alg <alg> integ_key <hex>")                                  \
18977 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18978   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18979   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18980   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18981 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18982 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
18983   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
18984   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
18985   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
18986 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18987 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18988   "(auth_data 0x<data> | auth_data <data>)")                            \
18989 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18990   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18991 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18992   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18993   "(local|remote)")                                                     \
18994 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18995 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18996 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18997 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18998 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18999 _(ikev2_initiate_sa_init, "<profile_name>")                             \
19000 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
19001 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
19002 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
19003 _(delete_loopback,"sw_if_index <nn>")                                   \
19004 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19005 _(map_add_domain,                                                       \
19006   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
19007   "ip6-src <ip6addr> "                                                  \
19008   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
19009 _(map_del_domain, "index <n>")                                          \
19010 _(map_add_del_rule,                                                     \
19011   "index <n> psid <n> dst <ip6addr> [del]")                             \
19012 _(map_domain_dump, "")                                                  \
19013 _(map_rule_dump, "index <map-domain>")                                  \
19014 _(want_interface_events,  "enable|disable")                             \
19015 _(want_stats,"enable|disable")                                          \
19016 _(get_first_msg_id, "client <name>")                                    \
19017 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19018 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19019   "fib-id <nn> [ip4][ip6][default]")                                    \
19020 _(get_node_graph, " ")                                                  \
19021 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19022 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19023 _(ioam_disable, "")                                                     \
19024 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19025                             " sw_if_index <sw_if_index> p <priority> "  \
19026                             "w <weight>] [del]")                        \
19027 _(one_add_del_locator, "locator-set <locator_name> "                    \
19028                         "iface <intf> | sw_if_index <sw_if_index> "     \
19029                         "p <priority> w <weight> [del]")                \
19030 _(one_add_del_local_eid,"vni <vni> eid "                                \
19031                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19032                          "locator-set <locator_name> [del]"             \
19033                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19034 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19035 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19036 _(one_enable_disable, "enable|disable")                                 \
19037 _(one_map_register_enable_disable, "enable|disable")                    \
19038 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19039 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19040                                "[seid <seid>] "                         \
19041                                "rloc <locator> p <prio> "               \
19042                                "w <weight> [rloc <loc> ... ] "          \
19043                                "action <action> [del-all]")             \
19044 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19045                           "<local-eid>")                                \
19046 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19047 _(one_use_petr, "ip-address> | disable")                                \
19048 _(one_map_request_mode, "src-dst|dst-only")                             \
19049 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19050 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19051 _(one_locator_set_dump, "[local | remote]")                             \
19052 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19053 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19054                        "[local] | [remote]")                            \
19055 _(one_stats_enable_disable, "enable|disalbe")                           \
19056 _(show_one_stats_enable_disable, "")                                    \
19057 _(one_eid_table_vni_dump, "")                                           \
19058 _(one_eid_table_map_dump, "l2|l3")                                      \
19059 _(one_map_resolver_dump, "")                                            \
19060 _(one_map_server_dump, "")                                              \
19061 _(one_adjacencies_get, "vni <vni>")                                     \
19062 _(show_one_rloc_probe_state, "")                                        \
19063 _(show_one_map_register_state, "")                                      \
19064 _(show_one_status, "")                                                  \
19065 _(one_stats_dump, "")                                                   \
19066 _(one_stats_flush, "")                                                  \
19067 _(one_get_map_request_itr_rlocs, "")                                    \
19068 _(show_one_pitr, "")                                                    \
19069 _(show_one_use_petr, "")                                                \
19070 _(show_one_map_request_mode, "")                                        \
19071 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19072                             " sw_if_index <sw_if_index> p <priority> "  \
19073                             "w <weight>] [del]")                        \
19074 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19075                         "iface <intf> | sw_if_index <sw_if_index> "     \
19076                         "p <priority> w <weight> [del]")                \
19077 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19078                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19079                          "locator-set <locator_name> [del]"             \
19080                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19081 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19082 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19083 _(lisp_enable_disable, "enable|disable")                                \
19084 _(lisp_map_register_enable_disable, "enable|disable")                   \
19085 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19086 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19087                                "[seid <seid>] "                         \
19088                                "rloc <locator> p <prio> "               \
19089                                "w <weight> [rloc <loc> ... ] "          \
19090                                "action <action> [del-all]")             \
19091 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19092                           "<local-eid>")                                \
19093 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19094 _(lisp_use_petr, "<ip-address> | disable")                              \
19095 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19096 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19097 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19098 _(lisp_locator_set_dump, "[local | remote]")                            \
19099 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19100 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19101                        "[local] | [remote]")                            \
19102 _(lisp_eid_table_vni_dump, "")                                          \
19103 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19104 _(lisp_map_resolver_dump, "")                                           \
19105 _(lisp_map_server_dump, "")                                             \
19106 _(lisp_adjacencies_get, "vni <vni>")                                    \
19107 _(gpe_fwd_entry_vnis_get, "")                                           \
19108 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19109 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19110 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19111 _(gpe_get_encap_mode, "")                                               \
19112 _(lisp_gpe_add_del_iface, "up|down")                                    \
19113 _(lisp_gpe_enable_disable, "enable|disable")                            \
19114 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19115   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19116 _(show_lisp_rloc_probe_state, "")                                       \
19117 _(show_lisp_map_register_state, "")                                     \
19118 _(show_lisp_status, "")                                                 \
19119 _(lisp_get_map_request_itr_rlocs, "")                                   \
19120 _(show_lisp_pitr, "")                                                   \
19121 _(show_lisp_use_petr, "")                                               \
19122 _(show_lisp_map_request_mode, "")                                       \
19123 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19124 _(af_packet_delete, "name <host interface name>")                       \
19125 _(policer_add_del, "name <policer name> <params> [del]")                \
19126 _(policer_dump, "[name <policer name>]")                                \
19127 _(policer_classify_set_interface,                                       \
19128   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19129   "  [l2-table <nn>] [del]")                                            \
19130 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19131 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19132     "[master|slave]")                                                   \
19133 _(netmap_delete, "name <interface name>")                               \
19134 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19135 _(mpls_fib_dump, "")                                                    \
19136 _(classify_table_ids, "")                                               \
19137 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19138 _(classify_table_info, "table_id <nn>")                                 \
19139 _(classify_session_dump, "table_id <nn>")                               \
19140 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19141     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19142     "[template_interval <nn>] [udp_checksum]")                          \
19143 _(ipfix_exporter_dump, "")                                              \
19144 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19145 _(ipfix_classify_stream_dump, "")                                       \
19146 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19147 _(ipfix_classify_table_dump, "")                                        \
19148 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19149 _(sw_interface_span_dump, "")                                           \
19150 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19151 _(pg_create_interface, "if_id <nn>")                                    \
19152 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19153 _(pg_enable_disable, "[stream <id>] disable")                           \
19154 _(ip_source_and_port_range_check_add_del,                               \
19155   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19156 _(ip_source_and_port_range_check_interface_add_del,                     \
19157   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19158   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19159 _(ipsec_gre_add_del_tunnel,                                             \
19160   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19161 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19162 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19163 _(l2_interface_pbb_tag_rewrite,                                         \
19164   "<intfc> | sw_if_index <nn> \n"                                       \
19165   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19166   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19167 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19168 _(flow_classify_set_interface,                                          \
19169   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19170 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19171 _(ip_fib_dump, "")                                                      \
19172 _(ip_mfib_dump, "")                                                     \
19173 _(ip6_fib_dump, "")                                                     \
19174 _(ip6_mfib_dump, "")                                                    \
19175 _(feature_enable_disable, "arc_name <arc_name> "                        \
19176   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19177 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19178 "[disable]")                                                            \
19179 _(l2_xconnect_dump, "")                                                 \
19180 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19181 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19182 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19183
19184 /* List of command functions, CLI names map directly to functions */
19185 #define foreach_cli_function                                    \
19186 _(comment, "usage: comment <ignore-rest-of-line>")              \
19187 _(dump_interface_table, "usage: dump_interface_table")          \
19188 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19189 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19190 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19191 _(dump_stats_table, "usage: dump_stats_table")                  \
19192 _(dump_macro_table, "usage: dump_macro_table ")                 \
19193 _(dump_node_table, "usage: dump_node_table")                    \
19194 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19195 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19196 _(echo, "usage: echo <message>")                                \
19197 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19198 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19199 _(help, "usage: help")                                          \
19200 _(q, "usage: quit")                                             \
19201 _(quit, "usage: quit")                                          \
19202 _(search_node_table, "usage: search_node_table <name>...")      \
19203 _(set, "usage: set <variable-name> <value>")                    \
19204 _(script, "usage: script <file-name>")                          \
19205 _(unset, "usage: unset <variable-name>")
19206
19207 #define _(N,n)                                  \
19208     static void vl_api_##n##_t_handler_uni      \
19209     (vl_api_##n##_t * mp)                       \
19210     {                                           \
19211         vat_main_t * vam = &vat_main;           \
19212         if (vam->json_output) {                 \
19213             vl_api_##n##_t_handler_json(mp);    \
19214         } else {                                \
19215             vl_api_##n##_t_handler(mp);         \
19216         }                                       \
19217     }
19218 foreach_vpe_api_reply_msg;
19219 #if VPP_API_TEST_BUILTIN == 0
19220 foreach_standalone_reply_msg;
19221 #endif
19222 #undef _
19223
19224 void
19225 vat_api_hookup (vat_main_t * vam)
19226 {
19227 #define _(N,n)                                                  \
19228     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19229                            vl_api_##n##_t_handler_uni,          \
19230                            vl_noop_handler,                     \
19231                            vl_api_##n##_t_endian,               \
19232                            vl_api_##n##_t_print,                \
19233                            sizeof(vl_api_##n##_t), 1);
19234   foreach_vpe_api_reply_msg;
19235 #if VPP_API_TEST_BUILTIN == 0
19236   foreach_standalone_reply_msg;
19237 #endif
19238 #undef _
19239
19240 #if (VPP_API_TEST_BUILTIN==0)
19241   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19242
19243   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19244
19245   vam->function_by_name = hash_create_string (0, sizeof (uword));
19246
19247   vam->help_by_name = hash_create_string (0, sizeof (uword));
19248 #endif
19249
19250   /* API messages we can send */
19251 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19252   foreach_vpe_api_msg;
19253 #undef _
19254
19255   /* Help strings */
19256 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19257   foreach_vpe_api_msg;
19258 #undef _
19259
19260   /* CLI functions */
19261 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19262   foreach_cli_function;
19263 #undef _
19264
19265   /* Help strings */
19266 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19267   foreach_cli_function;
19268 #undef _
19269 }
19270
19271 #if VPP_API_TEST_BUILTIN
19272 static clib_error_t *
19273 vat_api_hookup_shim (vlib_main_t * vm)
19274 {
19275   vat_api_hookup (&vat_main);
19276   return 0;
19277 }
19278
19279 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19280 #endif
19281
19282 /*
19283  * fd.io coding-style-patch-verification: ON
19284  *
19285  * Local Variables:
19286  * eval: (c-set-style "gnu")
19287  * End:
19288  */