P2P Ethernet
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1287 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1288
1289 /*
1290  * Special-case: build the bridge domain table, maintain
1291  * the next bd id vbl.
1292  */
1293 static void vl_api_bridge_domain_details_t_handler
1294   (vl_api_bridge_domain_details_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1298   int i;
1299
1300   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1301          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1302
1303   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1304          ntohl (mp->bd_id), mp->learn, mp->forward,
1305          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1306
1307   if (n_sw_ifs)
1308     {
1309       vl_api_bridge_domain_sw_if_t *sw_ifs;
1310       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1311              "Interface Name");
1312
1313       sw_ifs = mp->sw_if_details;
1314       for (i = 0; i < n_sw_ifs; i++)
1315         {
1316           u8 *sw_if_name = 0;
1317           u32 sw_if_index;
1318           hash_pair_t *p;
1319
1320           sw_if_index = ntohl (sw_ifs->sw_if_index);
1321
1322           /* *INDENT-OFF* */
1323           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1324                              ({
1325                                if ((u32) p->value[0] == sw_if_index)
1326                                  {
1327                                    sw_if_name = (u8 *)(p->key);
1328                                    break;
1329                                  }
1330                              }));
1331           /* *INDENT-ON* */
1332           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1333                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1334                  "sw_if_index not found!");
1335
1336           sw_ifs++;
1337         }
1338     }
1339 }
1340
1341 static void vl_api_bridge_domain_details_t_handler_json
1342   (vl_api_bridge_domain_details_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   vat_json_node_t *node, *array = NULL;
1346   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1347
1348   if (VAT_JSON_ARRAY != vam->json_tree.type)
1349     {
1350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1351       vat_json_init_array (&vam->json_tree);
1352     }
1353   node = vat_json_array_add (&vam->json_tree);
1354
1355   vat_json_init_object (node);
1356   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1357   vat_json_object_add_uint (node, "flood", mp->flood);
1358   vat_json_object_add_uint (node, "forward", mp->forward);
1359   vat_json_object_add_uint (node, "learn", mp->learn);
1360   vat_json_object_add_uint (node, "bvi_sw_if_index",
1361                             ntohl (mp->bvi_sw_if_index));
1362   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1363   array = vat_json_object_add (node, "sw_if");
1364   vat_json_init_array (array);
1365
1366
1367
1368   if (n_sw_ifs)
1369     {
1370       vl_api_bridge_domain_sw_if_t *sw_ifs;
1371       int i;
1372
1373       sw_ifs = mp->sw_if_details;
1374       for (i = 0; i < n_sw_ifs; i++)
1375         {
1376           node = vat_json_array_add (array);
1377           vat_json_init_object (node);
1378           vat_json_object_add_uint (node, "sw_if_index",
1379                                     ntohl (sw_ifs->sw_if_index));
1380           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1381           sw_ifs++;
1382         }
1383     }
1384 }
1385
1386 static void vl_api_control_ping_reply_t_handler
1387   (vl_api_control_ping_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->result_ready = 1;
1399     }
1400 }
1401
1402 static void vl_api_control_ping_reply_t_handler_json
1403   (vl_api_control_ping_reply_t * mp)
1404 {
1405   vat_main_t *vam = &vat_main;
1406   i32 retval = ntohl (mp->retval);
1407
1408   if (VAT_JSON_NONE != vam->json_tree.type)
1409     {
1410       vat_json_print (vam->ofp, &vam->json_tree);
1411       vat_json_free (&vam->json_tree);
1412       vam->json_tree.type = VAT_JSON_NONE;
1413     }
1414   else
1415     {
1416       /* just print [] */
1417       vat_json_init_array (&vam->json_tree);
1418       vat_json_print (vam->ofp, &vam->json_tree);
1419       vam->json_tree.type = VAT_JSON_NONE;
1420     }
1421
1422   vam->retval = retval;
1423   vam->result_ready = 1;
1424 }
1425
1426 static void
1427   vl_api_bridge_domain_set_mac_age_reply_t_handler
1428   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   i32 retval = ntohl (mp->retval);
1432   if (vam->async_mode)
1433     {
1434       vam->async_errors += (retval < 0);
1435     }
1436   else
1437     {
1438       vam->retval = retval;
1439       vam->result_ready = 1;
1440     }
1441 }
1442
1443 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1444   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   vat_json_node_t node;
1448
1449   vat_json_init_object (&node);
1450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1451
1452   vat_json_print (vam->ofp, &node);
1453   vat_json_free (&node);
1454
1455   vam->retval = ntohl (mp->retval);
1456   vam->result_ready = 1;
1457 }
1458
1459 static void
1460 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   i32 retval = ntohl (mp->retval);
1464   if (vam->async_mode)
1465     {
1466       vam->async_errors += (retval < 0);
1467     }
1468   else
1469     {
1470       vam->retval = retval;
1471       vam->result_ready = 1;
1472     }
1473 }
1474
1475 static void vl_api_l2_flags_reply_t_handler_json
1476   (vl_api_l2_flags_reply_t * mp)
1477 {
1478   vat_main_t *vam = &vat_main;
1479   vat_json_node_t node;
1480
1481   vat_json_init_object (&node);
1482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1483   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1484                             ntohl (mp->resulting_feature_bitmap));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491 }
1492
1493 static void vl_api_bridge_flags_reply_t_handler
1494   (vl_api_bridge_flags_reply_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   i32 retval = ntohl (mp->retval);
1498   if (vam->async_mode)
1499     {
1500       vam->async_errors += (retval < 0);
1501     }
1502   else
1503     {
1504       vam->retval = retval;
1505       vam->result_ready = 1;
1506     }
1507 }
1508
1509 static void vl_api_bridge_flags_reply_t_handler_json
1510   (vl_api_bridge_flags_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   vat_json_node_t node;
1514
1515   vat_json_init_object (&node);
1516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1518                             ntohl (mp->resulting_feature_bitmap));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void vl_api_tap_connect_reply_t_handler
1528   (vl_api_tap_connect_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->sw_if_index = ntohl (mp->sw_if_index);
1540       vam->result_ready = 1;
1541     }
1542
1543 }
1544
1545 static void vl_api_tap_connect_reply_t_handler_json
1546   (vl_api_tap_connect_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t node;
1550
1551   vat_json_init_object (&node);
1552   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1553   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560
1561 }
1562
1563 static void
1564 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1565 {
1566   vat_main_t *vam = &vat_main;
1567   i32 retval = ntohl (mp->retval);
1568   if (vam->async_mode)
1569     {
1570       vam->async_errors += (retval < 0);
1571     }
1572   else
1573     {
1574       vam->retval = retval;
1575       vam->sw_if_index = ntohl (mp->sw_if_index);
1576       vam->result_ready = 1;
1577     }
1578 }
1579
1580 static void vl_api_tap_modify_reply_t_handler_json
1581   (vl_api_tap_modify_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595 }
1596
1597 static void
1598 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611 }
1612
1613 static void vl_api_tap_delete_reply_t_handler_json
1614   (vl_api_tap_delete_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627 }
1628
1629 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1630   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1646   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1654                             ntohl (mp->sw_if_index));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1664   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->sw_if_index = ntohl (mp->sw_if_index);
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1681   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1698   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1714   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "fwd_entry_index",
1722                             clib_net_to_host_u32 (mp->fwd_entry_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void vl_api_one_add_del_locator_set_reply_t_handler
1732   (vl_api_one_add_del_locator_set_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1748   (vl_api_one_add_del_locator_set_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1765   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->sw_if_index = ntohl (mp->sw_if_index);
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1782   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1799   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->sw_if_index = ntohl (mp->sw_if_index);
1811       vam->result_ready = 1;
1812     }
1813 }
1814
1815 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1816   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   vat_json_node_t node;
1820
1821   vat_json_init_object (&node);
1822   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1823   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1824
1825   vat_json_print (vam->ofp, &node);
1826   vat_json_free (&node);
1827
1828   vam->retval = ntohl (mp->retval);
1829   vam->result_ready = 1;
1830 }
1831
1832 static void vl_api_gre_add_del_tunnel_reply_t_handler
1833   (vl_api_gre_add_del_tunnel_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837   if (vam->async_mode)
1838     {
1839       vam->async_errors += (retval < 0);
1840     }
1841   else
1842     {
1843       vam->retval = retval;
1844       vam->sw_if_index = ntohl (mp->sw_if_index);
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1850   (vl_api_gre_add_del_tunnel_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1858
1859   vat_json_print (vam->ofp, &node);
1860   vat_json_free (&node);
1861
1862   vam->retval = ntohl (mp->retval);
1863   vam->result_ready = 1;
1864 }
1865
1866 static void vl_api_create_vhost_user_if_reply_t_handler
1867   (vl_api_create_vhost_user_if_reply_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   i32 retval = ntohl (mp->retval);
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->sw_if_index = ntohl (mp->sw_if_index);
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_create_vhost_user_if_reply_t_handler_json
1884   (vl_api_create_vhost_user_if_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1892
1893   vat_json_print (vam->ofp, &node);
1894   vat_json_free (&node);
1895
1896   vam->retval = ntohl (mp->retval);
1897   vam->result_ready = 1;
1898 }
1899
1900 static void vl_api_ip_address_details_t_handler
1901   (vl_api_ip_address_details_t * mp)
1902 {
1903   vat_main_t *vam = &vat_main;
1904   static ip_address_details_t empty_ip_address_details = { {0} };
1905   ip_address_details_t *address = NULL;
1906   ip_details_t *current_ip_details = NULL;
1907   ip_details_t *details = NULL;
1908
1909   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1910
1911   if (!details || vam->current_sw_if_index >= vec_len (details)
1912       || !details[vam->current_sw_if_index].present)
1913     {
1914       errmsg ("ip address details arrived but not stored");
1915       errmsg ("ip_dump should be called first");
1916       return;
1917     }
1918
1919   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1920
1921 #define addresses (current_ip_details->addr)
1922
1923   vec_validate_init_empty (addresses, vec_len (addresses),
1924                            empty_ip_address_details);
1925
1926   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1927
1928   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1929   address->prefix_length = mp->prefix_length;
1930 #undef addresses
1931 }
1932
1933 static void vl_api_ip_address_details_t_handler_json
1934   (vl_api_ip_address_details_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   vat_json_node_t *node = NULL;
1938   struct in6_addr ip6;
1939   struct in_addr ip4;
1940
1941   if (VAT_JSON_ARRAY != vam->json_tree.type)
1942     {
1943       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1944       vat_json_init_array (&vam->json_tree);
1945     }
1946   node = vat_json_array_add (&vam->json_tree);
1947
1948   vat_json_init_object (node);
1949   if (vam->is_ipv6)
1950     {
1951       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1952       vat_json_object_add_ip6 (node, "ip", ip6);
1953     }
1954   else
1955     {
1956       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1957       vat_json_object_add_ip4 (node, "ip", ip4);
1958     }
1959   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1960 }
1961
1962 static void
1963 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1964 {
1965   vat_main_t *vam = &vat_main;
1966   static ip_details_t empty_ip_details = { 0 };
1967   ip_details_t *ip = NULL;
1968   u32 sw_if_index = ~0;
1969
1970   sw_if_index = ntohl (mp->sw_if_index);
1971
1972   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1973                            sw_if_index, empty_ip_details);
1974
1975   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1976                          sw_if_index);
1977
1978   ip->present = 1;
1979 }
1980
1981 static void
1982 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1983 {
1984   vat_main_t *vam = &vat_main;
1985
1986   if (VAT_JSON_ARRAY != vam->json_tree.type)
1987     {
1988       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1989       vat_json_init_array (&vam->json_tree);
1990     }
1991   vat_json_array_add_uint (&vam->json_tree,
1992                            clib_net_to_host_u32 (mp->sw_if_index));
1993 }
1994
1995 static void vl_api_map_domain_details_t_handler_json
1996   (vl_api_map_domain_details_t * mp)
1997 {
1998   vat_json_node_t *node = NULL;
1999   vat_main_t *vam = &vat_main;
2000   struct in6_addr ip6;
2001   struct in_addr ip4;
2002
2003   if (VAT_JSON_ARRAY != vam->json_tree.type)
2004     {
2005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2006       vat_json_init_array (&vam->json_tree);
2007     }
2008
2009   node = vat_json_array_add (&vam->json_tree);
2010   vat_json_init_object (node);
2011
2012   vat_json_object_add_uint (node, "domain_index",
2013                             clib_net_to_host_u32 (mp->domain_index));
2014   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2015   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2016   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2017   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2018   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2019   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2020   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2021   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2022   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2023   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2024   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2025   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2026   vat_json_object_add_uint (node, "flags", mp->flags);
2027   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2028   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2029 }
2030
2031 static void vl_api_map_domain_details_t_handler
2032   (vl_api_map_domain_details_t * mp)
2033 {
2034   vat_main_t *vam = &vat_main;
2035
2036   if (mp->is_translation)
2037     {
2038       print (vam->ofp,
2039              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2040              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2041              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2042              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2043              clib_net_to_host_u32 (mp->domain_index));
2044     }
2045   else
2046     {
2047       print (vam->ofp,
2048              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2049              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2050              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2051              format_ip6_address, mp->ip6_src,
2052              clib_net_to_host_u32 (mp->domain_index));
2053     }
2054   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2055          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2056          mp->is_translation ? "map-t" : "");
2057 }
2058
2059 static void vl_api_map_rule_details_t_handler_json
2060   (vl_api_map_rule_details_t * mp)
2061 {
2062   struct in6_addr ip6;
2063   vat_json_node_t *node = NULL;
2064   vat_main_t *vam = &vat_main;
2065
2066   if (VAT_JSON_ARRAY != vam->json_tree.type)
2067     {
2068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2069       vat_json_init_array (&vam->json_tree);
2070     }
2071
2072   node = vat_json_array_add (&vam->json_tree);
2073   vat_json_init_object (node);
2074
2075   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2076   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2077   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2078 }
2079
2080 static void
2081 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2085          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2086 }
2087
2088 static void
2089 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2090 {
2091   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2092           "router_addr %U host_mac %U",
2093           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2094           format_ip4_address, &mp->host_address,
2095           format_ip4_address, &mp->router_address,
2096           format_ethernet_address, mp->host_mac);
2097 }
2098
2099 static void vl_api_dhcp_compl_event_t_handler_json
2100   (vl_api_dhcp_compl_event_t * mp)
2101 {
2102   /* JSON output not supported */
2103 }
2104
2105 static void
2106 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2107                               u32 counter)
2108 {
2109   vat_main_t *vam = &vat_main;
2110   static u64 default_counter = 0;
2111
2112   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2113                            NULL);
2114   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2115                            sw_if_index, default_counter);
2116   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2117 }
2118
2119 static void
2120 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2121                                 interface_counter_t counter)
2122 {
2123   vat_main_t *vam = &vat_main;
2124   static interface_counter_t default_counter = { 0, };
2125
2126   vec_validate_init_empty (vam->combined_interface_counters,
2127                            vnet_counter_type, NULL);
2128   vec_validate_init_empty (vam->combined_interface_counters
2129                            [vnet_counter_type], sw_if_index, default_counter);
2130   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2131 }
2132
2133 static void vl_api_vnet_interface_simple_counters_t_handler
2134   (vl_api_vnet_interface_simple_counters_t * mp)
2135 {
2136   /* not supported */
2137 }
2138
2139 static void vl_api_vnet_interface_combined_counters_t_handler
2140   (vl_api_vnet_interface_combined_counters_t * mp)
2141 {
2142   /* not supported */
2143 }
2144
2145 static void vl_api_vnet_interface_simple_counters_t_handler_json
2146   (vl_api_vnet_interface_simple_counters_t * mp)
2147 {
2148   u64 *v_packets;
2149   u64 packets;
2150   u32 count;
2151   u32 first_sw_if_index;
2152   int i;
2153
2154   count = ntohl (mp->count);
2155   first_sw_if_index = ntohl (mp->first_sw_if_index);
2156
2157   v_packets = (u64 *) & mp->data;
2158   for (i = 0; i < count; i++)
2159     {
2160       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2161       set_simple_interface_counter (mp->vnet_counter_type,
2162                                     first_sw_if_index + i, packets);
2163       v_packets++;
2164     }
2165 }
2166
2167 static void vl_api_vnet_interface_combined_counters_t_handler_json
2168   (vl_api_vnet_interface_combined_counters_t * mp)
2169 {
2170   interface_counter_t counter;
2171   vlib_counter_t *v;
2172   u32 first_sw_if_index;
2173   int i;
2174   u32 count;
2175
2176   count = ntohl (mp->count);
2177   first_sw_if_index = ntohl (mp->first_sw_if_index);
2178
2179   v = (vlib_counter_t *) & mp->data;
2180   for (i = 0; i < count; i++)
2181     {
2182       counter.packets =
2183         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2184       counter.bytes =
2185         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2186       set_combined_interface_counter (mp->vnet_counter_type,
2187                                       first_sw_if_index + i, counter);
2188       v++;
2189     }
2190 }
2191
2192 static u32
2193 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2194 {
2195   vat_main_t *vam = &vat_main;
2196   u32 i;
2197
2198   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2199     {
2200       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2201         {
2202           return i;
2203         }
2204     }
2205   return ~0;
2206 }
2207
2208 static u32
2209 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   u32 i;
2213
2214   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2215     {
2216       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2217         {
2218           return i;
2219         }
2220     }
2221   return ~0;
2222 }
2223
2224 static void vl_api_vnet_ip4_fib_counters_t_handler
2225   (vl_api_vnet_ip4_fib_counters_t * mp)
2226 {
2227   /* not supported */
2228 }
2229
2230 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2231   (vl_api_vnet_ip4_fib_counters_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   vl_api_ip4_fib_counter_t *v;
2235   ip4_fib_counter_t *counter;
2236   struct in_addr ip4;
2237   u32 vrf_id;
2238   u32 vrf_index;
2239   u32 count;
2240   int i;
2241
2242   vrf_id = ntohl (mp->vrf_id);
2243   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2244   if (~0 == vrf_index)
2245     {
2246       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2247       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2248       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2249       vec_validate (vam->ip4_fib_counters, vrf_index);
2250       vam->ip4_fib_counters[vrf_index] = NULL;
2251     }
2252
2253   vec_free (vam->ip4_fib_counters[vrf_index]);
2254   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2255   count = ntohl (mp->count);
2256   for (i = 0; i < count; i++)
2257     {
2258       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2259       counter = &vam->ip4_fib_counters[vrf_index][i];
2260       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2261       counter->address = ip4;
2262       counter->address_length = v->address_length;
2263       counter->packets = clib_net_to_host_u64 (v->packets);
2264       counter->bytes = clib_net_to_host_u64 (v->bytes);
2265       v++;
2266     }
2267 }
2268
2269 static void vl_api_vnet_ip4_nbr_counters_t_handler
2270   (vl_api_vnet_ip4_nbr_counters_t * mp)
2271 {
2272   /* not supported */
2273 }
2274
2275 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2276   (vl_api_vnet_ip4_nbr_counters_t * mp)
2277 {
2278   vat_main_t *vam = &vat_main;
2279   vl_api_ip4_nbr_counter_t *v;
2280   ip4_nbr_counter_t *counter;
2281   u32 sw_if_index;
2282   u32 count;
2283   int i;
2284
2285   sw_if_index = ntohl (mp->sw_if_index);
2286   count = ntohl (mp->count);
2287   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2288
2289   if (mp->begin)
2290     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2291
2292   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2293   for (i = 0; i < count; i++)
2294     {
2295       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2296       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2297       counter->address.s_addr = v->address;
2298       counter->packets = clib_net_to_host_u64 (v->packets);
2299       counter->bytes = clib_net_to_host_u64 (v->bytes);
2300       counter->linkt = v->link_type;
2301       v++;
2302     }
2303 }
2304
2305 static void vl_api_vnet_ip6_fib_counters_t_handler
2306   (vl_api_vnet_ip6_fib_counters_t * mp)
2307 {
2308   /* not supported */
2309 }
2310
2311 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2312   (vl_api_vnet_ip6_fib_counters_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   vl_api_ip6_fib_counter_t *v;
2316   ip6_fib_counter_t *counter;
2317   struct in6_addr ip6;
2318   u32 vrf_id;
2319   u32 vrf_index;
2320   u32 count;
2321   int i;
2322
2323   vrf_id = ntohl (mp->vrf_id);
2324   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2325   if (~0 == vrf_index)
2326     {
2327       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2328       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2329       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2330       vec_validate (vam->ip6_fib_counters, vrf_index);
2331       vam->ip6_fib_counters[vrf_index] = NULL;
2332     }
2333
2334   vec_free (vam->ip6_fib_counters[vrf_index]);
2335   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2336   count = ntohl (mp->count);
2337   for (i = 0; i < count; i++)
2338     {
2339       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2340       counter = &vam->ip6_fib_counters[vrf_index][i];
2341       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2342       counter->address = ip6;
2343       counter->address_length = v->address_length;
2344       counter->packets = clib_net_to_host_u64 (v->packets);
2345       counter->bytes = clib_net_to_host_u64 (v->bytes);
2346       v++;
2347     }
2348 }
2349
2350 static void vl_api_vnet_ip6_nbr_counters_t_handler
2351   (vl_api_vnet_ip6_nbr_counters_t * mp)
2352 {
2353   /* not supported */
2354 }
2355
2356 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2357   (vl_api_vnet_ip6_nbr_counters_t * mp)
2358 {
2359   vat_main_t *vam = &vat_main;
2360   vl_api_ip6_nbr_counter_t *v;
2361   ip6_nbr_counter_t *counter;
2362   struct in6_addr ip6;
2363   u32 sw_if_index;
2364   u32 count;
2365   int i;
2366
2367   sw_if_index = ntohl (mp->sw_if_index);
2368   count = ntohl (mp->count);
2369   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2370
2371   if (mp->begin)
2372     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2373
2374   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2375   for (i = 0; i < count; i++)
2376     {
2377       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2378       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2379       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2380       counter->address = ip6;
2381       counter->packets = clib_net_to_host_u64 (v->packets);
2382       counter->bytes = clib_net_to_host_u64 (v->bytes);
2383       v++;
2384     }
2385 }
2386
2387 static void vl_api_get_first_msg_id_reply_t_handler
2388   (vl_api_get_first_msg_id_reply_t * mp)
2389 {
2390   vat_main_t *vam = &vat_main;
2391   i32 retval = ntohl (mp->retval);
2392
2393   if (vam->async_mode)
2394     {
2395       vam->async_errors += (retval < 0);
2396     }
2397   else
2398     {
2399       vam->retval = retval;
2400       vam->result_ready = 1;
2401     }
2402   if (retval >= 0)
2403     {
2404       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2405     }
2406 }
2407
2408 static void vl_api_get_first_msg_id_reply_t_handler_json
2409   (vl_api_get_first_msg_id_reply_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   vat_json_node_t node;
2413
2414   vat_json_init_object (&node);
2415   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2416   vat_json_object_add_uint (&node, "first_msg_id",
2417                             (uint) ntohs (mp->first_msg_id));
2418
2419   vat_json_print (vam->ofp, &node);
2420   vat_json_free (&node);
2421
2422   vam->retval = ntohl (mp->retval);
2423   vam->result_ready = 1;
2424 }
2425
2426 static void vl_api_get_node_graph_reply_t_handler
2427   (vl_api_get_node_graph_reply_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   api_main_t *am = &api_main;
2431   i32 retval = ntohl (mp->retval);
2432   u8 *pvt_copy, *reply;
2433   void *oldheap;
2434   vlib_node_t *node;
2435   int i;
2436
2437   if (vam->async_mode)
2438     {
2439       vam->async_errors += (retval < 0);
2440     }
2441   else
2442     {
2443       vam->retval = retval;
2444       vam->result_ready = 1;
2445     }
2446
2447   /* "Should never happen..." */
2448   if (retval != 0)
2449     return;
2450
2451   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2452   pvt_copy = vec_dup (reply);
2453
2454   /* Toss the shared-memory original... */
2455   pthread_mutex_lock (&am->vlib_rp->mutex);
2456   oldheap = svm_push_data_heap (am->vlib_rp);
2457
2458   vec_free (reply);
2459
2460   svm_pop_heap (oldheap);
2461   pthread_mutex_unlock (&am->vlib_rp->mutex);
2462
2463   if (vam->graph_nodes)
2464     {
2465       hash_free (vam->graph_node_index_by_name);
2466
2467       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2468         {
2469           node = vam->graph_nodes[i];
2470           vec_free (node->name);
2471           vec_free (node->next_nodes);
2472           vec_free (node);
2473         }
2474       vec_free (vam->graph_nodes);
2475     }
2476
2477   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2478   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2479   vec_free (pvt_copy);
2480
2481   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2482     {
2483       node = vam->graph_nodes[i];
2484       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2485     }
2486 }
2487
2488 static void vl_api_get_node_graph_reply_t_handler_json
2489   (vl_api_get_node_graph_reply_t * mp)
2490 {
2491   vat_main_t *vam = &vat_main;
2492   api_main_t *am = &api_main;
2493   void *oldheap;
2494   vat_json_node_t node;
2495   u8 *reply;
2496
2497   /* $$$$ make this real? */
2498   vat_json_init_object (&node);
2499   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2500   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2501
2502   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2503
2504   /* Toss the shared-memory original... */
2505   pthread_mutex_lock (&am->vlib_rp->mutex);
2506   oldheap = svm_push_data_heap (am->vlib_rp);
2507
2508   vec_free (reply);
2509
2510   svm_pop_heap (oldheap);
2511   pthread_mutex_unlock (&am->vlib_rp->mutex);
2512
2513   vat_json_print (vam->ofp, &node);
2514   vat_json_free (&node);
2515
2516   vam->retval = ntohl (mp->retval);
2517   vam->result_ready = 1;
2518 }
2519
2520 static void
2521 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   u8 *s = 0;
2525
2526   if (mp->local)
2527     {
2528       s = format (s, "%=16d%=16d%=16d",
2529                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2530     }
2531   else
2532     {
2533       s = format (s, "%=16U%=16d%=16d",
2534                   mp->is_ipv6 ? format_ip6_address :
2535                   format_ip4_address,
2536                   mp->ip_address, mp->priority, mp->weight);
2537     }
2538
2539   print (vam->ofp, "%v", s);
2540   vec_free (s);
2541 }
2542
2543 static void
2544 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   vat_json_node_t *node = NULL;
2548   struct in6_addr ip6;
2549   struct in_addr ip4;
2550
2551   if (VAT_JSON_ARRAY != vam->json_tree.type)
2552     {
2553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2554       vat_json_init_array (&vam->json_tree);
2555     }
2556   node = vat_json_array_add (&vam->json_tree);
2557   vat_json_init_object (node);
2558
2559   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2560   vat_json_object_add_uint (node, "priority", mp->priority);
2561   vat_json_object_add_uint (node, "weight", mp->weight);
2562
2563   if (mp->local)
2564     vat_json_object_add_uint (node, "sw_if_index",
2565                               clib_net_to_host_u32 (mp->sw_if_index));
2566   else
2567     {
2568       if (mp->is_ipv6)
2569         {
2570           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2571           vat_json_object_add_ip6 (node, "address", ip6);
2572         }
2573       else
2574         {
2575           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2576           vat_json_object_add_ip4 (node, "address", ip4);
2577         }
2578     }
2579 }
2580
2581 static void
2582 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2583                                           mp)
2584 {
2585   vat_main_t *vam = &vat_main;
2586   u8 *ls_name = 0;
2587
2588   ls_name = format (0, "%s", mp->ls_name);
2589
2590   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2591          ls_name);
2592   vec_free (ls_name);
2593 }
2594
2595 static void
2596   vl_api_one_locator_set_details_t_handler_json
2597   (vl_api_one_locator_set_details_t * mp)
2598 {
2599   vat_main_t *vam = &vat_main;
2600   vat_json_node_t *node = 0;
2601   u8 *ls_name = 0;
2602
2603   ls_name = format (0, "%s", mp->ls_name);
2604   vec_add1 (ls_name, 0);
2605
2606   if (VAT_JSON_ARRAY != vam->json_tree.type)
2607     {
2608       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2609       vat_json_init_array (&vam->json_tree);
2610     }
2611   node = vat_json_array_add (&vam->json_tree);
2612
2613   vat_json_init_object (node);
2614   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2615   vat_json_object_add_uint (node, "ls_index",
2616                             clib_net_to_host_u32 (mp->ls_index));
2617   vec_free (ls_name);
2618 }
2619
2620 typedef struct
2621 {
2622   u32 spi;
2623   u8 si;
2624 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2625
2626 uword
2627 unformat_nsh_address (unformat_input_t * input, va_list * args)
2628 {
2629   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2630   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2631 }
2632
2633 u8 *
2634 format_nsh_address_vat (u8 * s, va_list * args)
2635 {
2636   nsh_t *a = va_arg (*args, nsh_t *);
2637   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2638 }
2639
2640 static u8 *
2641 format_lisp_flat_eid (u8 * s, va_list * args)
2642 {
2643   u32 type = va_arg (*args, u32);
2644   u8 *eid = va_arg (*args, u8 *);
2645   u32 eid_len = va_arg (*args, u32);
2646
2647   switch (type)
2648     {
2649     case 0:
2650       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2651     case 1:
2652       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2653     case 2:
2654       return format (s, "%U", format_ethernet_address, eid);
2655     case 3:
2656       return format (s, "%U", format_nsh_address_vat, eid);
2657     }
2658   return 0;
2659 }
2660
2661 static u8 *
2662 format_lisp_eid_vat (u8 * s, va_list * args)
2663 {
2664   u32 type = va_arg (*args, u32);
2665   u8 *eid = va_arg (*args, u8 *);
2666   u32 eid_len = va_arg (*args, u32);
2667   u8 *seid = va_arg (*args, u8 *);
2668   u32 seid_len = va_arg (*args, u32);
2669   u32 is_src_dst = va_arg (*args, u32);
2670
2671   if (is_src_dst)
2672     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2673
2674   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2675
2676   return s;
2677 }
2678
2679 static void
2680 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683   u8 *s = 0, *eid = 0;
2684
2685   if (~0 == mp->locator_set_index)
2686     s = format (0, "action: %d", mp->action);
2687   else
2688     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2689
2690   eid = format (0, "%U", format_lisp_eid_vat,
2691                 mp->eid_type,
2692                 mp->eid,
2693                 mp->eid_prefix_len,
2694                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2695   vec_add1 (eid, 0);
2696
2697   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2698          clib_net_to_host_u32 (mp->vni),
2699          eid,
2700          mp->is_local ? "local" : "remote",
2701          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2702          clib_net_to_host_u16 (mp->key_id), mp->key);
2703
2704   vec_free (s);
2705   vec_free (eid);
2706 }
2707
2708 static void
2709 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2710                                              * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713   vat_json_node_t *node = 0;
2714   u8 *eid = 0;
2715
2716   if (VAT_JSON_ARRAY != vam->json_tree.type)
2717     {
2718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2719       vat_json_init_array (&vam->json_tree);
2720     }
2721   node = vat_json_array_add (&vam->json_tree);
2722
2723   vat_json_init_object (node);
2724   if (~0 == mp->locator_set_index)
2725     vat_json_object_add_uint (node, "action", mp->action);
2726   else
2727     vat_json_object_add_uint (node, "locator_set_index",
2728                               clib_net_to_host_u32 (mp->locator_set_index));
2729
2730   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2731   if (mp->eid_type == 3)
2732     {
2733       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2734       vat_json_init_object (nsh_json);
2735       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2736       vat_json_object_add_uint (nsh_json, "spi",
2737                                 clib_net_to_host_u32 (nsh->spi));
2738       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2739     }
2740   else
2741     {
2742       eid = format (0, "%U", format_lisp_eid_vat,
2743                     mp->eid_type,
2744                     mp->eid,
2745                     mp->eid_prefix_len,
2746                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2747       vec_add1 (eid, 0);
2748       vat_json_object_add_string_copy (node, "eid", eid);
2749       vec_free (eid);
2750     }
2751   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2752   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2753   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2754
2755   if (mp->key_id)
2756     {
2757       vat_json_object_add_uint (node, "key_id",
2758                                 clib_net_to_host_u16 (mp->key_id));
2759       vat_json_object_add_string_copy (node, "key", mp->key);
2760     }
2761 }
2762
2763 static void
2764 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   u8 *seid = 0, *deid = 0;
2768   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2769
2770   deid = format (0, "%U", format_lisp_eid_vat,
2771                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2772
2773   seid = format (0, "%U", format_lisp_eid_vat,
2774                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2775
2776   vec_add1 (deid, 0);
2777   vec_add1 (seid, 0);
2778
2779   if (mp->is_ip4)
2780     format_ip_address_fcn = format_ip4_address;
2781   else
2782     format_ip_address_fcn = format_ip6_address;
2783
2784
2785   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2786          clib_net_to_host_u32 (mp->vni),
2787          seid, deid,
2788          format_ip_address_fcn, mp->lloc,
2789          format_ip_address_fcn, mp->rloc,
2790          clib_net_to_host_u32 (mp->pkt_count),
2791          clib_net_to_host_u32 (mp->bytes));
2792
2793   vec_free (deid);
2794   vec_free (seid);
2795 }
2796
2797 static void
2798 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2799 {
2800   struct in6_addr ip6;
2801   struct in_addr ip4;
2802   vat_main_t *vam = &vat_main;
2803   vat_json_node_t *node = 0;
2804   u8 *deid = 0, *seid = 0;
2805
2806   if (VAT_JSON_ARRAY != vam->json_tree.type)
2807     {
2808       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2809       vat_json_init_array (&vam->json_tree);
2810     }
2811   node = vat_json_array_add (&vam->json_tree);
2812
2813   vat_json_init_object (node);
2814   deid = format (0, "%U", format_lisp_eid_vat,
2815                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2816
2817   seid = format (0, "%U", format_lisp_eid_vat,
2818                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2819
2820   vec_add1 (deid, 0);
2821   vec_add1 (seid, 0);
2822
2823   vat_json_object_add_string_copy (node, "seid", seid);
2824   vat_json_object_add_string_copy (node, "deid", deid);
2825   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2826
2827   if (mp->is_ip4)
2828     {
2829       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2830       vat_json_object_add_ip4 (node, "lloc", ip4);
2831       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2832       vat_json_object_add_ip4 (node, "rloc", ip4);
2833     }
2834   else
2835     {
2836       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2837       vat_json_object_add_ip6 (node, "lloc", ip6);
2838       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2839       vat_json_object_add_ip6 (node, "rloc", ip6);
2840     }
2841   vat_json_object_add_uint (node, "pkt_count",
2842                             clib_net_to_host_u32 (mp->pkt_count));
2843   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2844
2845   vec_free (deid);
2846   vec_free (seid);
2847 }
2848
2849 static void
2850   vl_api_one_eid_table_map_details_t_handler
2851   (vl_api_one_eid_table_map_details_t * mp)
2852 {
2853   vat_main_t *vam = &vat_main;
2854
2855   u8 *line = format (0, "%=10d%=10d",
2856                      clib_net_to_host_u32 (mp->vni),
2857                      clib_net_to_host_u32 (mp->dp_table));
2858   print (vam->ofp, "%v", line);
2859   vec_free (line);
2860 }
2861
2862 static void
2863   vl_api_one_eid_table_map_details_t_handler_json
2864   (vl_api_one_eid_table_map_details_t * mp)
2865 {
2866   vat_main_t *vam = &vat_main;
2867   vat_json_node_t *node = NULL;
2868
2869   if (VAT_JSON_ARRAY != vam->json_tree.type)
2870     {
2871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2872       vat_json_init_array (&vam->json_tree);
2873     }
2874   node = vat_json_array_add (&vam->json_tree);
2875   vat_json_init_object (node);
2876   vat_json_object_add_uint (node, "dp_table",
2877                             clib_net_to_host_u32 (mp->dp_table));
2878   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2879 }
2880
2881 static void
2882   vl_api_one_eid_table_vni_details_t_handler
2883   (vl_api_one_eid_table_vni_details_t * mp)
2884 {
2885   vat_main_t *vam = &vat_main;
2886
2887   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2888   print (vam->ofp, "%v", line);
2889   vec_free (line);
2890 }
2891
2892 static void
2893   vl_api_one_eid_table_vni_details_t_handler_json
2894   (vl_api_one_eid_table_vni_details_t * mp)
2895 {
2896   vat_main_t *vam = &vat_main;
2897   vat_json_node_t *node = NULL;
2898
2899   if (VAT_JSON_ARRAY != vam->json_tree.type)
2900     {
2901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2902       vat_json_init_array (&vam->json_tree);
2903     }
2904   node = vat_json_array_add (&vam->json_tree);
2905   vat_json_init_object (node);
2906   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2907 }
2908
2909 static void
2910   vl_api_show_one_map_register_state_reply_t_handler
2911   (vl_api_show_one_map_register_state_reply_t * mp)
2912 {
2913   vat_main_t *vam = &vat_main;
2914   int retval = clib_net_to_host_u32 (mp->retval);
2915
2916   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2917
2918   vam->retval = retval;
2919   vam->result_ready = 1;
2920 }
2921
2922 static void
2923   vl_api_show_one_map_register_state_reply_t_handler_json
2924   (vl_api_show_one_map_register_state_reply_t * mp)
2925 {
2926   vat_main_t *vam = &vat_main;
2927   vat_json_node_t _node, *node = &_node;
2928   int retval = clib_net_to_host_u32 (mp->retval);
2929
2930   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2931
2932   vat_json_init_object (node);
2933   vat_json_object_add_string_copy (node, "state", s);
2934
2935   vat_json_print (vam->ofp, node);
2936   vat_json_free (node);
2937
2938   vam->retval = retval;
2939   vam->result_ready = 1;
2940   vec_free (s);
2941 }
2942
2943 static void
2944   vl_api_show_one_rloc_probe_state_reply_t_handler
2945   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2946 {
2947   vat_main_t *vam = &vat_main;
2948   int retval = clib_net_to_host_u32 (mp->retval);
2949
2950   if (retval)
2951     goto end;
2952
2953   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2954 end:
2955   vam->retval = retval;
2956   vam->result_ready = 1;
2957 }
2958
2959 static void
2960   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2961   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2962 {
2963   vat_main_t *vam = &vat_main;
2964   vat_json_node_t _node, *node = &_node;
2965   int retval = clib_net_to_host_u32 (mp->retval);
2966
2967   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2968   vat_json_init_object (node);
2969   vat_json_object_add_string_copy (node, "state", s);
2970
2971   vat_json_print (vam->ofp, node);
2972   vat_json_free (node);
2973
2974   vam->retval = retval;
2975   vam->result_ready = 1;
2976   vec_free (s);
2977 }
2978
2979 static void
2980   vl_api_show_one_stats_enable_disable_reply_t_handler
2981   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2982 {
2983   vat_main_t *vam = &vat_main;
2984   int retval = clib_net_to_host_u32 (mp->retval);
2985
2986   if (retval)
2987     goto end;
2988
2989   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2990 end:
2991   vam->retval = retval;
2992   vam->result_ready = 1;
2993 }
2994
2995 static void
2996   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2997   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   vat_json_node_t _node, *node = &_node;
3001   int retval = clib_net_to_host_u32 (mp->retval);
3002
3003   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3004   vat_json_init_object (node);
3005   vat_json_object_add_string_copy (node, "state", s);
3006
3007   vat_json_print (vam->ofp, node);
3008   vat_json_free (node);
3009
3010   vam->retval = retval;
3011   vam->result_ready = 1;
3012   vec_free (s);
3013 }
3014
3015 static void
3016 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3017 {
3018   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3019   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3020   e->vni = clib_net_to_host_u32 (e->vni);
3021 }
3022
3023 static void
3024   gpe_fwd_entries_get_reply_t_net_to_host
3025   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3026 {
3027   u32 i;
3028
3029   mp->count = clib_net_to_host_u32 (mp->count);
3030   for (i = 0; i < mp->count; i++)
3031     {
3032       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3033     }
3034 }
3035
3036 static u8 *
3037 format_gpe_encap_mode (u8 * s, va_list * args)
3038 {
3039   u32 mode = va_arg (*args, u32);
3040
3041   switch (mode)
3042     {
3043     case 0:
3044       return format (s, "lisp");
3045     case 1:
3046       return format (s, "vxlan");
3047     }
3048   return 0;
3049 }
3050
3051 static void
3052   vl_api_gpe_get_encap_mode_reply_t_handler
3053   (vl_api_gpe_get_encap_mode_reply_t * mp)
3054 {
3055   vat_main_t *vam = &vat_main;
3056
3057   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3058   vam->retval = ntohl (mp->retval);
3059   vam->result_ready = 1;
3060 }
3061
3062 static void
3063   vl_api_gpe_get_encap_mode_reply_t_handler_json
3064   (vl_api_gpe_get_encap_mode_reply_t * mp)
3065 {
3066   vat_main_t *vam = &vat_main;
3067   vat_json_node_t node;
3068
3069   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3070   vec_add1 (encap_mode, 0);
3071
3072   vat_json_init_object (&node);
3073   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3074
3075   vec_free (encap_mode);
3076   vat_json_print (vam->ofp, &node);
3077   vat_json_free (&node);
3078
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_gpe_fwd_entry_path_details_t_handler
3085   (vl_api_gpe_fwd_entry_path_details_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3089
3090   if (mp->lcl_loc.is_ip4)
3091     format_ip_address_fcn = format_ip4_address;
3092   else
3093     format_ip_address_fcn = format_ip6_address;
3094
3095   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3096          format_ip_address_fcn, &mp->lcl_loc,
3097          format_ip_address_fcn, &mp->rmt_loc);
3098 }
3099
3100 static void
3101 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3102 {
3103   struct in6_addr ip6;
3104   struct in_addr ip4;
3105
3106   if (loc->is_ip4)
3107     {
3108       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3109       vat_json_object_add_ip4 (n, "address", ip4);
3110     }
3111   else
3112     {
3113       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3114       vat_json_object_add_ip6 (n, "address", ip6);
3115     }
3116   vat_json_object_add_uint (n, "weight", loc->weight);
3117 }
3118
3119 static void
3120   vl_api_gpe_fwd_entry_path_details_t_handler_json
3121   (vl_api_gpe_fwd_entry_path_details_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   vat_json_node_t *node = NULL;
3125   vat_json_node_t *loc_node;
3126
3127   if (VAT_JSON_ARRAY != vam->json_tree.type)
3128     {
3129       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3130       vat_json_init_array (&vam->json_tree);
3131     }
3132   node = vat_json_array_add (&vam->json_tree);
3133   vat_json_init_object (node);
3134
3135   loc_node = vat_json_object_add (node, "local_locator");
3136   vat_json_init_object (loc_node);
3137   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3138
3139   loc_node = vat_json_object_add (node, "remote_locator");
3140   vat_json_init_object (loc_node);
3141   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3142 }
3143
3144 static void
3145   vl_api_gpe_fwd_entries_get_reply_t_handler
3146   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3147 {
3148   vat_main_t *vam = &vat_main;
3149   u32 i;
3150   int retval = clib_net_to_host_u32 (mp->retval);
3151   vl_api_gpe_fwd_entry_t *e;
3152
3153   if (retval)
3154     goto end;
3155
3156   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3157
3158   for (i = 0; i < mp->count; i++)
3159     {
3160       e = &mp->entries[i];
3161       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3162              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3163              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3164     }
3165
3166 end:
3167   vam->retval = retval;
3168   vam->result_ready = 1;
3169 }
3170
3171 static void
3172   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3173   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3174 {
3175   u8 *s = 0;
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *e = 0, root;
3178   u32 i;
3179   int retval = clib_net_to_host_u32 (mp->retval);
3180   vl_api_gpe_fwd_entry_t *fwd;
3181
3182   if (retval)
3183     goto end;
3184
3185   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3186   vat_json_init_array (&root);
3187
3188   for (i = 0; i < mp->count; i++)
3189     {
3190       e = vat_json_array_add (&root);
3191       fwd = &mp->entries[i];
3192
3193       vat_json_init_object (e);
3194       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3195       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3196       vat_json_object_add_int (e, "vni", fwd->vni);
3197       vat_json_object_add_int (e, "action", fwd->action);
3198
3199       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3200                   fwd->leid_prefix_len);
3201       vec_add1 (s, 0);
3202       vat_json_object_add_string_copy (e, "leid", s);
3203       vec_free (s);
3204
3205       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3206                   fwd->reid_prefix_len);
3207       vec_add1 (s, 0);
3208       vat_json_object_add_string_copy (e, "reid", s);
3209       vec_free (s);
3210     }
3211
3212   vat_json_print (vam->ofp, &root);
3213   vat_json_free (&root);
3214
3215 end:
3216   vam->retval = retval;
3217   vam->result_ready = 1;
3218 }
3219
3220 static void
3221   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3222   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3223 {
3224   vat_main_t *vam = &vat_main;
3225   u32 i, n;
3226   int retval = clib_net_to_host_u32 (mp->retval);
3227   vl_api_gpe_native_fwd_rpath_t *r;
3228
3229   if (retval)
3230     goto end;
3231
3232   n = clib_net_to_host_u32 (mp->count);
3233
3234   for (i = 0; i < n; i++)
3235     {
3236       r = &mp->entries[i];
3237       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3238              clib_net_to_host_u32 (r->fib_index),
3239              clib_net_to_host_u32 (r->nh_sw_if_index),
3240              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3241     }
3242
3243 end:
3244   vam->retval = retval;
3245   vam->result_ready = 1;
3246 }
3247
3248 static void
3249   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3250   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   vat_json_node_t root, *e;
3254   u32 i, n;
3255   int retval = clib_net_to_host_u32 (mp->retval);
3256   vl_api_gpe_native_fwd_rpath_t *r;
3257   u8 *s;
3258
3259   if (retval)
3260     goto end;
3261
3262   n = clib_net_to_host_u32 (mp->count);
3263   vat_json_init_array (&root);
3264
3265   for (i = 0; i < n; i++)
3266     {
3267       e = vat_json_array_add (&root);
3268       vat_json_init_object (e);
3269       r = &mp->entries[i];
3270       s =
3271         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3272                 r->nh_addr);
3273       vec_add1 (s, 0);
3274       vat_json_object_add_string_copy (e, "ip4", s);
3275       vec_free (s);
3276
3277       vat_json_object_add_uint (e, "fib_index",
3278                                 clib_net_to_host_u32 (r->fib_index));
3279       vat_json_object_add_uint (e, "nh_sw_if_index",
3280                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3281     }
3282
3283   vat_json_print (vam->ofp, &root);
3284   vat_json_free (&root);
3285
3286 end:
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289 }
3290
3291 static void
3292   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3293   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   u32 i, n;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   if (retval)
3300     goto end;
3301
3302   n = clib_net_to_host_u32 (mp->count);
3303
3304   for (i = 0; i < n; i++)
3305     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3306
3307 end:
3308   vam->retval = retval;
3309   vam->result_ready = 1;
3310 }
3311
3312 static void
3313   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3314   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3315 {
3316   vat_main_t *vam = &vat_main;
3317   vat_json_node_t root;
3318   u32 i, n;
3319   int retval = clib_net_to_host_u32 (mp->retval);
3320
3321   if (retval)
3322     goto end;
3323
3324   n = clib_net_to_host_u32 (mp->count);
3325   vat_json_init_array (&root);
3326
3327   for (i = 0; i < n; i++)
3328     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3329
3330   vat_json_print (vam->ofp, &root);
3331   vat_json_free (&root);
3332
3333 end:
3334   vam->retval = retval;
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_one_l2_arp_entries_get_reply_t_handler
3340   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   u32 i, n;
3344   int retval = clib_net_to_host_u32 (mp->retval);
3345
3346   if (retval)
3347     goto end;
3348
3349   n = clib_net_to_host_u32 (mp->count);
3350
3351   for (i = 0; i < n; i++)
3352     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3353            format_ethernet_address, mp->entries[i].mac);
3354
3355 end:
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3362   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3363 {
3364   u8 *s = 0;
3365   vat_main_t *vam = &vat_main;
3366   vat_json_node_t *e = 0, root;
3367   u32 i, n;
3368   int retval = clib_net_to_host_u32 (mp->retval);
3369   vl_api_one_l2_arp_entry_t *arp_entry;
3370
3371   if (retval)
3372     goto end;
3373
3374   n = clib_net_to_host_u32 (mp->count);
3375   vat_json_init_array (&root);
3376
3377   for (i = 0; i < n; i++)
3378     {
3379       e = vat_json_array_add (&root);
3380       arp_entry = &mp->entries[i];
3381
3382       vat_json_init_object (e);
3383       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3384       vec_add1 (s, 0);
3385
3386       vat_json_object_add_string_copy (e, "mac", s);
3387       vec_free (s);
3388
3389       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3390       vec_add1 (s, 0);
3391       vat_json_object_add_string_copy (e, "ip4", s);
3392       vec_free (s);
3393     }
3394
3395   vat_json_print (vam->ofp, &root);
3396   vat_json_free (&root);
3397
3398 end:
3399   vam->retval = retval;
3400   vam->result_ready = 1;
3401 }
3402
3403 static void
3404   vl_api_one_l2_arp_bd_get_reply_t_handler
3405   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3406 {
3407   vat_main_t *vam = &vat_main;
3408   u32 i, n;
3409   int retval = clib_net_to_host_u32 (mp->retval);
3410
3411   if (retval)
3412     goto end;
3413
3414   n = clib_net_to_host_u32 (mp->count);
3415
3416   for (i = 0; i < n; i++)
3417     {
3418       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3419     }
3420
3421 end:
3422   vam->retval = retval;
3423   vam->result_ready = 1;
3424 }
3425
3426 static void
3427   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3428   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   vat_json_node_t root;
3432   u32 i, n;
3433   int retval = clib_net_to_host_u32 (mp->retval);
3434
3435   if (retval)
3436     goto end;
3437
3438   n = clib_net_to_host_u32 (mp->count);
3439   vat_json_init_array (&root);
3440
3441   for (i = 0; i < n; i++)
3442     {
3443       vat_json_array_add_uint (&root,
3444                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3445     }
3446
3447   vat_json_print (vam->ofp, &root);
3448   vat_json_free (&root);
3449
3450 end:
3451   vam->retval = retval;
3452   vam->result_ready = 1;
3453 }
3454
3455 static void
3456   vl_api_one_adjacencies_get_reply_t_handler
3457   (vl_api_one_adjacencies_get_reply_t * mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460   u32 i, n;
3461   int retval = clib_net_to_host_u32 (mp->retval);
3462   vl_api_one_adjacency_t *a;
3463
3464   if (retval)
3465     goto end;
3466
3467   n = clib_net_to_host_u32 (mp->count);
3468
3469   for (i = 0; i < n; i++)
3470     {
3471       a = &mp->adjacencies[i];
3472       print (vam->ofp, "%U %40U",
3473              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3474              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3475     }
3476
3477 end:
3478   vam->retval = retval;
3479   vam->result_ready = 1;
3480 }
3481
3482 static void
3483   vl_api_one_adjacencies_get_reply_t_handler_json
3484   (vl_api_one_adjacencies_get_reply_t * mp)
3485 {
3486   u8 *s = 0;
3487   vat_main_t *vam = &vat_main;
3488   vat_json_node_t *e = 0, root;
3489   u32 i, n;
3490   int retval = clib_net_to_host_u32 (mp->retval);
3491   vl_api_one_adjacency_t *a;
3492
3493   if (retval)
3494     goto end;
3495
3496   n = clib_net_to_host_u32 (mp->count);
3497   vat_json_init_array (&root);
3498
3499   for (i = 0; i < n; i++)
3500     {
3501       e = vat_json_array_add (&root);
3502       a = &mp->adjacencies[i];
3503
3504       vat_json_init_object (e);
3505       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3506                   a->leid_prefix_len);
3507       vec_add1 (s, 0);
3508       vat_json_object_add_string_copy (e, "leid", s);
3509       vec_free (s);
3510
3511       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3512                   a->reid_prefix_len);
3513       vec_add1 (s, 0);
3514       vat_json_object_add_string_copy (e, "reid", s);
3515       vec_free (s);
3516     }
3517
3518   vat_json_print (vam->ofp, &root);
3519   vat_json_free (&root);
3520
3521 end:
3522   vam->retval = retval;
3523   vam->result_ready = 1;
3524 }
3525
3526 static void
3527 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3528 {
3529   vat_main_t *vam = &vat_main;
3530
3531   print (vam->ofp, "%=20U",
3532          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3533          mp->ip_address);
3534 }
3535
3536 static void
3537   vl_api_one_map_server_details_t_handler_json
3538   (vl_api_one_map_server_details_t * mp)
3539 {
3540   vat_main_t *vam = &vat_main;
3541   vat_json_node_t *node = NULL;
3542   struct in6_addr ip6;
3543   struct in_addr ip4;
3544
3545   if (VAT_JSON_ARRAY != vam->json_tree.type)
3546     {
3547       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3548       vat_json_init_array (&vam->json_tree);
3549     }
3550   node = vat_json_array_add (&vam->json_tree);
3551
3552   vat_json_init_object (node);
3553   if (mp->is_ipv6)
3554     {
3555       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3556       vat_json_object_add_ip6 (node, "map-server", ip6);
3557     }
3558   else
3559     {
3560       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3561       vat_json_object_add_ip4 (node, "map-server", ip4);
3562     }
3563 }
3564
3565 static void
3566 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3567                                            * mp)
3568 {
3569   vat_main_t *vam = &vat_main;
3570
3571   print (vam->ofp, "%=20U",
3572          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3573          mp->ip_address);
3574 }
3575
3576 static void
3577   vl_api_one_map_resolver_details_t_handler_json
3578   (vl_api_one_map_resolver_details_t * mp)
3579 {
3580   vat_main_t *vam = &vat_main;
3581   vat_json_node_t *node = NULL;
3582   struct in6_addr ip6;
3583   struct in_addr ip4;
3584
3585   if (VAT_JSON_ARRAY != vam->json_tree.type)
3586     {
3587       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3588       vat_json_init_array (&vam->json_tree);
3589     }
3590   node = vat_json_array_add (&vam->json_tree);
3591
3592   vat_json_init_object (node);
3593   if (mp->is_ipv6)
3594     {
3595       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3596       vat_json_object_add_ip6 (node, "map resolver", ip6);
3597     }
3598   else
3599     {
3600       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3601       vat_json_object_add_ip4 (node, "map resolver", ip4);
3602     }
3603 }
3604
3605 static void
3606 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3607 {
3608   vat_main_t *vam = &vat_main;
3609   i32 retval = ntohl (mp->retval);
3610
3611   if (0 <= retval)
3612     {
3613       print (vam->ofp, "feature: %s\ngpe: %s",
3614              mp->feature_status ? "enabled" : "disabled",
3615              mp->gpe_status ? "enabled" : "disabled");
3616     }
3617
3618   vam->retval = retval;
3619   vam->result_ready = 1;
3620 }
3621
3622 static void
3623   vl_api_show_one_status_reply_t_handler_json
3624   (vl_api_show_one_status_reply_t * mp)
3625 {
3626   vat_main_t *vam = &vat_main;
3627   vat_json_node_t node;
3628   u8 *gpe_status = NULL;
3629   u8 *feature_status = NULL;
3630
3631   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3632   feature_status = format (0, "%s",
3633                            mp->feature_status ? "enabled" : "disabled");
3634   vec_add1 (gpe_status, 0);
3635   vec_add1 (feature_status, 0);
3636
3637   vat_json_init_object (&node);
3638   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3639   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3640
3641   vec_free (gpe_status);
3642   vec_free (feature_status);
3643
3644   vat_json_print (vam->ofp, &node);
3645   vat_json_free (&node);
3646
3647   vam->retval = ntohl (mp->retval);
3648   vam->result_ready = 1;
3649 }
3650
3651 static void
3652   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3653   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3654 {
3655   vat_main_t *vam = &vat_main;
3656   i32 retval = ntohl (mp->retval);
3657
3658   if (retval >= 0)
3659     {
3660       print (vam->ofp, "%=20s", mp->locator_set_name);
3661     }
3662
3663   vam->retval = retval;
3664   vam->result_ready = 1;
3665 }
3666
3667 static void
3668   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3669   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3670 {
3671   vat_main_t *vam = &vat_main;
3672   vat_json_node_t *node = NULL;
3673
3674   if (VAT_JSON_ARRAY != vam->json_tree.type)
3675     {
3676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3677       vat_json_init_array (&vam->json_tree);
3678     }
3679   node = vat_json_array_add (&vam->json_tree);
3680
3681   vat_json_init_object (node);
3682   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3683
3684   vat_json_print (vam->ofp, node);
3685   vat_json_free (node);
3686
3687   vam->retval = ntohl (mp->retval);
3688   vam->result_ready = 1;
3689 }
3690
3691 static u8 *
3692 format_lisp_map_request_mode (u8 * s, va_list * args)
3693 {
3694   u32 mode = va_arg (*args, u32);
3695
3696   switch (mode)
3697     {
3698     case 0:
3699       return format (0, "dst-only");
3700     case 1:
3701       return format (0, "src-dst");
3702     }
3703   return 0;
3704 }
3705
3706 static void
3707   vl_api_show_one_map_request_mode_reply_t_handler
3708   (vl_api_show_one_map_request_mode_reply_t * mp)
3709 {
3710   vat_main_t *vam = &vat_main;
3711   i32 retval = ntohl (mp->retval);
3712
3713   if (0 <= retval)
3714     {
3715       u32 mode = mp->mode;
3716       print (vam->ofp, "map_request_mode: %U",
3717              format_lisp_map_request_mode, mode);
3718     }
3719
3720   vam->retval = retval;
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_show_one_map_request_mode_reply_t_handler_json
3726   (vl_api_show_one_map_request_mode_reply_t * mp)
3727 {
3728   vat_main_t *vam = &vat_main;
3729   vat_json_node_t node;
3730   u8 *s = 0;
3731   u32 mode;
3732
3733   mode = mp->mode;
3734   s = format (0, "%U", format_lisp_map_request_mode, mode);
3735   vec_add1 (s, 0);
3736
3737   vat_json_init_object (&node);
3738   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3739   vat_json_print (vam->ofp, &node);
3740   vat_json_free (&node);
3741
3742   vec_free (s);
3743   vam->retval = ntohl (mp->retval);
3744   vam->result_ready = 1;
3745 }
3746
3747 static void
3748   vl_api_show_one_use_petr_reply_t_handler
3749   (vl_api_show_one_use_petr_reply_t * mp)
3750 {
3751   vat_main_t *vam = &vat_main;
3752   i32 retval = ntohl (mp->retval);
3753
3754   if (0 <= retval)
3755     {
3756       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3757       if (mp->status)
3758         {
3759           print (vam->ofp, "Proxy-ETR address; %U",
3760                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3761                  mp->address);
3762         }
3763     }
3764
3765   vam->retval = retval;
3766   vam->result_ready = 1;
3767 }
3768
3769 static void
3770   vl_api_show_one_use_petr_reply_t_handler_json
3771   (vl_api_show_one_use_petr_reply_t * mp)
3772 {
3773   vat_main_t *vam = &vat_main;
3774   vat_json_node_t node;
3775   u8 *status = 0;
3776   struct in_addr ip4;
3777   struct in6_addr ip6;
3778
3779   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3780   vec_add1 (status, 0);
3781
3782   vat_json_init_object (&node);
3783   vat_json_object_add_string_copy (&node, "status", status);
3784   if (mp->status)
3785     {
3786       if (mp->is_ip4)
3787         {
3788           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3789           vat_json_object_add_ip6 (&node, "address", ip6);
3790         }
3791       else
3792         {
3793           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3794           vat_json_object_add_ip4 (&node, "address", ip4);
3795         }
3796     }
3797
3798   vec_free (status);
3799
3800   vat_json_print (vam->ofp, &node);
3801   vat_json_free (&node);
3802
3803   vam->retval = ntohl (mp->retval);
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_show_one_nsh_mapping_reply_t_handler
3809   (vl_api_show_one_nsh_mapping_reply_t * mp)
3810 {
3811   vat_main_t *vam = &vat_main;
3812   i32 retval = ntohl (mp->retval);
3813
3814   if (0 <= retval)
3815     {
3816       print (vam->ofp, "%-20s%-16s",
3817              mp->is_set ? "set" : "not-set",
3818              mp->is_set ? (char *) mp->locator_set_name : "");
3819     }
3820
3821   vam->retval = retval;
3822   vam->result_ready = 1;
3823 }
3824
3825 static void
3826   vl_api_show_one_nsh_mapping_reply_t_handler_json
3827   (vl_api_show_one_nsh_mapping_reply_t * mp)
3828 {
3829   vat_main_t *vam = &vat_main;
3830   vat_json_node_t node;
3831   u8 *status = 0;
3832
3833   status = format (0, "%s", mp->is_set ? "yes" : "no");
3834   vec_add1 (status, 0);
3835
3836   vat_json_init_object (&node);
3837   vat_json_object_add_string_copy (&node, "is_set", status);
3838   if (mp->is_set)
3839     {
3840       vat_json_object_add_string_copy (&node, "locator_set",
3841                                        mp->locator_set_name);
3842     }
3843
3844   vec_free (status);
3845
3846   vat_json_print (vam->ofp, &node);
3847   vat_json_free (&node);
3848
3849   vam->retval = ntohl (mp->retval);
3850   vam->result_ready = 1;
3851 }
3852
3853 static void
3854 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3855 {
3856   vat_main_t *vam = &vat_main;
3857   i32 retval = ntohl (mp->retval);
3858
3859   if (0 <= retval)
3860     {
3861       print (vam->ofp, "%-20s%-16s",
3862              mp->status ? "enabled" : "disabled",
3863              mp->status ? (char *) mp->locator_set_name : "");
3864     }
3865
3866   vam->retval = retval;
3867   vam->result_ready = 1;
3868 }
3869
3870 static void
3871 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3872 {
3873   vat_main_t *vam = &vat_main;
3874   vat_json_node_t node;
3875   u8 *status = 0;
3876
3877   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3878   vec_add1 (status, 0);
3879
3880   vat_json_init_object (&node);
3881   vat_json_object_add_string_copy (&node, "status", status);
3882   if (mp->status)
3883     {
3884       vat_json_object_add_string_copy (&node, "locator_set",
3885                                        mp->locator_set_name);
3886     }
3887
3888   vec_free (status);
3889
3890   vat_json_print (vam->ofp, &node);
3891   vat_json_free (&node);
3892
3893   vam->retval = ntohl (mp->retval);
3894   vam->result_ready = 1;
3895 }
3896
3897 static u8 *
3898 format_policer_type (u8 * s, va_list * va)
3899 {
3900   u32 i = va_arg (*va, u32);
3901
3902   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3903     s = format (s, "1r2c");
3904   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3905     s = format (s, "1r3c");
3906   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3907     s = format (s, "2r3c-2698");
3908   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3909     s = format (s, "2r3c-4115");
3910   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3911     s = format (s, "2r3c-mef5cf1");
3912   else
3913     s = format (s, "ILLEGAL");
3914   return s;
3915 }
3916
3917 static u8 *
3918 format_policer_rate_type (u8 * s, va_list * va)
3919 {
3920   u32 i = va_arg (*va, u32);
3921
3922   if (i == SSE2_QOS_RATE_KBPS)
3923     s = format (s, "kbps");
3924   else if (i == SSE2_QOS_RATE_PPS)
3925     s = format (s, "pps");
3926   else
3927     s = format (s, "ILLEGAL");
3928   return s;
3929 }
3930
3931 static u8 *
3932 format_policer_round_type (u8 * s, va_list * va)
3933 {
3934   u32 i = va_arg (*va, u32);
3935
3936   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3937     s = format (s, "closest");
3938   else if (i == SSE2_QOS_ROUND_TO_UP)
3939     s = format (s, "up");
3940   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3941     s = format (s, "down");
3942   else
3943     s = format (s, "ILLEGAL");
3944   return s;
3945 }
3946
3947 static u8 *
3948 format_policer_action_type (u8 * s, va_list * va)
3949 {
3950   u32 i = va_arg (*va, u32);
3951
3952   if (i == SSE2_QOS_ACTION_DROP)
3953     s = format (s, "drop");
3954   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3955     s = format (s, "transmit");
3956   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3957     s = format (s, "mark-and-transmit");
3958   else
3959     s = format (s, "ILLEGAL");
3960   return s;
3961 }
3962
3963 static u8 *
3964 format_dscp (u8 * s, va_list * va)
3965 {
3966   u32 i = va_arg (*va, u32);
3967   char *t = 0;
3968
3969   switch (i)
3970     {
3971 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3972       foreach_vnet_dscp
3973 #undef _
3974     default:
3975       return format (s, "ILLEGAL");
3976     }
3977   s = format (s, "%s", t);
3978   return s;
3979 }
3980
3981 static void
3982 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3983 {
3984   vat_main_t *vam = &vat_main;
3985   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3986
3987   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3988     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3989   else
3990     conform_dscp_str = format (0, "");
3991
3992   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3993     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3994   else
3995     exceed_dscp_str = format (0, "");
3996
3997   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3998     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3999   else
4000     violate_dscp_str = format (0, "");
4001
4002   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4003          "rate type %U, round type %U, %s rate, %s color-aware, "
4004          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4005          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4006          "conform action %U%s, exceed action %U%s, violate action %U%s",
4007          mp->name,
4008          format_policer_type, mp->type,
4009          ntohl (mp->cir),
4010          ntohl (mp->eir),
4011          clib_net_to_host_u64 (mp->cb),
4012          clib_net_to_host_u64 (mp->eb),
4013          format_policer_rate_type, mp->rate_type,
4014          format_policer_round_type, mp->round_type,
4015          mp->single_rate ? "single" : "dual",
4016          mp->color_aware ? "is" : "not",
4017          ntohl (mp->cir_tokens_per_period),
4018          ntohl (mp->pir_tokens_per_period),
4019          ntohl (mp->scale),
4020          ntohl (mp->current_limit),
4021          ntohl (mp->current_bucket),
4022          ntohl (mp->extended_limit),
4023          ntohl (mp->extended_bucket),
4024          clib_net_to_host_u64 (mp->last_update_time),
4025          format_policer_action_type, mp->conform_action_type,
4026          conform_dscp_str,
4027          format_policer_action_type, mp->exceed_action_type,
4028          exceed_dscp_str,
4029          format_policer_action_type, mp->violate_action_type,
4030          violate_dscp_str);
4031
4032   vec_free (conform_dscp_str);
4033   vec_free (exceed_dscp_str);
4034   vec_free (violate_dscp_str);
4035 }
4036
4037 static void vl_api_policer_details_t_handler_json
4038   (vl_api_policer_details_t * mp)
4039 {
4040   vat_main_t *vam = &vat_main;
4041   vat_json_node_t *node;
4042   u8 *rate_type_str, *round_type_str, *type_str;
4043   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4044
4045   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4046   round_type_str =
4047     format (0, "%U", format_policer_round_type, mp->round_type);
4048   type_str = format (0, "%U", format_policer_type, mp->type);
4049   conform_action_str = format (0, "%U", format_policer_action_type,
4050                                mp->conform_action_type);
4051   exceed_action_str = format (0, "%U", format_policer_action_type,
4052                               mp->exceed_action_type);
4053   violate_action_str = format (0, "%U", format_policer_action_type,
4054                                mp->violate_action_type);
4055
4056   if (VAT_JSON_ARRAY != vam->json_tree.type)
4057     {
4058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4059       vat_json_init_array (&vam->json_tree);
4060     }
4061   node = vat_json_array_add (&vam->json_tree);
4062
4063   vat_json_init_object (node);
4064   vat_json_object_add_string_copy (node, "name", mp->name);
4065   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4066   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4067   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4068   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4069   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4070   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4071   vat_json_object_add_string_copy (node, "type", type_str);
4072   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4073   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4074   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4075   vat_json_object_add_uint (node, "cir_tokens_per_period",
4076                             ntohl (mp->cir_tokens_per_period));
4077   vat_json_object_add_uint (node, "eir_tokens_per_period",
4078                             ntohl (mp->pir_tokens_per_period));
4079   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4080   vat_json_object_add_uint (node, "current_bucket",
4081                             ntohl (mp->current_bucket));
4082   vat_json_object_add_uint (node, "extended_limit",
4083                             ntohl (mp->extended_limit));
4084   vat_json_object_add_uint (node, "extended_bucket",
4085                             ntohl (mp->extended_bucket));
4086   vat_json_object_add_uint (node, "last_update_time",
4087                             ntohl (mp->last_update_time));
4088   vat_json_object_add_string_copy (node, "conform_action",
4089                                    conform_action_str);
4090   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4091     {
4092       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4093       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4094       vec_free (dscp_str);
4095     }
4096   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4097   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4098     {
4099       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4100       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4101       vec_free (dscp_str);
4102     }
4103   vat_json_object_add_string_copy (node, "violate_action",
4104                                    violate_action_str);
4105   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4106     {
4107       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4108       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4109       vec_free (dscp_str);
4110     }
4111
4112   vec_free (rate_type_str);
4113   vec_free (round_type_str);
4114   vec_free (type_str);
4115   vec_free (conform_action_str);
4116   vec_free (exceed_action_str);
4117   vec_free (violate_action_str);
4118 }
4119
4120 static void
4121 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4122                                            mp)
4123 {
4124   vat_main_t *vam = &vat_main;
4125   int i, count = ntohl (mp->count);
4126
4127   if (count > 0)
4128     print (vam->ofp, "classify table ids (%d) : ", count);
4129   for (i = 0; i < count; i++)
4130     {
4131       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4132       print (vam->ofp, (i < count - 1) ? "," : "");
4133     }
4134   vam->retval = ntohl (mp->retval);
4135   vam->result_ready = 1;
4136 }
4137
4138 static void
4139   vl_api_classify_table_ids_reply_t_handler_json
4140   (vl_api_classify_table_ids_reply_t * mp)
4141 {
4142   vat_main_t *vam = &vat_main;
4143   int i, count = ntohl (mp->count);
4144
4145   if (count > 0)
4146     {
4147       vat_json_node_t node;
4148
4149       vat_json_init_object (&node);
4150       for (i = 0; i < count; i++)
4151         {
4152           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4153         }
4154       vat_json_print (vam->ofp, &node);
4155       vat_json_free (&node);
4156     }
4157   vam->retval = ntohl (mp->retval);
4158   vam->result_ready = 1;
4159 }
4160
4161 static void
4162   vl_api_classify_table_by_interface_reply_t_handler
4163   (vl_api_classify_table_by_interface_reply_t * mp)
4164 {
4165   vat_main_t *vam = &vat_main;
4166   u32 table_id;
4167
4168   table_id = ntohl (mp->l2_table_id);
4169   if (table_id != ~0)
4170     print (vam->ofp, "l2 table id : %d", table_id);
4171   else
4172     print (vam->ofp, "l2 table id : No input ACL tables configured");
4173   table_id = ntohl (mp->ip4_table_id);
4174   if (table_id != ~0)
4175     print (vam->ofp, "ip4 table id : %d", table_id);
4176   else
4177     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4178   table_id = ntohl (mp->ip6_table_id);
4179   if (table_id != ~0)
4180     print (vam->ofp, "ip6 table id : %d", table_id);
4181   else
4182     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4183   vam->retval = ntohl (mp->retval);
4184   vam->result_ready = 1;
4185 }
4186
4187 static void
4188   vl_api_classify_table_by_interface_reply_t_handler_json
4189   (vl_api_classify_table_by_interface_reply_t * mp)
4190 {
4191   vat_main_t *vam = &vat_main;
4192   vat_json_node_t node;
4193
4194   vat_json_init_object (&node);
4195
4196   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4197   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4198   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4199
4200   vat_json_print (vam->ofp, &node);
4201   vat_json_free (&node);
4202
4203   vam->retval = ntohl (mp->retval);
4204   vam->result_ready = 1;
4205 }
4206
4207 static void vl_api_policer_add_del_reply_t_handler
4208   (vl_api_policer_add_del_reply_t * mp)
4209 {
4210   vat_main_t *vam = &vat_main;
4211   i32 retval = ntohl (mp->retval);
4212   if (vam->async_mode)
4213     {
4214       vam->async_errors += (retval < 0);
4215     }
4216   else
4217     {
4218       vam->retval = retval;
4219       vam->result_ready = 1;
4220       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4221         /*
4222          * Note: this is just barely thread-safe, depends on
4223          * the main thread spinning waiting for an answer...
4224          */
4225         errmsg ("policer index %d", ntohl (mp->policer_index));
4226     }
4227 }
4228
4229 static void vl_api_policer_add_del_reply_t_handler_json
4230   (vl_api_policer_add_del_reply_t * mp)
4231 {
4232   vat_main_t *vam = &vat_main;
4233   vat_json_node_t node;
4234
4235   vat_json_init_object (&node);
4236   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4237   vat_json_object_add_uint (&node, "policer_index",
4238                             ntohl (mp->policer_index));
4239
4240   vat_json_print (vam->ofp, &node);
4241   vat_json_free (&node);
4242
4243   vam->retval = ntohl (mp->retval);
4244   vam->result_ready = 1;
4245 }
4246
4247 /* Format hex dump. */
4248 u8 *
4249 format_hex_bytes (u8 * s, va_list * va)
4250 {
4251   u8 *bytes = va_arg (*va, u8 *);
4252   int n_bytes = va_arg (*va, int);
4253   uword i;
4254
4255   /* Print short or long form depending on byte count. */
4256   uword short_form = n_bytes <= 32;
4257   uword indent = format_get_indent (s);
4258
4259   if (n_bytes == 0)
4260     return s;
4261
4262   for (i = 0; i < n_bytes; i++)
4263     {
4264       if (!short_form && (i % 32) == 0)
4265         s = format (s, "%08x: ", i);
4266       s = format (s, "%02x", bytes[i]);
4267       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4268         s = format (s, "\n%U", format_white_space, indent);
4269     }
4270
4271   return s;
4272 }
4273
4274 static void
4275 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4276                                             * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   i32 retval = ntohl (mp->retval);
4280   if (retval == 0)
4281     {
4282       print (vam->ofp, "classify table info :");
4283       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4284              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4285              ntohl (mp->miss_next_index));
4286       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4287              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4288              ntohl (mp->match_n_vectors));
4289       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4290              ntohl (mp->mask_length));
4291     }
4292   vam->retval = retval;
4293   vam->result_ready = 1;
4294 }
4295
4296 static void
4297   vl_api_classify_table_info_reply_t_handler_json
4298   (vl_api_classify_table_info_reply_t * mp)
4299 {
4300   vat_main_t *vam = &vat_main;
4301   vat_json_node_t node;
4302
4303   i32 retval = ntohl (mp->retval);
4304   if (retval == 0)
4305     {
4306       vat_json_init_object (&node);
4307
4308       vat_json_object_add_int (&node, "sessions",
4309                                ntohl (mp->active_sessions));
4310       vat_json_object_add_int (&node, "nexttbl",
4311                                ntohl (mp->next_table_index));
4312       vat_json_object_add_int (&node, "nextnode",
4313                                ntohl (mp->miss_next_index));
4314       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4315       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4316       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4317       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4318                       ntohl (mp->mask_length), 0);
4319       vat_json_object_add_string_copy (&node, "mask", s);
4320
4321       vat_json_print (vam->ofp, &node);
4322       vat_json_free (&node);
4323     }
4324   vam->retval = ntohl (mp->retval);
4325   vam->result_ready = 1;
4326 }
4327
4328 static void
4329 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4330                                            mp)
4331 {
4332   vat_main_t *vam = &vat_main;
4333
4334   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4335          ntohl (mp->hit_next_index), ntohl (mp->advance),
4336          ntohl (mp->opaque_index));
4337   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4338          ntohl (mp->match_length));
4339 }
4340
4341 static void
4342   vl_api_classify_session_details_t_handler_json
4343   (vl_api_classify_session_details_t * mp)
4344 {
4345   vat_main_t *vam = &vat_main;
4346   vat_json_node_t *node = NULL;
4347
4348   if (VAT_JSON_ARRAY != vam->json_tree.type)
4349     {
4350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4351       vat_json_init_array (&vam->json_tree);
4352     }
4353   node = vat_json_array_add (&vam->json_tree);
4354
4355   vat_json_init_object (node);
4356   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4357   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4358   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4359   u8 *s =
4360     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4361             0);
4362   vat_json_object_add_string_copy (node, "match", s);
4363 }
4364
4365 static void vl_api_pg_create_interface_reply_t_handler
4366   (vl_api_pg_create_interface_reply_t * mp)
4367 {
4368   vat_main_t *vam = &vat_main;
4369
4370   vam->retval = ntohl (mp->retval);
4371   vam->result_ready = 1;
4372 }
4373
4374 static void vl_api_pg_create_interface_reply_t_handler_json
4375   (vl_api_pg_create_interface_reply_t * mp)
4376 {
4377   vat_main_t *vam = &vat_main;
4378   vat_json_node_t node;
4379
4380   i32 retval = ntohl (mp->retval);
4381   if (retval == 0)
4382     {
4383       vat_json_init_object (&node);
4384
4385       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4386
4387       vat_json_print (vam->ofp, &node);
4388       vat_json_free (&node);
4389     }
4390   vam->retval = ntohl (mp->retval);
4391   vam->result_ready = 1;
4392 }
4393
4394 static void vl_api_policer_classify_details_t_handler
4395   (vl_api_policer_classify_details_t * mp)
4396 {
4397   vat_main_t *vam = &vat_main;
4398
4399   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4400          ntohl (mp->table_index));
4401 }
4402
4403 static void vl_api_policer_classify_details_t_handler_json
4404   (vl_api_policer_classify_details_t * mp)
4405 {
4406   vat_main_t *vam = &vat_main;
4407   vat_json_node_t *node;
4408
4409   if (VAT_JSON_ARRAY != vam->json_tree.type)
4410     {
4411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4412       vat_json_init_array (&vam->json_tree);
4413     }
4414   node = vat_json_array_add (&vam->json_tree);
4415
4416   vat_json_init_object (node);
4417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4418   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4419 }
4420
4421 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4422   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4423 {
4424   vat_main_t *vam = &vat_main;
4425   i32 retval = ntohl (mp->retval);
4426   if (vam->async_mode)
4427     {
4428       vam->async_errors += (retval < 0);
4429     }
4430   else
4431     {
4432       vam->retval = retval;
4433       vam->sw_if_index = ntohl (mp->sw_if_index);
4434       vam->result_ready = 1;
4435     }
4436 }
4437
4438 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4439   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4440 {
4441   vat_main_t *vam = &vat_main;
4442   vat_json_node_t node;
4443
4444   vat_json_init_object (&node);
4445   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4446   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4447
4448   vat_json_print (vam->ofp, &node);
4449   vat_json_free (&node);
4450
4451   vam->retval = ntohl (mp->retval);
4452   vam->result_ready = 1;
4453 }
4454
4455 static void vl_api_flow_classify_details_t_handler
4456   (vl_api_flow_classify_details_t * mp)
4457 {
4458   vat_main_t *vam = &vat_main;
4459
4460   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4461          ntohl (mp->table_index));
4462 }
4463
4464 static void vl_api_flow_classify_details_t_handler_json
4465   (vl_api_flow_classify_details_t * mp)
4466 {
4467   vat_main_t *vam = &vat_main;
4468   vat_json_node_t *node;
4469
4470   if (VAT_JSON_ARRAY != vam->json_tree.type)
4471     {
4472       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4473       vat_json_init_array (&vam->json_tree);
4474     }
4475   node = vat_json_array_add (&vam->json_tree);
4476
4477   vat_json_init_object (node);
4478   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4479   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4480 }
4481
4482 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4483 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4484 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4485 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4486 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4487 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4488 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4489 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4490 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4491 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4492 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4493 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4494 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4495 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4496 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4497 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4498 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4499 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4500
4501 /*
4502  * Generate boilerplate reply handlers, which
4503  * dig the return value out of the xxx_reply_t API message,
4504  * stick it into vam->retval, and set vam->result_ready
4505  *
4506  * Could also do this by pointing N message decode slots at
4507  * a single function, but that could break in subtle ways.
4508  */
4509
4510 #define foreach_standard_reply_retval_handler           \
4511 _(sw_interface_set_flags_reply)                         \
4512 _(sw_interface_add_del_address_reply)                   \
4513 _(sw_interface_set_table_reply)                         \
4514 _(sw_interface_set_mpls_enable_reply)                   \
4515 _(sw_interface_set_vpath_reply)                         \
4516 _(sw_interface_set_vxlan_bypass_reply)                  \
4517 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4518 _(sw_interface_set_l2_bridge_reply)                     \
4519 _(bridge_domain_add_del_reply)                          \
4520 _(sw_interface_set_l2_xconnect_reply)                   \
4521 _(l2fib_add_del_reply)                                  \
4522 _(l2fib_flush_int_reply)                                \
4523 _(l2fib_flush_bd_reply)                                 \
4524 _(ip_add_del_route_reply)                               \
4525 _(ip_mroute_add_del_reply)                              \
4526 _(mpls_route_add_del_reply)                             \
4527 _(mpls_ip_bind_unbind_reply)                            \
4528 _(proxy_arp_add_del_reply)                              \
4529 _(proxy_arp_intfc_enable_disable_reply)                 \
4530 _(sw_interface_set_unnumbered_reply)                    \
4531 _(ip_neighbor_add_del_reply)                            \
4532 _(reset_vrf_reply)                                      \
4533 _(oam_add_del_reply)                                    \
4534 _(reset_fib_reply)                                      \
4535 _(dhcp_proxy_config_reply)                              \
4536 _(dhcp_proxy_set_vss_reply)                             \
4537 _(dhcp_client_config_reply)                             \
4538 _(set_ip_flow_hash_reply)                               \
4539 _(sw_interface_ip6_enable_disable_reply)                \
4540 _(sw_interface_ip6_set_link_local_address_reply)        \
4541 _(ip6nd_proxy_add_del_reply)                            \
4542 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4543 _(sw_interface_ip6nd_ra_config_reply)                   \
4544 _(set_arp_neighbor_limit_reply)                         \
4545 _(l2_patch_add_del_reply)                               \
4546 _(sr_policy_add_reply)                                  \
4547 _(sr_policy_mod_reply)                                  \
4548 _(sr_policy_del_reply)                                  \
4549 _(sr_localsid_add_del_reply)                            \
4550 _(sr_steering_add_del_reply)                            \
4551 _(classify_add_del_session_reply)                       \
4552 _(classify_set_interface_ip_table_reply)                \
4553 _(classify_set_interface_l2_tables_reply)               \
4554 _(l2tpv3_set_tunnel_cookies_reply)                      \
4555 _(l2tpv3_interface_enable_disable_reply)                \
4556 _(l2tpv3_set_lookup_key_reply)                          \
4557 _(l2_fib_clear_table_reply)                             \
4558 _(l2_interface_efp_filter_reply)                        \
4559 _(l2_interface_vlan_tag_rewrite_reply)                  \
4560 _(modify_vhost_user_if_reply)                           \
4561 _(delete_vhost_user_if_reply)                           \
4562 _(want_ip4_arp_events_reply)                            \
4563 _(want_ip6_nd_events_reply)                             \
4564 _(input_acl_set_interface_reply)                        \
4565 _(ipsec_spd_add_del_reply)                              \
4566 _(ipsec_interface_add_del_spd_reply)                    \
4567 _(ipsec_spd_add_del_entry_reply)                        \
4568 _(ipsec_sad_add_del_entry_reply)                        \
4569 _(ipsec_sa_set_key_reply)                               \
4570 _(ipsec_tunnel_if_add_del_reply)                        \
4571 _(ikev2_profile_add_del_reply)                          \
4572 _(ikev2_profile_set_auth_reply)                         \
4573 _(ikev2_profile_set_id_reply)                           \
4574 _(ikev2_profile_set_ts_reply)                           \
4575 _(ikev2_set_local_key_reply)                            \
4576 _(ikev2_set_responder_reply)                            \
4577 _(ikev2_set_ike_transforms_reply)                       \
4578 _(ikev2_set_esp_transforms_reply)                       \
4579 _(ikev2_set_sa_lifetime_reply)                          \
4580 _(ikev2_initiate_sa_init_reply)                         \
4581 _(ikev2_initiate_del_ike_sa_reply)                      \
4582 _(ikev2_initiate_del_child_sa_reply)                    \
4583 _(ikev2_initiate_rekey_child_sa_reply)                  \
4584 _(delete_loopback_reply)                                \
4585 _(bd_ip_mac_add_del_reply)                              \
4586 _(map_del_domain_reply)                                 \
4587 _(map_add_del_rule_reply)                               \
4588 _(want_interface_events_reply)                          \
4589 _(want_stats_reply)                                     \
4590 _(cop_interface_enable_disable_reply)                   \
4591 _(cop_whitelist_enable_disable_reply)                   \
4592 _(sw_interface_clear_stats_reply)                       \
4593 _(ioam_enable_reply)                              \
4594 _(ioam_disable_reply)                              \
4595 _(one_add_del_locator_reply)                            \
4596 _(one_add_del_local_eid_reply)                          \
4597 _(one_add_del_remote_mapping_reply)                     \
4598 _(one_add_del_adjacency_reply)                          \
4599 _(one_add_del_map_resolver_reply)                       \
4600 _(one_add_del_map_server_reply)                         \
4601 _(one_enable_disable_reply)                             \
4602 _(one_rloc_probe_enable_disable_reply)                  \
4603 _(one_map_register_enable_disable_reply)                \
4604 _(one_pitr_set_locator_set_reply)                       \
4605 _(one_map_request_mode_reply)                           \
4606 _(one_add_del_map_request_itr_rlocs_reply)              \
4607 _(one_eid_table_add_del_map_reply)                      \
4608 _(one_use_petr_reply)                                   \
4609 _(one_stats_enable_disable_reply)                       \
4610 _(one_add_del_l2_arp_entry_reply)                       \
4611 _(one_stats_flush_reply)                                \
4612 _(gpe_enable_disable_reply)                             \
4613 _(gpe_set_encap_mode_reply)                             \
4614 _(gpe_add_del_iface_reply)                              \
4615 _(gpe_add_del_native_fwd_rpath_reply)                   \
4616 _(af_packet_delete_reply)                               \
4617 _(policer_classify_set_interface_reply)                 \
4618 _(netmap_create_reply)                                  \
4619 _(netmap_delete_reply)                                  \
4620 _(set_ipfix_exporter_reply)                             \
4621 _(set_ipfix_classify_stream_reply)                      \
4622 _(ipfix_classify_table_add_del_reply)                   \
4623 _(flow_classify_set_interface_reply)                    \
4624 _(sw_interface_span_enable_disable_reply)               \
4625 _(pg_capture_reply)                                     \
4626 _(pg_enable_disable_reply)                              \
4627 _(ip_source_and_port_range_check_add_del_reply)         \
4628 _(ip_source_and_port_range_check_interface_add_del_reply)\
4629 _(delete_subif_reply)                                   \
4630 _(l2_interface_pbb_tag_rewrite_reply)                   \
4631 _(punt_reply)                                           \
4632 _(feature_enable_disable_reply)                         \
4633 _(sw_interface_tag_add_del_reply)                       \
4634 _(sw_interface_set_mtu_reply)                           \
4635 _(p2p_ethernet_add_reply)                               \
4636 _(p2p_ethernet_del_reply)                               \
4637 _(lldp_config_reply)                                    \
4638 _(sw_interface_set_lldp_reply)
4639
4640 #define _(n)                                    \
4641     static void vl_api_##n##_t_handler          \
4642     (vl_api_##n##_t * mp)                       \
4643     {                                           \
4644         vat_main_t * vam = &vat_main;           \
4645         i32 retval = ntohl(mp->retval);         \
4646         if (vam->async_mode) {                  \
4647             vam->async_errors += (retval < 0);  \
4648         } else {                                \
4649             vam->retval = retval;               \
4650             vam->result_ready = 1;              \
4651         }                                       \
4652     }
4653 foreach_standard_reply_retval_handler;
4654 #undef _
4655
4656 #define _(n)                                    \
4657     static void vl_api_##n##_t_handler_json     \
4658     (vl_api_##n##_t * mp)                       \
4659     {                                           \
4660         vat_main_t * vam = &vat_main;           \
4661         vat_json_node_t node;                   \
4662         vat_json_init_object(&node);            \
4663         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4664         vat_json_print(vam->ofp, &node);        \
4665         vam->retval = ntohl(mp->retval);        \
4666         vam->result_ready = 1;                  \
4667     }
4668 foreach_standard_reply_retval_handler;
4669 #undef _
4670
4671 /*
4672  * Table of message reply handlers, must include boilerplate handlers
4673  * we just generated
4674  */
4675
4676 #define foreach_vpe_api_reply_msg                                       \
4677 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4678 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4679 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4680 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4681 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4682 _(CLI_REPLY, cli_reply)                                                 \
4683 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4684 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4685   sw_interface_add_del_address_reply)                                   \
4686 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4687 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4688 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4689 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4690 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4691 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4692   sw_interface_set_l2_xconnect_reply)                                   \
4693 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4694   sw_interface_set_l2_bridge_reply)                                     \
4695 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4696 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4697 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4698 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4699 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4700 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4701 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4702 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4703 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4704 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4705 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4706 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4707 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4708 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4709 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4710 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4711 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4712 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4713   proxy_arp_intfc_enable_disable_reply)                                 \
4714 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4715 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4716   sw_interface_set_unnumbered_reply)                                    \
4717 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4718 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4719 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4720 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4721 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4722 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4723 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4724 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4725 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4726 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4727 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4728 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4729   sw_interface_ip6_enable_disable_reply)                                \
4730 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4731   sw_interface_ip6_set_link_local_address_reply)                        \
4732 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4733 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4734 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4735   sw_interface_ip6nd_ra_prefix_reply)                                   \
4736 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4737   sw_interface_ip6nd_ra_config_reply)                                   \
4738 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4739 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4740 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4741 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4742 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4743 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4744 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4745 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4746 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4747 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4748 classify_set_interface_ip_table_reply)                                  \
4749 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4750   classify_set_interface_l2_tables_reply)                               \
4751 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4752 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4753 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4754 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4755 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4756   l2tpv3_interface_enable_disable_reply)                                \
4757 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4758 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4759 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4760 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4761 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4762 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4763 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4764 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4765 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4766 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4767 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4768 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4769 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4770 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4771 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4772 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4773 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4774 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4775 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4776 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4777 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4778 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4779 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4780 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4781 _(IP_DETAILS, ip_details)                                               \
4782 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4783 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4784 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4785 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4786 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4787 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4788 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4789 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4790 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4791 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4792 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4793 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4794 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4795 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4796 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4797 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4798 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4799 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4800 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4801 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4802 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4803 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4804 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4805 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4806 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4807 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4808 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4809 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4810 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4811 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4812 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4813 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4814 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4815 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4816 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4817 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4818 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4819 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4820 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4821 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4822 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4823 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4824 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4825 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4826 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4827   one_map_register_enable_disable_reply)                                \
4828 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4829   one_rloc_probe_enable_disable_reply)                                  \
4830 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4831 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4832 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4833 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4834 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4835 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4836 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4837 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4838 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4839 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4840 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4841 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4842 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4843 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4844 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4845 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4846   show_one_stats_enable_disable_reply)                                  \
4847 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4848 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4849 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4850 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4851 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4852 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4853 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4854 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4855 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4856 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4857 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
4858 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
4859   gpe_add_del_native_fwd_rpath_reply)                                   \
4860 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4861   gpe_fwd_entry_path_details)                                           \
4862 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4863 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4864   one_add_del_map_request_itr_rlocs_reply)                              \
4865 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4866   one_get_map_request_itr_rlocs_reply)                                  \
4867 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4868 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4869 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4870 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4871 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4872 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4873   show_one_map_register_state_reply)                                    \
4874 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4875 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4876 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4877 _(POLICER_DETAILS, policer_details)                                     \
4878 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4879 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4880 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4881 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4882 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4883 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4884 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4885 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4886 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4887 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4888 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4889 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4890 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4891 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4892 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4893 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4894 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4895 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4896 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4897 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4898 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4899 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4900 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4901 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4902 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4903  ip_source_and_port_range_check_add_del_reply)                          \
4904 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4905  ip_source_and_port_range_check_interface_add_del_reply)                \
4906 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4907 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4908 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4909 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4910 _(PUNT_REPLY, punt_reply)                                               \
4911 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4912 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4913 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4914 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4915 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4916 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4917 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4918 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
4919 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
4920 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
4921 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
4922 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)
4923
4924 #define foreach_standalone_reply_msg                                    \
4925 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4926 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4927 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4928 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4929 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4930 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4931 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4932
4933 typedef struct
4934 {
4935   u8 *name;
4936   u32 value;
4937 } name_sort_t;
4938
4939
4940 #define STR_VTR_OP_CASE(op)     \
4941     case L2_VTR_ ## op:         \
4942         return "" # op;
4943
4944 static const char *
4945 str_vtr_op (u32 vtr_op)
4946 {
4947   switch (vtr_op)
4948     {
4949       STR_VTR_OP_CASE (DISABLED);
4950       STR_VTR_OP_CASE (PUSH_1);
4951       STR_VTR_OP_CASE (PUSH_2);
4952       STR_VTR_OP_CASE (POP_1);
4953       STR_VTR_OP_CASE (POP_2);
4954       STR_VTR_OP_CASE (TRANSLATE_1_1);
4955       STR_VTR_OP_CASE (TRANSLATE_1_2);
4956       STR_VTR_OP_CASE (TRANSLATE_2_1);
4957       STR_VTR_OP_CASE (TRANSLATE_2_2);
4958     }
4959
4960   return "UNKNOWN";
4961 }
4962
4963 static int
4964 dump_sub_interface_table (vat_main_t * vam)
4965 {
4966   const sw_interface_subif_t *sub = NULL;
4967
4968   if (vam->json_output)
4969     {
4970       clib_warning
4971         ("JSON output supported only for VPE API calls and dump_stats_table");
4972       return -99;
4973     }
4974
4975   print (vam->ofp,
4976          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4977          "Interface", "sw_if_index",
4978          "sub id", "dot1ad", "tags", "outer id",
4979          "inner id", "exact", "default", "outer any", "inner any");
4980
4981   vec_foreach (sub, vam->sw_if_subif_table)
4982   {
4983     print (vam->ofp,
4984            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4985            sub->interface_name,
4986            sub->sw_if_index,
4987            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4988            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4989            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4990            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4991     if (sub->vtr_op != L2_VTR_DISABLED)
4992       {
4993         print (vam->ofp,
4994                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4995                "tag1: %d tag2: %d ]",
4996                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4997                sub->vtr_tag1, sub->vtr_tag2);
4998       }
4999   }
5000
5001   return 0;
5002 }
5003
5004 static int
5005 name_sort_cmp (void *a1, void *a2)
5006 {
5007   name_sort_t *n1 = a1;
5008   name_sort_t *n2 = a2;
5009
5010   return strcmp ((char *) n1->name, (char *) n2->name);
5011 }
5012
5013 static int
5014 dump_interface_table (vat_main_t * vam)
5015 {
5016   hash_pair_t *p;
5017   name_sort_t *nses = 0, *ns;
5018
5019   if (vam->json_output)
5020     {
5021       clib_warning
5022         ("JSON output supported only for VPE API calls and dump_stats_table");
5023       return -99;
5024     }
5025
5026   /* *INDENT-OFF* */
5027   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5028   ({
5029     vec_add2 (nses, ns, 1);
5030     ns->name = (u8 *)(p->key);
5031     ns->value = (u32) p->value[0];
5032   }));
5033   /* *INDENT-ON* */
5034
5035   vec_sort_with_function (nses, name_sort_cmp);
5036
5037   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5038   vec_foreach (ns, nses)
5039   {
5040     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5041   }
5042   vec_free (nses);
5043   return 0;
5044 }
5045
5046 static int
5047 dump_ip_table (vat_main_t * vam, int is_ipv6)
5048 {
5049   const ip_details_t *det = NULL;
5050   const ip_address_details_t *address = NULL;
5051   u32 i = ~0;
5052
5053   print (vam->ofp, "%-12s", "sw_if_index");
5054
5055   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5056   {
5057     i++;
5058     if (!det->present)
5059       {
5060         continue;
5061       }
5062     print (vam->ofp, "%-12d", i);
5063     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5064     if (!det->addr)
5065       {
5066         continue;
5067       }
5068     vec_foreach (address, det->addr)
5069     {
5070       print (vam->ofp,
5071              "            %-30U%-13d",
5072              is_ipv6 ? format_ip6_address : format_ip4_address,
5073              address->ip, address->prefix_length);
5074     }
5075   }
5076
5077   return 0;
5078 }
5079
5080 static int
5081 dump_ipv4_table (vat_main_t * vam)
5082 {
5083   if (vam->json_output)
5084     {
5085       clib_warning
5086         ("JSON output supported only for VPE API calls and dump_stats_table");
5087       return -99;
5088     }
5089
5090   return dump_ip_table (vam, 0);
5091 }
5092
5093 static int
5094 dump_ipv6_table (vat_main_t * vam)
5095 {
5096   if (vam->json_output)
5097     {
5098       clib_warning
5099         ("JSON output supported only for VPE API calls and dump_stats_table");
5100       return -99;
5101     }
5102
5103   return dump_ip_table (vam, 1);
5104 }
5105
5106 static char *
5107 counter_type_to_str (u8 counter_type, u8 is_combined)
5108 {
5109   if (!is_combined)
5110     {
5111       switch (counter_type)
5112         {
5113         case VNET_INTERFACE_COUNTER_DROP:
5114           return "drop";
5115         case VNET_INTERFACE_COUNTER_PUNT:
5116           return "punt";
5117         case VNET_INTERFACE_COUNTER_IP4:
5118           return "ip4";
5119         case VNET_INTERFACE_COUNTER_IP6:
5120           return "ip6";
5121         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5122           return "rx-no-buf";
5123         case VNET_INTERFACE_COUNTER_RX_MISS:
5124           return "rx-miss";
5125         case VNET_INTERFACE_COUNTER_RX_ERROR:
5126           return "rx-error";
5127         case VNET_INTERFACE_COUNTER_TX_ERROR:
5128           return "tx-error";
5129         default:
5130           return "INVALID-COUNTER-TYPE";
5131         }
5132     }
5133   else
5134     {
5135       switch (counter_type)
5136         {
5137         case VNET_INTERFACE_COUNTER_RX:
5138           return "rx";
5139         case VNET_INTERFACE_COUNTER_TX:
5140           return "tx";
5141         default:
5142           return "INVALID-COUNTER-TYPE";
5143         }
5144     }
5145 }
5146
5147 static int
5148 dump_stats_table (vat_main_t * vam)
5149 {
5150   vat_json_node_t node;
5151   vat_json_node_t *msg_array;
5152   vat_json_node_t *msg;
5153   vat_json_node_t *counter_array;
5154   vat_json_node_t *counter;
5155   interface_counter_t c;
5156   u64 packets;
5157   ip4_fib_counter_t *c4;
5158   ip6_fib_counter_t *c6;
5159   ip4_nbr_counter_t *n4;
5160   ip6_nbr_counter_t *n6;
5161   int i, j;
5162
5163   if (!vam->json_output)
5164     {
5165       clib_warning ("dump_stats_table supported only in JSON format");
5166       return -99;
5167     }
5168
5169   vat_json_init_object (&node);
5170
5171   /* interface counters */
5172   msg_array = vat_json_object_add (&node, "interface_counters");
5173   vat_json_init_array (msg_array);
5174   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5175     {
5176       msg = vat_json_array_add (msg_array);
5177       vat_json_init_object (msg);
5178       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5179                                        (u8 *) counter_type_to_str (i, 0));
5180       vat_json_object_add_int (msg, "is_combined", 0);
5181       counter_array = vat_json_object_add (msg, "data");
5182       vat_json_init_array (counter_array);
5183       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5184         {
5185           packets = vam->simple_interface_counters[i][j];
5186           vat_json_array_add_uint (counter_array, packets);
5187         }
5188     }
5189   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5190     {
5191       msg = vat_json_array_add (msg_array);
5192       vat_json_init_object (msg);
5193       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5194                                        (u8 *) counter_type_to_str (i, 1));
5195       vat_json_object_add_int (msg, "is_combined", 1);
5196       counter_array = vat_json_object_add (msg, "data");
5197       vat_json_init_array (counter_array);
5198       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5199         {
5200           c = vam->combined_interface_counters[i][j];
5201           counter = vat_json_array_add (counter_array);
5202           vat_json_init_object (counter);
5203           vat_json_object_add_uint (counter, "packets", c.packets);
5204           vat_json_object_add_uint (counter, "bytes", c.bytes);
5205         }
5206     }
5207
5208   /* ip4 fib counters */
5209   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5210   vat_json_init_array (msg_array);
5211   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5212     {
5213       msg = vat_json_array_add (msg_array);
5214       vat_json_init_object (msg);
5215       vat_json_object_add_uint (msg, "vrf_id",
5216                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5217       counter_array = vat_json_object_add (msg, "c");
5218       vat_json_init_array (counter_array);
5219       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5220         {
5221           counter = vat_json_array_add (counter_array);
5222           vat_json_init_object (counter);
5223           c4 = &vam->ip4_fib_counters[i][j];
5224           vat_json_object_add_ip4 (counter, "address", c4->address);
5225           vat_json_object_add_uint (counter, "address_length",
5226                                     c4->address_length);
5227           vat_json_object_add_uint (counter, "packets", c4->packets);
5228           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5229         }
5230     }
5231
5232   /* ip6 fib counters */
5233   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5234   vat_json_init_array (msg_array);
5235   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5236     {
5237       msg = vat_json_array_add (msg_array);
5238       vat_json_init_object (msg);
5239       vat_json_object_add_uint (msg, "vrf_id",
5240                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5241       counter_array = vat_json_object_add (msg, "c");
5242       vat_json_init_array (counter_array);
5243       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5244         {
5245           counter = vat_json_array_add (counter_array);
5246           vat_json_init_object (counter);
5247           c6 = &vam->ip6_fib_counters[i][j];
5248           vat_json_object_add_ip6 (counter, "address", c6->address);
5249           vat_json_object_add_uint (counter, "address_length",
5250                                     c6->address_length);
5251           vat_json_object_add_uint (counter, "packets", c6->packets);
5252           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5253         }
5254     }
5255
5256   /* ip4 nbr counters */
5257   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5258   vat_json_init_array (msg_array);
5259   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5260     {
5261       msg = vat_json_array_add (msg_array);
5262       vat_json_init_object (msg);
5263       vat_json_object_add_uint (msg, "sw_if_index", i);
5264       counter_array = vat_json_object_add (msg, "c");
5265       vat_json_init_array (counter_array);
5266       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5267         {
5268           counter = vat_json_array_add (counter_array);
5269           vat_json_init_object (counter);
5270           n4 = &vam->ip4_nbr_counters[i][j];
5271           vat_json_object_add_ip4 (counter, "address", n4->address);
5272           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5273           vat_json_object_add_uint (counter, "packets", n4->packets);
5274           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5275         }
5276     }
5277
5278   /* ip6 nbr counters */
5279   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5280   vat_json_init_array (msg_array);
5281   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5282     {
5283       msg = vat_json_array_add (msg_array);
5284       vat_json_init_object (msg);
5285       vat_json_object_add_uint (msg, "sw_if_index", i);
5286       counter_array = vat_json_object_add (msg, "c");
5287       vat_json_init_array (counter_array);
5288       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5289         {
5290           counter = vat_json_array_add (counter_array);
5291           vat_json_init_object (counter);
5292           n6 = &vam->ip6_nbr_counters[i][j];
5293           vat_json_object_add_ip6 (counter, "address", n6->address);
5294           vat_json_object_add_uint (counter, "packets", n6->packets);
5295           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5296         }
5297     }
5298
5299   vat_json_print (vam->ofp, &node);
5300   vat_json_free (&node);
5301
5302   return 0;
5303 }
5304
5305 int
5306 exec (vat_main_t * vam)
5307 {
5308   api_main_t *am = &api_main;
5309   vl_api_cli_t *mp;
5310   f64 timeout;
5311   void *oldheap;
5312   u8 *cmd = 0;
5313   unformat_input_t *i = vam->input;
5314
5315   if (vec_len (i->buffer) == 0)
5316     return -1;
5317
5318   if (vam->exec_mode == 0 && unformat (i, "mode"))
5319     {
5320       vam->exec_mode = 1;
5321       return 0;
5322     }
5323   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5324     {
5325       vam->exec_mode = 0;
5326       return 0;
5327     }
5328
5329
5330   M (CLI, mp);
5331
5332   /*
5333    * Copy cmd into shared memory.
5334    * In order for the CLI command to work, it
5335    * must be a vector ending in \n, not a C-string ending
5336    * in \n\0.
5337    */
5338   pthread_mutex_lock (&am->vlib_rp->mutex);
5339   oldheap = svm_push_data_heap (am->vlib_rp);
5340
5341   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5342   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5343
5344   svm_pop_heap (oldheap);
5345   pthread_mutex_unlock (&am->vlib_rp->mutex);
5346
5347   mp->cmd_in_shmem = pointer_to_uword (cmd);
5348   S (mp);
5349   timeout = vat_time_now (vam) + 10.0;
5350
5351   while (vat_time_now (vam) < timeout)
5352     {
5353       if (vam->result_ready == 1)
5354         {
5355           u8 *free_me;
5356           if (vam->shmem_result != NULL)
5357             print (vam->ofp, "%s", vam->shmem_result);
5358           pthread_mutex_lock (&am->vlib_rp->mutex);
5359           oldheap = svm_push_data_heap (am->vlib_rp);
5360
5361           free_me = (u8 *) vam->shmem_result;
5362           vec_free (free_me);
5363
5364           svm_pop_heap (oldheap);
5365           pthread_mutex_unlock (&am->vlib_rp->mutex);
5366           return 0;
5367         }
5368     }
5369   return -99;
5370 }
5371
5372 /*
5373  * Future replacement of exec() that passes CLI buffers directly in
5374  * the API messages instead of an additional shared memory area.
5375  */
5376 static int
5377 exec_inband (vat_main_t * vam)
5378 {
5379   vl_api_cli_inband_t *mp;
5380   unformat_input_t *i = vam->input;
5381   int ret;
5382
5383   if (vec_len (i->buffer) == 0)
5384     return -1;
5385
5386   if (vam->exec_mode == 0 && unformat (i, "mode"))
5387     {
5388       vam->exec_mode = 1;
5389       return 0;
5390     }
5391   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5392     {
5393       vam->exec_mode = 0;
5394       return 0;
5395     }
5396
5397   /*
5398    * In order for the CLI command to work, it
5399    * must be a vector ending in \n, not a C-string ending
5400    * in \n\0.
5401    */
5402   u32 len = vec_len (vam->input->buffer);
5403   M2 (CLI_INBAND, mp, len);
5404   clib_memcpy (mp->cmd, vam->input->buffer, len);
5405   mp->length = htonl (len);
5406
5407   S (mp);
5408   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5409   return ret;
5410 }
5411
5412 static int
5413 api_create_loopback (vat_main_t * vam)
5414 {
5415   unformat_input_t *i = vam->input;
5416   vl_api_create_loopback_t *mp;
5417   vl_api_create_loopback_instance_t *mp_lbi;
5418   u8 mac_address[6];
5419   u8 mac_set = 0;
5420   u8 is_specified = 0;
5421   u32 user_instance = 0;
5422   int ret;
5423
5424   memset (mac_address, 0, sizeof (mac_address));
5425
5426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5427     {
5428       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5429         mac_set = 1;
5430       if (unformat (i, "instance %d", &user_instance))
5431         is_specified = 1;
5432       else
5433         break;
5434     }
5435
5436   if (is_specified)
5437     {
5438       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5439       mp_lbi->is_specified = is_specified;
5440       if (is_specified)
5441         mp_lbi->user_instance = htonl (user_instance);
5442       if (mac_set)
5443         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5444       S (mp_lbi);
5445     }
5446   else
5447     {
5448       /* Construct the API message */
5449       M (CREATE_LOOPBACK, mp);
5450       if (mac_set)
5451         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5452       S (mp);
5453     }
5454
5455   W (ret);
5456   return ret;
5457 }
5458
5459 static int
5460 api_delete_loopback (vat_main_t * vam)
5461 {
5462   unformat_input_t *i = vam->input;
5463   vl_api_delete_loopback_t *mp;
5464   u32 sw_if_index = ~0;
5465   int ret;
5466
5467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5468     {
5469       if (unformat (i, "sw_if_index %d", &sw_if_index))
5470         ;
5471       else
5472         break;
5473     }
5474
5475   if (sw_if_index == ~0)
5476     {
5477       errmsg ("missing sw_if_index");
5478       return -99;
5479     }
5480
5481   /* Construct the API message */
5482   M (DELETE_LOOPBACK, mp);
5483   mp->sw_if_index = ntohl (sw_if_index);
5484
5485   S (mp);
5486   W (ret);
5487   return ret;
5488 }
5489
5490 static int
5491 api_want_stats (vat_main_t * vam)
5492 {
5493   unformat_input_t *i = vam->input;
5494   vl_api_want_stats_t *mp;
5495   int enable = -1;
5496   int ret;
5497
5498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5499     {
5500       if (unformat (i, "enable"))
5501         enable = 1;
5502       else if (unformat (i, "disable"))
5503         enable = 0;
5504       else
5505         break;
5506     }
5507
5508   if (enable == -1)
5509     {
5510       errmsg ("missing enable|disable");
5511       return -99;
5512     }
5513
5514   M (WANT_STATS, mp);
5515   mp->enable_disable = enable;
5516
5517   S (mp);
5518   W (ret);
5519   return ret;
5520 }
5521
5522 static int
5523 api_want_interface_events (vat_main_t * vam)
5524 {
5525   unformat_input_t *i = vam->input;
5526   vl_api_want_interface_events_t *mp;
5527   int enable = -1;
5528   int ret;
5529
5530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5531     {
5532       if (unformat (i, "enable"))
5533         enable = 1;
5534       else if (unformat (i, "disable"))
5535         enable = 0;
5536       else
5537         break;
5538     }
5539
5540   if (enable == -1)
5541     {
5542       errmsg ("missing enable|disable");
5543       return -99;
5544     }
5545
5546   M (WANT_INTERFACE_EVENTS, mp);
5547   mp->enable_disable = enable;
5548
5549   vam->interface_event_display = enable;
5550
5551   S (mp);
5552   W (ret);
5553   return ret;
5554 }
5555
5556
5557 /* Note: non-static, called once to set up the initial intfc table */
5558 int
5559 api_sw_interface_dump (vat_main_t * vam)
5560 {
5561   vl_api_sw_interface_dump_t *mp;
5562   vl_api_control_ping_t *mp_ping;
5563   hash_pair_t *p;
5564   name_sort_t *nses = 0, *ns;
5565   sw_interface_subif_t *sub = NULL;
5566   int ret;
5567
5568   /* Toss the old name table */
5569   /* *INDENT-OFF* */
5570   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5571   ({
5572     vec_add2 (nses, ns, 1);
5573     ns->name = (u8 *)(p->key);
5574     ns->value = (u32) p->value[0];
5575   }));
5576   /* *INDENT-ON* */
5577
5578   hash_free (vam->sw_if_index_by_interface_name);
5579
5580   vec_foreach (ns, nses) vec_free (ns->name);
5581
5582   vec_free (nses);
5583
5584   vec_foreach (sub, vam->sw_if_subif_table)
5585   {
5586     vec_free (sub->interface_name);
5587   }
5588   vec_free (vam->sw_if_subif_table);
5589
5590   /* recreate the interface name hash table */
5591   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5592
5593   /* Get list of ethernets */
5594   M (SW_INTERFACE_DUMP, mp);
5595   mp->name_filter_valid = 1;
5596   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5597   S (mp);
5598
5599   /* and local / loopback interfaces */
5600   M (SW_INTERFACE_DUMP, mp);
5601   mp->name_filter_valid = 1;
5602   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5603   S (mp);
5604
5605   /* and packet-generator interfaces */
5606   M (SW_INTERFACE_DUMP, mp);
5607   mp->name_filter_valid = 1;
5608   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5609   S (mp);
5610
5611   /* and vxlan-gpe tunnel interfaces */
5612   M (SW_INTERFACE_DUMP, mp);
5613   mp->name_filter_valid = 1;
5614   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5615            sizeof (mp->name_filter) - 1);
5616   S (mp);
5617
5618   /* and vxlan tunnel interfaces */
5619   M (SW_INTERFACE_DUMP, mp);
5620   mp->name_filter_valid = 1;
5621   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5622   S (mp);
5623
5624   /* and host (af_packet) interfaces */
5625   M (SW_INTERFACE_DUMP, mp);
5626   mp->name_filter_valid = 1;
5627   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5628   S (mp);
5629
5630   /* and l2tpv3 tunnel interfaces */
5631   M (SW_INTERFACE_DUMP, mp);
5632   mp->name_filter_valid = 1;
5633   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5634            sizeof (mp->name_filter) - 1);
5635   S (mp);
5636
5637   /* and GRE tunnel interfaces */
5638   M (SW_INTERFACE_DUMP, mp);
5639   mp->name_filter_valid = 1;
5640   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5641   S (mp);
5642
5643   /* and LISP-GPE interfaces */
5644   M (SW_INTERFACE_DUMP, mp);
5645   mp->name_filter_valid = 1;
5646   strncpy ((char *) mp->name_filter, "lisp_gpe",
5647            sizeof (mp->name_filter) - 1);
5648   S (mp);
5649
5650   /* and IPSEC tunnel interfaces */
5651   M (SW_INTERFACE_DUMP, mp);
5652   mp->name_filter_valid = 1;
5653   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5654   S (mp);
5655
5656   /* Use a control ping for synchronization */
5657   M (CONTROL_PING, mp_ping);
5658   S (mp_ping);
5659
5660   W (ret);
5661   return ret;
5662 }
5663
5664 static int
5665 api_sw_interface_set_flags (vat_main_t * vam)
5666 {
5667   unformat_input_t *i = vam->input;
5668   vl_api_sw_interface_set_flags_t *mp;
5669   u32 sw_if_index;
5670   u8 sw_if_index_set = 0;
5671   u8 admin_up = 0, link_up = 0;
5672   int ret;
5673
5674   /* Parse args required to build the message */
5675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5676     {
5677       if (unformat (i, "admin-up"))
5678         admin_up = 1;
5679       else if (unformat (i, "admin-down"))
5680         admin_up = 0;
5681       else if (unformat (i, "link-up"))
5682         link_up = 1;
5683       else if (unformat (i, "link-down"))
5684         link_up = 0;
5685       else
5686         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5687         sw_if_index_set = 1;
5688       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5689         sw_if_index_set = 1;
5690       else
5691         break;
5692     }
5693
5694   if (sw_if_index_set == 0)
5695     {
5696       errmsg ("missing interface name or sw_if_index");
5697       return -99;
5698     }
5699
5700   /* Construct the API message */
5701   M (SW_INTERFACE_SET_FLAGS, mp);
5702   mp->sw_if_index = ntohl (sw_if_index);
5703   mp->admin_up_down = admin_up;
5704   mp->link_up_down = link_up;
5705
5706   /* send it... */
5707   S (mp);
5708
5709   /* Wait for a reply, return the good/bad news... */
5710   W (ret);
5711   return ret;
5712 }
5713
5714 static int
5715 api_sw_interface_clear_stats (vat_main_t * vam)
5716 {
5717   unformat_input_t *i = vam->input;
5718   vl_api_sw_interface_clear_stats_t *mp;
5719   u32 sw_if_index;
5720   u8 sw_if_index_set = 0;
5721   int ret;
5722
5723   /* Parse args required to build the message */
5724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5725     {
5726       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5727         sw_if_index_set = 1;
5728       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5729         sw_if_index_set = 1;
5730       else
5731         break;
5732     }
5733
5734   /* Construct the API message */
5735   M (SW_INTERFACE_CLEAR_STATS, mp);
5736
5737   if (sw_if_index_set == 1)
5738     mp->sw_if_index = ntohl (sw_if_index);
5739   else
5740     mp->sw_if_index = ~0;
5741
5742   /* send it... */
5743   S (mp);
5744
5745   /* Wait for a reply, return the good/bad news... */
5746   W (ret);
5747   return ret;
5748 }
5749
5750 static int
5751 api_sw_interface_add_del_address (vat_main_t * vam)
5752 {
5753   unformat_input_t *i = vam->input;
5754   vl_api_sw_interface_add_del_address_t *mp;
5755   u32 sw_if_index;
5756   u8 sw_if_index_set = 0;
5757   u8 is_add = 1, del_all = 0;
5758   u32 address_length = 0;
5759   u8 v4_address_set = 0;
5760   u8 v6_address_set = 0;
5761   ip4_address_t v4address;
5762   ip6_address_t v6address;
5763   int ret;
5764
5765   /* Parse args required to build the message */
5766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5767     {
5768       if (unformat (i, "del-all"))
5769         del_all = 1;
5770       else if (unformat (i, "del"))
5771         is_add = 0;
5772       else
5773         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5774         sw_if_index_set = 1;
5775       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5776         sw_if_index_set = 1;
5777       else if (unformat (i, "%U/%d",
5778                          unformat_ip4_address, &v4address, &address_length))
5779         v4_address_set = 1;
5780       else if (unformat (i, "%U/%d",
5781                          unformat_ip6_address, &v6address, &address_length))
5782         v6_address_set = 1;
5783       else
5784         break;
5785     }
5786
5787   if (sw_if_index_set == 0)
5788     {
5789       errmsg ("missing interface name or sw_if_index");
5790       return -99;
5791     }
5792   if (v4_address_set && v6_address_set)
5793     {
5794       errmsg ("both v4 and v6 addresses set");
5795       return -99;
5796     }
5797   if (!v4_address_set && !v6_address_set && !del_all)
5798     {
5799       errmsg ("no addresses set");
5800       return -99;
5801     }
5802
5803   /* Construct the API message */
5804   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5805
5806   mp->sw_if_index = ntohl (sw_if_index);
5807   mp->is_add = is_add;
5808   mp->del_all = del_all;
5809   if (v6_address_set)
5810     {
5811       mp->is_ipv6 = 1;
5812       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5813     }
5814   else
5815     {
5816       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5817     }
5818   mp->address_length = address_length;
5819
5820   /* send it... */
5821   S (mp);
5822
5823   /* Wait for a reply, return good/bad news  */
5824   W (ret);
5825   return ret;
5826 }
5827
5828 static int
5829 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5830 {
5831   unformat_input_t *i = vam->input;
5832   vl_api_sw_interface_set_mpls_enable_t *mp;
5833   u32 sw_if_index;
5834   u8 sw_if_index_set = 0;
5835   u8 enable = 1;
5836   int ret;
5837
5838   /* Parse args required to build the message */
5839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5840     {
5841       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5842         sw_if_index_set = 1;
5843       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5844         sw_if_index_set = 1;
5845       else if (unformat (i, "disable"))
5846         enable = 0;
5847       else if (unformat (i, "dis"))
5848         enable = 0;
5849       else
5850         break;
5851     }
5852
5853   if (sw_if_index_set == 0)
5854     {
5855       errmsg ("missing interface name or sw_if_index");
5856       return -99;
5857     }
5858
5859   /* Construct the API message */
5860   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5861
5862   mp->sw_if_index = ntohl (sw_if_index);
5863   mp->enable = enable;
5864
5865   /* send it... */
5866   S (mp);
5867
5868   /* Wait for a reply... */
5869   W (ret);
5870   return ret;
5871 }
5872
5873 static int
5874 api_sw_interface_set_table (vat_main_t * vam)
5875 {
5876   unformat_input_t *i = vam->input;
5877   vl_api_sw_interface_set_table_t *mp;
5878   u32 sw_if_index, vrf_id = 0;
5879   u8 sw_if_index_set = 0;
5880   u8 is_ipv6 = 0;
5881   int ret;
5882
5883   /* Parse args required to build the message */
5884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5885     {
5886       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5887         sw_if_index_set = 1;
5888       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5889         sw_if_index_set = 1;
5890       else if (unformat (i, "vrf %d", &vrf_id))
5891         ;
5892       else if (unformat (i, "ipv6"))
5893         is_ipv6 = 1;
5894       else
5895         break;
5896     }
5897
5898   if (sw_if_index_set == 0)
5899     {
5900       errmsg ("missing interface name or sw_if_index");
5901       return -99;
5902     }
5903
5904   /* Construct the API message */
5905   M (SW_INTERFACE_SET_TABLE, mp);
5906
5907   mp->sw_if_index = ntohl (sw_if_index);
5908   mp->is_ipv6 = is_ipv6;
5909   mp->vrf_id = ntohl (vrf_id);
5910
5911   /* send it... */
5912   S (mp);
5913
5914   /* Wait for a reply... */
5915   W (ret);
5916   return ret;
5917 }
5918
5919 static void vl_api_sw_interface_get_table_reply_t_handler
5920   (vl_api_sw_interface_get_table_reply_t * mp)
5921 {
5922   vat_main_t *vam = &vat_main;
5923
5924   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5925
5926   vam->retval = ntohl (mp->retval);
5927   vam->result_ready = 1;
5928
5929 }
5930
5931 static void vl_api_sw_interface_get_table_reply_t_handler_json
5932   (vl_api_sw_interface_get_table_reply_t * mp)
5933 {
5934   vat_main_t *vam = &vat_main;
5935   vat_json_node_t node;
5936
5937   vat_json_init_object (&node);
5938   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5939   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5940
5941   vat_json_print (vam->ofp, &node);
5942   vat_json_free (&node);
5943
5944   vam->retval = ntohl (mp->retval);
5945   vam->result_ready = 1;
5946 }
5947
5948 static int
5949 api_sw_interface_get_table (vat_main_t * vam)
5950 {
5951   unformat_input_t *i = vam->input;
5952   vl_api_sw_interface_get_table_t *mp;
5953   u32 sw_if_index;
5954   u8 sw_if_index_set = 0;
5955   u8 is_ipv6 = 0;
5956   int ret;
5957
5958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5959     {
5960       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5961         sw_if_index_set = 1;
5962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5963         sw_if_index_set = 1;
5964       else if (unformat (i, "ipv6"))
5965         is_ipv6 = 1;
5966       else
5967         break;
5968     }
5969
5970   if (sw_if_index_set == 0)
5971     {
5972       errmsg ("missing interface name or sw_if_index");
5973       return -99;
5974     }
5975
5976   M (SW_INTERFACE_GET_TABLE, mp);
5977   mp->sw_if_index = htonl (sw_if_index);
5978   mp->is_ipv6 = is_ipv6;
5979
5980   S (mp);
5981   W (ret);
5982   return ret;
5983 }
5984
5985 static int
5986 api_sw_interface_set_vpath (vat_main_t * vam)
5987 {
5988   unformat_input_t *i = vam->input;
5989   vl_api_sw_interface_set_vpath_t *mp;
5990   u32 sw_if_index = 0;
5991   u8 sw_if_index_set = 0;
5992   u8 is_enable = 0;
5993   int ret;
5994
5995   /* Parse args required to build the message */
5996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5997     {
5998       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5999         sw_if_index_set = 1;
6000       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6001         sw_if_index_set = 1;
6002       else if (unformat (i, "enable"))
6003         is_enable = 1;
6004       else if (unformat (i, "disable"))
6005         is_enable = 0;
6006       else
6007         break;
6008     }
6009
6010   if (sw_if_index_set == 0)
6011     {
6012       errmsg ("missing interface name or sw_if_index");
6013       return -99;
6014     }
6015
6016   /* Construct the API message */
6017   M (SW_INTERFACE_SET_VPATH, mp);
6018
6019   mp->sw_if_index = ntohl (sw_if_index);
6020   mp->enable = is_enable;
6021
6022   /* send it... */
6023   S (mp);
6024
6025   /* Wait for a reply... */
6026   W (ret);
6027   return ret;
6028 }
6029
6030 static int
6031 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6032 {
6033   unformat_input_t *i = vam->input;
6034   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6035   u32 sw_if_index = 0;
6036   u8 sw_if_index_set = 0;
6037   u8 is_enable = 1;
6038   u8 is_ipv6 = 0;
6039   int ret;
6040
6041   /* Parse args required to build the message */
6042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6043     {
6044       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6045         sw_if_index_set = 1;
6046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6047         sw_if_index_set = 1;
6048       else if (unformat (i, "enable"))
6049         is_enable = 1;
6050       else if (unformat (i, "disable"))
6051         is_enable = 0;
6052       else if (unformat (i, "ip4"))
6053         is_ipv6 = 0;
6054       else if (unformat (i, "ip6"))
6055         is_ipv6 = 1;
6056       else
6057         break;
6058     }
6059
6060   if (sw_if_index_set == 0)
6061     {
6062       errmsg ("missing interface name or sw_if_index");
6063       return -99;
6064     }
6065
6066   /* Construct the API message */
6067   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6068
6069   mp->sw_if_index = ntohl (sw_if_index);
6070   mp->enable = is_enable;
6071   mp->is_ipv6 = is_ipv6;
6072
6073   /* send it... */
6074   S (mp);
6075
6076   /* Wait for a reply... */
6077   W (ret);
6078   return ret;
6079 }
6080
6081
6082 static int
6083 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6084 {
6085   unformat_input_t *i = vam->input;
6086   vl_api_sw_interface_set_l2_xconnect_t *mp;
6087   u32 rx_sw_if_index;
6088   u8 rx_sw_if_index_set = 0;
6089   u32 tx_sw_if_index;
6090   u8 tx_sw_if_index_set = 0;
6091   u8 enable = 1;
6092   int ret;
6093
6094   /* Parse args required to build the message */
6095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6096     {
6097       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6098         rx_sw_if_index_set = 1;
6099       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6100         tx_sw_if_index_set = 1;
6101       else if (unformat (i, "rx"))
6102         {
6103           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6104             {
6105               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6106                             &rx_sw_if_index))
6107                 rx_sw_if_index_set = 1;
6108             }
6109           else
6110             break;
6111         }
6112       else if (unformat (i, "tx"))
6113         {
6114           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6115             {
6116               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6117                             &tx_sw_if_index))
6118                 tx_sw_if_index_set = 1;
6119             }
6120           else
6121             break;
6122         }
6123       else if (unformat (i, "enable"))
6124         enable = 1;
6125       else if (unformat (i, "disable"))
6126         enable = 0;
6127       else
6128         break;
6129     }
6130
6131   if (rx_sw_if_index_set == 0)
6132     {
6133       errmsg ("missing rx interface name or rx_sw_if_index");
6134       return -99;
6135     }
6136
6137   if (enable && (tx_sw_if_index_set == 0))
6138     {
6139       errmsg ("missing tx interface name or tx_sw_if_index");
6140       return -99;
6141     }
6142
6143   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6144
6145   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6146   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6147   mp->enable = enable;
6148
6149   S (mp);
6150   W (ret);
6151   return ret;
6152 }
6153
6154 static int
6155 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6156 {
6157   unformat_input_t *i = vam->input;
6158   vl_api_sw_interface_set_l2_bridge_t *mp;
6159   u32 rx_sw_if_index;
6160   u8 rx_sw_if_index_set = 0;
6161   u32 bd_id;
6162   u8 bd_id_set = 0;
6163   u8 bvi = 0;
6164   u32 shg = 0;
6165   u8 enable = 1;
6166   int ret;
6167
6168   /* Parse args required to build the message */
6169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6170     {
6171       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6172         rx_sw_if_index_set = 1;
6173       else if (unformat (i, "bd_id %d", &bd_id))
6174         bd_id_set = 1;
6175       else
6176         if (unformat
6177             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6178         rx_sw_if_index_set = 1;
6179       else if (unformat (i, "shg %d", &shg))
6180         ;
6181       else if (unformat (i, "bvi"))
6182         bvi = 1;
6183       else if (unformat (i, "enable"))
6184         enable = 1;
6185       else if (unformat (i, "disable"))
6186         enable = 0;
6187       else
6188         break;
6189     }
6190
6191   if (rx_sw_if_index_set == 0)
6192     {
6193       errmsg ("missing rx interface name or sw_if_index");
6194       return -99;
6195     }
6196
6197   if (enable && (bd_id_set == 0))
6198     {
6199       errmsg ("missing bridge domain");
6200       return -99;
6201     }
6202
6203   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6204
6205   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6206   mp->bd_id = ntohl (bd_id);
6207   mp->shg = (u8) shg;
6208   mp->bvi = bvi;
6209   mp->enable = enable;
6210
6211   S (mp);
6212   W (ret);
6213   return ret;
6214 }
6215
6216 static int
6217 api_bridge_domain_dump (vat_main_t * vam)
6218 {
6219   unformat_input_t *i = vam->input;
6220   vl_api_bridge_domain_dump_t *mp;
6221   vl_api_control_ping_t *mp_ping;
6222   u32 bd_id = ~0;
6223   int ret;
6224
6225   /* Parse args required to build the message */
6226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6227     {
6228       if (unformat (i, "bd_id %d", &bd_id))
6229         ;
6230       else
6231         break;
6232     }
6233
6234   M (BRIDGE_DOMAIN_DUMP, mp);
6235   mp->bd_id = ntohl (bd_id);
6236   S (mp);
6237
6238   /* Use a control ping for synchronization */
6239   M (CONTROL_PING, mp_ping);
6240   S (mp_ping);
6241
6242   W (ret);
6243   return ret;
6244 }
6245
6246 static int
6247 api_bridge_domain_add_del (vat_main_t * vam)
6248 {
6249   unformat_input_t *i = vam->input;
6250   vl_api_bridge_domain_add_del_t *mp;
6251   u32 bd_id = ~0;
6252   u8 is_add = 1;
6253   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6254   u32 mac_age = 0;
6255   int ret;
6256
6257   /* Parse args required to build the message */
6258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6259     {
6260       if (unformat (i, "bd_id %d", &bd_id))
6261         ;
6262       else if (unformat (i, "flood %d", &flood))
6263         ;
6264       else if (unformat (i, "uu-flood %d", &uu_flood))
6265         ;
6266       else if (unformat (i, "forward %d", &forward))
6267         ;
6268       else if (unformat (i, "learn %d", &learn))
6269         ;
6270       else if (unformat (i, "arp-term %d", &arp_term))
6271         ;
6272       else if (unformat (i, "mac-age %d", &mac_age))
6273         ;
6274       else if (unformat (i, "del"))
6275         {
6276           is_add = 0;
6277           flood = uu_flood = forward = learn = 0;
6278         }
6279       else
6280         break;
6281     }
6282
6283   if (bd_id == ~0)
6284     {
6285       errmsg ("missing bridge domain");
6286       return -99;
6287     }
6288
6289   if (mac_age > 255)
6290     {
6291       errmsg ("mac age must be less than 256 ");
6292       return -99;
6293     }
6294
6295   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6296
6297   mp->bd_id = ntohl (bd_id);
6298   mp->flood = flood;
6299   mp->uu_flood = uu_flood;
6300   mp->forward = forward;
6301   mp->learn = learn;
6302   mp->arp_term = arp_term;
6303   mp->is_add = is_add;
6304   mp->mac_age = (u8) mac_age;
6305
6306   S (mp);
6307   W (ret);
6308   return ret;
6309 }
6310
6311 static int
6312 api_l2fib_flush_bd (vat_main_t * vam)
6313 {
6314   unformat_input_t *i = vam->input;
6315   vl_api_l2fib_flush_bd_t *mp;
6316   u32 bd_id = ~0;
6317   int ret;
6318
6319   /* Parse args required to build the message */
6320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6321     {
6322       if (unformat (i, "bd_id %d", &bd_id));
6323       else
6324         break;
6325     }
6326
6327   if (bd_id == ~0)
6328     {
6329       errmsg ("missing bridge domain");
6330       return -99;
6331     }
6332
6333   M (L2FIB_FLUSH_BD, mp);
6334
6335   mp->bd_id = htonl (bd_id);
6336
6337   S (mp);
6338   W (ret);
6339   return ret;
6340 }
6341
6342 static int
6343 api_l2fib_flush_int (vat_main_t * vam)
6344 {
6345   unformat_input_t *i = vam->input;
6346   vl_api_l2fib_flush_int_t *mp;
6347   u32 sw_if_index = ~0;
6348   int ret;
6349
6350   /* Parse args required to build the message */
6351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6352     {
6353       if (unformat (i, "sw_if_index %d", &sw_if_index));
6354       else
6355         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6356       else
6357         break;
6358     }
6359
6360   if (sw_if_index == ~0)
6361     {
6362       errmsg ("missing interface name or sw_if_index");
6363       return -99;
6364     }
6365
6366   M (L2FIB_FLUSH_INT, mp);
6367
6368   mp->sw_if_index = ntohl (sw_if_index);
6369
6370   S (mp);
6371   W (ret);
6372   return ret;
6373 }
6374
6375 static int
6376 api_l2fib_add_del (vat_main_t * vam)
6377 {
6378   unformat_input_t *i = vam->input;
6379   vl_api_l2fib_add_del_t *mp;
6380   f64 timeout;
6381   u64 mac = 0;
6382   u8 mac_set = 0;
6383   u32 bd_id;
6384   u8 bd_id_set = 0;
6385   u32 sw_if_index = ~0;
6386   u8 sw_if_index_set = 0;
6387   u8 is_add = 1;
6388   u8 static_mac = 0;
6389   u8 filter_mac = 0;
6390   u8 bvi_mac = 0;
6391   int count = 1;
6392   f64 before = 0;
6393   int j;
6394
6395   /* Parse args required to build the message */
6396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6397     {
6398       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6399         mac_set = 1;
6400       else if (unformat (i, "bd_id %d", &bd_id))
6401         bd_id_set = 1;
6402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6403         sw_if_index_set = 1;
6404       else if (unformat (i, "sw_if"))
6405         {
6406           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6407             {
6408               if (unformat
6409                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6410                 sw_if_index_set = 1;
6411             }
6412           else
6413             break;
6414         }
6415       else if (unformat (i, "static"))
6416         static_mac = 1;
6417       else if (unformat (i, "filter"))
6418         {
6419           filter_mac = 1;
6420           static_mac = 1;
6421         }
6422       else if (unformat (i, "bvi"))
6423         {
6424           bvi_mac = 1;
6425           static_mac = 1;
6426         }
6427       else if (unformat (i, "del"))
6428         is_add = 0;
6429       else if (unformat (i, "count %d", &count))
6430         ;
6431       else
6432         break;
6433     }
6434
6435   if (mac_set == 0)
6436     {
6437       errmsg ("missing mac address");
6438       return -99;
6439     }
6440
6441   if (bd_id_set == 0)
6442     {
6443       errmsg ("missing bridge domain");
6444       return -99;
6445     }
6446
6447   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6448     {
6449       errmsg ("missing interface name or sw_if_index");
6450       return -99;
6451     }
6452
6453   if (count > 1)
6454     {
6455       /* Turn on async mode */
6456       vam->async_mode = 1;
6457       vam->async_errors = 0;
6458       before = vat_time_now (vam);
6459     }
6460
6461   for (j = 0; j < count; j++)
6462     {
6463       M (L2FIB_ADD_DEL, mp);
6464
6465       mp->mac = mac;
6466       mp->bd_id = ntohl (bd_id);
6467       mp->is_add = is_add;
6468
6469       if (is_add)
6470         {
6471           mp->sw_if_index = ntohl (sw_if_index);
6472           mp->static_mac = static_mac;
6473           mp->filter_mac = filter_mac;
6474           mp->bvi_mac = bvi_mac;
6475         }
6476       increment_mac_address (&mac);
6477       /* send it... */
6478       S (mp);
6479     }
6480
6481   if (count > 1)
6482     {
6483       vl_api_control_ping_t *mp_ping;
6484       f64 after;
6485
6486       /* Shut off async mode */
6487       vam->async_mode = 0;
6488
6489       M (CONTROL_PING, mp_ping);
6490       S (mp_ping);
6491
6492       timeout = vat_time_now (vam) + 1.0;
6493       while (vat_time_now (vam) < timeout)
6494         if (vam->result_ready == 1)
6495           goto out;
6496       vam->retval = -99;
6497
6498     out:
6499       if (vam->retval == -99)
6500         errmsg ("timeout");
6501
6502       if (vam->async_errors > 0)
6503         {
6504           errmsg ("%d asynchronous errors", vam->async_errors);
6505           vam->retval = -98;
6506         }
6507       vam->async_errors = 0;
6508       after = vat_time_now (vam);
6509
6510       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6511              count, after - before, count / (after - before));
6512     }
6513   else
6514     {
6515       int ret;
6516
6517       /* Wait for a reply... */
6518       W (ret);
6519       return ret;
6520     }
6521   /* Return the good/bad news */
6522   return (vam->retval);
6523 }
6524
6525 static int
6526 api_bridge_domain_set_mac_age (vat_main_t * vam)
6527 {
6528   unformat_input_t *i = vam->input;
6529   vl_api_bridge_domain_set_mac_age_t *mp;
6530   u32 bd_id = ~0;
6531   u32 mac_age = 0;
6532   int ret;
6533
6534   /* Parse args required to build the message */
6535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6536     {
6537       if (unformat (i, "bd_id %d", &bd_id));
6538       else if (unformat (i, "mac-age %d", &mac_age));
6539       else
6540         break;
6541     }
6542
6543   if (bd_id == ~0)
6544     {
6545       errmsg ("missing bridge domain");
6546       return -99;
6547     }
6548
6549   if (mac_age > 255)
6550     {
6551       errmsg ("mac age must be less than 256 ");
6552       return -99;
6553     }
6554
6555   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6556
6557   mp->bd_id = htonl (bd_id);
6558   mp->mac_age = (u8) mac_age;
6559
6560   S (mp);
6561   W (ret);
6562   return ret;
6563 }
6564
6565 static int
6566 api_l2_flags (vat_main_t * vam)
6567 {
6568   unformat_input_t *i = vam->input;
6569   vl_api_l2_flags_t *mp;
6570   u32 sw_if_index;
6571   u32 feature_bitmap = 0;
6572   u8 sw_if_index_set = 0;
6573   int ret;
6574
6575   /* Parse args required to build the message */
6576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6577     {
6578       if (unformat (i, "sw_if_index %d", &sw_if_index))
6579         sw_if_index_set = 1;
6580       else if (unformat (i, "sw_if"))
6581         {
6582           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6583             {
6584               if (unformat
6585                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6586                 sw_if_index_set = 1;
6587             }
6588           else
6589             break;
6590         }
6591       else if (unformat (i, "learn"))
6592         feature_bitmap |= L2INPUT_FEAT_LEARN;
6593       else if (unformat (i, "forward"))
6594         feature_bitmap |= L2INPUT_FEAT_FWD;
6595       else if (unformat (i, "flood"))
6596         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6597       else if (unformat (i, "uu-flood"))
6598         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6599       else
6600         break;
6601     }
6602
6603   if (sw_if_index_set == 0)
6604     {
6605       errmsg ("missing interface name or sw_if_index");
6606       return -99;
6607     }
6608
6609   M (L2_FLAGS, mp);
6610
6611   mp->sw_if_index = ntohl (sw_if_index);
6612   mp->feature_bitmap = ntohl (feature_bitmap);
6613
6614   S (mp);
6615   W (ret);
6616   return ret;
6617 }
6618
6619 static int
6620 api_bridge_flags (vat_main_t * vam)
6621 {
6622   unformat_input_t *i = vam->input;
6623   vl_api_bridge_flags_t *mp;
6624   u32 bd_id;
6625   u8 bd_id_set = 0;
6626   u8 is_set = 1;
6627   u32 flags = 0;
6628   int ret;
6629
6630   /* Parse args required to build the message */
6631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6632     {
6633       if (unformat (i, "bd_id %d", &bd_id))
6634         bd_id_set = 1;
6635       else if (unformat (i, "learn"))
6636         flags |= L2_LEARN;
6637       else if (unformat (i, "forward"))
6638         flags |= L2_FWD;
6639       else if (unformat (i, "flood"))
6640         flags |= L2_FLOOD;
6641       else if (unformat (i, "uu-flood"))
6642         flags |= L2_UU_FLOOD;
6643       else if (unformat (i, "arp-term"))
6644         flags |= L2_ARP_TERM;
6645       else if (unformat (i, "off"))
6646         is_set = 0;
6647       else if (unformat (i, "disable"))
6648         is_set = 0;
6649       else
6650         break;
6651     }
6652
6653   if (bd_id_set == 0)
6654     {
6655       errmsg ("missing bridge domain");
6656       return -99;
6657     }
6658
6659   M (BRIDGE_FLAGS, mp);
6660
6661   mp->bd_id = ntohl (bd_id);
6662   mp->feature_bitmap = ntohl (flags);
6663   mp->is_set = is_set;
6664
6665   S (mp);
6666   W (ret);
6667   return ret;
6668 }
6669
6670 static int
6671 api_bd_ip_mac_add_del (vat_main_t * vam)
6672 {
6673   unformat_input_t *i = vam->input;
6674   vl_api_bd_ip_mac_add_del_t *mp;
6675   u32 bd_id;
6676   u8 is_ipv6 = 0;
6677   u8 is_add = 1;
6678   u8 bd_id_set = 0;
6679   u8 ip_set = 0;
6680   u8 mac_set = 0;
6681   ip4_address_t v4addr;
6682   ip6_address_t v6addr;
6683   u8 macaddr[6];
6684   int ret;
6685
6686
6687   /* Parse args required to build the message */
6688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6689     {
6690       if (unformat (i, "bd_id %d", &bd_id))
6691         {
6692           bd_id_set++;
6693         }
6694       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6695         {
6696           ip_set++;
6697         }
6698       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6699         {
6700           ip_set++;
6701           is_ipv6++;
6702         }
6703       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6704         {
6705           mac_set++;
6706         }
6707       else if (unformat (i, "del"))
6708         is_add = 0;
6709       else
6710         break;
6711     }
6712
6713   if (bd_id_set == 0)
6714     {
6715       errmsg ("missing bridge domain");
6716       return -99;
6717     }
6718   else if (ip_set == 0)
6719     {
6720       errmsg ("missing IP address");
6721       return -99;
6722     }
6723   else if (mac_set == 0)
6724     {
6725       errmsg ("missing MAC address");
6726       return -99;
6727     }
6728
6729   M (BD_IP_MAC_ADD_DEL, mp);
6730
6731   mp->bd_id = ntohl (bd_id);
6732   mp->is_ipv6 = is_ipv6;
6733   mp->is_add = is_add;
6734   if (is_ipv6)
6735     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6736   else
6737     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6738   clib_memcpy (mp->mac_address, macaddr, 6);
6739   S (mp);
6740   W (ret);
6741   return ret;
6742 }
6743
6744 static int
6745 api_tap_connect (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_tap_connect_t *mp;
6749   u8 mac_address[6];
6750   u8 random_mac = 1;
6751   u8 name_set = 0;
6752   u8 *tap_name;
6753   u8 *tag = 0;
6754   ip4_address_t ip4_address;
6755   u32 ip4_mask_width;
6756   int ip4_address_set = 0;
6757   ip6_address_t ip6_address;
6758   u32 ip6_mask_width;
6759   int ip6_address_set = 0;
6760   int ret;
6761
6762   memset (mac_address, 0, sizeof (mac_address));
6763
6764   /* Parse args required to build the message */
6765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6766     {
6767       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6768         {
6769           random_mac = 0;
6770         }
6771       else if (unformat (i, "random-mac"))
6772         random_mac = 1;
6773       else if (unformat (i, "tapname %s", &tap_name))
6774         name_set = 1;
6775       else if (unformat (i, "tag %s", &tag))
6776         ;
6777       else if (unformat (i, "address %U/%d",
6778                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6779         ip4_address_set = 1;
6780       else if (unformat (i, "address %U/%d",
6781                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6782         ip6_address_set = 1;
6783       else
6784         break;
6785     }
6786
6787   if (name_set == 0)
6788     {
6789       errmsg ("missing tap name");
6790       return -99;
6791     }
6792   if (vec_len (tap_name) > 63)
6793     {
6794       errmsg ("tap name too long");
6795       return -99;
6796     }
6797   vec_add1 (tap_name, 0);
6798
6799   if (vec_len (tag) > 63)
6800     {
6801       errmsg ("tag too long");
6802       return -99;
6803     }
6804
6805   /* Construct the API message */
6806   M (TAP_CONNECT, mp);
6807
6808   mp->use_random_mac = random_mac;
6809   clib_memcpy (mp->mac_address, mac_address, 6);
6810   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6811   if (tag)
6812     clib_memcpy (mp->tag, tag, vec_len (tag));
6813
6814   if (ip4_address_set)
6815     {
6816       mp->ip4_address_set = 1;
6817       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6818       mp->ip4_mask_width = ip4_mask_width;
6819     }
6820   if (ip6_address_set)
6821     {
6822       mp->ip6_address_set = 1;
6823       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6824       mp->ip6_mask_width = ip6_mask_width;
6825     }
6826
6827   vec_free (tap_name);
6828   vec_free (tag);
6829
6830   /* send it... */
6831   S (mp);
6832
6833   /* Wait for a reply... */
6834   W (ret);
6835   return ret;
6836 }
6837
6838 static int
6839 api_tap_modify (vat_main_t * vam)
6840 {
6841   unformat_input_t *i = vam->input;
6842   vl_api_tap_modify_t *mp;
6843   u8 mac_address[6];
6844   u8 random_mac = 1;
6845   u8 name_set = 0;
6846   u8 *tap_name;
6847   u32 sw_if_index = ~0;
6848   u8 sw_if_index_set = 0;
6849   int ret;
6850
6851   memset (mac_address, 0, sizeof (mac_address));
6852
6853   /* Parse args required to build the message */
6854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6855     {
6856       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6857         sw_if_index_set = 1;
6858       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6859         sw_if_index_set = 1;
6860       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6861         {
6862           random_mac = 0;
6863         }
6864       else if (unformat (i, "random-mac"))
6865         random_mac = 1;
6866       else if (unformat (i, "tapname %s", &tap_name))
6867         name_set = 1;
6868       else
6869         break;
6870     }
6871
6872   if (sw_if_index_set == 0)
6873     {
6874       errmsg ("missing vpp interface name");
6875       return -99;
6876     }
6877   if (name_set == 0)
6878     {
6879       errmsg ("missing tap name");
6880       return -99;
6881     }
6882   if (vec_len (tap_name) > 63)
6883     {
6884       errmsg ("tap name too long");
6885     }
6886   vec_add1 (tap_name, 0);
6887
6888   /* Construct the API message */
6889   M (TAP_MODIFY, mp);
6890
6891   mp->use_random_mac = random_mac;
6892   mp->sw_if_index = ntohl (sw_if_index);
6893   clib_memcpy (mp->mac_address, mac_address, 6);
6894   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6895   vec_free (tap_name);
6896
6897   /* send it... */
6898   S (mp);
6899
6900   /* Wait for a reply... */
6901   W (ret);
6902   return ret;
6903 }
6904
6905 static int
6906 api_tap_delete (vat_main_t * vam)
6907 {
6908   unformat_input_t *i = vam->input;
6909   vl_api_tap_delete_t *mp;
6910   u32 sw_if_index = ~0;
6911   u8 sw_if_index_set = 0;
6912   int ret;
6913
6914   /* Parse args required to build the message */
6915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6916     {
6917       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6918         sw_if_index_set = 1;
6919       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6920         sw_if_index_set = 1;
6921       else
6922         break;
6923     }
6924
6925   if (sw_if_index_set == 0)
6926     {
6927       errmsg ("missing vpp interface name");
6928       return -99;
6929     }
6930
6931   /* Construct the API message */
6932   M (TAP_DELETE, mp);
6933
6934   mp->sw_if_index = ntohl (sw_if_index);
6935
6936   /* send it... */
6937   S (mp);
6938
6939   /* Wait for a reply... */
6940   W (ret);
6941   return ret;
6942 }
6943
6944 static int
6945 api_ip_add_del_route (vat_main_t * vam)
6946 {
6947   unformat_input_t *i = vam->input;
6948   vl_api_ip_add_del_route_t *mp;
6949   u32 sw_if_index = ~0, vrf_id = 0;
6950   u8 is_ipv6 = 0;
6951   u8 is_local = 0, is_drop = 0;
6952   u8 is_unreach = 0, is_prohibit = 0;
6953   u8 create_vrf_if_needed = 0;
6954   u8 is_add = 1;
6955   u32 next_hop_weight = 1;
6956   u8 not_last = 0;
6957   u8 is_multipath = 0;
6958   u8 address_set = 0;
6959   u8 address_length_set = 0;
6960   u32 next_hop_table_id = 0;
6961   u32 resolve_attempts = 0;
6962   u32 dst_address_length = 0;
6963   u8 next_hop_set = 0;
6964   ip4_address_t v4_dst_address, v4_next_hop_address;
6965   ip6_address_t v6_dst_address, v6_next_hop_address;
6966   int count = 1;
6967   int j;
6968   f64 before = 0;
6969   u32 random_add_del = 0;
6970   u32 *random_vector = 0;
6971   uword *random_hash;
6972   u32 random_seed = 0xdeaddabe;
6973   u32 classify_table_index = ~0;
6974   u8 is_classify = 0;
6975   u8 resolve_host = 0, resolve_attached = 0;
6976   mpls_label_t *next_hop_out_label_stack = NULL;
6977   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6978   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6979
6980   /* Parse args required to build the message */
6981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6982     {
6983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6984         ;
6985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6986         ;
6987       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6988         {
6989           address_set = 1;
6990           is_ipv6 = 0;
6991         }
6992       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6993         {
6994           address_set = 1;
6995           is_ipv6 = 1;
6996         }
6997       else if (unformat (i, "/%d", &dst_address_length))
6998         {
6999           address_length_set = 1;
7000         }
7001
7002       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7003                                          &v4_next_hop_address))
7004         {
7005           next_hop_set = 1;
7006         }
7007       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7008                                          &v6_next_hop_address))
7009         {
7010           next_hop_set = 1;
7011         }
7012       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7013         ;
7014       else if (unformat (i, "weight %d", &next_hop_weight))
7015         ;
7016       else if (unformat (i, "drop"))
7017         {
7018           is_drop = 1;
7019         }
7020       else if (unformat (i, "null-send-unreach"))
7021         {
7022           is_unreach = 1;
7023         }
7024       else if (unformat (i, "null-send-prohibit"))
7025         {
7026           is_prohibit = 1;
7027         }
7028       else if (unformat (i, "local"))
7029         {
7030           is_local = 1;
7031         }
7032       else if (unformat (i, "classify %d", &classify_table_index))
7033         {
7034           is_classify = 1;
7035         }
7036       else if (unformat (i, "del"))
7037         is_add = 0;
7038       else if (unformat (i, "add"))
7039         is_add = 1;
7040       else if (unformat (i, "not-last"))
7041         not_last = 1;
7042       else if (unformat (i, "resolve-via-host"))
7043         resolve_host = 1;
7044       else if (unformat (i, "resolve-via-attached"))
7045         resolve_attached = 1;
7046       else if (unformat (i, "multipath"))
7047         is_multipath = 1;
7048       else if (unformat (i, "vrf %d", &vrf_id))
7049         ;
7050       else if (unformat (i, "create-vrf"))
7051         create_vrf_if_needed = 1;
7052       else if (unformat (i, "count %d", &count))
7053         ;
7054       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7055         ;
7056       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7057         ;
7058       else if (unformat (i, "out-label %d", &next_hop_out_label))
7059         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7060       else if (unformat (i, "via-label %d", &next_hop_via_label))
7061         ;
7062       else if (unformat (i, "random"))
7063         random_add_del = 1;
7064       else if (unformat (i, "seed %d", &random_seed))
7065         ;
7066       else
7067         {
7068           clib_warning ("parse error '%U'", format_unformat_error, i);
7069           return -99;
7070         }
7071     }
7072
7073   if (!next_hop_set && !is_drop && !is_local &&
7074       !is_classify && !is_unreach && !is_prohibit &&
7075       MPLS_LABEL_INVALID == next_hop_via_label)
7076     {
7077       errmsg
7078         ("next hop / local / drop / unreach / prohibit / classify not set");
7079       return -99;
7080     }
7081
7082   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7083     {
7084       errmsg ("next hop and next-hop via label set");
7085       return -99;
7086     }
7087   if (address_set == 0)
7088     {
7089       errmsg ("missing addresses");
7090       return -99;
7091     }
7092
7093   if (address_length_set == 0)
7094     {
7095       errmsg ("missing address length");
7096       return -99;
7097     }
7098
7099   /* Generate a pile of unique, random routes */
7100   if (random_add_del)
7101     {
7102       u32 this_random_address;
7103       random_hash = hash_create (count, sizeof (uword));
7104
7105       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7106       for (j = 0; j <= count; j++)
7107         {
7108           do
7109             {
7110               this_random_address = random_u32 (&random_seed);
7111               this_random_address =
7112                 clib_host_to_net_u32 (this_random_address);
7113             }
7114           while (hash_get (random_hash, this_random_address));
7115           vec_add1 (random_vector, this_random_address);
7116           hash_set (random_hash, this_random_address, 1);
7117         }
7118       hash_free (random_hash);
7119       v4_dst_address.as_u32 = random_vector[0];
7120     }
7121
7122   if (count > 1)
7123     {
7124       /* Turn on async mode */
7125       vam->async_mode = 1;
7126       vam->async_errors = 0;
7127       before = vat_time_now (vam);
7128     }
7129
7130   for (j = 0; j < count; j++)
7131     {
7132       /* Construct the API message */
7133       M2 (IP_ADD_DEL_ROUTE, mp,
7134           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7135
7136       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7137       mp->table_id = ntohl (vrf_id);
7138       mp->create_vrf_if_needed = create_vrf_if_needed;
7139
7140       mp->is_add = is_add;
7141       mp->is_drop = is_drop;
7142       mp->is_unreach = is_unreach;
7143       mp->is_prohibit = is_prohibit;
7144       mp->is_ipv6 = is_ipv6;
7145       mp->is_local = is_local;
7146       mp->is_classify = is_classify;
7147       mp->is_multipath = is_multipath;
7148       mp->is_resolve_host = resolve_host;
7149       mp->is_resolve_attached = resolve_attached;
7150       mp->not_last = not_last;
7151       mp->next_hop_weight = next_hop_weight;
7152       mp->dst_address_length = dst_address_length;
7153       mp->next_hop_table_id = ntohl (next_hop_table_id);
7154       mp->classify_table_index = ntohl (classify_table_index);
7155       mp->next_hop_via_label = ntohl (next_hop_via_label);
7156       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7157       if (0 != mp->next_hop_n_out_labels)
7158         {
7159           memcpy (mp->next_hop_out_label_stack,
7160                   next_hop_out_label_stack,
7161                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7162           vec_free (next_hop_out_label_stack);
7163         }
7164
7165       if (is_ipv6)
7166         {
7167           clib_memcpy (mp->dst_address, &v6_dst_address,
7168                        sizeof (v6_dst_address));
7169           if (next_hop_set)
7170             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7171                          sizeof (v6_next_hop_address));
7172           increment_v6_address (&v6_dst_address);
7173         }
7174       else
7175         {
7176           clib_memcpy (mp->dst_address, &v4_dst_address,
7177                        sizeof (v4_dst_address));
7178           if (next_hop_set)
7179             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7180                          sizeof (v4_next_hop_address));
7181           if (random_add_del)
7182             v4_dst_address.as_u32 = random_vector[j + 1];
7183           else
7184             increment_v4_address (&v4_dst_address);
7185         }
7186       /* send it... */
7187       S (mp);
7188       /* If we receive SIGTERM, stop now... */
7189       if (vam->do_exit)
7190         break;
7191     }
7192
7193   /* When testing multiple add/del ops, use a control-ping to sync */
7194   if (count > 1)
7195     {
7196       vl_api_control_ping_t *mp_ping;
7197       f64 after;
7198       f64 timeout;
7199
7200       /* Shut off async mode */
7201       vam->async_mode = 0;
7202
7203       M (CONTROL_PING, mp_ping);
7204       S (mp_ping);
7205
7206       timeout = vat_time_now (vam) + 1.0;
7207       while (vat_time_now (vam) < timeout)
7208         if (vam->result_ready == 1)
7209           goto out;
7210       vam->retval = -99;
7211
7212     out:
7213       if (vam->retval == -99)
7214         errmsg ("timeout");
7215
7216       if (vam->async_errors > 0)
7217         {
7218           errmsg ("%d asynchronous errors", vam->async_errors);
7219           vam->retval = -98;
7220         }
7221       vam->async_errors = 0;
7222       after = vat_time_now (vam);
7223
7224       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7225       if (j > 0)
7226         count = j;
7227
7228       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7229              count, after - before, count / (after - before));
7230     }
7231   else
7232     {
7233       int ret;
7234
7235       /* Wait for a reply... */
7236       W (ret);
7237       return ret;
7238     }
7239
7240   /* Return the good/bad news */
7241   return (vam->retval);
7242 }
7243
7244 static int
7245 api_ip_mroute_add_del (vat_main_t * vam)
7246 {
7247   unformat_input_t *i = vam->input;
7248   vl_api_ip_mroute_add_del_t *mp;
7249   u32 sw_if_index = ~0, vrf_id = 0;
7250   u8 is_ipv6 = 0;
7251   u8 is_local = 0;
7252   u8 create_vrf_if_needed = 0;
7253   u8 is_add = 1;
7254   u8 address_set = 0;
7255   u32 grp_address_length = 0;
7256   ip4_address_t v4_grp_address, v4_src_address;
7257   ip6_address_t v6_grp_address, v6_src_address;
7258   mfib_itf_flags_t iflags = 0;
7259   mfib_entry_flags_t eflags = 0;
7260   int ret;
7261
7262   /* Parse args required to build the message */
7263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7264     {
7265       if (unformat (i, "sw_if_index %d", &sw_if_index))
7266         ;
7267       else if (unformat (i, "%U %U",
7268                          unformat_ip4_address, &v4_src_address,
7269                          unformat_ip4_address, &v4_grp_address))
7270         {
7271           grp_address_length = 64;
7272           address_set = 1;
7273           is_ipv6 = 0;
7274         }
7275       else if (unformat (i, "%U %U",
7276                          unformat_ip6_address, &v6_src_address,
7277                          unformat_ip6_address, &v6_grp_address))
7278         {
7279           grp_address_length = 256;
7280           address_set = 1;
7281           is_ipv6 = 1;
7282         }
7283       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7284         {
7285           memset (&v4_src_address, 0, sizeof (v4_src_address));
7286           grp_address_length = 32;
7287           address_set = 1;
7288           is_ipv6 = 0;
7289         }
7290       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7291         {
7292           memset (&v6_src_address, 0, sizeof (v6_src_address));
7293           grp_address_length = 128;
7294           address_set = 1;
7295           is_ipv6 = 1;
7296         }
7297       else if (unformat (i, "/%d", &grp_address_length))
7298         ;
7299       else if (unformat (i, "local"))
7300         {
7301           is_local = 1;
7302         }
7303       else if (unformat (i, "del"))
7304         is_add = 0;
7305       else if (unformat (i, "add"))
7306         is_add = 1;
7307       else if (unformat (i, "vrf %d", &vrf_id))
7308         ;
7309       else if (unformat (i, "create-vrf"))
7310         create_vrf_if_needed = 1;
7311       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7312         ;
7313       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7314         ;
7315       else
7316         {
7317           clib_warning ("parse error '%U'", format_unformat_error, i);
7318           return -99;
7319         }
7320     }
7321
7322   if (address_set == 0)
7323     {
7324       errmsg ("missing addresses\n");
7325       return -99;
7326     }
7327
7328   /* Construct the API message */
7329   M (IP_MROUTE_ADD_DEL, mp);
7330
7331   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7332   mp->table_id = ntohl (vrf_id);
7333   mp->create_vrf_if_needed = create_vrf_if_needed;
7334
7335   mp->is_add = is_add;
7336   mp->is_ipv6 = is_ipv6;
7337   mp->is_local = is_local;
7338   mp->itf_flags = ntohl (iflags);
7339   mp->entry_flags = ntohl (eflags);
7340   mp->grp_address_length = grp_address_length;
7341   mp->grp_address_length = ntohs (mp->grp_address_length);
7342
7343   if (is_ipv6)
7344     {
7345       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7346       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7347     }
7348   else
7349     {
7350       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7351       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7352
7353     }
7354
7355   /* send it... */
7356   S (mp);
7357   /* Wait for a reply... */
7358   W (ret);
7359   return ret;
7360 }
7361
7362 static int
7363 api_mpls_route_add_del (vat_main_t * vam)
7364 {
7365   unformat_input_t *i = vam->input;
7366   vl_api_mpls_route_add_del_t *mp;
7367   u32 sw_if_index = ~0, table_id = 0;
7368   u8 create_table_if_needed = 0;
7369   u8 is_add = 1;
7370   u32 next_hop_weight = 1;
7371   u8 is_multipath = 0;
7372   u32 next_hop_table_id = 0;
7373   u8 next_hop_set = 0;
7374   ip4_address_t v4_next_hop_address = {
7375     .as_u32 = 0,
7376   };
7377   ip6_address_t v6_next_hop_address = { {0} };
7378   int count = 1;
7379   int j;
7380   f64 before = 0;
7381   u32 classify_table_index = ~0;
7382   u8 is_classify = 0;
7383   u8 resolve_host = 0, resolve_attached = 0;
7384   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7385   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7386   mpls_label_t *next_hop_out_label_stack = NULL;
7387   mpls_label_t local_label = MPLS_LABEL_INVALID;
7388   u8 is_eos = 0;
7389   u8 next_hop_proto_is_ip4 = 1;
7390
7391   /* Parse args required to build the message */
7392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7393     {
7394       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7395         ;
7396       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7397         ;
7398       else if (unformat (i, "%d", &local_label))
7399         ;
7400       else if (unformat (i, "eos"))
7401         is_eos = 1;
7402       else if (unformat (i, "non-eos"))
7403         is_eos = 0;
7404       else if (unformat (i, "via %U", unformat_ip4_address,
7405                          &v4_next_hop_address))
7406         {
7407           next_hop_set = 1;
7408           next_hop_proto_is_ip4 = 1;
7409         }
7410       else if (unformat (i, "via %U", unformat_ip6_address,
7411                          &v6_next_hop_address))
7412         {
7413           next_hop_set = 1;
7414           next_hop_proto_is_ip4 = 0;
7415         }
7416       else if (unformat (i, "weight %d", &next_hop_weight))
7417         ;
7418       else if (unformat (i, "create-table"))
7419         create_table_if_needed = 1;
7420       else if (unformat (i, "classify %d", &classify_table_index))
7421         {
7422           is_classify = 1;
7423         }
7424       else if (unformat (i, "del"))
7425         is_add = 0;
7426       else if (unformat (i, "add"))
7427         is_add = 1;
7428       else if (unformat (i, "resolve-via-host"))
7429         resolve_host = 1;
7430       else if (unformat (i, "resolve-via-attached"))
7431         resolve_attached = 1;
7432       else if (unformat (i, "multipath"))
7433         is_multipath = 1;
7434       else if (unformat (i, "count %d", &count))
7435         ;
7436       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7437         {
7438           next_hop_set = 1;
7439           next_hop_proto_is_ip4 = 1;
7440         }
7441       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7442         {
7443           next_hop_set = 1;
7444           next_hop_proto_is_ip4 = 0;
7445         }
7446       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7447         ;
7448       else if (unformat (i, "via-label %d", &next_hop_via_label))
7449         ;
7450       else if (unformat (i, "out-label %d", &next_hop_out_label))
7451         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7452       else
7453         {
7454           clib_warning ("parse error '%U'", format_unformat_error, i);
7455           return -99;
7456         }
7457     }
7458
7459   if (!next_hop_set && !is_classify)
7460     {
7461       errmsg ("next hop / classify not set");
7462       return -99;
7463     }
7464
7465   if (MPLS_LABEL_INVALID == local_label)
7466     {
7467       errmsg ("missing label");
7468       return -99;
7469     }
7470
7471   if (count > 1)
7472     {
7473       /* Turn on async mode */
7474       vam->async_mode = 1;
7475       vam->async_errors = 0;
7476       before = vat_time_now (vam);
7477     }
7478
7479   for (j = 0; j < count; j++)
7480     {
7481       /* Construct the API message */
7482       M2 (MPLS_ROUTE_ADD_DEL, mp,
7483           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7484
7485       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7486       mp->mr_table_id = ntohl (table_id);
7487       mp->mr_create_table_if_needed = create_table_if_needed;
7488
7489       mp->mr_is_add = is_add;
7490       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7491       mp->mr_is_classify = is_classify;
7492       mp->mr_is_multipath = is_multipath;
7493       mp->mr_is_resolve_host = resolve_host;
7494       mp->mr_is_resolve_attached = resolve_attached;
7495       mp->mr_next_hop_weight = next_hop_weight;
7496       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7497       mp->mr_classify_table_index = ntohl (classify_table_index);
7498       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7499       mp->mr_label = ntohl (local_label);
7500       mp->mr_eos = is_eos;
7501
7502       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7503       if (0 != mp->mr_next_hop_n_out_labels)
7504         {
7505           memcpy (mp->mr_next_hop_out_label_stack,
7506                   next_hop_out_label_stack,
7507                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7508           vec_free (next_hop_out_label_stack);
7509         }
7510
7511       if (next_hop_set)
7512         {
7513           if (next_hop_proto_is_ip4)
7514             {
7515               clib_memcpy (mp->mr_next_hop,
7516                            &v4_next_hop_address,
7517                            sizeof (v4_next_hop_address));
7518             }
7519           else
7520             {
7521               clib_memcpy (mp->mr_next_hop,
7522                            &v6_next_hop_address,
7523                            sizeof (v6_next_hop_address));
7524             }
7525         }
7526       local_label++;
7527
7528       /* send it... */
7529       S (mp);
7530       /* If we receive SIGTERM, stop now... */
7531       if (vam->do_exit)
7532         break;
7533     }
7534
7535   /* When testing multiple add/del ops, use a control-ping to sync */
7536   if (count > 1)
7537     {
7538       vl_api_control_ping_t *mp_ping;
7539       f64 after;
7540       f64 timeout;
7541
7542       /* Shut off async mode */
7543       vam->async_mode = 0;
7544
7545       M (CONTROL_PING, mp_ping);
7546       S (mp_ping);
7547
7548       timeout = vat_time_now (vam) + 1.0;
7549       while (vat_time_now (vam) < timeout)
7550         if (vam->result_ready == 1)
7551           goto out;
7552       vam->retval = -99;
7553
7554     out:
7555       if (vam->retval == -99)
7556         errmsg ("timeout");
7557
7558       if (vam->async_errors > 0)
7559         {
7560           errmsg ("%d asynchronous errors", vam->async_errors);
7561           vam->retval = -98;
7562         }
7563       vam->async_errors = 0;
7564       after = vat_time_now (vam);
7565
7566       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7567       if (j > 0)
7568         count = j;
7569
7570       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7571              count, after - before, count / (after - before));
7572     }
7573   else
7574     {
7575       int ret;
7576
7577       /* Wait for a reply... */
7578       W (ret);
7579       return ret;
7580     }
7581
7582   /* Return the good/bad news */
7583   return (vam->retval);
7584 }
7585
7586 static int
7587 api_mpls_ip_bind_unbind (vat_main_t * vam)
7588 {
7589   unformat_input_t *i = vam->input;
7590   vl_api_mpls_ip_bind_unbind_t *mp;
7591   u32 ip_table_id = 0;
7592   u8 create_table_if_needed = 0;
7593   u8 is_bind = 1;
7594   u8 is_ip4 = 1;
7595   ip4_address_t v4_address;
7596   ip6_address_t v6_address;
7597   u32 address_length;
7598   u8 address_set = 0;
7599   mpls_label_t local_label = MPLS_LABEL_INVALID;
7600   int ret;
7601
7602   /* Parse args required to build the message */
7603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7604     {
7605       if (unformat (i, "%U/%d", unformat_ip4_address,
7606                     &v4_address, &address_length))
7607         {
7608           is_ip4 = 1;
7609           address_set = 1;
7610         }
7611       else if (unformat (i, "%U/%d", unformat_ip6_address,
7612                          &v6_address, &address_length))
7613         {
7614           is_ip4 = 0;
7615           address_set = 1;
7616         }
7617       else if (unformat (i, "%d", &local_label))
7618         ;
7619       else if (unformat (i, "create-table"))
7620         create_table_if_needed = 1;
7621       else if (unformat (i, "table-id %d", &ip_table_id))
7622         ;
7623       else if (unformat (i, "unbind"))
7624         is_bind = 0;
7625       else if (unformat (i, "bind"))
7626         is_bind = 1;
7627       else
7628         {
7629           clib_warning ("parse error '%U'", format_unformat_error, i);
7630           return -99;
7631         }
7632     }
7633
7634   if (!address_set)
7635     {
7636       errmsg ("IP addres not set");
7637       return -99;
7638     }
7639
7640   if (MPLS_LABEL_INVALID == local_label)
7641     {
7642       errmsg ("missing label");
7643       return -99;
7644     }
7645
7646   /* Construct the API message */
7647   M (MPLS_IP_BIND_UNBIND, mp);
7648
7649   mp->mb_create_table_if_needed = create_table_if_needed;
7650   mp->mb_is_bind = is_bind;
7651   mp->mb_is_ip4 = is_ip4;
7652   mp->mb_ip_table_id = ntohl (ip_table_id);
7653   mp->mb_mpls_table_id = 0;
7654   mp->mb_label = ntohl (local_label);
7655   mp->mb_address_length = address_length;
7656
7657   if (is_ip4)
7658     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7659   else
7660     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7661
7662   /* send it... */
7663   S (mp);
7664
7665   /* Wait for a reply... */
7666   W (ret);
7667   return ret;
7668 }
7669
7670 static int
7671 api_proxy_arp_add_del (vat_main_t * vam)
7672 {
7673   unformat_input_t *i = vam->input;
7674   vl_api_proxy_arp_add_del_t *mp;
7675   u32 vrf_id = 0;
7676   u8 is_add = 1;
7677   ip4_address_t lo, hi;
7678   u8 range_set = 0;
7679   int ret;
7680
7681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7682     {
7683       if (unformat (i, "vrf %d", &vrf_id))
7684         ;
7685       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7686                          unformat_ip4_address, &hi))
7687         range_set = 1;
7688       else if (unformat (i, "del"))
7689         is_add = 0;
7690       else
7691         {
7692           clib_warning ("parse error '%U'", format_unformat_error, i);
7693           return -99;
7694         }
7695     }
7696
7697   if (range_set == 0)
7698     {
7699       errmsg ("address range not set");
7700       return -99;
7701     }
7702
7703   M (PROXY_ARP_ADD_DEL, mp);
7704
7705   mp->vrf_id = ntohl (vrf_id);
7706   mp->is_add = is_add;
7707   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7708   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7709
7710   S (mp);
7711   W (ret);
7712   return ret;
7713 }
7714
7715 static int
7716 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7717 {
7718   unformat_input_t *i = vam->input;
7719   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7720   u32 sw_if_index;
7721   u8 enable = 1;
7722   u8 sw_if_index_set = 0;
7723   int ret;
7724
7725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7726     {
7727       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7728         sw_if_index_set = 1;
7729       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7730         sw_if_index_set = 1;
7731       else if (unformat (i, "enable"))
7732         enable = 1;
7733       else if (unformat (i, "disable"))
7734         enable = 0;
7735       else
7736         {
7737           clib_warning ("parse error '%U'", format_unformat_error, i);
7738           return -99;
7739         }
7740     }
7741
7742   if (sw_if_index_set == 0)
7743     {
7744       errmsg ("missing interface name or sw_if_index");
7745       return -99;
7746     }
7747
7748   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7749
7750   mp->sw_if_index = ntohl (sw_if_index);
7751   mp->enable_disable = enable;
7752
7753   S (mp);
7754   W (ret);
7755   return ret;
7756 }
7757
7758 static int
7759 api_mpls_tunnel_add_del (vat_main_t * vam)
7760 {
7761   unformat_input_t *i = vam->input;
7762   vl_api_mpls_tunnel_add_del_t *mp;
7763
7764   u8 is_add = 1;
7765   u8 l2_only = 0;
7766   u32 sw_if_index = ~0;
7767   u32 next_hop_sw_if_index = ~0;
7768   u32 next_hop_proto_is_ip4 = 1;
7769
7770   u32 next_hop_table_id = 0;
7771   ip4_address_t v4_next_hop_address = {
7772     .as_u32 = 0,
7773   };
7774   ip6_address_t v6_next_hop_address = { {0} };
7775   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7776   int ret;
7777
7778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7779     {
7780       if (unformat (i, "add"))
7781         is_add = 1;
7782       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7783         is_add = 0;
7784       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7785         ;
7786       else if (unformat (i, "via %U",
7787                          unformat_ip4_address, &v4_next_hop_address))
7788         {
7789           next_hop_proto_is_ip4 = 1;
7790         }
7791       else if (unformat (i, "via %U",
7792                          unformat_ip6_address, &v6_next_hop_address))
7793         {
7794           next_hop_proto_is_ip4 = 0;
7795         }
7796       else if (unformat (i, "l2-only"))
7797         l2_only = 1;
7798       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7799         ;
7800       else if (unformat (i, "out-label %d", &next_hop_out_label))
7801         vec_add1 (labels, ntohl (next_hop_out_label));
7802       else
7803         {
7804           clib_warning ("parse error '%U'", format_unformat_error, i);
7805           return -99;
7806         }
7807     }
7808
7809   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7810
7811   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7812   mp->mt_sw_if_index = ntohl (sw_if_index);
7813   mp->mt_is_add = is_add;
7814   mp->mt_l2_only = l2_only;
7815   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7816   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7817
7818   mp->mt_next_hop_n_out_labels = vec_len (labels);
7819
7820   if (0 != mp->mt_next_hop_n_out_labels)
7821     {
7822       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7823                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7824       vec_free (labels);
7825     }
7826
7827   if (next_hop_proto_is_ip4)
7828     {
7829       clib_memcpy (mp->mt_next_hop,
7830                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7831     }
7832   else
7833     {
7834       clib_memcpy (mp->mt_next_hop,
7835                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7836     }
7837
7838   S (mp);
7839   W (ret);
7840   return ret;
7841 }
7842
7843 static int
7844 api_sw_interface_set_unnumbered (vat_main_t * vam)
7845 {
7846   unformat_input_t *i = vam->input;
7847   vl_api_sw_interface_set_unnumbered_t *mp;
7848   u32 sw_if_index;
7849   u32 unnum_sw_index = ~0;
7850   u8 is_add = 1;
7851   u8 sw_if_index_set = 0;
7852   int ret;
7853
7854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7855     {
7856       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7857         sw_if_index_set = 1;
7858       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7859         sw_if_index_set = 1;
7860       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7861         ;
7862       else if (unformat (i, "del"))
7863         is_add = 0;
7864       else
7865         {
7866           clib_warning ("parse error '%U'", format_unformat_error, i);
7867           return -99;
7868         }
7869     }
7870
7871   if (sw_if_index_set == 0)
7872     {
7873       errmsg ("missing interface name or sw_if_index");
7874       return -99;
7875     }
7876
7877   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7878
7879   mp->sw_if_index = ntohl (sw_if_index);
7880   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7881   mp->is_add = is_add;
7882
7883   S (mp);
7884   W (ret);
7885   return ret;
7886 }
7887
7888 static int
7889 api_ip_neighbor_add_del (vat_main_t * vam)
7890 {
7891   unformat_input_t *i = vam->input;
7892   vl_api_ip_neighbor_add_del_t *mp;
7893   u32 sw_if_index;
7894   u8 sw_if_index_set = 0;
7895   u8 is_add = 1;
7896   u8 is_static = 0;
7897   u8 is_no_fib_entry = 0;
7898   u8 mac_address[6];
7899   u8 mac_set = 0;
7900   u8 v4_address_set = 0;
7901   u8 v6_address_set = 0;
7902   ip4_address_t v4address;
7903   ip6_address_t v6address;
7904   int ret;
7905
7906   memset (mac_address, 0, sizeof (mac_address));
7907
7908   /* Parse args required to build the message */
7909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7910     {
7911       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7912         {
7913           mac_set = 1;
7914         }
7915       else if (unformat (i, "del"))
7916         is_add = 0;
7917       else
7918         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7919         sw_if_index_set = 1;
7920       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7921         sw_if_index_set = 1;
7922       else if (unformat (i, "is_static"))
7923         is_static = 1;
7924       else if (unformat (i, "no-fib-entry"))
7925         is_no_fib_entry = 1;
7926       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7927         v4_address_set = 1;
7928       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7929         v6_address_set = 1;
7930       else
7931         {
7932           clib_warning ("parse error '%U'", format_unformat_error, i);
7933           return -99;
7934         }
7935     }
7936
7937   if (sw_if_index_set == 0)
7938     {
7939       errmsg ("missing interface name or sw_if_index");
7940       return -99;
7941     }
7942   if (v4_address_set && v6_address_set)
7943     {
7944       errmsg ("both v4 and v6 addresses set");
7945       return -99;
7946     }
7947   if (!v4_address_set && !v6_address_set)
7948     {
7949       errmsg ("no address set");
7950       return -99;
7951     }
7952
7953   /* Construct the API message */
7954   M (IP_NEIGHBOR_ADD_DEL, mp);
7955
7956   mp->sw_if_index = ntohl (sw_if_index);
7957   mp->is_add = is_add;
7958   mp->is_static = is_static;
7959   mp->is_no_adj_fib = is_no_fib_entry;
7960   if (mac_set)
7961     clib_memcpy (mp->mac_address, mac_address, 6);
7962   if (v6_address_set)
7963     {
7964       mp->is_ipv6 = 1;
7965       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7966     }
7967   else
7968     {
7969       /* mp->is_ipv6 = 0; via memset in M macro above */
7970       clib_memcpy (mp->dst_address, &v4address, 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 static int
7982 api_reset_vrf (vat_main_t * vam)
7983 {
7984   unformat_input_t *i = vam->input;
7985   vl_api_reset_vrf_t *mp;
7986   u32 vrf_id = 0;
7987   u8 is_ipv6 = 0;
7988   u8 vrf_id_set = 0;
7989   int ret;
7990
7991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7992     {
7993       if (unformat (i, "vrf %d", &vrf_id))
7994         vrf_id_set = 1;
7995       else if (unformat (i, "ipv6"))
7996         is_ipv6 = 1;
7997       else
7998         {
7999           clib_warning ("parse error '%U'", format_unformat_error, i);
8000           return -99;
8001         }
8002     }
8003
8004   if (vrf_id_set == 0)
8005     {
8006       errmsg ("missing vrf id");
8007       return -99;
8008     }
8009
8010   M (RESET_VRF, mp);
8011
8012   mp->vrf_id = ntohl (vrf_id);
8013   mp->is_ipv6 = is_ipv6;
8014
8015   S (mp);
8016   W (ret);
8017   return ret;
8018 }
8019
8020 static int
8021 api_create_vlan_subif (vat_main_t * vam)
8022 {
8023   unformat_input_t *i = vam->input;
8024   vl_api_create_vlan_subif_t *mp;
8025   u32 sw_if_index;
8026   u8 sw_if_index_set = 0;
8027   u32 vlan_id;
8028   u8 vlan_id_set = 0;
8029   int ret;
8030
8031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8032     {
8033       if (unformat (i, "sw_if_index %d", &sw_if_index))
8034         sw_if_index_set = 1;
8035       else
8036         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8037         sw_if_index_set = 1;
8038       else if (unformat (i, "vlan %d", &vlan_id))
8039         vlan_id_set = 1;
8040       else
8041         {
8042           clib_warning ("parse error '%U'", format_unformat_error, i);
8043           return -99;
8044         }
8045     }
8046
8047   if (sw_if_index_set == 0)
8048     {
8049       errmsg ("missing interface name or sw_if_index");
8050       return -99;
8051     }
8052
8053   if (vlan_id_set == 0)
8054     {
8055       errmsg ("missing vlan_id");
8056       return -99;
8057     }
8058   M (CREATE_VLAN_SUBIF, mp);
8059
8060   mp->sw_if_index = ntohl (sw_if_index);
8061   mp->vlan_id = ntohl (vlan_id);
8062
8063   S (mp);
8064   W (ret);
8065   return ret;
8066 }
8067
8068 #define foreach_create_subif_bit                \
8069 _(no_tags)                                      \
8070 _(one_tag)                                      \
8071 _(two_tags)                                     \
8072 _(dot1ad)                                       \
8073 _(exact_match)                                  \
8074 _(default_sub)                                  \
8075 _(outer_vlan_id_any)                            \
8076 _(inner_vlan_id_any)
8077
8078 static int
8079 api_create_subif (vat_main_t * vam)
8080 {
8081   unformat_input_t *i = vam->input;
8082   vl_api_create_subif_t *mp;
8083   u32 sw_if_index;
8084   u8 sw_if_index_set = 0;
8085   u32 sub_id;
8086   u8 sub_id_set = 0;
8087   u32 no_tags = 0;
8088   u32 one_tag = 0;
8089   u32 two_tags = 0;
8090   u32 dot1ad = 0;
8091   u32 exact_match = 0;
8092   u32 default_sub = 0;
8093   u32 outer_vlan_id_any = 0;
8094   u32 inner_vlan_id_any = 0;
8095   u32 tmp;
8096   u16 outer_vlan_id = 0;
8097   u16 inner_vlan_id = 0;
8098   int ret;
8099
8100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8101     {
8102       if (unformat (i, "sw_if_index %d", &sw_if_index))
8103         sw_if_index_set = 1;
8104       else
8105         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8106         sw_if_index_set = 1;
8107       else if (unformat (i, "sub_id %d", &sub_id))
8108         sub_id_set = 1;
8109       else if (unformat (i, "outer_vlan_id %d", &tmp))
8110         outer_vlan_id = tmp;
8111       else if (unformat (i, "inner_vlan_id %d", &tmp))
8112         inner_vlan_id = tmp;
8113
8114 #define _(a) else if (unformat (i, #a)) a = 1 ;
8115       foreach_create_subif_bit
8116 #undef _
8117         else
8118         {
8119           clib_warning ("parse error '%U'", format_unformat_error, i);
8120           return -99;
8121         }
8122     }
8123
8124   if (sw_if_index_set == 0)
8125     {
8126       errmsg ("missing interface name or sw_if_index");
8127       return -99;
8128     }
8129
8130   if (sub_id_set == 0)
8131     {
8132       errmsg ("missing sub_id");
8133       return -99;
8134     }
8135   M (CREATE_SUBIF, mp);
8136
8137   mp->sw_if_index = ntohl (sw_if_index);
8138   mp->sub_id = ntohl (sub_id);
8139
8140 #define _(a) mp->a = a;
8141   foreach_create_subif_bit;
8142 #undef _
8143
8144   mp->outer_vlan_id = ntohs (outer_vlan_id);
8145   mp->inner_vlan_id = ntohs (inner_vlan_id);
8146
8147   S (mp);
8148   W (ret);
8149   return ret;
8150 }
8151
8152 static int
8153 api_oam_add_del (vat_main_t * vam)
8154 {
8155   unformat_input_t *i = vam->input;
8156   vl_api_oam_add_del_t *mp;
8157   u32 vrf_id = 0;
8158   u8 is_add = 1;
8159   ip4_address_t src, dst;
8160   u8 src_set = 0;
8161   u8 dst_set = 0;
8162   int ret;
8163
8164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8165     {
8166       if (unformat (i, "vrf %d", &vrf_id))
8167         ;
8168       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8169         src_set = 1;
8170       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8171         dst_set = 1;
8172       else if (unformat (i, "del"))
8173         is_add = 0;
8174       else
8175         {
8176           clib_warning ("parse error '%U'", format_unformat_error, i);
8177           return -99;
8178         }
8179     }
8180
8181   if (src_set == 0)
8182     {
8183       errmsg ("missing src addr");
8184       return -99;
8185     }
8186
8187   if (dst_set == 0)
8188     {
8189       errmsg ("missing dst addr");
8190       return -99;
8191     }
8192
8193   M (OAM_ADD_DEL, mp);
8194
8195   mp->vrf_id = ntohl (vrf_id);
8196   mp->is_add = is_add;
8197   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8198   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8199
8200   S (mp);
8201   W (ret);
8202   return ret;
8203 }
8204
8205 static int
8206 api_reset_fib (vat_main_t * vam)
8207 {
8208   unformat_input_t *i = vam->input;
8209   vl_api_reset_fib_t *mp;
8210   u32 vrf_id = 0;
8211   u8 is_ipv6 = 0;
8212   u8 vrf_id_set = 0;
8213
8214   int ret;
8215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8216     {
8217       if (unformat (i, "vrf %d", &vrf_id))
8218         vrf_id_set = 1;
8219       else if (unformat (i, "ipv6"))
8220         is_ipv6 = 1;
8221       else
8222         {
8223           clib_warning ("parse error '%U'", format_unformat_error, i);
8224           return -99;
8225         }
8226     }
8227
8228   if (vrf_id_set == 0)
8229     {
8230       errmsg ("missing vrf id");
8231       return -99;
8232     }
8233
8234   M (RESET_FIB, mp);
8235
8236   mp->vrf_id = ntohl (vrf_id);
8237   mp->is_ipv6 = is_ipv6;
8238
8239   S (mp);
8240   W (ret);
8241   return ret;
8242 }
8243
8244 static int
8245 api_dhcp_proxy_config (vat_main_t * vam)
8246 {
8247   unformat_input_t *i = vam->input;
8248   vl_api_dhcp_proxy_config_t *mp;
8249   u32 rx_vrf_id = 0;
8250   u32 server_vrf_id = 0;
8251   u8 is_add = 1;
8252   u8 v4_address_set = 0;
8253   u8 v6_address_set = 0;
8254   ip4_address_t v4address;
8255   ip6_address_t v6address;
8256   u8 v4_src_address_set = 0;
8257   u8 v6_src_address_set = 0;
8258   ip4_address_t v4srcaddress;
8259   ip6_address_t v6srcaddress;
8260   int ret;
8261
8262   /* Parse args required to build the message */
8263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8264     {
8265       if (unformat (i, "del"))
8266         is_add = 0;
8267       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8268         ;
8269       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8270         ;
8271       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8272         v4_address_set = 1;
8273       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8274         v6_address_set = 1;
8275       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8276         v4_src_address_set = 1;
8277       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8278         v6_src_address_set = 1;
8279       else
8280         break;
8281     }
8282
8283   if (v4_address_set && v6_address_set)
8284     {
8285       errmsg ("both v4 and v6 server addresses set");
8286       return -99;
8287     }
8288   if (!v4_address_set && !v6_address_set)
8289     {
8290       errmsg ("no server addresses set");
8291       return -99;
8292     }
8293
8294   if (v4_src_address_set && v6_src_address_set)
8295     {
8296       errmsg ("both v4 and v6  src addresses set");
8297       return -99;
8298     }
8299   if (!v4_src_address_set && !v6_src_address_set)
8300     {
8301       errmsg ("no src addresses set");
8302       return -99;
8303     }
8304
8305   if (!(v4_src_address_set && v4_address_set) &&
8306       !(v6_src_address_set && v6_address_set))
8307     {
8308       errmsg ("no matching server and src addresses set");
8309       return -99;
8310     }
8311
8312   /* Construct the API message */
8313   M (DHCP_PROXY_CONFIG, mp);
8314
8315   mp->is_add = is_add;
8316   mp->rx_vrf_id = ntohl (rx_vrf_id);
8317   mp->server_vrf_id = ntohl (server_vrf_id);
8318   if (v6_address_set)
8319     {
8320       mp->is_ipv6 = 1;
8321       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8322       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8323     }
8324   else
8325     {
8326       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8327       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8328     }
8329
8330   /* send it... */
8331   S (mp);
8332
8333   /* Wait for a reply, return good/bad news  */
8334   W (ret);
8335   return ret;
8336 }
8337
8338 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8339 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8340
8341 static void
8342 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8343 {
8344   vat_main_t *vam = &vat_main;
8345   u32 i, count = mp->count;
8346   vl_api_dhcp_server_t *s;
8347
8348   if (mp->is_ipv6)
8349     print (vam->ofp,
8350            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8351            ntohl (mp->rx_vrf_id),
8352            format_ip6_address, mp->dhcp_src_address,
8353            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8354   else
8355     print (vam->ofp,
8356            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8357            ntohl (mp->rx_vrf_id),
8358            format_ip4_address, mp->dhcp_src_address,
8359            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8360
8361   for (i = 0; i < count; i++)
8362     {
8363       s = &mp->servers[i];
8364
8365       if (mp->is_ipv6)
8366         print (vam->ofp,
8367                " Server Table-ID %d, Server Address %U",
8368                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8369       else
8370         print (vam->ofp,
8371                " Server Table-ID %d, Server Address %U",
8372                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8373     }
8374 }
8375
8376 static void vl_api_dhcp_proxy_details_t_handler_json
8377   (vl_api_dhcp_proxy_details_t * mp)
8378 {
8379   vat_main_t *vam = &vat_main;
8380   vat_json_node_t *node = NULL;
8381   u32 i, count = mp->count;
8382   struct in_addr ip4;
8383   struct in6_addr ip6;
8384   vl_api_dhcp_server_t *s;
8385
8386   if (VAT_JSON_ARRAY != vam->json_tree.type)
8387     {
8388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8389       vat_json_init_array (&vam->json_tree);
8390     }
8391   node = vat_json_array_add (&vam->json_tree);
8392
8393   vat_json_init_object (node);
8394   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8395   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8396   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8397
8398   if (mp->is_ipv6)
8399     {
8400       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8401       vat_json_object_add_ip6 (node, "src_address", ip6);
8402     }
8403   else
8404     {
8405       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8406       vat_json_object_add_ip4 (node, "src_address", ip4);
8407     }
8408
8409   for (i = 0; i < count; i++)
8410     {
8411       s = &mp->servers[i];
8412
8413       vat_json_object_add_uint (node, "server-table-id",
8414                                 ntohl (s->server_vrf_id));
8415
8416       if (mp->is_ipv6)
8417         {
8418           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8419           vat_json_object_add_ip4 (node, "src_address", ip4);
8420         }
8421       else
8422         {
8423           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8424           vat_json_object_add_ip6 (node, "server_address", ip6);
8425         }
8426     }
8427 }
8428
8429 static int
8430 api_dhcp_proxy_dump (vat_main_t * vam)
8431 {
8432   unformat_input_t *i = vam->input;
8433   vl_api_control_ping_t *mp_ping;
8434   vl_api_dhcp_proxy_dump_t *mp;
8435   u8 is_ipv6 = 0;
8436   int ret;
8437
8438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8439     {
8440       if (unformat (i, "ipv6"))
8441         is_ipv6 = 1;
8442       else
8443         {
8444           clib_warning ("parse error '%U'", format_unformat_error, i);
8445           return -99;
8446         }
8447     }
8448
8449   M (DHCP_PROXY_DUMP, mp);
8450
8451   mp->is_ip6 = is_ipv6;
8452   S (mp);
8453
8454   /* Use a control ping for synchronization */
8455   M (CONTROL_PING, mp_ping);
8456   S (mp_ping);
8457
8458   W (ret);
8459   return ret;
8460 }
8461
8462 static int
8463 api_dhcp_proxy_set_vss (vat_main_t * vam)
8464 {
8465   unformat_input_t *i = vam->input;
8466   vl_api_dhcp_proxy_set_vss_t *mp;
8467   u8 is_ipv6 = 0;
8468   u8 is_add = 1;
8469   u32 tbl_id;
8470   u8 tbl_id_set = 0;
8471   u32 oui;
8472   u8 oui_set = 0;
8473   u32 fib_id;
8474   u8 fib_id_set = 0;
8475   int ret;
8476
8477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8478     {
8479       if (unformat (i, "tbl_id %d", &tbl_id))
8480         tbl_id_set = 1;
8481       if (unformat (i, "fib_id %d", &fib_id))
8482         fib_id_set = 1;
8483       if (unformat (i, "oui %d", &oui))
8484         oui_set = 1;
8485       else if (unformat (i, "ipv6"))
8486         is_ipv6 = 1;
8487       else if (unformat (i, "del"))
8488         is_add = 0;
8489       else
8490         {
8491           clib_warning ("parse error '%U'", format_unformat_error, i);
8492           return -99;
8493         }
8494     }
8495
8496   if (tbl_id_set == 0)
8497     {
8498       errmsg ("missing tbl id");
8499       return -99;
8500     }
8501
8502   if (fib_id_set == 0)
8503     {
8504       errmsg ("missing fib id");
8505       return -99;
8506     }
8507   if (oui_set == 0)
8508     {
8509       errmsg ("missing oui");
8510       return -99;
8511     }
8512
8513   M (DHCP_PROXY_SET_VSS, mp);
8514   mp->tbl_id = ntohl (tbl_id);
8515   mp->fib_id = ntohl (fib_id);
8516   mp->oui = ntohl (oui);
8517   mp->is_ipv6 = is_ipv6;
8518   mp->is_add = is_add;
8519
8520   S (mp);
8521   W (ret);
8522   return ret;
8523 }
8524
8525 static int
8526 api_dhcp_client_config (vat_main_t * vam)
8527 {
8528   unformat_input_t *i = vam->input;
8529   vl_api_dhcp_client_config_t *mp;
8530   u32 sw_if_index;
8531   u8 sw_if_index_set = 0;
8532   u8 is_add = 1;
8533   u8 *hostname = 0;
8534   u8 disable_event = 0;
8535   int ret;
8536
8537   /* Parse args required to build the message */
8538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8539     {
8540       if (unformat (i, "del"))
8541         is_add = 0;
8542       else
8543         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8544         sw_if_index_set = 1;
8545       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8546         sw_if_index_set = 1;
8547       else if (unformat (i, "hostname %s", &hostname))
8548         ;
8549       else if (unformat (i, "disable_event"))
8550         disable_event = 1;
8551       else
8552         break;
8553     }
8554
8555   if (sw_if_index_set == 0)
8556     {
8557       errmsg ("missing interface name or sw_if_index");
8558       return -99;
8559     }
8560
8561   if (vec_len (hostname) > 63)
8562     {
8563       errmsg ("hostname too long");
8564     }
8565   vec_add1 (hostname, 0);
8566
8567   /* Construct the API message */
8568   M (DHCP_CLIENT_CONFIG, mp);
8569
8570   mp->sw_if_index = htonl (sw_if_index);
8571   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8572   vec_free (hostname);
8573   mp->is_add = is_add;
8574   mp->want_dhcp_event = disable_event ? 0 : 1;
8575   mp->pid = htonl (getpid ());
8576
8577   /* send it... */
8578   S (mp);
8579
8580   /* Wait for a reply, return good/bad news  */
8581   W (ret);
8582   return ret;
8583 }
8584
8585 static int
8586 api_set_ip_flow_hash (vat_main_t * vam)
8587 {
8588   unformat_input_t *i = vam->input;
8589   vl_api_set_ip_flow_hash_t *mp;
8590   u32 vrf_id = 0;
8591   u8 is_ipv6 = 0;
8592   u8 vrf_id_set = 0;
8593   u8 src = 0;
8594   u8 dst = 0;
8595   u8 sport = 0;
8596   u8 dport = 0;
8597   u8 proto = 0;
8598   u8 reverse = 0;
8599   int ret;
8600
8601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8602     {
8603       if (unformat (i, "vrf %d", &vrf_id))
8604         vrf_id_set = 1;
8605       else if (unformat (i, "ipv6"))
8606         is_ipv6 = 1;
8607       else if (unformat (i, "src"))
8608         src = 1;
8609       else if (unformat (i, "dst"))
8610         dst = 1;
8611       else if (unformat (i, "sport"))
8612         sport = 1;
8613       else if (unformat (i, "dport"))
8614         dport = 1;
8615       else if (unformat (i, "proto"))
8616         proto = 1;
8617       else if (unformat (i, "reverse"))
8618         reverse = 1;
8619
8620       else
8621         {
8622           clib_warning ("parse error '%U'", format_unformat_error, i);
8623           return -99;
8624         }
8625     }
8626
8627   if (vrf_id_set == 0)
8628     {
8629       errmsg ("missing vrf id");
8630       return -99;
8631     }
8632
8633   M (SET_IP_FLOW_HASH, mp);
8634   mp->src = src;
8635   mp->dst = dst;
8636   mp->sport = sport;
8637   mp->dport = dport;
8638   mp->proto = proto;
8639   mp->reverse = reverse;
8640   mp->vrf_id = ntohl (vrf_id);
8641   mp->is_ipv6 = is_ipv6;
8642
8643   S (mp);
8644   W (ret);
8645   return ret;
8646 }
8647
8648 static int
8649 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8650 {
8651   unformat_input_t *i = vam->input;
8652   vl_api_sw_interface_ip6_enable_disable_t *mp;
8653   u32 sw_if_index;
8654   u8 sw_if_index_set = 0;
8655   u8 enable = 0;
8656   int ret;
8657
8658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8661         sw_if_index_set = 1;
8662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8663         sw_if_index_set = 1;
8664       else if (unformat (i, "enable"))
8665         enable = 1;
8666       else if (unformat (i, "disable"))
8667         enable = 0;
8668       else
8669         {
8670           clib_warning ("parse error '%U'", format_unformat_error, i);
8671           return -99;
8672         }
8673     }
8674
8675   if (sw_if_index_set == 0)
8676     {
8677       errmsg ("missing interface name or sw_if_index");
8678       return -99;
8679     }
8680
8681   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8682
8683   mp->sw_if_index = ntohl (sw_if_index);
8684   mp->enable = enable;
8685
8686   S (mp);
8687   W (ret);
8688   return ret;
8689 }
8690
8691 static int
8692 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8693 {
8694   unformat_input_t *i = vam->input;
8695   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8696   u32 sw_if_index;
8697   u8 sw_if_index_set = 0;
8698   u8 v6_address_set = 0;
8699   ip6_address_t v6address;
8700   int ret;
8701
8702   /* Parse args required to build the message */
8703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8704     {
8705       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8706         sw_if_index_set = 1;
8707       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8708         sw_if_index_set = 1;
8709       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8710         v6_address_set = 1;
8711       else
8712         break;
8713     }
8714
8715   if (sw_if_index_set == 0)
8716     {
8717       errmsg ("missing interface name or sw_if_index");
8718       return -99;
8719     }
8720   if (!v6_address_set)
8721     {
8722       errmsg ("no address set");
8723       return -99;
8724     }
8725
8726   /* Construct the API message */
8727   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8728
8729   mp->sw_if_index = ntohl (sw_if_index);
8730   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8731
8732   /* send it... */
8733   S (mp);
8734
8735   /* Wait for a reply, return good/bad news  */
8736   W (ret);
8737   return ret;
8738 }
8739
8740 static int
8741 api_ip6nd_proxy_add_del (vat_main_t * vam)
8742 {
8743   unformat_input_t *i = vam->input;
8744   vl_api_ip6nd_proxy_add_del_t *mp;
8745   u32 sw_if_index = ~0;
8746   u8 v6_address_set = 0;
8747   ip6_address_t v6address;
8748   u8 is_del = 0;
8749   int ret;
8750
8751   /* Parse args required to build the message */
8752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8753     {
8754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8755         ;
8756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8757         ;
8758       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8759         v6_address_set = 1;
8760       if (unformat (i, "del"))
8761         is_del = 1;
8762       else
8763         {
8764           clib_warning ("parse error '%U'", format_unformat_error, i);
8765           return -99;
8766         }
8767     }
8768
8769   if (sw_if_index == ~0)
8770     {
8771       errmsg ("missing interface name or sw_if_index");
8772       return -99;
8773     }
8774   if (!v6_address_set)
8775     {
8776       errmsg ("no address set");
8777       return -99;
8778     }
8779
8780   /* Construct the API message */
8781   M (IP6ND_PROXY_ADD_DEL, mp);
8782
8783   mp->is_del = is_del;
8784   mp->sw_if_index = ntohl (sw_if_index);
8785   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8786
8787   /* send it... */
8788   S (mp);
8789
8790   /* Wait for a reply, return good/bad news  */
8791   W (ret);
8792   return ret;
8793 }
8794
8795 static int
8796 api_ip6nd_proxy_dump (vat_main_t * vam)
8797 {
8798   vl_api_ip6nd_proxy_dump_t *mp;
8799   vl_api_control_ping_t *mp_ping;
8800   int ret;
8801
8802   M (IP6ND_PROXY_DUMP, mp);
8803
8804   S (mp);
8805
8806   /* Use a control ping for synchronization */
8807   M (CONTROL_PING, mp_ping);
8808   S (mp_ping);
8809
8810   W (ret);
8811   return ret;
8812 }
8813
8814 static void vl_api_ip6nd_proxy_details_t_handler
8815   (vl_api_ip6nd_proxy_details_t * mp)
8816 {
8817   vat_main_t *vam = &vat_main;
8818
8819   print (vam->ofp, "host %U sw_if_index %d",
8820          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8821 }
8822
8823 static void vl_api_ip6nd_proxy_details_t_handler_json
8824   (vl_api_ip6nd_proxy_details_t * mp)
8825 {
8826   vat_main_t *vam = &vat_main;
8827   struct in6_addr ip6;
8828   vat_json_node_t *node = NULL;
8829
8830   if (VAT_JSON_ARRAY != vam->json_tree.type)
8831     {
8832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8833       vat_json_init_array (&vam->json_tree);
8834     }
8835   node = vat_json_array_add (&vam->json_tree);
8836
8837   vat_json_init_object (node);
8838   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8839
8840   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8841   vat_json_object_add_ip6 (node, "host", ip6);
8842 }
8843
8844 static int
8845 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8846 {
8847   unformat_input_t *i = vam->input;
8848   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8849   u32 sw_if_index;
8850   u8 sw_if_index_set = 0;
8851   u32 address_length = 0;
8852   u8 v6_address_set = 0;
8853   ip6_address_t v6address;
8854   u8 use_default = 0;
8855   u8 no_advertise = 0;
8856   u8 off_link = 0;
8857   u8 no_autoconfig = 0;
8858   u8 no_onlink = 0;
8859   u8 is_no = 0;
8860   u32 val_lifetime = 0;
8861   u32 pref_lifetime = 0;
8862   int ret;
8863
8864   /* Parse args required to build the message */
8865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8866     {
8867       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8868         sw_if_index_set = 1;
8869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8870         sw_if_index_set = 1;
8871       else if (unformat (i, "%U/%d",
8872                          unformat_ip6_address, &v6address, &address_length))
8873         v6_address_set = 1;
8874       else if (unformat (i, "val_life %d", &val_lifetime))
8875         ;
8876       else if (unformat (i, "pref_life %d", &pref_lifetime))
8877         ;
8878       else if (unformat (i, "def"))
8879         use_default = 1;
8880       else if (unformat (i, "noadv"))
8881         no_advertise = 1;
8882       else if (unformat (i, "offl"))
8883         off_link = 1;
8884       else if (unformat (i, "noauto"))
8885         no_autoconfig = 1;
8886       else if (unformat (i, "nolink"))
8887         no_onlink = 1;
8888       else if (unformat (i, "isno"))
8889         is_no = 1;
8890       else
8891         {
8892           clib_warning ("parse error '%U'", format_unformat_error, i);
8893           return -99;
8894         }
8895     }
8896
8897   if (sw_if_index_set == 0)
8898     {
8899       errmsg ("missing interface name or sw_if_index");
8900       return -99;
8901     }
8902   if (!v6_address_set)
8903     {
8904       errmsg ("no address set");
8905       return -99;
8906     }
8907
8908   /* Construct the API message */
8909   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8910
8911   mp->sw_if_index = ntohl (sw_if_index);
8912   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8913   mp->address_length = address_length;
8914   mp->use_default = use_default;
8915   mp->no_advertise = no_advertise;
8916   mp->off_link = off_link;
8917   mp->no_autoconfig = no_autoconfig;
8918   mp->no_onlink = no_onlink;
8919   mp->is_no = is_no;
8920   mp->val_lifetime = ntohl (val_lifetime);
8921   mp->pref_lifetime = ntohl (pref_lifetime);
8922
8923   /* send it... */
8924   S (mp);
8925
8926   /* Wait for a reply, return good/bad news  */
8927   W (ret);
8928   return ret;
8929 }
8930
8931 static int
8932 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8933 {
8934   unformat_input_t *i = vam->input;
8935   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8936   u32 sw_if_index;
8937   u8 sw_if_index_set = 0;
8938   u8 suppress = 0;
8939   u8 managed = 0;
8940   u8 other = 0;
8941   u8 ll_option = 0;
8942   u8 send_unicast = 0;
8943   u8 cease = 0;
8944   u8 is_no = 0;
8945   u8 default_router = 0;
8946   u32 max_interval = 0;
8947   u32 min_interval = 0;
8948   u32 lifetime = 0;
8949   u32 initial_count = 0;
8950   u32 initial_interval = 0;
8951   int ret;
8952
8953
8954   /* Parse args required to build the message */
8955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8956     {
8957       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8958         sw_if_index_set = 1;
8959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8960         sw_if_index_set = 1;
8961       else if (unformat (i, "maxint %d", &max_interval))
8962         ;
8963       else if (unformat (i, "minint %d", &min_interval))
8964         ;
8965       else if (unformat (i, "life %d", &lifetime))
8966         ;
8967       else if (unformat (i, "count %d", &initial_count))
8968         ;
8969       else if (unformat (i, "interval %d", &initial_interval))
8970         ;
8971       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8972         suppress = 1;
8973       else if (unformat (i, "managed"))
8974         managed = 1;
8975       else if (unformat (i, "other"))
8976         other = 1;
8977       else if (unformat (i, "ll"))
8978         ll_option = 1;
8979       else if (unformat (i, "send"))
8980         send_unicast = 1;
8981       else if (unformat (i, "cease"))
8982         cease = 1;
8983       else if (unformat (i, "isno"))
8984         is_no = 1;
8985       else if (unformat (i, "def"))
8986         default_router = 1;
8987       else
8988         {
8989           clib_warning ("parse error '%U'", format_unformat_error, i);
8990           return -99;
8991         }
8992     }
8993
8994   if (sw_if_index_set == 0)
8995     {
8996       errmsg ("missing interface name or sw_if_index");
8997       return -99;
8998     }
8999
9000   /* Construct the API message */
9001   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9002
9003   mp->sw_if_index = ntohl (sw_if_index);
9004   mp->max_interval = ntohl (max_interval);
9005   mp->min_interval = ntohl (min_interval);
9006   mp->lifetime = ntohl (lifetime);
9007   mp->initial_count = ntohl (initial_count);
9008   mp->initial_interval = ntohl (initial_interval);
9009   mp->suppress = suppress;
9010   mp->managed = managed;
9011   mp->other = other;
9012   mp->ll_option = ll_option;
9013   mp->send_unicast = send_unicast;
9014   mp->cease = cease;
9015   mp->is_no = is_no;
9016   mp->default_router = default_router;
9017
9018   /* send it... */
9019   S (mp);
9020
9021   /* Wait for a reply, return good/bad news  */
9022   W (ret);
9023   return ret;
9024 }
9025
9026 static int
9027 api_set_arp_neighbor_limit (vat_main_t * vam)
9028 {
9029   unformat_input_t *i = vam->input;
9030   vl_api_set_arp_neighbor_limit_t *mp;
9031   u32 arp_nbr_limit;
9032   u8 limit_set = 0;
9033   u8 is_ipv6 = 0;
9034   int ret;
9035
9036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9037     {
9038       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9039         limit_set = 1;
9040       else if (unformat (i, "ipv6"))
9041         is_ipv6 = 1;
9042       else
9043         {
9044           clib_warning ("parse error '%U'", format_unformat_error, i);
9045           return -99;
9046         }
9047     }
9048
9049   if (limit_set == 0)
9050     {
9051       errmsg ("missing limit value");
9052       return -99;
9053     }
9054
9055   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9056
9057   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9058   mp->is_ipv6 = is_ipv6;
9059
9060   S (mp);
9061   W (ret);
9062   return ret;
9063 }
9064
9065 static int
9066 api_l2_patch_add_del (vat_main_t * vam)
9067 {
9068   unformat_input_t *i = vam->input;
9069   vl_api_l2_patch_add_del_t *mp;
9070   u32 rx_sw_if_index;
9071   u8 rx_sw_if_index_set = 0;
9072   u32 tx_sw_if_index;
9073   u8 tx_sw_if_index_set = 0;
9074   u8 is_add = 1;
9075   int ret;
9076
9077   /* Parse args required to build the message */
9078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9079     {
9080       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9081         rx_sw_if_index_set = 1;
9082       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9083         tx_sw_if_index_set = 1;
9084       else if (unformat (i, "rx"))
9085         {
9086           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9087             {
9088               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9089                             &rx_sw_if_index))
9090                 rx_sw_if_index_set = 1;
9091             }
9092           else
9093             break;
9094         }
9095       else if (unformat (i, "tx"))
9096         {
9097           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9098             {
9099               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9100                             &tx_sw_if_index))
9101                 tx_sw_if_index_set = 1;
9102             }
9103           else
9104             break;
9105         }
9106       else if (unformat (i, "del"))
9107         is_add = 0;
9108       else
9109         break;
9110     }
9111
9112   if (rx_sw_if_index_set == 0)
9113     {
9114       errmsg ("missing rx interface name or rx_sw_if_index");
9115       return -99;
9116     }
9117
9118   if (tx_sw_if_index_set == 0)
9119     {
9120       errmsg ("missing tx interface name or tx_sw_if_index");
9121       return -99;
9122     }
9123
9124   M (L2_PATCH_ADD_DEL, mp);
9125
9126   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9127   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9128   mp->is_add = is_add;
9129
9130   S (mp);
9131   W (ret);
9132   return ret;
9133 }
9134
9135 u8 is_del;
9136 u8 localsid_addr[16];
9137 u8 end_psp;
9138 u8 behavior;
9139 u32 sw_if_index;
9140 u32 vlan_index;
9141 u32 fib_table;
9142 u8 nh_addr[16];
9143
9144 static int
9145 api_sr_localsid_add_del (vat_main_t * vam)
9146 {
9147   unformat_input_t *i = vam->input;
9148   vl_api_sr_localsid_add_del_t *mp;
9149
9150   u8 is_del;
9151   ip6_address_t localsid;
9152   u8 end_psp = 0;
9153   u8 behavior = ~0;
9154   u32 sw_if_index;
9155   u32 fib_table = ~(u32) 0;
9156   ip6_address_t next_hop;
9157
9158   bool nexthop_set = 0;
9159
9160   int ret;
9161
9162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9163     {
9164       if (unformat (i, "del"))
9165         is_del = 1;
9166       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9167       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9168         nexthop_set = 1;
9169       else if (unformat (i, "behavior %u", &behavior));
9170       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9171       else if (unformat (i, "fib-table %u", &fib_table));
9172       else if (unformat (i, "end.psp %u", &behavior));
9173       else
9174         break;
9175     }
9176
9177   M (SR_LOCALSID_ADD_DEL, mp);
9178
9179   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9180   if (nexthop_set)
9181     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9182   mp->behavior = behavior;
9183   mp->sw_if_index = ntohl (sw_if_index);
9184   mp->fib_table = ntohl (fib_table);
9185   mp->end_psp = end_psp;
9186   mp->is_del = is_del;
9187
9188   S (mp);
9189   W (ret);
9190   return ret;
9191 }
9192
9193 static int
9194 api_ioam_enable (vat_main_t * vam)
9195 {
9196   unformat_input_t *input = vam->input;
9197   vl_api_ioam_enable_t *mp;
9198   u32 id = 0;
9199   int has_trace_option = 0;
9200   int has_pot_option = 0;
9201   int has_seqno_option = 0;
9202   int has_analyse_option = 0;
9203   int ret;
9204
9205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9206     {
9207       if (unformat (input, "trace"))
9208         has_trace_option = 1;
9209       else if (unformat (input, "pot"))
9210         has_pot_option = 1;
9211       else if (unformat (input, "seqno"))
9212         has_seqno_option = 1;
9213       else if (unformat (input, "analyse"))
9214         has_analyse_option = 1;
9215       else
9216         break;
9217     }
9218   M (IOAM_ENABLE, mp);
9219   mp->id = htons (id);
9220   mp->seqno = has_seqno_option;
9221   mp->analyse = has_analyse_option;
9222   mp->pot_enable = has_pot_option;
9223   mp->trace_enable = has_trace_option;
9224
9225   S (mp);
9226   W (ret);
9227   return ret;
9228 }
9229
9230
9231 static int
9232 api_ioam_disable (vat_main_t * vam)
9233 {
9234   vl_api_ioam_disable_t *mp;
9235   int ret;
9236
9237   M (IOAM_DISABLE, mp);
9238   S (mp);
9239   W (ret);
9240   return ret;
9241 }
9242
9243 #define foreach_tcp_proto_field                 \
9244 _(src_port)                                     \
9245 _(dst_port)
9246
9247 #define foreach_udp_proto_field                 \
9248 _(src_port)                                     \
9249 _(dst_port)
9250
9251 #define foreach_ip4_proto_field                 \
9252 _(src_address)                                  \
9253 _(dst_address)                                  \
9254 _(tos)                                          \
9255 _(length)                                       \
9256 _(fragment_id)                                  \
9257 _(ttl)                                          \
9258 _(protocol)                                     \
9259 _(checksum)
9260
9261 typedef struct
9262 {
9263   u16 src_port, dst_port;
9264 } tcpudp_header_t;
9265
9266 #if VPP_API_TEST_BUILTIN == 0
9267 uword
9268 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9269 {
9270   u8 **maskp = va_arg (*args, u8 **);
9271   u8 *mask = 0;
9272   u8 found_something = 0;
9273   tcp_header_t *tcp;
9274
9275 #define _(a) u8 a=0;
9276   foreach_tcp_proto_field;
9277 #undef _
9278
9279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9280     {
9281       if (0);
9282 #define _(a) else if (unformat (input, #a)) a=1;
9283       foreach_tcp_proto_field
9284 #undef _
9285         else
9286         break;
9287     }
9288
9289 #define _(a) found_something += a;
9290   foreach_tcp_proto_field;
9291 #undef _
9292
9293   if (found_something == 0)
9294     return 0;
9295
9296   vec_validate (mask, sizeof (*tcp) - 1);
9297
9298   tcp = (tcp_header_t *) mask;
9299
9300 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9301   foreach_tcp_proto_field;
9302 #undef _
9303
9304   *maskp = mask;
9305   return 1;
9306 }
9307
9308 uword
9309 unformat_udp_mask (unformat_input_t * input, va_list * args)
9310 {
9311   u8 **maskp = va_arg (*args, u8 **);
9312   u8 *mask = 0;
9313   u8 found_something = 0;
9314   udp_header_t *udp;
9315
9316 #define _(a) u8 a=0;
9317   foreach_udp_proto_field;
9318 #undef _
9319
9320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9321     {
9322       if (0);
9323 #define _(a) else if (unformat (input, #a)) a=1;
9324       foreach_udp_proto_field
9325 #undef _
9326         else
9327         break;
9328     }
9329
9330 #define _(a) found_something += a;
9331   foreach_udp_proto_field;
9332 #undef _
9333
9334   if (found_something == 0)
9335     return 0;
9336
9337   vec_validate (mask, sizeof (*udp) - 1);
9338
9339   udp = (udp_header_t *) mask;
9340
9341 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9342   foreach_udp_proto_field;
9343 #undef _
9344
9345   *maskp = mask;
9346   return 1;
9347 }
9348
9349 uword
9350 unformat_l4_mask (unformat_input_t * input, va_list * args)
9351 {
9352   u8 **maskp = va_arg (*args, u8 **);
9353   u16 src_port = 0, dst_port = 0;
9354   tcpudp_header_t *tcpudp;
9355
9356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9357     {
9358       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9359         return 1;
9360       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9361         return 1;
9362       else if (unformat (input, "src_port"))
9363         src_port = 0xFFFF;
9364       else if (unformat (input, "dst_port"))
9365         dst_port = 0xFFFF;
9366       else
9367         return 0;
9368     }
9369
9370   if (!src_port && !dst_port)
9371     return 0;
9372
9373   u8 *mask = 0;
9374   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9375
9376   tcpudp = (tcpudp_header_t *) mask;
9377   tcpudp->src_port = src_port;
9378   tcpudp->dst_port = dst_port;
9379
9380   *maskp = mask;
9381
9382   return 1;
9383 }
9384
9385 uword
9386 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9387 {
9388   u8 **maskp = va_arg (*args, u8 **);
9389   u8 *mask = 0;
9390   u8 found_something = 0;
9391   ip4_header_t *ip;
9392
9393 #define _(a) u8 a=0;
9394   foreach_ip4_proto_field;
9395 #undef _
9396   u8 version = 0;
9397   u8 hdr_length = 0;
9398
9399
9400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9401     {
9402       if (unformat (input, "version"))
9403         version = 1;
9404       else if (unformat (input, "hdr_length"))
9405         hdr_length = 1;
9406       else if (unformat (input, "src"))
9407         src_address = 1;
9408       else if (unformat (input, "dst"))
9409         dst_address = 1;
9410       else if (unformat (input, "proto"))
9411         protocol = 1;
9412
9413 #define _(a) else if (unformat (input, #a)) a=1;
9414       foreach_ip4_proto_field
9415 #undef _
9416         else
9417         break;
9418     }
9419
9420 #define _(a) found_something += a;
9421   foreach_ip4_proto_field;
9422 #undef _
9423
9424   if (found_something == 0)
9425     return 0;
9426
9427   vec_validate (mask, sizeof (*ip) - 1);
9428
9429   ip = (ip4_header_t *) mask;
9430
9431 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9432   foreach_ip4_proto_field;
9433 #undef _
9434
9435   ip->ip_version_and_header_length = 0;
9436
9437   if (version)
9438     ip->ip_version_and_header_length |= 0xF0;
9439
9440   if (hdr_length)
9441     ip->ip_version_and_header_length |= 0x0F;
9442
9443   *maskp = mask;
9444   return 1;
9445 }
9446
9447 #define foreach_ip6_proto_field                 \
9448 _(src_address)                                  \
9449 _(dst_address)                                  \
9450 _(payload_length)                               \
9451 _(hop_limit)                                    \
9452 _(protocol)
9453
9454 uword
9455 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9456 {
9457   u8 **maskp = va_arg (*args, u8 **);
9458   u8 *mask = 0;
9459   u8 found_something = 0;
9460   ip6_header_t *ip;
9461   u32 ip_version_traffic_class_and_flow_label;
9462
9463 #define _(a) u8 a=0;
9464   foreach_ip6_proto_field;
9465 #undef _
9466   u8 version = 0;
9467   u8 traffic_class = 0;
9468   u8 flow_label = 0;
9469
9470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9471     {
9472       if (unformat (input, "version"))
9473         version = 1;
9474       else if (unformat (input, "traffic-class"))
9475         traffic_class = 1;
9476       else if (unformat (input, "flow-label"))
9477         flow_label = 1;
9478       else if (unformat (input, "src"))
9479         src_address = 1;
9480       else if (unformat (input, "dst"))
9481         dst_address = 1;
9482       else if (unformat (input, "proto"))
9483         protocol = 1;
9484
9485 #define _(a) else if (unformat (input, #a)) a=1;
9486       foreach_ip6_proto_field
9487 #undef _
9488         else
9489         break;
9490     }
9491
9492 #define _(a) found_something += a;
9493   foreach_ip6_proto_field;
9494 #undef _
9495
9496   if (found_something == 0)
9497     return 0;
9498
9499   vec_validate (mask, sizeof (*ip) - 1);
9500
9501   ip = (ip6_header_t *) mask;
9502
9503 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9504   foreach_ip6_proto_field;
9505 #undef _
9506
9507   ip_version_traffic_class_and_flow_label = 0;
9508
9509   if (version)
9510     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9511
9512   if (traffic_class)
9513     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9514
9515   if (flow_label)
9516     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9517
9518   ip->ip_version_traffic_class_and_flow_label =
9519     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9520
9521   *maskp = mask;
9522   return 1;
9523 }
9524
9525 uword
9526 unformat_l3_mask (unformat_input_t * input, va_list * args)
9527 {
9528   u8 **maskp = va_arg (*args, u8 **);
9529
9530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9531     {
9532       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9533         return 1;
9534       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9535         return 1;
9536       else
9537         break;
9538     }
9539   return 0;
9540 }
9541
9542 uword
9543 unformat_l2_mask (unformat_input_t * input, va_list * args)
9544 {
9545   u8 **maskp = va_arg (*args, u8 **);
9546   u8 *mask = 0;
9547   u8 src = 0;
9548   u8 dst = 0;
9549   u8 proto = 0;
9550   u8 tag1 = 0;
9551   u8 tag2 = 0;
9552   u8 ignore_tag1 = 0;
9553   u8 ignore_tag2 = 0;
9554   u8 cos1 = 0;
9555   u8 cos2 = 0;
9556   u8 dot1q = 0;
9557   u8 dot1ad = 0;
9558   int len = 14;
9559
9560   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9561     {
9562       if (unformat (input, "src"))
9563         src = 1;
9564       else if (unformat (input, "dst"))
9565         dst = 1;
9566       else if (unformat (input, "proto"))
9567         proto = 1;
9568       else if (unformat (input, "tag1"))
9569         tag1 = 1;
9570       else if (unformat (input, "tag2"))
9571         tag2 = 1;
9572       else if (unformat (input, "ignore-tag1"))
9573         ignore_tag1 = 1;
9574       else if (unformat (input, "ignore-tag2"))
9575         ignore_tag2 = 1;
9576       else if (unformat (input, "cos1"))
9577         cos1 = 1;
9578       else if (unformat (input, "cos2"))
9579         cos2 = 1;
9580       else if (unformat (input, "dot1q"))
9581         dot1q = 1;
9582       else if (unformat (input, "dot1ad"))
9583         dot1ad = 1;
9584       else
9585         break;
9586     }
9587   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9588        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9589     return 0;
9590
9591   if (tag1 || ignore_tag1 || cos1 || dot1q)
9592     len = 18;
9593   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9594     len = 22;
9595
9596   vec_validate (mask, len - 1);
9597
9598   if (dst)
9599     memset (mask, 0xff, 6);
9600
9601   if (src)
9602     memset (mask + 6, 0xff, 6);
9603
9604   if (tag2 || dot1ad)
9605     {
9606       /* inner vlan tag */
9607       if (tag2)
9608         {
9609           mask[19] = 0xff;
9610           mask[18] = 0x0f;
9611         }
9612       if (cos2)
9613         mask[18] |= 0xe0;
9614       if (proto)
9615         mask[21] = mask[20] = 0xff;
9616       if (tag1)
9617         {
9618           mask[15] = 0xff;
9619           mask[14] = 0x0f;
9620         }
9621       if (cos1)
9622         mask[14] |= 0xe0;
9623       *maskp = mask;
9624       return 1;
9625     }
9626   if (tag1 | dot1q)
9627     {
9628       if (tag1)
9629         {
9630           mask[15] = 0xff;
9631           mask[14] = 0x0f;
9632         }
9633       if (cos1)
9634         mask[14] |= 0xe0;
9635       if (proto)
9636         mask[16] = mask[17] = 0xff;
9637
9638       *maskp = mask;
9639       return 1;
9640     }
9641   if (cos2)
9642     mask[18] |= 0xe0;
9643   if (cos1)
9644     mask[14] |= 0xe0;
9645   if (proto)
9646     mask[12] = mask[13] = 0xff;
9647
9648   *maskp = mask;
9649   return 1;
9650 }
9651
9652 uword
9653 unformat_classify_mask (unformat_input_t * input, va_list * args)
9654 {
9655   u8 **maskp = va_arg (*args, u8 **);
9656   u32 *skipp = va_arg (*args, u32 *);
9657   u32 *matchp = va_arg (*args, u32 *);
9658   u32 match;
9659   u8 *mask = 0;
9660   u8 *l2 = 0;
9661   u8 *l3 = 0;
9662   u8 *l4 = 0;
9663   int i;
9664
9665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9666     {
9667       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9668         ;
9669       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9670         ;
9671       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9672         ;
9673       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9674         ;
9675       else
9676         break;
9677     }
9678
9679   if (l4 && !l3)
9680     {
9681       vec_free (mask);
9682       vec_free (l2);
9683       vec_free (l4);
9684       return 0;
9685     }
9686
9687   if (mask || l2 || l3 || l4)
9688     {
9689       if (l2 || l3 || l4)
9690         {
9691           /* "With a free Ethernet header in every package" */
9692           if (l2 == 0)
9693             vec_validate (l2, 13);
9694           mask = l2;
9695           if (vec_len (l3))
9696             {
9697               vec_append (mask, l3);
9698               vec_free (l3);
9699             }
9700           if (vec_len (l4))
9701             {
9702               vec_append (mask, l4);
9703               vec_free (l4);
9704             }
9705         }
9706
9707       /* Scan forward looking for the first significant mask octet */
9708       for (i = 0; i < vec_len (mask); i++)
9709         if (mask[i])
9710           break;
9711
9712       /* compute (skip, match) params */
9713       *skipp = i / sizeof (u32x4);
9714       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9715
9716       /* Pad mask to an even multiple of the vector size */
9717       while (vec_len (mask) % sizeof (u32x4))
9718         vec_add1 (mask, 0);
9719
9720       match = vec_len (mask) / sizeof (u32x4);
9721
9722       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9723         {
9724           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9725           if (*tmp || *(tmp + 1))
9726             break;
9727           match--;
9728         }
9729       if (match == 0)
9730         clib_warning ("BUG: match 0");
9731
9732       _vec_len (mask) = match * sizeof (u32x4);
9733
9734       *matchp = match;
9735       *maskp = mask;
9736
9737       return 1;
9738     }
9739
9740   return 0;
9741 }
9742 #endif /* VPP_API_TEST_BUILTIN */
9743
9744 #define foreach_l2_next                         \
9745 _(drop, DROP)                                   \
9746 _(ethernet, ETHERNET_INPUT)                     \
9747 _(ip4, IP4_INPUT)                               \
9748 _(ip6, IP6_INPUT)
9749
9750 uword
9751 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9752 {
9753   u32 *miss_next_indexp = va_arg (*args, u32 *);
9754   u32 next_index = 0;
9755   u32 tmp;
9756
9757 #define _(n,N) \
9758   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9759   foreach_l2_next;
9760 #undef _
9761
9762   if (unformat (input, "%d", &tmp))
9763     {
9764       next_index = tmp;
9765       goto out;
9766     }
9767
9768   return 0;
9769
9770 out:
9771   *miss_next_indexp = next_index;
9772   return 1;
9773 }
9774
9775 #define foreach_ip_next                         \
9776 _(drop, DROP)                                   \
9777 _(local, LOCAL)                                 \
9778 _(rewrite, REWRITE)
9779
9780 uword
9781 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9782 {
9783   u32 *miss_next_indexp = va_arg (*args, u32 *);
9784   u32 next_index = 0;
9785   u32 tmp;
9786
9787 #define _(n,N) \
9788   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9789   foreach_ip_next;
9790 #undef _
9791
9792   if (unformat (input, "%d", &tmp))
9793     {
9794       next_index = tmp;
9795       goto out;
9796     }
9797
9798   return 0;
9799
9800 out:
9801   *miss_next_indexp = next_index;
9802   return 1;
9803 }
9804
9805 #define foreach_acl_next                        \
9806 _(deny, DENY)
9807
9808 uword
9809 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9810 {
9811   u32 *miss_next_indexp = va_arg (*args, u32 *);
9812   u32 next_index = 0;
9813   u32 tmp;
9814
9815 #define _(n,N) \
9816   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9817   foreach_acl_next;
9818 #undef _
9819
9820   if (unformat (input, "permit"))
9821     {
9822       next_index = ~0;
9823       goto out;
9824     }
9825   else if (unformat (input, "%d", &tmp))
9826     {
9827       next_index = tmp;
9828       goto out;
9829     }
9830
9831   return 0;
9832
9833 out:
9834   *miss_next_indexp = next_index;
9835   return 1;
9836 }
9837
9838 uword
9839 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9840 {
9841   u32 *r = va_arg (*args, u32 *);
9842
9843   if (unformat (input, "conform-color"))
9844     *r = POLICE_CONFORM;
9845   else if (unformat (input, "exceed-color"))
9846     *r = POLICE_EXCEED;
9847   else
9848     return 0;
9849
9850   return 1;
9851 }
9852
9853 static int
9854 api_classify_add_del_table (vat_main_t * vam)
9855 {
9856   unformat_input_t *i = vam->input;
9857   vl_api_classify_add_del_table_t *mp;
9858
9859   u32 nbuckets = 2;
9860   u32 skip = ~0;
9861   u32 match = ~0;
9862   int is_add = 1;
9863   int del_chain = 0;
9864   u32 table_index = ~0;
9865   u32 next_table_index = ~0;
9866   u32 miss_next_index = ~0;
9867   u32 memory_size = 32 << 20;
9868   u8 *mask = 0;
9869   u32 current_data_flag = 0;
9870   int current_data_offset = 0;
9871   int ret;
9872
9873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9874     {
9875       if (unformat (i, "del"))
9876         is_add = 0;
9877       else if (unformat (i, "del-chain"))
9878         {
9879           is_add = 0;
9880           del_chain = 1;
9881         }
9882       else if (unformat (i, "buckets %d", &nbuckets))
9883         ;
9884       else if (unformat (i, "memory_size %d", &memory_size))
9885         ;
9886       else if (unformat (i, "skip %d", &skip))
9887         ;
9888       else if (unformat (i, "match %d", &match))
9889         ;
9890       else if (unformat (i, "table %d", &table_index))
9891         ;
9892       else if (unformat (i, "mask %U", unformat_classify_mask,
9893                          &mask, &skip, &match))
9894         ;
9895       else if (unformat (i, "next-table %d", &next_table_index))
9896         ;
9897       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9898                          &miss_next_index))
9899         ;
9900       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9901                          &miss_next_index))
9902         ;
9903       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9904                          &miss_next_index))
9905         ;
9906       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9907         ;
9908       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9909         ;
9910       else
9911         break;
9912     }
9913
9914   if (is_add && mask == 0)
9915     {
9916       errmsg ("Mask required");
9917       return -99;
9918     }
9919
9920   if (is_add && skip == ~0)
9921     {
9922       errmsg ("skip count required");
9923       return -99;
9924     }
9925
9926   if (is_add && match == ~0)
9927     {
9928       errmsg ("match count required");
9929       return -99;
9930     }
9931
9932   if (!is_add && table_index == ~0)
9933     {
9934       errmsg ("table index required for delete");
9935       return -99;
9936     }
9937
9938   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9939
9940   mp->is_add = is_add;
9941   mp->del_chain = del_chain;
9942   mp->table_index = ntohl (table_index);
9943   mp->nbuckets = ntohl (nbuckets);
9944   mp->memory_size = ntohl (memory_size);
9945   mp->skip_n_vectors = ntohl (skip);
9946   mp->match_n_vectors = ntohl (match);
9947   mp->next_table_index = ntohl (next_table_index);
9948   mp->miss_next_index = ntohl (miss_next_index);
9949   mp->current_data_flag = ntohl (current_data_flag);
9950   mp->current_data_offset = ntohl (current_data_offset);
9951   clib_memcpy (mp->mask, mask, vec_len (mask));
9952
9953   vec_free (mask);
9954
9955   S (mp);
9956   W (ret);
9957   return ret;
9958 }
9959
9960 #if VPP_API_TEST_BUILTIN == 0
9961 uword
9962 unformat_l4_match (unformat_input_t * input, va_list * args)
9963 {
9964   u8 **matchp = va_arg (*args, u8 **);
9965
9966   u8 *proto_header = 0;
9967   int src_port = 0;
9968   int dst_port = 0;
9969
9970   tcpudp_header_t h;
9971
9972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9973     {
9974       if (unformat (input, "src_port %d", &src_port))
9975         ;
9976       else if (unformat (input, "dst_port %d", &dst_port))
9977         ;
9978       else
9979         return 0;
9980     }
9981
9982   h.src_port = clib_host_to_net_u16 (src_port);
9983   h.dst_port = clib_host_to_net_u16 (dst_port);
9984   vec_validate (proto_header, sizeof (h) - 1);
9985   memcpy (proto_header, &h, sizeof (h));
9986
9987   *matchp = proto_header;
9988
9989   return 1;
9990 }
9991
9992 uword
9993 unformat_ip4_match (unformat_input_t * input, va_list * args)
9994 {
9995   u8 **matchp = va_arg (*args, u8 **);
9996   u8 *match = 0;
9997   ip4_header_t *ip;
9998   int version = 0;
9999   u32 version_val;
10000   int hdr_length = 0;
10001   u32 hdr_length_val;
10002   int src = 0, dst = 0;
10003   ip4_address_t src_val, dst_val;
10004   int proto = 0;
10005   u32 proto_val;
10006   int tos = 0;
10007   u32 tos_val;
10008   int length = 0;
10009   u32 length_val;
10010   int fragment_id = 0;
10011   u32 fragment_id_val;
10012   int ttl = 0;
10013   int ttl_val;
10014   int checksum = 0;
10015   u32 checksum_val;
10016
10017   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10018     {
10019       if (unformat (input, "version %d", &version_val))
10020         version = 1;
10021       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10022         hdr_length = 1;
10023       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10024         src = 1;
10025       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10026         dst = 1;
10027       else if (unformat (input, "proto %d", &proto_val))
10028         proto = 1;
10029       else if (unformat (input, "tos %d", &tos_val))
10030         tos = 1;
10031       else if (unformat (input, "length %d", &length_val))
10032         length = 1;
10033       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10034         fragment_id = 1;
10035       else if (unformat (input, "ttl %d", &ttl_val))
10036         ttl = 1;
10037       else if (unformat (input, "checksum %d", &checksum_val))
10038         checksum = 1;
10039       else
10040         break;
10041     }
10042
10043   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10044       + ttl + checksum == 0)
10045     return 0;
10046
10047   /*
10048    * Aligned because we use the real comparison functions
10049    */
10050   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10051
10052   ip = (ip4_header_t *) match;
10053
10054   /* These are realistically matched in practice */
10055   if (src)
10056     ip->src_address.as_u32 = src_val.as_u32;
10057
10058   if (dst)
10059     ip->dst_address.as_u32 = dst_val.as_u32;
10060
10061   if (proto)
10062     ip->protocol = proto_val;
10063
10064
10065   /* These are not, but they're included for completeness */
10066   if (version)
10067     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10068
10069   if (hdr_length)
10070     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10071
10072   if (tos)
10073     ip->tos = tos_val;
10074
10075   if (length)
10076     ip->length = clib_host_to_net_u16 (length_val);
10077
10078   if (ttl)
10079     ip->ttl = ttl_val;
10080
10081   if (checksum)
10082     ip->checksum = clib_host_to_net_u16 (checksum_val);
10083
10084   *matchp = match;
10085   return 1;
10086 }
10087
10088 uword
10089 unformat_ip6_match (unformat_input_t * input, va_list * args)
10090 {
10091   u8 **matchp = va_arg (*args, u8 **);
10092   u8 *match = 0;
10093   ip6_header_t *ip;
10094   int version = 0;
10095   u32 version_val;
10096   u8 traffic_class = 0;
10097   u32 traffic_class_val = 0;
10098   u8 flow_label = 0;
10099   u8 flow_label_val;
10100   int src = 0, dst = 0;
10101   ip6_address_t src_val, dst_val;
10102   int proto = 0;
10103   u32 proto_val;
10104   int payload_length = 0;
10105   u32 payload_length_val;
10106   int hop_limit = 0;
10107   int hop_limit_val;
10108   u32 ip_version_traffic_class_and_flow_label;
10109
10110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10111     {
10112       if (unformat (input, "version %d", &version_val))
10113         version = 1;
10114       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10115         traffic_class = 1;
10116       else if (unformat (input, "flow_label %d", &flow_label_val))
10117         flow_label = 1;
10118       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10119         src = 1;
10120       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10121         dst = 1;
10122       else if (unformat (input, "proto %d", &proto_val))
10123         proto = 1;
10124       else if (unformat (input, "payload_length %d", &payload_length_val))
10125         payload_length = 1;
10126       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10127         hop_limit = 1;
10128       else
10129         break;
10130     }
10131
10132   if (version + traffic_class + flow_label + src + dst + proto +
10133       payload_length + hop_limit == 0)
10134     return 0;
10135
10136   /*
10137    * Aligned because we use the real comparison functions
10138    */
10139   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10140
10141   ip = (ip6_header_t *) match;
10142
10143   if (src)
10144     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10145
10146   if (dst)
10147     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10148
10149   if (proto)
10150     ip->protocol = proto_val;
10151
10152   ip_version_traffic_class_and_flow_label = 0;
10153
10154   if (version)
10155     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10156
10157   if (traffic_class)
10158     ip_version_traffic_class_and_flow_label |=
10159       (traffic_class_val & 0xFF) << 20;
10160
10161   if (flow_label)
10162     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10163
10164   ip->ip_version_traffic_class_and_flow_label =
10165     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10166
10167   if (payload_length)
10168     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10169
10170   if (hop_limit)
10171     ip->hop_limit = hop_limit_val;
10172
10173   *matchp = match;
10174   return 1;
10175 }
10176
10177 uword
10178 unformat_l3_match (unformat_input_t * input, va_list * args)
10179 {
10180   u8 **matchp = va_arg (*args, u8 **);
10181
10182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10183     {
10184       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10185         return 1;
10186       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10187         return 1;
10188       else
10189         break;
10190     }
10191   return 0;
10192 }
10193
10194 uword
10195 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10196 {
10197   u8 *tagp = va_arg (*args, u8 *);
10198   u32 tag;
10199
10200   if (unformat (input, "%d", &tag))
10201     {
10202       tagp[0] = (tag >> 8) & 0x0F;
10203       tagp[1] = tag & 0xFF;
10204       return 1;
10205     }
10206
10207   return 0;
10208 }
10209
10210 uword
10211 unformat_l2_match (unformat_input_t * input, va_list * args)
10212 {
10213   u8 **matchp = va_arg (*args, u8 **);
10214   u8 *match = 0;
10215   u8 src = 0;
10216   u8 src_val[6];
10217   u8 dst = 0;
10218   u8 dst_val[6];
10219   u8 proto = 0;
10220   u16 proto_val;
10221   u8 tag1 = 0;
10222   u8 tag1_val[2];
10223   u8 tag2 = 0;
10224   u8 tag2_val[2];
10225   int len = 14;
10226   u8 ignore_tag1 = 0;
10227   u8 ignore_tag2 = 0;
10228   u8 cos1 = 0;
10229   u8 cos2 = 0;
10230   u32 cos1_val = 0;
10231   u32 cos2_val = 0;
10232
10233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10234     {
10235       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10236         src = 1;
10237       else
10238         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10239         dst = 1;
10240       else if (unformat (input, "proto %U",
10241                          unformat_ethernet_type_host_byte_order, &proto_val))
10242         proto = 1;
10243       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10244         tag1 = 1;
10245       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10246         tag2 = 1;
10247       else if (unformat (input, "ignore-tag1"))
10248         ignore_tag1 = 1;
10249       else if (unformat (input, "ignore-tag2"))
10250         ignore_tag2 = 1;
10251       else if (unformat (input, "cos1 %d", &cos1_val))
10252         cos1 = 1;
10253       else if (unformat (input, "cos2 %d", &cos2_val))
10254         cos2 = 1;
10255       else
10256         break;
10257     }
10258   if ((src + dst + proto + tag1 + tag2 +
10259        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10260     return 0;
10261
10262   if (tag1 || ignore_tag1 || cos1)
10263     len = 18;
10264   if (tag2 || ignore_tag2 || cos2)
10265     len = 22;
10266
10267   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10268
10269   if (dst)
10270     clib_memcpy (match, dst_val, 6);
10271
10272   if (src)
10273     clib_memcpy (match + 6, src_val, 6);
10274
10275   if (tag2)
10276     {
10277       /* inner vlan tag */
10278       match[19] = tag2_val[1];
10279       match[18] = tag2_val[0];
10280       if (cos2)
10281         match[18] |= (cos2_val & 0x7) << 5;
10282       if (proto)
10283         {
10284           match[21] = proto_val & 0xff;
10285           match[20] = proto_val >> 8;
10286         }
10287       if (tag1)
10288         {
10289           match[15] = tag1_val[1];
10290           match[14] = tag1_val[0];
10291         }
10292       if (cos1)
10293         match[14] |= (cos1_val & 0x7) << 5;
10294       *matchp = match;
10295       return 1;
10296     }
10297   if (tag1)
10298     {
10299       match[15] = tag1_val[1];
10300       match[14] = tag1_val[0];
10301       if (proto)
10302         {
10303           match[17] = proto_val & 0xff;
10304           match[16] = proto_val >> 8;
10305         }
10306       if (cos1)
10307         match[14] |= (cos1_val & 0x7) << 5;
10308
10309       *matchp = match;
10310       return 1;
10311     }
10312   if (cos2)
10313     match[18] |= (cos2_val & 0x7) << 5;
10314   if (cos1)
10315     match[14] |= (cos1_val & 0x7) << 5;
10316   if (proto)
10317     {
10318       match[13] = proto_val & 0xff;
10319       match[12] = proto_val >> 8;
10320     }
10321
10322   *matchp = match;
10323   return 1;
10324 }
10325 #endif
10326
10327 uword
10328 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10329 {
10330   u8 **matchp = va_arg (*args, u8 **);
10331   u32 skip_n_vectors = va_arg (*args, u32);
10332   u32 match_n_vectors = va_arg (*args, u32);
10333
10334   u8 *match = 0;
10335   u8 *l2 = 0;
10336   u8 *l3 = 0;
10337   u8 *l4 = 0;
10338
10339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10340     {
10341       if (unformat (input, "hex %U", unformat_hex_string, &match))
10342         ;
10343       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10344         ;
10345       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10346         ;
10347       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10348         ;
10349       else
10350         break;
10351     }
10352
10353   if (l4 && !l3)
10354     {
10355       vec_free (match);
10356       vec_free (l2);
10357       vec_free (l4);
10358       return 0;
10359     }
10360
10361   if (match || l2 || l3 || l4)
10362     {
10363       if (l2 || l3 || l4)
10364         {
10365           /* "Win a free Ethernet header in every packet" */
10366           if (l2 == 0)
10367             vec_validate_aligned (l2, 13, sizeof (u32x4));
10368           match = l2;
10369           if (vec_len (l3))
10370             {
10371               vec_append_aligned (match, l3, sizeof (u32x4));
10372               vec_free (l3);
10373             }
10374           if (vec_len (l4))
10375             {
10376               vec_append_aligned (match, l4, sizeof (u32x4));
10377               vec_free (l4);
10378             }
10379         }
10380
10381       /* Make sure the vector is big enough even if key is all 0's */
10382       vec_validate_aligned
10383         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10384          sizeof (u32x4));
10385
10386       /* Set size, include skipped vectors */
10387       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10388
10389       *matchp = match;
10390
10391       return 1;
10392     }
10393
10394   return 0;
10395 }
10396
10397 static int
10398 api_classify_add_del_session (vat_main_t * vam)
10399 {
10400   unformat_input_t *i = vam->input;
10401   vl_api_classify_add_del_session_t *mp;
10402   int is_add = 1;
10403   u32 table_index = ~0;
10404   u32 hit_next_index = ~0;
10405   u32 opaque_index = ~0;
10406   u8 *match = 0;
10407   i32 advance = 0;
10408   u32 skip_n_vectors = 0;
10409   u32 match_n_vectors = 0;
10410   u32 action = 0;
10411   u32 metadata = 0;
10412   int ret;
10413
10414   /*
10415    * Warning: you have to supply skip_n and match_n
10416    * because the API client cant simply look at the classify
10417    * table object.
10418    */
10419
10420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10421     {
10422       if (unformat (i, "del"))
10423         is_add = 0;
10424       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10425                          &hit_next_index))
10426         ;
10427       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10428                          &hit_next_index))
10429         ;
10430       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10431                          &hit_next_index))
10432         ;
10433       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10434         ;
10435       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10436         ;
10437       else if (unformat (i, "opaque-index %d", &opaque_index))
10438         ;
10439       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10440         ;
10441       else if (unformat (i, "match_n %d", &match_n_vectors))
10442         ;
10443       else if (unformat (i, "match %U", api_unformat_classify_match,
10444                          &match, skip_n_vectors, match_n_vectors))
10445         ;
10446       else if (unformat (i, "advance %d", &advance))
10447         ;
10448       else if (unformat (i, "table-index %d", &table_index))
10449         ;
10450       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10451         action = 1;
10452       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10453         action = 2;
10454       else if (unformat (i, "action %d", &action))
10455         ;
10456       else if (unformat (i, "metadata %d", &metadata))
10457         ;
10458       else
10459         break;
10460     }
10461
10462   if (table_index == ~0)
10463     {
10464       errmsg ("Table index required");
10465       return -99;
10466     }
10467
10468   if (is_add && match == 0)
10469     {
10470       errmsg ("Match value required");
10471       return -99;
10472     }
10473
10474   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10475
10476   mp->is_add = is_add;
10477   mp->table_index = ntohl (table_index);
10478   mp->hit_next_index = ntohl (hit_next_index);
10479   mp->opaque_index = ntohl (opaque_index);
10480   mp->advance = ntohl (advance);
10481   mp->action = action;
10482   mp->metadata = ntohl (metadata);
10483   clib_memcpy (mp->match, match, vec_len (match));
10484   vec_free (match);
10485
10486   S (mp);
10487   W (ret);
10488   return ret;
10489 }
10490
10491 static int
10492 api_classify_set_interface_ip_table (vat_main_t * vam)
10493 {
10494   unformat_input_t *i = vam->input;
10495   vl_api_classify_set_interface_ip_table_t *mp;
10496   u32 sw_if_index;
10497   int sw_if_index_set;
10498   u32 table_index = ~0;
10499   u8 is_ipv6 = 0;
10500   int ret;
10501
10502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10503     {
10504       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10505         sw_if_index_set = 1;
10506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10507         sw_if_index_set = 1;
10508       else if (unformat (i, "table %d", &table_index))
10509         ;
10510       else
10511         {
10512           clib_warning ("parse error '%U'", format_unformat_error, i);
10513           return -99;
10514         }
10515     }
10516
10517   if (sw_if_index_set == 0)
10518     {
10519       errmsg ("missing interface name or sw_if_index");
10520       return -99;
10521     }
10522
10523
10524   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10525
10526   mp->sw_if_index = ntohl (sw_if_index);
10527   mp->table_index = ntohl (table_index);
10528   mp->is_ipv6 = is_ipv6;
10529
10530   S (mp);
10531   W (ret);
10532   return ret;
10533 }
10534
10535 static int
10536 api_classify_set_interface_l2_tables (vat_main_t * vam)
10537 {
10538   unformat_input_t *i = vam->input;
10539   vl_api_classify_set_interface_l2_tables_t *mp;
10540   u32 sw_if_index;
10541   int sw_if_index_set;
10542   u32 ip4_table_index = ~0;
10543   u32 ip6_table_index = ~0;
10544   u32 other_table_index = ~0;
10545   u32 is_input = 1;
10546   int ret;
10547
10548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10549     {
10550       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10551         sw_if_index_set = 1;
10552       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10553         sw_if_index_set = 1;
10554       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10555         ;
10556       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10557         ;
10558       else if (unformat (i, "other-table %d", &other_table_index))
10559         ;
10560       else if (unformat (i, "is-input %d", &is_input))
10561         ;
10562       else
10563         {
10564           clib_warning ("parse error '%U'", format_unformat_error, i);
10565           return -99;
10566         }
10567     }
10568
10569   if (sw_if_index_set == 0)
10570     {
10571       errmsg ("missing interface name or sw_if_index");
10572       return -99;
10573     }
10574
10575
10576   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10577
10578   mp->sw_if_index = ntohl (sw_if_index);
10579   mp->ip4_table_index = ntohl (ip4_table_index);
10580   mp->ip6_table_index = ntohl (ip6_table_index);
10581   mp->other_table_index = ntohl (other_table_index);
10582   mp->is_input = (u8) is_input;
10583
10584   S (mp);
10585   W (ret);
10586   return ret;
10587 }
10588
10589 static int
10590 api_set_ipfix_exporter (vat_main_t * vam)
10591 {
10592   unformat_input_t *i = vam->input;
10593   vl_api_set_ipfix_exporter_t *mp;
10594   ip4_address_t collector_address;
10595   u8 collector_address_set = 0;
10596   u32 collector_port = ~0;
10597   ip4_address_t src_address;
10598   u8 src_address_set = 0;
10599   u32 vrf_id = ~0;
10600   u32 path_mtu = ~0;
10601   u32 template_interval = ~0;
10602   u8 udp_checksum = 0;
10603   int ret;
10604
10605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10606     {
10607       if (unformat (i, "collector_address %U", unformat_ip4_address,
10608                     &collector_address))
10609         collector_address_set = 1;
10610       else if (unformat (i, "collector_port %d", &collector_port))
10611         ;
10612       else if (unformat (i, "src_address %U", unformat_ip4_address,
10613                          &src_address))
10614         src_address_set = 1;
10615       else if (unformat (i, "vrf_id %d", &vrf_id))
10616         ;
10617       else if (unformat (i, "path_mtu %d", &path_mtu))
10618         ;
10619       else if (unformat (i, "template_interval %d", &template_interval))
10620         ;
10621       else if (unformat (i, "udp_checksum"))
10622         udp_checksum = 1;
10623       else
10624         break;
10625     }
10626
10627   if (collector_address_set == 0)
10628     {
10629       errmsg ("collector_address required");
10630       return -99;
10631     }
10632
10633   if (src_address_set == 0)
10634     {
10635       errmsg ("src_address required");
10636       return -99;
10637     }
10638
10639   M (SET_IPFIX_EXPORTER, mp);
10640
10641   memcpy (mp->collector_address, collector_address.data,
10642           sizeof (collector_address.data));
10643   mp->collector_port = htons ((u16) collector_port);
10644   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10645   mp->vrf_id = htonl (vrf_id);
10646   mp->path_mtu = htonl (path_mtu);
10647   mp->template_interval = htonl (template_interval);
10648   mp->udp_checksum = udp_checksum;
10649
10650   S (mp);
10651   W (ret);
10652   return ret;
10653 }
10654
10655 static int
10656 api_set_ipfix_classify_stream (vat_main_t * vam)
10657 {
10658   unformat_input_t *i = vam->input;
10659   vl_api_set_ipfix_classify_stream_t *mp;
10660   u32 domain_id = 0;
10661   u32 src_port = UDP_DST_PORT_ipfix;
10662   int ret;
10663
10664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10665     {
10666       if (unformat (i, "domain %d", &domain_id))
10667         ;
10668       else if (unformat (i, "src_port %d", &src_port))
10669         ;
10670       else
10671         {
10672           errmsg ("unknown input `%U'", format_unformat_error, i);
10673           return -99;
10674         }
10675     }
10676
10677   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10678
10679   mp->domain_id = htonl (domain_id);
10680   mp->src_port = htons ((u16) src_port);
10681
10682   S (mp);
10683   W (ret);
10684   return ret;
10685 }
10686
10687 static int
10688 api_ipfix_classify_table_add_del (vat_main_t * vam)
10689 {
10690   unformat_input_t *i = vam->input;
10691   vl_api_ipfix_classify_table_add_del_t *mp;
10692   int is_add = -1;
10693   u32 classify_table_index = ~0;
10694   u8 ip_version = 0;
10695   u8 transport_protocol = 255;
10696   int ret;
10697
10698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10699     {
10700       if (unformat (i, "add"))
10701         is_add = 1;
10702       else if (unformat (i, "del"))
10703         is_add = 0;
10704       else if (unformat (i, "table %d", &classify_table_index))
10705         ;
10706       else if (unformat (i, "ip4"))
10707         ip_version = 4;
10708       else if (unformat (i, "ip6"))
10709         ip_version = 6;
10710       else if (unformat (i, "tcp"))
10711         transport_protocol = 6;
10712       else if (unformat (i, "udp"))
10713         transport_protocol = 17;
10714       else
10715         {
10716           errmsg ("unknown input `%U'", format_unformat_error, i);
10717           return -99;
10718         }
10719     }
10720
10721   if (is_add == -1)
10722     {
10723       errmsg ("expecting: add|del");
10724       return -99;
10725     }
10726   if (classify_table_index == ~0)
10727     {
10728       errmsg ("classifier table not specified");
10729       return -99;
10730     }
10731   if (ip_version == 0)
10732     {
10733       errmsg ("IP version not specified");
10734       return -99;
10735     }
10736
10737   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10738
10739   mp->is_add = is_add;
10740   mp->table_id = htonl (classify_table_index);
10741   mp->ip_version = ip_version;
10742   mp->transport_protocol = transport_protocol;
10743
10744   S (mp);
10745   W (ret);
10746   return ret;
10747 }
10748
10749 static int
10750 api_get_node_index (vat_main_t * vam)
10751 {
10752   unformat_input_t *i = vam->input;
10753   vl_api_get_node_index_t *mp;
10754   u8 *name = 0;
10755   int ret;
10756
10757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10758     {
10759       if (unformat (i, "node %s", &name))
10760         ;
10761       else
10762         break;
10763     }
10764   if (name == 0)
10765     {
10766       errmsg ("node name required");
10767       return -99;
10768     }
10769   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10770     {
10771       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10772       return -99;
10773     }
10774
10775   M (GET_NODE_INDEX, mp);
10776   clib_memcpy (mp->node_name, name, vec_len (name));
10777   vec_free (name);
10778
10779   S (mp);
10780   W (ret);
10781   return ret;
10782 }
10783
10784 static int
10785 api_get_next_index (vat_main_t * vam)
10786 {
10787   unformat_input_t *i = vam->input;
10788   vl_api_get_next_index_t *mp;
10789   u8 *node_name = 0, *next_node_name = 0;
10790   int ret;
10791
10792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10793     {
10794       if (unformat (i, "node-name %s", &node_name))
10795         ;
10796       else if (unformat (i, "next-node-name %s", &next_node_name))
10797         break;
10798     }
10799
10800   if (node_name == 0)
10801     {
10802       errmsg ("node name required");
10803       return -99;
10804     }
10805   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10806     {
10807       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10808       return -99;
10809     }
10810
10811   if (next_node_name == 0)
10812     {
10813       errmsg ("next node name required");
10814       return -99;
10815     }
10816   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10817     {
10818       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10819       return -99;
10820     }
10821
10822   M (GET_NEXT_INDEX, mp);
10823   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10824   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10825   vec_free (node_name);
10826   vec_free (next_node_name);
10827
10828   S (mp);
10829   W (ret);
10830   return ret;
10831 }
10832
10833 static int
10834 api_add_node_next (vat_main_t * vam)
10835 {
10836   unformat_input_t *i = vam->input;
10837   vl_api_add_node_next_t *mp;
10838   u8 *name = 0;
10839   u8 *next = 0;
10840   int ret;
10841
10842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10843     {
10844       if (unformat (i, "node %s", &name))
10845         ;
10846       else if (unformat (i, "next %s", &next))
10847         ;
10848       else
10849         break;
10850     }
10851   if (name == 0)
10852     {
10853       errmsg ("node name required");
10854       return -99;
10855     }
10856   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10857     {
10858       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10859       return -99;
10860     }
10861   if (next == 0)
10862     {
10863       errmsg ("next node required");
10864       return -99;
10865     }
10866   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10867     {
10868       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10869       return -99;
10870     }
10871
10872   M (ADD_NODE_NEXT, mp);
10873   clib_memcpy (mp->node_name, name, vec_len (name));
10874   clib_memcpy (mp->next_name, next, vec_len (next));
10875   vec_free (name);
10876   vec_free (next);
10877
10878   S (mp);
10879   W (ret);
10880   return ret;
10881 }
10882
10883 static int
10884 api_l2tpv3_create_tunnel (vat_main_t * vam)
10885 {
10886   unformat_input_t *i = vam->input;
10887   ip6_address_t client_address, our_address;
10888   int client_address_set = 0;
10889   int our_address_set = 0;
10890   u32 local_session_id = 0;
10891   u32 remote_session_id = 0;
10892   u64 local_cookie = 0;
10893   u64 remote_cookie = 0;
10894   u8 l2_sublayer_present = 0;
10895   vl_api_l2tpv3_create_tunnel_t *mp;
10896   int ret;
10897
10898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10899     {
10900       if (unformat (i, "client_address %U", unformat_ip6_address,
10901                     &client_address))
10902         client_address_set = 1;
10903       else if (unformat (i, "our_address %U", unformat_ip6_address,
10904                          &our_address))
10905         our_address_set = 1;
10906       else if (unformat (i, "local_session_id %d", &local_session_id))
10907         ;
10908       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10909         ;
10910       else if (unformat (i, "local_cookie %lld", &local_cookie))
10911         ;
10912       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10913         ;
10914       else if (unformat (i, "l2-sublayer-present"))
10915         l2_sublayer_present = 1;
10916       else
10917         break;
10918     }
10919
10920   if (client_address_set == 0)
10921     {
10922       errmsg ("client_address required");
10923       return -99;
10924     }
10925
10926   if (our_address_set == 0)
10927     {
10928       errmsg ("our_address required");
10929       return -99;
10930     }
10931
10932   M (L2TPV3_CREATE_TUNNEL, mp);
10933
10934   clib_memcpy (mp->client_address, client_address.as_u8,
10935                sizeof (mp->client_address));
10936
10937   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10938
10939   mp->local_session_id = ntohl (local_session_id);
10940   mp->remote_session_id = ntohl (remote_session_id);
10941   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10942   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10943   mp->l2_sublayer_present = l2_sublayer_present;
10944   mp->is_ipv6 = 1;
10945
10946   S (mp);
10947   W (ret);
10948   return ret;
10949 }
10950
10951 static int
10952 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10953 {
10954   unformat_input_t *i = vam->input;
10955   u32 sw_if_index;
10956   u8 sw_if_index_set = 0;
10957   u64 new_local_cookie = 0;
10958   u64 new_remote_cookie = 0;
10959   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10960   int ret;
10961
10962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10963     {
10964       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10965         sw_if_index_set = 1;
10966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10967         sw_if_index_set = 1;
10968       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10969         ;
10970       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10971         ;
10972       else
10973         break;
10974     }
10975
10976   if (sw_if_index_set == 0)
10977     {
10978       errmsg ("missing interface name or sw_if_index");
10979       return -99;
10980     }
10981
10982   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10983
10984   mp->sw_if_index = ntohl (sw_if_index);
10985   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10986   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10987
10988   S (mp);
10989   W (ret);
10990   return ret;
10991 }
10992
10993 static int
10994 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10995 {
10996   unformat_input_t *i = vam->input;
10997   vl_api_l2tpv3_interface_enable_disable_t *mp;
10998   u32 sw_if_index;
10999   u8 sw_if_index_set = 0;
11000   u8 enable_disable = 1;
11001   int ret;
11002
11003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11004     {
11005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11006         sw_if_index_set = 1;
11007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11008         sw_if_index_set = 1;
11009       else if (unformat (i, "enable"))
11010         enable_disable = 1;
11011       else if (unformat (i, "disable"))
11012         enable_disable = 0;
11013       else
11014         break;
11015     }
11016
11017   if (sw_if_index_set == 0)
11018     {
11019       errmsg ("missing interface name or sw_if_index");
11020       return -99;
11021     }
11022
11023   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11024
11025   mp->sw_if_index = ntohl (sw_if_index);
11026   mp->enable_disable = enable_disable;
11027
11028   S (mp);
11029   W (ret);
11030   return ret;
11031 }
11032
11033 static int
11034 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11035 {
11036   unformat_input_t *i = vam->input;
11037   vl_api_l2tpv3_set_lookup_key_t *mp;
11038   u8 key = ~0;
11039   int ret;
11040
11041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11042     {
11043       if (unformat (i, "lookup_v6_src"))
11044         key = L2T_LOOKUP_SRC_ADDRESS;
11045       else if (unformat (i, "lookup_v6_dst"))
11046         key = L2T_LOOKUP_DST_ADDRESS;
11047       else if (unformat (i, "lookup_session_id"))
11048         key = L2T_LOOKUP_SESSION_ID;
11049       else
11050         break;
11051     }
11052
11053   if (key == (u8) ~ 0)
11054     {
11055       errmsg ("l2tp session lookup key unset");
11056       return -99;
11057     }
11058
11059   M (L2TPV3_SET_LOOKUP_KEY, mp);
11060
11061   mp->key = key;
11062
11063   S (mp);
11064   W (ret);
11065   return ret;
11066 }
11067
11068 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11069   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11070 {
11071   vat_main_t *vam = &vat_main;
11072
11073   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11074          format_ip6_address, mp->our_address,
11075          format_ip6_address, mp->client_address,
11076          clib_net_to_host_u32 (mp->sw_if_index));
11077
11078   print (vam->ofp,
11079          "   local cookies %016llx %016llx remote cookie %016llx",
11080          clib_net_to_host_u64 (mp->local_cookie[0]),
11081          clib_net_to_host_u64 (mp->local_cookie[1]),
11082          clib_net_to_host_u64 (mp->remote_cookie));
11083
11084   print (vam->ofp, "   local session-id %d remote session-id %d",
11085          clib_net_to_host_u32 (mp->local_session_id),
11086          clib_net_to_host_u32 (mp->remote_session_id));
11087
11088   print (vam->ofp, "   l2 specific sublayer %s\n",
11089          mp->l2_sublayer_present ? "preset" : "absent");
11090
11091 }
11092
11093 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11094   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11095 {
11096   vat_main_t *vam = &vat_main;
11097   vat_json_node_t *node = NULL;
11098   struct in6_addr addr;
11099
11100   if (VAT_JSON_ARRAY != vam->json_tree.type)
11101     {
11102       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11103       vat_json_init_array (&vam->json_tree);
11104     }
11105   node = vat_json_array_add (&vam->json_tree);
11106
11107   vat_json_init_object (node);
11108
11109   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11110   vat_json_object_add_ip6 (node, "our_address", addr);
11111   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11112   vat_json_object_add_ip6 (node, "client_address", addr);
11113
11114   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11115   vat_json_init_array (lc);
11116   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11117   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11118   vat_json_object_add_uint (node, "remote_cookie",
11119                             clib_net_to_host_u64 (mp->remote_cookie));
11120
11121   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11122   vat_json_object_add_uint (node, "local_session_id",
11123                             clib_net_to_host_u32 (mp->local_session_id));
11124   vat_json_object_add_uint (node, "remote_session_id",
11125                             clib_net_to_host_u32 (mp->remote_session_id));
11126   vat_json_object_add_string_copy (node, "l2_sublayer",
11127                                    mp->l2_sublayer_present ? (u8 *) "present"
11128                                    : (u8 *) "absent");
11129 }
11130
11131 static int
11132 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11133 {
11134   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11135   vl_api_control_ping_t *mp_ping;
11136   int ret;
11137
11138   /* Get list of l2tpv3-tunnel interfaces */
11139   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11140   S (mp);
11141
11142   /* Use a control ping for synchronization */
11143   M (CONTROL_PING, mp_ping);
11144   S (mp_ping);
11145
11146   W (ret);
11147   return ret;
11148 }
11149
11150
11151 static void vl_api_sw_interface_tap_details_t_handler
11152   (vl_api_sw_interface_tap_details_t * mp)
11153 {
11154   vat_main_t *vam = &vat_main;
11155
11156   print (vam->ofp, "%-16s %d",
11157          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11158 }
11159
11160 static void vl_api_sw_interface_tap_details_t_handler_json
11161   (vl_api_sw_interface_tap_details_t * mp)
11162 {
11163   vat_main_t *vam = &vat_main;
11164   vat_json_node_t *node = NULL;
11165
11166   if (VAT_JSON_ARRAY != vam->json_tree.type)
11167     {
11168       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11169       vat_json_init_array (&vam->json_tree);
11170     }
11171   node = vat_json_array_add (&vam->json_tree);
11172
11173   vat_json_init_object (node);
11174   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11175   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11176 }
11177
11178 static int
11179 api_sw_interface_tap_dump (vat_main_t * vam)
11180 {
11181   vl_api_sw_interface_tap_dump_t *mp;
11182   vl_api_control_ping_t *mp_ping;
11183   int ret;
11184
11185   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11186   /* Get list of tap interfaces */
11187   M (SW_INTERFACE_TAP_DUMP, mp);
11188   S (mp);
11189
11190   /* Use a control ping for synchronization */
11191   M (CONTROL_PING, mp_ping);
11192   S (mp_ping);
11193
11194   W (ret);
11195   return ret;
11196 }
11197
11198 static uword unformat_vxlan_decap_next
11199   (unformat_input_t * input, va_list * args)
11200 {
11201   u32 *result = va_arg (*args, u32 *);
11202   u32 tmp;
11203
11204   if (unformat (input, "l2"))
11205     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11206   else if (unformat (input, "%d", &tmp))
11207     *result = tmp;
11208   else
11209     return 0;
11210   return 1;
11211 }
11212
11213 static int
11214 api_vxlan_add_del_tunnel (vat_main_t * vam)
11215 {
11216   unformat_input_t *line_input = vam->input;
11217   vl_api_vxlan_add_del_tunnel_t *mp;
11218   ip46_address_t src, dst;
11219   u8 is_add = 1;
11220   u8 ipv4_set = 0, ipv6_set = 0;
11221   u8 src_set = 0;
11222   u8 dst_set = 0;
11223   u8 grp_set = 0;
11224   u32 mcast_sw_if_index = ~0;
11225   u32 encap_vrf_id = 0;
11226   u32 decap_next_index = ~0;
11227   u32 vni = 0;
11228   int ret;
11229
11230   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11231   memset (&src, 0, sizeof src);
11232   memset (&dst, 0, sizeof dst);
11233
11234   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11235     {
11236       if (unformat (line_input, "del"))
11237         is_add = 0;
11238       else
11239         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11240         {
11241           ipv4_set = 1;
11242           src_set = 1;
11243         }
11244       else
11245         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11246         {
11247           ipv4_set = 1;
11248           dst_set = 1;
11249         }
11250       else
11251         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11252         {
11253           ipv6_set = 1;
11254           src_set = 1;
11255         }
11256       else
11257         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11258         {
11259           ipv6_set = 1;
11260           dst_set = 1;
11261         }
11262       else if (unformat (line_input, "group %U %U",
11263                          unformat_ip4_address, &dst.ip4,
11264                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11265         {
11266           grp_set = dst_set = 1;
11267           ipv4_set = 1;
11268         }
11269       else if (unformat (line_input, "group %U",
11270                          unformat_ip4_address, &dst.ip4))
11271         {
11272           grp_set = dst_set = 1;
11273           ipv4_set = 1;
11274         }
11275       else if (unformat (line_input, "group %U %U",
11276                          unformat_ip6_address, &dst.ip6,
11277                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11278         {
11279           grp_set = dst_set = 1;
11280           ipv6_set = 1;
11281         }
11282       else if (unformat (line_input, "group %U",
11283                          unformat_ip6_address, &dst.ip6))
11284         {
11285           grp_set = dst_set = 1;
11286           ipv6_set = 1;
11287         }
11288       else
11289         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11290         ;
11291       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11292         ;
11293       else if (unformat (line_input, "decap-next %U",
11294                          unformat_vxlan_decap_next, &decap_next_index))
11295         ;
11296       else if (unformat (line_input, "vni %d", &vni))
11297         ;
11298       else
11299         {
11300           errmsg ("parse error '%U'", format_unformat_error, line_input);
11301           return -99;
11302         }
11303     }
11304
11305   if (src_set == 0)
11306     {
11307       errmsg ("tunnel src address not specified");
11308       return -99;
11309     }
11310   if (dst_set == 0)
11311     {
11312       errmsg ("tunnel dst address not specified");
11313       return -99;
11314     }
11315
11316   if (grp_set && !ip46_address_is_multicast (&dst))
11317     {
11318       errmsg ("tunnel group address not multicast");
11319       return -99;
11320     }
11321   if (grp_set && mcast_sw_if_index == ~0)
11322     {
11323       errmsg ("tunnel nonexistent multicast device");
11324       return -99;
11325     }
11326   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11327     {
11328       errmsg ("tunnel dst address must be unicast");
11329       return -99;
11330     }
11331
11332
11333   if (ipv4_set && ipv6_set)
11334     {
11335       errmsg ("both IPv4 and IPv6 addresses specified");
11336       return -99;
11337     }
11338
11339   if ((vni == 0) || (vni >> 24))
11340     {
11341       errmsg ("vni not specified or out of range");
11342       return -99;
11343     }
11344
11345   M (VXLAN_ADD_DEL_TUNNEL, mp);
11346
11347   if (ipv6_set)
11348     {
11349       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11350       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11351     }
11352   else
11353     {
11354       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11355       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11356     }
11357   mp->encap_vrf_id = ntohl (encap_vrf_id);
11358   mp->decap_next_index = ntohl (decap_next_index);
11359   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11360   mp->vni = ntohl (vni);
11361   mp->is_add = is_add;
11362   mp->is_ipv6 = ipv6_set;
11363
11364   S (mp);
11365   W (ret);
11366   return ret;
11367 }
11368
11369 static void vl_api_vxlan_tunnel_details_t_handler
11370   (vl_api_vxlan_tunnel_details_t * mp)
11371 {
11372   vat_main_t *vam = &vat_main;
11373   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11374   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11375
11376   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11377          ntohl (mp->sw_if_index),
11378          format_ip46_address, &src, IP46_TYPE_ANY,
11379          format_ip46_address, &dst, IP46_TYPE_ANY,
11380          ntohl (mp->encap_vrf_id),
11381          ntohl (mp->decap_next_index), ntohl (mp->vni),
11382          ntohl (mp->mcast_sw_if_index));
11383 }
11384
11385 static void vl_api_vxlan_tunnel_details_t_handler_json
11386   (vl_api_vxlan_tunnel_details_t * mp)
11387 {
11388   vat_main_t *vam = &vat_main;
11389   vat_json_node_t *node = NULL;
11390
11391   if (VAT_JSON_ARRAY != vam->json_tree.type)
11392     {
11393       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11394       vat_json_init_array (&vam->json_tree);
11395     }
11396   node = vat_json_array_add (&vam->json_tree);
11397
11398   vat_json_init_object (node);
11399   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11400   if (mp->is_ipv6)
11401     {
11402       struct in6_addr ip6;
11403
11404       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11405       vat_json_object_add_ip6 (node, "src_address", ip6);
11406       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11407       vat_json_object_add_ip6 (node, "dst_address", ip6);
11408     }
11409   else
11410     {
11411       struct in_addr ip4;
11412
11413       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11414       vat_json_object_add_ip4 (node, "src_address", ip4);
11415       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11416       vat_json_object_add_ip4 (node, "dst_address", ip4);
11417     }
11418   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11419   vat_json_object_add_uint (node, "decap_next_index",
11420                             ntohl (mp->decap_next_index));
11421   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11422   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11423   vat_json_object_add_uint (node, "mcast_sw_if_index",
11424                             ntohl (mp->mcast_sw_if_index));
11425 }
11426
11427 static int
11428 api_vxlan_tunnel_dump (vat_main_t * vam)
11429 {
11430   unformat_input_t *i = vam->input;
11431   vl_api_vxlan_tunnel_dump_t *mp;
11432   vl_api_control_ping_t *mp_ping;
11433   u32 sw_if_index;
11434   u8 sw_if_index_set = 0;
11435   int ret;
11436
11437   /* Parse args required to build the message */
11438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11439     {
11440       if (unformat (i, "sw_if_index %d", &sw_if_index))
11441         sw_if_index_set = 1;
11442       else
11443         break;
11444     }
11445
11446   if (sw_if_index_set == 0)
11447     {
11448       sw_if_index = ~0;
11449     }
11450
11451   if (!vam->json_output)
11452     {
11453       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11454              "sw_if_index", "src_address", "dst_address",
11455              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11456     }
11457
11458   /* Get list of vxlan-tunnel interfaces */
11459   M (VXLAN_TUNNEL_DUMP, mp);
11460
11461   mp->sw_if_index = htonl (sw_if_index);
11462
11463   S (mp);
11464
11465   /* Use a control ping for synchronization */
11466   M (CONTROL_PING, mp_ping);
11467   S (mp_ping);
11468
11469   W (ret);
11470   return ret;
11471 }
11472
11473 static int
11474 api_gre_add_del_tunnel (vat_main_t * vam)
11475 {
11476   unformat_input_t *line_input = vam->input;
11477   vl_api_gre_add_del_tunnel_t *mp;
11478   ip4_address_t src4, dst4;
11479   ip6_address_t src6, dst6;
11480   u8 is_add = 1;
11481   u8 ipv4_set = 0;
11482   u8 ipv6_set = 0;
11483   u8 teb = 0;
11484   u8 src_set = 0;
11485   u8 dst_set = 0;
11486   u32 outer_fib_id = 0;
11487   int ret;
11488
11489   memset (&src4, 0, sizeof src4);
11490   memset (&dst4, 0, sizeof dst4);
11491   memset (&src6, 0, sizeof src6);
11492   memset (&dst6, 0, sizeof dst6);
11493
11494   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11495     {
11496       if (unformat (line_input, "del"))
11497         is_add = 0;
11498       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11499         {
11500           src_set = 1;
11501           ipv4_set = 1;
11502         }
11503       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11504         {
11505           dst_set = 1;
11506           ipv4_set = 1;
11507         }
11508       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11509         {
11510           src_set = 1;
11511           ipv6_set = 1;
11512         }
11513       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11514         {
11515           dst_set = 1;
11516           ipv6_set = 1;
11517         }
11518       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11519         ;
11520       else if (unformat (line_input, "teb"))
11521         teb = 1;
11522       else
11523         {
11524           errmsg ("parse error '%U'", format_unformat_error, line_input);
11525           return -99;
11526         }
11527     }
11528
11529   if (src_set == 0)
11530     {
11531       errmsg ("tunnel src address not specified");
11532       return -99;
11533     }
11534   if (dst_set == 0)
11535     {
11536       errmsg ("tunnel dst address not specified");
11537       return -99;
11538     }
11539   if (ipv4_set && ipv6_set)
11540     {
11541       errmsg ("both IPv4 and IPv6 addresses specified");
11542       return -99;
11543     }
11544
11545
11546   M (GRE_ADD_DEL_TUNNEL, mp);
11547
11548   if (ipv4_set)
11549     {
11550       clib_memcpy (&mp->src_address, &src4, 4);
11551       clib_memcpy (&mp->dst_address, &dst4, 4);
11552     }
11553   else
11554     {
11555       clib_memcpy (&mp->src_address, &src6, 16);
11556       clib_memcpy (&mp->dst_address, &dst6, 16);
11557     }
11558   mp->outer_fib_id = ntohl (outer_fib_id);
11559   mp->is_add = is_add;
11560   mp->teb = teb;
11561   mp->is_ipv6 = ipv6_set;
11562
11563   S (mp);
11564   W (ret);
11565   return ret;
11566 }
11567
11568 static void vl_api_gre_tunnel_details_t_handler
11569   (vl_api_gre_tunnel_details_t * mp)
11570 {
11571   vat_main_t *vam = &vat_main;
11572   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11573   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11574
11575   print (vam->ofp, "%11d%24U%24U%6d%14d",
11576          ntohl (mp->sw_if_index),
11577          format_ip46_address, &src, IP46_TYPE_ANY,
11578          format_ip46_address, &dst, IP46_TYPE_ANY,
11579          mp->teb, ntohl (mp->outer_fib_id));
11580 }
11581
11582 static void vl_api_gre_tunnel_details_t_handler_json
11583   (vl_api_gre_tunnel_details_t * mp)
11584 {
11585   vat_main_t *vam = &vat_main;
11586   vat_json_node_t *node = NULL;
11587   struct in_addr ip4;
11588   struct in6_addr ip6;
11589
11590   if (VAT_JSON_ARRAY != vam->json_tree.type)
11591     {
11592       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11593       vat_json_init_array (&vam->json_tree);
11594     }
11595   node = vat_json_array_add (&vam->json_tree);
11596
11597   vat_json_init_object (node);
11598   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11599   if (!mp->is_ipv6)
11600     {
11601       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11602       vat_json_object_add_ip4 (node, "src_address", ip4);
11603       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11604       vat_json_object_add_ip4 (node, "dst_address", ip4);
11605     }
11606   else
11607     {
11608       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11609       vat_json_object_add_ip6 (node, "src_address", ip6);
11610       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11611       vat_json_object_add_ip6 (node, "dst_address", ip6);
11612     }
11613   vat_json_object_add_uint (node, "teb", mp->teb);
11614   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11615   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11616 }
11617
11618 static int
11619 api_gre_tunnel_dump (vat_main_t * vam)
11620 {
11621   unformat_input_t *i = vam->input;
11622   vl_api_gre_tunnel_dump_t *mp;
11623   vl_api_control_ping_t *mp_ping;
11624   u32 sw_if_index;
11625   u8 sw_if_index_set = 0;
11626   int ret;
11627
11628   /* Parse args required to build the message */
11629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (i, "sw_if_index %d", &sw_if_index))
11632         sw_if_index_set = 1;
11633       else
11634         break;
11635     }
11636
11637   if (sw_if_index_set == 0)
11638     {
11639       sw_if_index = ~0;
11640     }
11641
11642   if (!vam->json_output)
11643     {
11644       print (vam->ofp, "%11s%24s%24s%6s%14s",
11645              "sw_if_index", "src_address", "dst_address", "teb",
11646              "outer_fib_id");
11647     }
11648
11649   /* Get list of gre-tunnel interfaces */
11650   M (GRE_TUNNEL_DUMP, mp);
11651
11652   mp->sw_if_index = htonl (sw_if_index);
11653
11654   S (mp);
11655
11656   /* Use a control ping for synchronization */
11657   M (CONTROL_PING, mp_ping);
11658   S (mp_ping);
11659
11660   W (ret);
11661   return ret;
11662 }
11663
11664 static int
11665 api_l2_fib_clear_table (vat_main_t * vam)
11666 {
11667 //  unformat_input_t * i = vam->input;
11668   vl_api_l2_fib_clear_table_t *mp;
11669   int ret;
11670
11671   M (L2_FIB_CLEAR_TABLE, mp);
11672
11673   S (mp);
11674   W (ret);
11675   return ret;
11676 }
11677
11678 static int
11679 api_l2_interface_efp_filter (vat_main_t * vam)
11680 {
11681   unformat_input_t *i = vam->input;
11682   vl_api_l2_interface_efp_filter_t *mp;
11683   u32 sw_if_index;
11684   u8 enable = 1;
11685   u8 sw_if_index_set = 0;
11686   int ret;
11687
11688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11689     {
11690       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11691         sw_if_index_set = 1;
11692       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11693         sw_if_index_set = 1;
11694       else if (unformat (i, "enable"))
11695         enable = 1;
11696       else if (unformat (i, "disable"))
11697         enable = 0;
11698       else
11699         {
11700           clib_warning ("parse error '%U'", format_unformat_error, i);
11701           return -99;
11702         }
11703     }
11704
11705   if (sw_if_index_set == 0)
11706     {
11707       errmsg ("missing sw_if_index");
11708       return -99;
11709     }
11710
11711   M (L2_INTERFACE_EFP_FILTER, mp);
11712
11713   mp->sw_if_index = ntohl (sw_if_index);
11714   mp->enable_disable = enable;
11715
11716   S (mp);
11717   W (ret);
11718   return ret;
11719 }
11720
11721 #define foreach_vtr_op                          \
11722 _("disable",  L2_VTR_DISABLED)                  \
11723 _("push-1",  L2_VTR_PUSH_1)                     \
11724 _("push-2",  L2_VTR_PUSH_2)                     \
11725 _("pop-1",  L2_VTR_POP_1)                       \
11726 _("pop-2",  L2_VTR_POP_2)                       \
11727 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11728 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11729 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11730 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11731
11732 static int
11733 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11734 {
11735   unformat_input_t *i = vam->input;
11736   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11737   u32 sw_if_index;
11738   u8 sw_if_index_set = 0;
11739   u8 vtr_op_set = 0;
11740   u32 vtr_op = 0;
11741   u32 push_dot1q = 1;
11742   u32 tag1 = ~0;
11743   u32 tag2 = ~0;
11744   int ret;
11745
11746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11747     {
11748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11749         sw_if_index_set = 1;
11750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11751         sw_if_index_set = 1;
11752       else if (unformat (i, "vtr_op %d", &vtr_op))
11753         vtr_op_set = 1;
11754 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11755       foreach_vtr_op
11756 #undef _
11757         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11758         ;
11759       else if (unformat (i, "tag1 %d", &tag1))
11760         ;
11761       else if (unformat (i, "tag2 %d", &tag2))
11762         ;
11763       else
11764         {
11765           clib_warning ("parse error '%U'", format_unformat_error, i);
11766           return -99;
11767         }
11768     }
11769
11770   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11771     {
11772       errmsg ("missing vtr operation or sw_if_index");
11773       return -99;
11774     }
11775
11776   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11777   mp->sw_if_index = ntohl (sw_if_index);
11778   mp->vtr_op = ntohl (vtr_op);
11779   mp->push_dot1q = ntohl (push_dot1q);
11780   mp->tag1 = ntohl (tag1);
11781   mp->tag2 = ntohl (tag2);
11782
11783   S (mp);
11784   W (ret);
11785   return ret;
11786 }
11787
11788 static int
11789 api_create_vhost_user_if (vat_main_t * vam)
11790 {
11791   unformat_input_t *i = vam->input;
11792   vl_api_create_vhost_user_if_t *mp;
11793   u8 *file_name;
11794   u8 is_server = 0;
11795   u8 file_name_set = 0;
11796   u32 custom_dev_instance = ~0;
11797   u8 hwaddr[6];
11798   u8 use_custom_mac = 0;
11799   u8 *tag = 0;
11800   int ret;
11801
11802   /* Shut up coverity */
11803   memset (hwaddr, 0, sizeof (hwaddr));
11804
11805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11806     {
11807       if (unformat (i, "socket %s", &file_name))
11808         {
11809           file_name_set = 1;
11810         }
11811       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11812         ;
11813       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11814         use_custom_mac = 1;
11815       else if (unformat (i, "server"))
11816         is_server = 1;
11817       else if (unformat (i, "tag %s", &tag))
11818         ;
11819       else
11820         break;
11821     }
11822
11823   if (file_name_set == 0)
11824     {
11825       errmsg ("missing socket file name");
11826       return -99;
11827     }
11828
11829   if (vec_len (file_name) > 255)
11830     {
11831       errmsg ("socket file name too long");
11832       return -99;
11833     }
11834   vec_add1 (file_name, 0);
11835
11836   M (CREATE_VHOST_USER_IF, mp);
11837
11838   mp->is_server = is_server;
11839   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11840   vec_free (file_name);
11841   if (custom_dev_instance != ~0)
11842     {
11843       mp->renumber = 1;
11844       mp->custom_dev_instance = ntohl (custom_dev_instance);
11845     }
11846   mp->use_custom_mac = use_custom_mac;
11847   clib_memcpy (mp->mac_address, hwaddr, 6);
11848   if (tag)
11849     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11850   vec_free (tag);
11851
11852   S (mp);
11853   W (ret);
11854   return ret;
11855 }
11856
11857 static int
11858 api_modify_vhost_user_if (vat_main_t * vam)
11859 {
11860   unformat_input_t *i = vam->input;
11861   vl_api_modify_vhost_user_if_t *mp;
11862   u8 *file_name;
11863   u8 is_server = 0;
11864   u8 file_name_set = 0;
11865   u32 custom_dev_instance = ~0;
11866   u8 sw_if_index_set = 0;
11867   u32 sw_if_index = (u32) ~ 0;
11868   int ret;
11869
11870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11871     {
11872       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11873         sw_if_index_set = 1;
11874       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11875         sw_if_index_set = 1;
11876       else if (unformat (i, "socket %s", &file_name))
11877         {
11878           file_name_set = 1;
11879         }
11880       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11881         ;
11882       else if (unformat (i, "server"))
11883         is_server = 1;
11884       else
11885         break;
11886     }
11887
11888   if (sw_if_index_set == 0)
11889     {
11890       errmsg ("missing sw_if_index or interface name");
11891       return -99;
11892     }
11893
11894   if (file_name_set == 0)
11895     {
11896       errmsg ("missing socket file name");
11897       return -99;
11898     }
11899
11900   if (vec_len (file_name) > 255)
11901     {
11902       errmsg ("socket file name too long");
11903       return -99;
11904     }
11905   vec_add1 (file_name, 0);
11906
11907   M (MODIFY_VHOST_USER_IF, mp);
11908
11909   mp->sw_if_index = ntohl (sw_if_index);
11910   mp->is_server = is_server;
11911   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11912   vec_free (file_name);
11913   if (custom_dev_instance != ~0)
11914     {
11915       mp->renumber = 1;
11916       mp->custom_dev_instance = ntohl (custom_dev_instance);
11917     }
11918
11919   S (mp);
11920   W (ret);
11921   return ret;
11922 }
11923
11924 static int
11925 api_delete_vhost_user_if (vat_main_t * vam)
11926 {
11927   unformat_input_t *i = vam->input;
11928   vl_api_delete_vhost_user_if_t *mp;
11929   u32 sw_if_index = ~0;
11930   u8 sw_if_index_set = 0;
11931   int ret;
11932
11933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11934     {
11935       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11936         sw_if_index_set = 1;
11937       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11938         sw_if_index_set = 1;
11939       else
11940         break;
11941     }
11942
11943   if (sw_if_index_set == 0)
11944     {
11945       errmsg ("missing sw_if_index or interface name");
11946       return -99;
11947     }
11948
11949
11950   M (DELETE_VHOST_USER_IF, mp);
11951
11952   mp->sw_if_index = ntohl (sw_if_index);
11953
11954   S (mp);
11955   W (ret);
11956   return ret;
11957 }
11958
11959 static void vl_api_sw_interface_vhost_user_details_t_handler
11960   (vl_api_sw_interface_vhost_user_details_t * mp)
11961 {
11962   vat_main_t *vam = &vat_main;
11963
11964   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11965          (char *) mp->interface_name,
11966          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11967          clib_net_to_host_u64 (mp->features), mp->is_server,
11968          ntohl (mp->num_regions), (char *) mp->sock_filename);
11969   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11970 }
11971
11972 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11973   (vl_api_sw_interface_vhost_user_details_t * mp)
11974 {
11975   vat_main_t *vam = &vat_main;
11976   vat_json_node_t *node = NULL;
11977
11978   if (VAT_JSON_ARRAY != vam->json_tree.type)
11979     {
11980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11981       vat_json_init_array (&vam->json_tree);
11982     }
11983   node = vat_json_array_add (&vam->json_tree);
11984
11985   vat_json_init_object (node);
11986   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11987   vat_json_object_add_string_copy (node, "interface_name",
11988                                    mp->interface_name);
11989   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11990                             ntohl (mp->virtio_net_hdr_sz));
11991   vat_json_object_add_uint (node, "features",
11992                             clib_net_to_host_u64 (mp->features));
11993   vat_json_object_add_uint (node, "is_server", mp->is_server);
11994   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11995   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11996   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11997 }
11998
11999 static int
12000 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12001 {
12002   vl_api_sw_interface_vhost_user_dump_t *mp;
12003   vl_api_control_ping_t *mp_ping;
12004   int ret;
12005   print (vam->ofp,
12006          "Interface name            idx hdr_sz features server regions filename");
12007
12008   /* Get list of vhost-user interfaces */
12009   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12010   S (mp);
12011
12012   /* Use a control ping for synchronization */
12013   M (CONTROL_PING, mp_ping);
12014   S (mp_ping);
12015
12016   W (ret);
12017   return ret;
12018 }
12019
12020 static int
12021 api_show_version (vat_main_t * vam)
12022 {
12023   vl_api_show_version_t *mp;
12024   int ret;
12025
12026   M (SHOW_VERSION, mp);
12027
12028   S (mp);
12029   W (ret);
12030   return ret;
12031 }
12032
12033
12034 static int
12035 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12036 {
12037   unformat_input_t *line_input = vam->input;
12038   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12039   ip4_address_t local4, remote4;
12040   ip6_address_t local6, remote6;
12041   u8 is_add = 1;
12042   u8 ipv4_set = 0, ipv6_set = 0;
12043   u8 local_set = 0;
12044   u8 remote_set = 0;
12045   u8 grp_set = 0;
12046   u32 mcast_sw_if_index = ~0;
12047   u32 encap_vrf_id = 0;
12048   u32 decap_vrf_id = 0;
12049   u8 protocol = ~0;
12050   u32 vni;
12051   u8 vni_set = 0;
12052   int ret;
12053
12054   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12055   memset (&local4, 0, sizeof local4);
12056   memset (&remote4, 0, sizeof remote4);
12057   memset (&local6, 0, sizeof local6);
12058   memset (&remote6, 0, sizeof remote6);
12059
12060   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12061     {
12062       if (unformat (line_input, "del"))
12063         is_add = 0;
12064       else if (unformat (line_input, "local %U",
12065                          unformat_ip4_address, &local4))
12066         {
12067           local_set = 1;
12068           ipv4_set = 1;
12069         }
12070       else if (unformat (line_input, "remote %U",
12071                          unformat_ip4_address, &remote4))
12072         {
12073           remote_set = 1;
12074           ipv4_set = 1;
12075         }
12076       else if (unformat (line_input, "local %U",
12077                          unformat_ip6_address, &local6))
12078         {
12079           local_set = 1;
12080           ipv6_set = 1;
12081         }
12082       else if (unformat (line_input, "remote %U",
12083                          unformat_ip6_address, &remote6))
12084         {
12085           remote_set = 1;
12086           ipv6_set = 1;
12087         }
12088       else if (unformat (line_input, "group %U %U",
12089                          unformat_ip4_address, &remote4,
12090                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12091         {
12092           grp_set = remote_set = 1;
12093           ipv4_set = 1;
12094         }
12095       else if (unformat (line_input, "group %U",
12096                          unformat_ip4_address, &remote4))
12097         {
12098           grp_set = remote_set = 1;
12099           ipv4_set = 1;
12100         }
12101       else if (unformat (line_input, "group %U %U",
12102                          unformat_ip6_address, &remote6,
12103                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12104         {
12105           grp_set = remote_set = 1;
12106           ipv6_set = 1;
12107         }
12108       else if (unformat (line_input, "group %U",
12109                          unformat_ip6_address, &remote6))
12110         {
12111           grp_set = remote_set = 1;
12112           ipv6_set = 1;
12113         }
12114       else
12115         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12116         ;
12117       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12118         ;
12119       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12120         ;
12121       else if (unformat (line_input, "vni %d", &vni))
12122         vni_set = 1;
12123       else if (unformat (line_input, "next-ip4"))
12124         protocol = 1;
12125       else if (unformat (line_input, "next-ip6"))
12126         protocol = 2;
12127       else if (unformat (line_input, "next-ethernet"))
12128         protocol = 3;
12129       else if (unformat (line_input, "next-nsh"))
12130         protocol = 4;
12131       else
12132         {
12133           errmsg ("parse error '%U'", format_unformat_error, line_input);
12134           return -99;
12135         }
12136     }
12137
12138   if (local_set == 0)
12139     {
12140       errmsg ("tunnel local address not specified");
12141       return -99;
12142     }
12143   if (remote_set == 0)
12144     {
12145       errmsg ("tunnel remote address not specified");
12146       return -99;
12147     }
12148   if (grp_set && mcast_sw_if_index == ~0)
12149     {
12150       errmsg ("tunnel nonexistent multicast device");
12151       return -99;
12152     }
12153   if (ipv4_set && ipv6_set)
12154     {
12155       errmsg ("both IPv4 and IPv6 addresses specified");
12156       return -99;
12157     }
12158
12159   if (vni_set == 0)
12160     {
12161       errmsg ("vni not specified");
12162       return -99;
12163     }
12164
12165   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12166
12167
12168   if (ipv6_set)
12169     {
12170       clib_memcpy (&mp->local, &local6, sizeof (local6));
12171       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12172     }
12173   else
12174     {
12175       clib_memcpy (&mp->local, &local4, sizeof (local4));
12176       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12177     }
12178
12179   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12180   mp->encap_vrf_id = ntohl (encap_vrf_id);
12181   mp->decap_vrf_id = ntohl (decap_vrf_id);
12182   mp->protocol = protocol;
12183   mp->vni = ntohl (vni);
12184   mp->is_add = is_add;
12185   mp->is_ipv6 = ipv6_set;
12186
12187   S (mp);
12188   W (ret);
12189   return ret;
12190 }
12191
12192 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12193   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12194 {
12195   vat_main_t *vam = &vat_main;
12196   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12197   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12198
12199   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12200          ntohl (mp->sw_if_index),
12201          format_ip46_address, &local, IP46_TYPE_ANY,
12202          format_ip46_address, &remote, IP46_TYPE_ANY,
12203          ntohl (mp->vni), mp->protocol,
12204          ntohl (mp->mcast_sw_if_index),
12205          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12206 }
12207
12208
12209 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12210   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12211 {
12212   vat_main_t *vam = &vat_main;
12213   vat_json_node_t *node = NULL;
12214   struct in_addr ip4;
12215   struct in6_addr ip6;
12216
12217   if (VAT_JSON_ARRAY != vam->json_tree.type)
12218     {
12219       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12220       vat_json_init_array (&vam->json_tree);
12221     }
12222   node = vat_json_array_add (&vam->json_tree);
12223
12224   vat_json_init_object (node);
12225   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12226   if (mp->is_ipv6)
12227     {
12228       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12229       vat_json_object_add_ip6 (node, "local", ip6);
12230       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12231       vat_json_object_add_ip6 (node, "remote", ip6);
12232     }
12233   else
12234     {
12235       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12236       vat_json_object_add_ip4 (node, "local", ip4);
12237       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12238       vat_json_object_add_ip4 (node, "remote", ip4);
12239     }
12240   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12241   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12242   vat_json_object_add_uint (node, "mcast_sw_if_index",
12243                             ntohl (mp->mcast_sw_if_index));
12244   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12245   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12246   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12247 }
12248
12249 static int
12250 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12251 {
12252   unformat_input_t *i = vam->input;
12253   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12254   vl_api_control_ping_t *mp_ping;
12255   u32 sw_if_index;
12256   u8 sw_if_index_set = 0;
12257   int ret;
12258
12259   /* Parse args required to build the message */
12260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12261     {
12262       if (unformat (i, "sw_if_index %d", &sw_if_index))
12263         sw_if_index_set = 1;
12264       else
12265         break;
12266     }
12267
12268   if (sw_if_index_set == 0)
12269     {
12270       sw_if_index = ~0;
12271     }
12272
12273   if (!vam->json_output)
12274     {
12275       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12276              "sw_if_index", "local", "remote", "vni",
12277              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12278     }
12279
12280   /* Get list of vxlan-tunnel interfaces */
12281   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12282
12283   mp->sw_if_index = htonl (sw_if_index);
12284
12285   S (mp);
12286
12287   /* Use a control ping for synchronization */
12288   M (CONTROL_PING, mp_ping);
12289   S (mp_ping);
12290
12291   W (ret);
12292   return ret;
12293 }
12294
12295
12296 u8 *
12297 format_l2_fib_mac_address (u8 * s, va_list * args)
12298 {
12299   u8 *a = va_arg (*args, u8 *);
12300
12301   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12302                  a[2], a[3], a[4], a[5], a[6], a[7]);
12303 }
12304
12305 static void vl_api_l2_fib_table_details_t_handler
12306   (vl_api_l2_fib_table_details_t * mp)
12307 {
12308   vat_main_t *vam = &vat_main;
12309
12310   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12311          "       %d       %d     %d",
12312          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12313          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12314          mp->bvi_mac);
12315 }
12316
12317 static void vl_api_l2_fib_table_details_t_handler_json
12318   (vl_api_l2_fib_table_details_t * mp)
12319 {
12320   vat_main_t *vam = &vat_main;
12321   vat_json_node_t *node = NULL;
12322
12323   if (VAT_JSON_ARRAY != vam->json_tree.type)
12324     {
12325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12326       vat_json_init_array (&vam->json_tree);
12327     }
12328   node = vat_json_array_add (&vam->json_tree);
12329
12330   vat_json_init_object (node);
12331   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12332   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12333   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12334   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12335   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12336   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12337 }
12338
12339 static int
12340 api_l2_fib_table_dump (vat_main_t * vam)
12341 {
12342   unformat_input_t *i = vam->input;
12343   vl_api_l2_fib_table_dump_t *mp;
12344   vl_api_control_ping_t *mp_ping;
12345   u32 bd_id;
12346   u8 bd_id_set = 0;
12347   int ret;
12348
12349   /* Parse args required to build the message */
12350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12351     {
12352       if (unformat (i, "bd_id %d", &bd_id))
12353         bd_id_set = 1;
12354       else
12355         break;
12356     }
12357
12358   if (bd_id_set == 0)
12359     {
12360       errmsg ("missing bridge domain");
12361       return -99;
12362     }
12363
12364   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12365
12366   /* Get list of l2 fib entries */
12367   M (L2_FIB_TABLE_DUMP, mp);
12368
12369   mp->bd_id = ntohl (bd_id);
12370   S (mp);
12371
12372   /* Use a control ping for synchronization */
12373   M (CONTROL_PING, mp_ping);
12374   S (mp_ping);
12375
12376   W (ret);
12377   return ret;
12378 }
12379
12380
12381 static int
12382 api_interface_name_renumber (vat_main_t * vam)
12383 {
12384   unformat_input_t *line_input = vam->input;
12385   vl_api_interface_name_renumber_t *mp;
12386   u32 sw_if_index = ~0;
12387   u32 new_show_dev_instance = ~0;
12388   int ret;
12389
12390   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12391     {
12392       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12393                     &sw_if_index))
12394         ;
12395       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12396         ;
12397       else if (unformat (line_input, "new_show_dev_instance %d",
12398                          &new_show_dev_instance))
12399         ;
12400       else
12401         break;
12402     }
12403
12404   if (sw_if_index == ~0)
12405     {
12406       errmsg ("missing interface name or sw_if_index");
12407       return -99;
12408     }
12409
12410   if (new_show_dev_instance == ~0)
12411     {
12412       errmsg ("missing new_show_dev_instance");
12413       return -99;
12414     }
12415
12416   M (INTERFACE_NAME_RENUMBER, mp);
12417
12418   mp->sw_if_index = ntohl (sw_if_index);
12419   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12420
12421   S (mp);
12422   W (ret);
12423   return ret;
12424 }
12425
12426 static int
12427 api_want_ip4_arp_events (vat_main_t * vam)
12428 {
12429   unformat_input_t *line_input = vam->input;
12430   vl_api_want_ip4_arp_events_t *mp;
12431   ip4_address_t address;
12432   int address_set = 0;
12433   u32 enable_disable = 1;
12434   int ret;
12435
12436   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12437     {
12438       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12439         address_set = 1;
12440       else if (unformat (line_input, "del"))
12441         enable_disable = 0;
12442       else
12443         break;
12444     }
12445
12446   if (address_set == 0)
12447     {
12448       errmsg ("missing addresses");
12449       return -99;
12450     }
12451
12452   M (WANT_IP4_ARP_EVENTS, mp);
12453   mp->enable_disable = enable_disable;
12454   mp->pid = htonl (getpid ());
12455   mp->address = address.as_u32;
12456
12457   S (mp);
12458   W (ret);
12459   return ret;
12460 }
12461
12462 static int
12463 api_want_ip6_nd_events (vat_main_t * vam)
12464 {
12465   unformat_input_t *line_input = vam->input;
12466   vl_api_want_ip6_nd_events_t *mp;
12467   ip6_address_t address;
12468   int address_set = 0;
12469   u32 enable_disable = 1;
12470   int ret;
12471
12472   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12473     {
12474       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12475         address_set = 1;
12476       else if (unformat (line_input, "del"))
12477         enable_disable = 0;
12478       else
12479         break;
12480     }
12481
12482   if (address_set == 0)
12483     {
12484       errmsg ("missing addresses");
12485       return -99;
12486     }
12487
12488   M (WANT_IP6_ND_EVENTS, mp);
12489   mp->enable_disable = enable_disable;
12490   mp->pid = htonl (getpid ());
12491   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12492
12493   S (mp);
12494   W (ret);
12495   return ret;
12496 }
12497
12498 static int
12499 api_input_acl_set_interface (vat_main_t * vam)
12500 {
12501   unformat_input_t *i = vam->input;
12502   vl_api_input_acl_set_interface_t *mp;
12503   u32 sw_if_index;
12504   int sw_if_index_set;
12505   u32 ip4_table_index = ~0;
12506   u32 ip6_table_index = ~0;
12507   u32 l2_table_index = ~0;
12508   u8 is_add = 1;
12509   int ret;
12510
12511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12512     {
12513       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12514         sw_if_index_set = 1;
12515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12516         sw_if_index_set = 1;
12517       else if (unformat (i, "del"))
12518         is_add = 0;
12519       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12520         ;
12521       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12522         ;
12523       else if (unformat (i, "l2-table %d", &l2_table_index))
12524         ;
12525       else
12526         {
12527           clib_warning ("parse error '%U'", format_unformat_error, i);
12528           return -99;
12529         }
12530     }
12531
12532   if (sw_if_index_set == 0)
12533     {
12534       errmsg ("missing interface name or sw_if_index");
12535       return -99;
12536     }
12537
12538   M (INPUT_ACL_SET_INTERFACE, mp);
12539
12540   mp->sw_if_index = ntohl (sw_if_index);
12541   mp->ip4_table_index = ntohl (ip4_table_index);
12542   mp->ip6_table_index = ntohl (ip6_table_index);
12543   mp->l2_table_index = ntohl (l2_table_index);
12544   mp->is_add = is_add;
12545
12546   S (mp);
12547   W (ret);
12548   return ret;
12549 }
12550
12551 static int
12552 api_ip_address_dump (vat_main_t * vam)
12553 {
12554   unformat_input_t *i = vam->input;
12555   vl_api_ip_address_dump_t *mp;
12556   vl_api_control_ping_t *mp_ping;
12557   u32 sw_if_index = ~0;
12558   u8 sw_if_index_set = 0;
12559   u8 ipv4_set = 0;
12560   u8 ipv6_set = 0;
12561   int ret;
12562
12563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12564     {
12565       if (unformat (i, "sw_if_index %d", &sw_if_index))
12566         sw_if_index_set = 1;
12567       else
12568         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12569         sw_if_index_set = 1;
12570       else if (unformat (i, "ipv4"))
12571         ipv4_set = 1;
12572       else if (unformat (i, "ipv6"))
12573         ipv6_set = 1;
12574       else
12575         break;
12576     }
12577
12578   if (ipv4_set && ipv6_set)
12579     {
12580       errmsg ("ipv4 and ipv6 flags cannot be both set");
12581       return -99;
12582     }
12583
12584   if ((!ipv4_set) && (!ipv6_set))
12585     {
12586       errmsg ("no ipv4 nor ipv6 flag set");
12587       return -99;
12588     }
12589
12590   if (sw_if_index_set == 0)
12591     {
12592       errmsg ("missing interface name or sw_if_index");
12593       return -99;
12594     }
12595
12596   vam->current_sw_if_index = sw_if_index;
12597   vam->is_ipv6 = ipv6_set;
12598
12599   M (IP_ADDRESS_DUMP, mp);
12600   mp->sw_if_index = ntohl (sw_if_index);
12601   mp->is_ipv6 = ipv6_set;
12602   S (mp);
12603
12604   /* Use a control ping for synchronization */
12605   M (CONTROL_PING, mp_ping);
12606   S (mp_ping);
12607
12608   W (ret);
12609   return ret;
12610 }
12611
12612 static int
12613 api_ip_dump (vat_main_t * vam)
12614 {
12615   vl_api_ip_dump_t *mp;
12616   vl_api_control_ping_t *mp_ping;
12617   unformat_input_t *in = vam->input;
12618   int ipv4_set = 0;
12619   int ipv6_set = 0;
12620   int is_ipv6;
12621   int i;
12622   int ret;
12623
12624   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12625     {
12626       if (unformat (in, "ipv4"))
12627         ipv4_set = 1;
12628       else if (unformat (in, "ipv6"))
12629         ipv6_set = 1;
12630       else
12631         break;
12632     }
12633
12634   if (ipv4_set && ipv6_set)
12635     {
12636       errmsg ("ipv4 and ipv6 flags cannot be both set");
12637       return -99;
12638     }
12639
12640   if ((!ipv4_set) && (!ipv6_set))
12641     {
12642       errmsg ("no ipv4 nor ipv6 flag set");
12643       return -99;
12644     }
12645
12646   is_ipv6 = ipv6_set;
12647   vam->is_ipv6 = is_ipv6;
12648
12649   /* free old data */
12650   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12651     {
12652       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12653     }
12654   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12655
12656   M (IP_DUMP, mp);
12657   mp->is_ipv6 = ipv6_set;
12658   S (mp);
12659
12660   /* Use a control ping for synchronization */
12661   M (CONTROL_PING, mp_ping);
12662   S (mp_ping);
12663
12664   W (ret);
12665   return ret;
12666 }
12667
12668 static int
12669 api_ipsec_spd_add_del (vat_main_t * vam)
12670 {
12671   unformat_input_t *i = vam->input;
12672   vl_api_ipsec_spd_add_del_t *mp;
12673   u32 spd_id = ~0;
12674   u8 is_add = 1;
12675   int ret;
12676
12677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12678     {
12679       if (unformat (i, "spd_id %d", &spd_id))
12680         ;
12681       else if (unformat (i, "del"))
12682         is_add = 0;
12683       else
12684         {
12685           clib_warning ("parse error '%U'", format_unformat_error, i);
12686           return -99;
12687         }
12688     }
12689   if (spd_id == ~0)
12690     {
12691       errmsg ("spd_id must be set");
12692       return -99;
12693     }
12694
12695   M (IPSEC_SPD_ADD_DEL, mp);
12696
12697   mp->spd_id = ntohl (spd_id);
12698   mp->is_add = is_add;
12699
12700   S (mp);
12701   W (ret);
12702   return ret;
12703 }
12704
12705 static int
12706 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12707 {
12708   unformat_input_t *i = vam->input;
12709   vl_api_ipsec_interface_add_del_spd_t *mp;
12710   u32 sw_if_index;
12711   u8 sw_if_index_set = 0;
12712   u32 spd_id = (u32) ~ 0;
12713   u8 is_add = 1;
12714   int ret;
12715
12716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12717     {
12718       if (unformat (i, "del"))
12719         is_add = 0;
12720       else if (unformat (i, "spd_id %d", &spd_id))
12721         ;
12722       else
12723         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12724         sw_if_index_set = 1;
12725       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12726         sw_if_index_set = 1;
12727       else
12728         {
12729           clib_warning ("parse error '%U'", format_unformat_error, i);
12730           return -99;
12731         }
12732
12733     }
12734
12735   if (spd_id == (u32) ~ 0)
12736     {
12737       errmsg ("spd_id must be set");
12738       return -99;
12739     }
12740
12741   if (sw_if_index_set == 0)
12742     {
12743       errmsg ("missing interface name or sw_if_index");
12744       return -99;
12745     }
12746
12747   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12748
12749   mp->spd_id = ntohl (spd_id);
12750   mp->sw_if_index = ntohl (sw_if_index);
12751   mp->is_add = is_add;
12752
12753   S (mp);
12754   W (ret);
12755   return ret;
12756 }
12757
12758 static int
12759 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12760 {
12761   unformat_input_t *i = vam->input;
12762   vl_api_ipsec_spd_add_del_entry_t *mp;
12763   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12764   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12765   i32 priority = 0;
12766   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12767   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12768   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12769   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12770   int ret;
12771
12772   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12773   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12774   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12775   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12776   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12777   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12778
12779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12780     {
12781       if (unformat (i, "del"))
12782         is_add = 0;
12783       if (unformat (i, "outbound"))
12784         is_outbound = 1;
12785       if (unformat (i, "inbound"))
12786         is_outbound = 0;
12787       else if (unformat (i, "spd_id %d", &spd_id))
12788         ;
12789       else if (unformat (i, "sa_id %d", &sa_id))
12790         ;
12791       else if (unformat (i, "priority %d", &priority))
12792         ;
12793       else if (unformat (i, "protocol %d", &protocol))
12794         ;
12795       else if (unformat (i, "lport_start %d", &lport_start))
12796         ;
12797       else if (unformat (i, "lport_stop %d", &lport_stop))
12798         ;
12799       else if (unformat (i, "rport_start %d", &rport_start))
12800         ;
12801       else if (unformat (i, "rport_stop %d", &rport_stop))
12802         ;
12803       else
12804         if (unformat
12805             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12806         {
12807           is_ipv6 = 0;
12808           is_ip_any = 0;
12809         }
12810       else
12811         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12812         {
12813           is_ipv6 = 0;
12814           is_ip_any = 0;
12815         }
12816       else
12817         if (unformat
12818             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12819         {
12820           is_ipv6 = 0;
12821           is_ip_any = 0;
12822         }
12823       else
12824         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12825         {
12826           is_ipv6 = 0;
12827           is_ip_any = 0;
12828         }
12829       else
12830         if (unformat
12831             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12832         {
12833           is_ipv6 = 1;
12834           is_ip_any = 0;
12835         }
12836       else
12837         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12838         {
12839           is_ipv6 = 1;
12840           is_ip_any = 0;
12841         }
12842       else
12843         if (unformat
12844             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12845         {
12846           is_ipv6 = 1;
12847           is_ip_any = 0;
12848         }
12849       else
12850         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12851         {
12852           is_ipv6 = 1;
12853           is_ip_any = 0;
12854         }
12855       else
12856         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12857         {
12858           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12859             {
12860               clib_warning ("unsupported action: 'resolve'");
12861               return -99;
12862             }
12863         }
12864       else
12865         {
12866           clib_warning ("parse error '%U'", format_unformat_error, i);
12867           return -99;
12868         }
12869
12870     }
12871
12872   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12873
12874   mp->spd_id = ntohl (spd_id);
12875   mp->priority = ntohl (priority);
12876   mp->is_outbound = is_outbound;
12877
12878   mp->is_ipv6 = is_ipv6;
12879   if (is_ipv6 || is_ip_any)
12880     {
12881       clib_memcpy (mp->remote_address_start, &raddr6_start,
12882                    sizeof (ip6_address_t));
12883       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12884                    sizeof (ip6_address_t));
12885       clib_memcpy (mp->local_address_start, &laddr6_start,
12886                    sizeof (ip6_address_t));
12887       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12888                    sizeof (ip6_address_t));
12889     }
12890   else
12891     {
12892       clib_memcpy (mp->remote_address_start, &raddr4_start,
12893                    sizeof (ip4_address_t));
12894       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12895                    sizeof (ip4_address_t));
12896       clib_memcpy (mp->local_address_start, &laddr4_start,
12897                    sizeof (ip4_address_t));
12898       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12899                    sizeof (ip4_address_t));
12900     }
12901   mp->protocol = (u8) protocol;
12902   mp->local_port_start = ntohs ((u16) lport_start);
12903   mp->local_port_stop = ntohs ((u16) lport_stop);
12904   mp->remote_port_start = ntohs ((u16) rport_start);
12905   mp->remote_port_stop = ntohs ((u16) rport_stop);
12906   mp->policy = (u8) policy;
12907   mp->sa_id = ntohl (sa_id);
12908   mp->is_add = is_add;
12909   mp->is_ip_any = is_ip_any;
12910   S (mp);
12911   W (ret);
12912   return ret;
12913 }
12914
12915 static int
12916 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12917 {
12918   unformat_input_t *i = vam->input;
12919   vl_api_ipsec_sad_add_del_entry_t *mp;
12920   u32 sad_id = 0, spi = 0;
12921   u8 *ck = 0, *ik = 0;
12922   u8 is_add = 1;
12923
12924   u8 protocol = IPSEC_PROTOCOL_AH;
12925   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12926   u32 crypto_alg = 0, integ_alg = 0;
12927   ip4_address_t tun_src4;
12928   ip4_address_t tun_dst4;
12929   ip6_address_t tun_src6;
12930   ip6_address_t tun_dst6;
12931   int ret;
12932
12933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12934     {
12935       if (unformat (i, "del"))
12936         is_add = 0;
12937       else if (unformat (i, "sad_id %d", &sad_id))
12938         ;
12939       else if (unformat (i, "spi %d", &spi))
12940         ;
12941       else if (unformat (i, "esp"))
12942         protocol = IPSEC_PROTOCOL_ESP;
12943       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12944         {
12945           is_tunnel = 1;
12946           is_tunnel_ipv6 = 0;
12947         }
12948       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12949         {
12950           is_tunnel = 1;
12951           is_tunnel_ipv6 = 0;
12952         }
12953       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12954         {
12955           is_tunnel = 1;
12956           is_tunnel_ipv6 = 1;
12957         }
12958       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12959         {
12960           is_tunnel = 1;
12961           is_tunnel_ipv6 = 1;
12962         }
12963       else
12964         if (unformat
12965             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12966         {
12967           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12968               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12969             {
12970               clib_warning ("unsupported crypto-alg: '%U'",
12971                             format_ipsec_crypto_alg, crypto_alg);
12972               return -99;
12973             }
12974         }
12975       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12976         ;
12977       else
12978         if (unformat
12979             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12980         {
12981           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12982               integ_alg >= IPSEC_INTEG_N_ALG)
12983             {
12984               clib_warning ("unsupported integ-alg: '%U'",
12985                             format_ipsec_integ_alg, integ_alg);
12986               return -99;
12987             }
12988         }
12989       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12990         ;
12991       else
12992         {
12993           clib_warning ("parse error '%U'", format_unformat_error, i);
12994           return -99;
12995         }
12996
12997     }
12998
12999   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13000
13001   mp->sad_id = ntohl (sad_id);
13002   mp->is_add = is_add;
13003   mp->protocol = protocol;
13004   mp->spi = ntohl (spi);
13005   mp->is_tunnel = is_tunnel;
13006   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13007   mp->crypto_algorithm = crypto_alg;
13008   mp->integrity_algorithm = integ_alg;
13009   mp->crypto_key_length = vec_len (ck);
13010   mp->integrity_key_length = vec_len (ik);
13011
13012   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13013     mp->crypto_key_length = sizeof (mp->crypto_key);
13014
13015   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13016     mp->integrity_key_length = sizeof (mp->integrity_key);
13017
13018   if (ck)
13019     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13020   if (ik)
13021     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13022
13023   if (is_tunnel)
13024     {
13025       if (is_tunnel_ipv6)
13026         {
13027           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13028                        sizeof (ip6_address_t));
13029           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13030                        sizeof (ip6_address_t));
13031         }
13032       else
13033         {
13034           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13035                        sizeof (ip4_address_t));
13036           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13037                        sizeof (ip4_address_t));
13038         }
13039     }
13040
13041   S (mp);
13042   W (ret);
13043   return ret;
13044 }
13045
13046 static int
13047 api_ipsec_sa_set_key (vat_main_t * vam)
13048 {
13049   unformat_input_t *i = vam->input;
13050   vl_api_ipsec_sa_set_key_t *mp;
13051   u32 sa_id;
13052   u8 *ck = 0, *ik = 0;
13053   int ret;
13054
13055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13056     {
13057       if (unformat (i, "sa_id %d", &sa_id))
13058         ;
13059       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13060         ;
13061       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13062         ;
13063       else
13064         {
13065           clib_warning ("parse error '%U'", format_unformat_error, i);
13066           return -99;
13067         }
13068     }
13069
13070   M (IPSEC_SA_SET_KEY, mp);
13071
13072   mp->sa_id = ntohl (sa_id);
13073   mp->crypto_key_length = vec_len (ck);
13074   mp->integrity_key_length = vec_len (ik);
13075
13076   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13077     mp->crypto_key_length = sizeof (mp->crypto_key);
13078
13079   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13080     mp->integrity_key_length = sizeof (mp->integrity_key);
13081
13082   if (ck)
13083     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13084   if (ik)
13085     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13086
13087   S (mp);
13088   W (ret);
13089   return ret;
13090 }
13091
13092 static int
13093 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13094 {
13095   unformat_input_t *i = vam->input;
13096   vl_api_ipsec_tunnel_if_add_del_t *mp;
13097   u32 local_spi = 0, remote_spi = 0;
13098   u32 crypto_alg = 0, integ_alg = 0;
13099   u8 *lck = NULL, *rck = NULL;
13100   u8 *lik = NULL, *rik = NULL;
13101   ip4_address_t local_ip = { {0} };
13102   ip4_address_t remote_ip = { {0} };
13103   u8 is_add = 1;
13104   u8 esn = 0;
13105   u8 anti_replay = 0;
13106   int ret;
13107
13108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13109     {
13110       if (unformat (i, "del"))
13111         is_add = 0;
13112       else if (unformat (i, "esn"))
13113         esn = 1;
13114       else if (unformat (i, "anti_replay"))
13115         anti_replay = 1;
13116       else if (unformat (i, "local_spi %d", &local_spi))
13117         ;
13118       else if (unformat (i, "remote_spi %d", &remote_spi))
13119         ;
13120       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13121         ;
13122       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13123         ;
13124       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13125         ;
13126       else
13127         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13128         ;
13129       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13130         ;
13131       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13132         ;
13133       else
13134         if (unformat
13135             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13136         {
13137           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13138               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13139             {
13140               errmsg ("unsupported crypto-alg: '%U'\n",
13141                       format_ipsec_crypto_alg, crypto_alg);
13142               return -99;
13143             }
13144         }
13145       else
13146         if (unformat
13147             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13148         {
13149           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13150               integ_alg >= IPSEC_INTEG_N_ALG)
13151             {
13152               errmsg ("unsupported integ-alg: '%U'\n",
13153                       format_ipsec_integ_alg, integ_alg);
13154               return -99;
13155             }
13156         }
13157       else
13158         {
13159           errmsg ("parse error '%U'\n", format_unformat_error, i);
13160           return -99;
13161         }
13162     }
13163
13164   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13165
13166   mp->is_add = is_add;
13167   mp->esn = esn;
13168   mp->anti_replay = anti_replay;
13169
13170   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13171   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13172
13173   mp->local_spi = htonl (local_spi);
13174   mp->remote_spi = htonl (remote_spi);
13175   mp->crypto_alg = (u8) crypto_alg;
13176
13177   mp->local_crypto_key_len = 0;
13178   if (lck)
13179     {
13180       mp->local_crypto_key_len = vec_len (lck);
13181       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13182         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13183       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13184     }
13185
13186   mp->remote_crypto_key_len = 0;
13187   if (rck)
13188     {
13189       mp->remote_crypto_key_len = vec_len (rck);
13190       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13191         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13192       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13193     }
13194
13195   mp->integ_alg = (u8) integ_alg;
13196
13197   mp->local_integ_key_len = 0;
13198   if (lik)
13199     {
13200       mp->local_integ_key_len = vec_len (lik);
13201       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13202         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13203       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13204     }
13205
13206   mp->remote_integ_key_len = 0;
13207   if (rik)
13208     {
13209       mp->remote_integ_key_len = vec_len (rik);
13210       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13211         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13212       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13213     }
13214
13215   S (mp);
13216   W (ret);
13217   return ret;
13218 }
13219
13220 static int
13221 api_ikev2_profile_add_del (vat_main_t * vam)
13222 {
13223   unformat_input_t *i = vam->input;
13224   vl_api_ikev2_profile_add_del_t *mp;
13225   u8 is_add = 1;
13226   u8 *name = 0;
13227   int ret;
13228
13229   const char *valid_chars = "a-zA-Z0-9_";
13230
13231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13232     {
13233       if (unformat (i, "del"))
13234         is_add = 0;
13235       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
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_PROFILE_ADD_DEL, mp);
13257
13258   clib_memcpy (mp->name, name, vec_len (name));
13259   mp->is_add = is_add;
13260   vec_free (name);
13261
13262   S (mp);
13263   W (ret);
13264   return ret;
13265 }
13266
13267 static int
13268 api_ikev2_profile_set_auth (vat_main_t * vam)
13269 {
13270   unformat_input_t *i = vam->input;
13271   vl_api_ikev2_profile_set_auth_t *mp;
13272   u8 *name = 0;
13273   u8 *data = 0;
13274   u32 auth_method = 0;
13275   u8 is_hex = 0;
13276   int ret;
13277
13278   const char *valid_chars = "a-zA-Z0-9_";
13279
13280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13281     {
13282       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13283         vec_add1 (name, 0);
13284       else if (unformat (i, "auth_method %U",
13285                          unformat_ikev2_auth_method, &auth_method))
13286         ;
13287       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13288         is_hex = 1;
13289       else if (unformat (i, "auth_data %v", &data))
13290         ;
13291       else
13292         {
13293           errmsg ("parse error '%U'", format_unformat_error, i);
13294           return -99;
13295         }
13296     }
13297
13298   if (!vec_len (name))
13299     {
13300       errmsg ("profile name must be specified");
13301       return -99;
13302     }
13303
13304   if (vec_len (name) > 64)
13305     {
13306       errmsg ("profile name too long");
13307       return -99;
13308     }
13309
13310   if (!vec_len (data))
13311     {
13312       errmsg ("auth_data must be specified");
13313       return -99;
13314     }
13315
13316   if (!auth_method)
13317     {
13318       errmsg ("auth_method must be specified");
13319       return -99;
13320     }
13321
13322   M (IKEV2_PROFILE_SET_AUTH, mp);
13323
13324   mp->is_hex = is_hex;
13325   mp->auth_method = (u8) auth_method;
13326   mp->data_len = vec_len (data);
13327   clib_memcpy (mp->name, name, vec_len (name));
13328   clib_memcpy (mp->data, data, vec_len (data));
13329   vec_free (name);
13330   vec_free (data);
13331
13332   S (mp);
13333   W (ret);
13334   return ret;
13335 }
13336
13337 static int
13338 api_ikev2_profile_set_id (vat_main_t * vam)
13339 {
13340   unformat_input_t *i = vam->input;
13341   vl_api_ikev2_profile_set_id_t *mp;
13342   u8 *name = 0;
13343   u8 *data = 0;
13344   u8 is_local = 0;
13345   u32 id_type = 0;
13346   ip4_address_t ip4;
13347   int ret;
13348
13349   const char *valid_chars = "a-zA-Z0-9_";
13350
13351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13352     {
13353       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13354         vec_add1 (name, 0);
13355       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13356         ;
13357       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13358         {
13359           data = vec_new (u8, 4);
13360           clib_memcpy (data, ip4.as_u8, 4);
13361         }
13362       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13363         ;
13364       else if (unformat (i, "id_data %v", &data))
13365         ;
13366       else if (unformat (i, "local"))
13367         is_local = 1;
13368       else if (unformat (i, "remote"))
13369         is_local = 0;
13370       else
13371         {
13372           errmsg ("parse error '%U'", format_unformat_error, i);
13373           return -99;
13374         }
13375     }
13376
13377   if (!vec_len (name))
13378     {
13379       errmsg ("profile name must be specified");
13380       return -99;
13381     }
13382
13383   if (vec_len (name) > 64)
13384     {
13385       errmsg ("profile name too long");
13386       return -99;
13387     }
13388
13389   if (!vec_len (data))
13390     {
13391       errmsg ("id_data must be specified");
13392       return -99;
13393     }
13394
13395   if (!id_type)
13396     {
13397       errmsg ("id_type must be specified");
13398       return -99;
13399     }
13400
13401   M (IKEV2_PROFILE_SET_ID, mp);
13402
13403   mp->is_local = is_local;
13404   mp->id_type = (u8) id_type;
13405   mp->data_len = vec_len (data);
13406   clib_memcpy (mp->name, name, vec_len (name));
13407   clib_memcpy (mp->data, data, vec_len (data));
13408   vec_free (name);
13409   vec_free (data);
13410
13411   S (mp);
13412   W (ret);
13413   return ret;
13414 }
13415
13416 static int
13417 api_ikev2_profile_set_ts (vat_main_t * vam)
13418 {
13419   unformat_input_t *i = vam->input;
13420   vl_api_ikev2_profile_set_ts_t *mp;
13421   u8 *name = 0;
13422   u8 is_local = 0;
13423   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13424   ip4_address_t start_addr, end_addr;
13425
13426   const char *valid_chars = "a-zA-Z0-9_";
13427   int ret;
13428
13429   start_addr.as_u32 = 0;
13430   end_addr.as_u32 = (u32) ~ 0;
13431
13432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13433     {
13434       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13435         vec_add1 (name, 0);
13436       else if (unformat (i, "protocol %d", &proto))
13437         ;
13438       else if (unformat (i, "start_port %d", &start_port))
13439         ;
13440       else if (unformat (i, "end_port %d", &end_port))
13441         ;
13442       else
13443         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13444         ;
13445       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13446         ;
13447       else if (unformat (i, "local"))
13448         is_local = 1;
13449       else if (unformat (i, "remote"))
13450         is_local = 0;
13451       else
13452         {
13453           errmsg ("parse error '%U'", format_unformat_error, i);
13454           return -99;
13455         }
13456     }
13457
13458   if (!vec_len (name))
13459     {
13460       errmsg ("profile name must be specified");
13461       return -99;
13462     }
13463
13464   if (vec_len (name) > 64)
13465     {
13466       errmsg ("profile name too long");
13467       return -99;
13468     }
13469
13470   M (IKEV2_PROFILE_SET_TS, mp);
13471
13472   mp->is_local = is_local;
13473   mp->proto = (u8) proto;
13474   mp->start_port = (u16) start_port;
13475   mp->end_port = (u16) end_port;
13476   mp->start_addr = start_addr.as_u32;
13477   mp->end_addr = end_addr.as_u32;
13478   clib_memcpy (mp->name, name, vec_len (name));
13479   vec_free (name);
13480
13481   S (mp);
13482   W (ret);
13483   return ret;
13484 }
13485
13486 static int
13487 api_ikev2_set_local_key (vat_main_t * vam)
13488 {
13489   unformat_input_t *i = vam->input;
13490   vl_api_ikev2_set_local_key_t *mp;
13491   u8 *file = 0;
13492   int ret;
13493
13494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13495     {
13496       if (unformat (i, "file %v", &file))
13497         vec_add1 (file, 0);
13498       else
13499         {
13500           errmsg ("parse error '%U'", format_unformat_error, i);
13501           return -99;
13502         }
13503     }
13504
13505   if (!vec_len (file))
13506     {
13507       errmsg ("RSA key file must be specified");
13508       return -99;
13509     }
13510
13511   if (vec_len (file) > 256)
13512     {
13513       errmsg ("file name too long");
13514       return -99;
13515     }
13516
13517   M (IKEV2_SET_LOCAL_KEY, mp);
13518
13519   clib_memcpy (mp->key_file, file, vec_len (file));
13520   vec_free (file);
13521
13522   S (mp);
13523   W (ret);
13524   return ret;
13525 }
13526
13527 static int
13528 api_ikev2_set_responder (vat_main_t * vam)
13529 {
13530   unformat_input_t *i = vam->input;
13531   vl_api_ikev2_set_responder_t *mp;
13532   int ret;
13533   u8 *name = 0;
13534   u32 sw_if_index = ~0;
13535   ip4_address_t address;
13536
13537   const char *valid_chars = "a-zA-Z0-9_";
13538
13539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13540     {
13541       if (unformat
13542           (i, "%U interface %d address %U", unformat_token, valid_chars,
13543            &name, &sw_if_index, unformat_ip4_address, &address))
13544         vec_add1 (name, 0);
13545       else
13546         {
13547           errmsg ("parse error '%U'", format_unformat_error, i);
13548           return -99;
13549         }
13550     }
13551
13552   if (!vec_len (name))
13553     {
13554       errmsg ("profile name must be specified");
13555       return -99;
13556     }
13557
13558   if (vec_len (name) > 64)
13559     {
13560       errmsg ("profile name too long");
13561       return -99;
13562     }
13563
13564   M (IKEV2_SET_RESPONDER, mp);
13565
13566   clib_memcpy (mp->name, name, vec_len (name));
13567   vec_free (name);
13568
13569   mp->sw_if_index = sw_if_index;
13570   clib_memcpy (mp->address, &address, sizeof (address));
13571
13572   S (mp);
13573   W (ret);
13574   return ret;
13575 }
13576
13577 static int
13578 api_ikev2_set_ike_transforms (vat_main_t * vam)
13579 {
13580   unformat_input_t *i = vam->input;
13581   vl_api_ikev2_set_ike_transforms_t *mp;
13582   int ret;
13583   u8 *name = 0;
13584   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13585
13586   const char *valid_chars = "a-zA-Z0-9_";
13587
13588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13589     {
13590       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13591                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13592         vec_add1 (name, 0);
13593       else
13594         {
13595           errmsg ("parse error '%U'", format_unformat_error, i);
13596           return -99;
13597         }
13598     }
13599
13600   if (!vec_len (name))
13601     {
13602       errmsg ("profile name must be specified");
13603       return -99;
13604     }
13605
13606   if (vec_len (name) > 64)
13607     {
13608       errmsg ("profile name too long");
13609       return -99;
13610     }
13611
13612   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13613
13614   clib_memcpy (mp->name, name, vec_len (name));
13615   vec_free (name);
13616   mp->crypto_alg = crypto_alg;
13617   mp->crypto_key_size = crypto_key_size;
13618   mp->integ_alg = integ_alg;
13619   mp->dh_group = dh_group;
13620
13621   S (mp);
13622   W (ret);
13623   return ret;
13624 }
13625
13626
13627 static int
13628 api_ikev2_set_esp_transforms (vat_main_t * vam)
13629 {
13630   unformat_input_t *i = vam->input;
13631   vl_api_ikev2_set_esp_transforms_t *mp;
13632   int ret;
13633   u8 *name = 0;
13634   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13635
13636   const char *valid_chars = "a-zA-Z0-9_";
13637
13638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13639     {
13640       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13641                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13642         vec_add1 (name, 0);
13643       else
13644         {
13645           errmsg ("parse error '%U'", format_unformat_error, i);
13646           return -99;
13647         }
13648     }
13649
13650   if (!vec_len (name))
13651     {
13652       errmsg ("profile name must be specified");
13653       return -99;
13654     }
13655
13656   if (vec_len (name) > 64)
13657     {
13658       errmsg ("profile name too long");
13659       return -99;
13660     }
13661
13662   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13663
13664   clib_memcpy (mp->name, name, vec_len (name));
13665   vec_free (name);
13666   mp->crypto_alg = crypto_alg;
13667   mp->crypto_key_size = crypto_key_size;
13668   mp->integ_alg = integ_alg;
13669   mp->dh_group = dh_group;
13670
13671   S (mp);
13672   W (ret);
13673   return ret;
13674 }
13675
13676 static int
13677 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13678 {
13679   unformat_input_t *i = vam->input;
13680   vl_api_ikev2_set_sa_lifetime_t *mp;
13681   int ret;
13682   u8 *name = 0;
13683   u64 lifetime, lifetime_maxdata;
13684   u32 lifetime_jitter, handover;
13685
13686   const char *valid_chars = "a-zA-Z0-9_";
13687
13688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13689     {
13690       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13691                     &lifetime, &lifetime_jitter, &handover,
13692                     &lifetime_maxdata))
13693         vec_add1 (name, 0);
13694       else
13695         {
13696           errmsg ("parse error '%U'", format_unformat_error, i);
13697           return -99;
13698         }
13699     }
13700
13701   if (!vec_len (name))
13702     {
13703       errmsg ("profile name must be specified");
13704       return -99;
13705     }
13706
13707   if (vec_len (name) > 64)
13708     {
13709       errmsg ("profile name too long");
13710       return -99;
13711     }
13712
13713   M (IKEV2_SET_SA_LIFETIME, mp);
13714
13715   clib_memcpy (mp->name, name, vec_len (name));
13716   vec_free (name);
13717   mp->lifetime = lifetime;
13718   mp->lifetime_jitter = lifetime_jitter;
13719   mp->handover = handover;
13720   mp->lifetime_maxdata = lifetime_maxdata;
13721
13722   S (mp);
13723   W (ret);
13724   return ret;
13725 }
13726
13727 static int
13728 api_ikev2_initiate_sa_init (vat_main_t * vam)
13729 {
13730   unformat_input_t *i = vam->input;
13731   vl_api_ikev2_initiate_sa_init_t *mp;
13732   int ret;
13733   u8 *name = 0;
13734
13735   const char *valid_chars = "a-zA-Z0-9_";
13736
13737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13738     {
13739       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13740         vec_add1 (name, 0);
13741       else
13742         {
13743           errmsg ("parse error '%U'", format_unformat_error, i);
13744           return -99;
13745         }
13746     }
13747
13748   if (!vec_len (name))
13749     {
13750       errmsg ("profile name must be specified");
13751       return -99;
13752     }
13753
13754   if (vec_len (name) > 64)
13755     {
13756       errmsg ("profile name too long");
13757       return -99;
13758     }
13759
13760   M (IKEV2_INITIATE_SA_INIT, mp);
13761
13762   clib_memcpy (mp->name, name, vec_len (name));
13763   vec_free (name);
13764
13765   S (mp);
13766   W (ret);
13767   return ret;
13768 }
13769
13770 static int
13771 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13772 {
13773   unformat_input_t *i = vam->input;
13774   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13775   int ret;
13776   u64 ispi;
13777
13778
13779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13780     {
13781       if (unformat (i, "%lx", &ispi))
13782         ;
13783       else
13784         {
13785           errmsg ("parse error '%U'", format_unformat_error, i);
13786           return -99;
13787         }
13788     }
13789
13790   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13791
13792   mp->ispi = ispi;
13793
13794   S (mp);
13795   W (ret);
13796   return ret;
13797 }
13798
13799 static int
13800 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13801 {
13802   unformat_input_t *i = vam->input;
13803   vl_api_ikev2_initiate_del_child_sa_t *mp;
13804   int ret;
13805   u32 ispi;
13806
13807
13808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13809     {
13810       if (unformat (i, "%x", &ispi))
13811         ;
13812       else
13813         {
13814           errmsg ("parse error '%U'", format_unformat_error, i);
13815           return -99;
13816         }
13817     }
13818
13819   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13820
13821   mp->ispi = ispi;
13822
13823   S (mp);
13824   W (ret);
13825   return ret;
13826 }
13827
13828 static int
13829 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13830 {
13831   unformat_input_t *i = vam->input;
13832   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13833   int ret;
13834   u32 ispi;
13835
13836
13837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13838     {
13839       if (unformat (i, "%x", &ispi))
13840         ;
13841       else
13842         {
13843           errmsg ("parse error '%U'", format_unformat_error, i);
13844           return -99;
13845         }
13846     }
13847
13848   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13849
13850   mp->ispi = ispi;
13851
13852   S (mp);
13853   W (ret);
13854   return ret;
13855 }
13856
13857 /*
13858  * MAP
13859  */
13860 static int
13861 api_map_add_domain (vat_main_t * vam)
13862 {
13863   unformat_input_t *i = vam->input;
13864   vl_api_map_add_domain_t *mp;
13865
13866   ip4_address_t ip4_prefix;
13867   ip6_address_t ip6_prefix;
13868   ip6_address_t ip6_src;
13869   u32 num_m_args = 0;
13870   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13871     0, psid_length = 0;
13872   u8 is_translation = 0;
13873   u32 mtu = 0;
13874   u32 ip6_src_len = 128;
13875   int ret;
13876
13877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13878     {
13879       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13880                     &ip4_prefix, &ip4_prefix_len))
13881         num_m_args++;
13882       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13883                          &ip6_prefix, &ip6_prefix_len))
13884         num_m_args++;
13885       else
13886         if (unformat
13887             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13888              &ip6_src_len))
13889         num_m_args++;
13890       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13891         num_m_args++;
13892       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13893         num_m_args++;
13894       else if (unformat (i, "psid-offset %d", &psid_offset))
13895         num_m_args++;
13896       else if (unformat (i, "psid-len %d", &psid_length))
13897         num_m_args++;
13898       else if (unformat (i, "mtu %d", &mtu))
13899         num_m_args++;
13900       else if (unformat (i, "map-t"))
13901         is_translation = 1;
13902       else
13903         {
13904           clib_warning ("parse error '%U'", format_unformat_error, i);
13905           return -99;
13906         }
13907     }
13908
13909   if (num_m_args < 3)
13910     {
13911       errmsg ("mandatory argument(s) missing");
13912       return -99;
13913     }
13914
13915   /* Construct the API message */
13916   M (MAP_ADD_DOMAIN, mp);
13917
13918   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13919   mp->ip4_prefix_len = ip4_prefix_len;
13920
13921   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13922   mp->ip6_prefix_len = ip6_prefix_len;
13923
13924   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13925   mp->ip6_src_prefix_len = ip6_src_len;
13926
13927   mp->ea_bits_len = ea_bits_len;
13928   mp->psid_offset = psid_offset;
13929   mp->psid_length = psid_length;
13930   mp->is_translation = is_translation;
13931   mp->mtu = htons (mtu);
13932
13933   /* send it... */
13934   S (mp);
13935
13936   /* Wait for a reply, return good/bad news  */
13937   W (ret);
13938   return ret;
13939 }
13940
13941 static int
13942 api_map_del_domain (vat_main_t * vam)
13943 {
13944   unformat_input_t *i = vam->input;
13945   vl_api_map_del_domain_t *mp;
13946
13947   u32 num_m_args = 0;
13948   u32 index;
13949   int ret;
13950
13951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13952     {
13953       if (unformat (i, "index %d", &index))
13954         num_m_args++;
13955       else
13956         {
13957           clib_warning ("parse error '%U'", format_unformat_error, i);
13958           return -99;
13959         }
13960     }
13961
13962   if (num_m_args != 1)
13963     {
13964       errmsg ("mandatory argument(s) missing");
13965       return -99;
13966     }
13967
13968   /* Construct the API message */
13969   M (MAP_DEL_DOMAIN, mp);
13970
13971   mp->index = ntohl (index);
13972
13973   /* send it... */
13974   S (mp);
13975
13976   /* Wait for a reply, return good/bad news  */
13977   W (ret);
13978   return ret;
13979 }
13980
13981 static int
13982 api_map_add_del_rule (vat_main_t * vam)
13983 {
13984   unformat_input_t *i = vam->input;
13985   vl_api_map_add_del_rule_t *mp;
13986   u8 is_add = 1;
13987   ip6_address_t ip6_dst;
13988   u32 num_m_args = 0, index, psid = 0;
13989   int ret;
13990
13991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13992     {
13993       if (unformat (i, "index %d", &index))
13994         num_m_args++;
13995       else if (unformat (i, "psid %d", &psid))
13996         num_m_args++;
13997       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13998         num_m_args++;
13999       else if (unformat (i, "del"))
14000         {
14001           is_add = 0;
14002         }
14003       else
14004         {
14005           clib_warning ("parse error '%U'", format_unformat_error, i);
14006           return -99;
14007         }
14008     }
14009
14010   /* Construct the API message */
14011   M (MAP_ADD_DEL_RULE, mp);
14012
14013   mp->index = ntohl (index);
14014   mp->is_add = is_add;
14015   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14016   mp->psid = ntohs (psid);
14017
14018   /* send it... */
14019   S (mp);
14020
14021   /* Wait for a reply, return good/bad news  */
14022   W (ret);
14023   return ret;
14024 }
14025
14026 static int
14027 api_map_domain_dump (vat_main_t * vam)
14028 {
14029   vl_api_map_domain_dump_t *mp;
14030   vl_api_control_ping_t *mp_ping;
14031   int ret;
14032
14033   /* Construct the API message */
14034   M (MAP_DOMAIN_DUMP, mp);
14035
14036   /* send it... */
14037   S (mp);
14038
14039   /* Use a control ping for synchronization */
14040   M (CONTROL_PING, mp_ping);
14041   S (mp_ping);
14042
14043   W (ret);
14044   return ret;
14045 }
14046
14047 static int
14048 api_map_rule_dump (vat_main_t * vam)
14049 {
14050   unformat_input_t *i = vam->input;
14051   vl_api_map_rule_dump_t *mp;
14052   vl_api_control_ping_t *mp_ping;
14053   u32 domain_index = ~0;
14054   int ret;
14055
14056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14057     {
14058       if (unformat (i, "index %u", &domain_index))
14059         ;
14060       else
14061         break;
14062     }
14063
14064   if (domain_index == ~0)
14065     {
14066       clib_warning ("parse error: domain index expected");
14067       return -99;
14068     }
14069
14070   /* Construct the API message */
14071   M (MAP_RULE_DUMP, mp);
14072
14073   mp->domain_index = htonl (domain_index);
14074
14075   /* send it... */
14076   S (mp);
14077
14078   /* Use a control ping for synchronization */
14079   M (CONTROL_PING, mp_ping);
14080   S (mp_ping);
14081
14082   W (ret);
14083   return ret;
14084 }
14085
14086 static void vl_api_map_add_domain_reply_t_handler
14087   (vl_api_map_add_domain_reply_t * mp)
14088 {
14089   vat_main_t *vam = &vat_main;
14090   i32 retval = ntohl (mp->retval);
14091
14092   if (vam->async_mode)
14093     {
14094       vam->async_errors += (retval < 0);
14095     }
14096   else
14097     {
14098       vam->retval = retval;
14099       vam->result_ready = 1;
14100     }
14101 }
14102
14103 static void vl_api_map_add_domain_reply_t_handler_json
14104   (vl_api_map_add_domain_reply_t * mp)
14105 {
14106   vat_main_t *vam = &vat_main;
14107   vat_json_node_t node;
14108
14109   vat_json_init_object (&node);
14110   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14111   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14112
14113   vat_json_print (vam->ofp, &node);
14114   vat_json_free (&node);
14115
14116   vam->retval = ntohl (mp->retval);
14117   vam->result_ready = 1;
14118 }
14119
14120 static int
14121 api_get_first_msg_id (vat_main_t * vam)
14122 {
14123   vl_api_get_first_msg_id_t *mp;
14124   unformat_input_t *i = vam->input;
14125   u8 *name;
14126   u8 name_set = 0;
14127   int ret;
14128
14129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14130     {
14131       if (unformat (i, "client %s", &name))
14132         name_set = 1;
14133       else
14134         break;
14135     }
14136
14137   if (name_set == 0)
14138     {
14139       errmsg ("missing client name");
14140       return -99;
14141     }
14142   vec_add1 (name, 0);
14143
14144   if (vec_len (name) > 63)
14145     {
14146       errmsg ("client name too long");
14147       return -99;
14148     }
14149
14150   M (GET_FIRST_MSG_ID, mp);
14151   clib_memcpy (mp->name, name, vec_len (name));
14152   S (mp);
14153   W (ret);
14154   return ret;
14155 }
14156
14157 static int
14158 api_cop_interface_enable_disable (vat_main_t * vam)
14159 {
14160   unformat_input_t *line_input = vam->input;
14161   vl_api_cop_interface_enable_disable_t *mp;
14162   u32 sw_if_index = ~0;
14163   u8 enable_disable = 1;
14164   int ret;
14165
14166   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14167     {
14168       if (unformat (line_input, "disable"))
14169         enable_disable = 0;
14170       if (unformat (line_input, "enable"))
14171         enable_disable = 1;
14172       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14173                          vam, &sw_if_index))
14174         ;
14175       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14176         ;
14177       else
14178         break;
14179     }
14180
14181   if (sw_if_index == ~0)
14182     {
14183       errmsg ("missing interface name or sw_if_index");
14184       return -99;
14185     }
14186
14187   /* Construct the API message */
14188   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14189   mp->sw_if_index = ntohl (sw_if_index);
14190   mp->enable_disable = enable_disable;
14191
14192   /* send it... */
14193   S (mp);
14194   /* Wait for the reply */
14195   W (ret);
14196   return ret;
14197 }
14198
14199 static int
14200 api_cop_whitelist_enable_disable (vat_main_t * vam)
14201 {
14202   unformat_input_t *line_input = vam->input;
14203   vl_api_cop_whitelist_enable_disable_t *mp;
14204   u32 sw_if_index = ~0;
14205   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14206   u32 fib_id = 0;
14207   int ret;
14208
14209   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14210     {
14211       if (unformat (line_input, "ip4"))
14212         ip4 = 1;
14213       else if (unformat (line_input, "ip6"))
14214         ip6 = 1;
14215       else if (unformat (line_input, "default"))
14216         default_cop = 1;
14217       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14218                          vam, &sw_if_index))
14219         ;
14220       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14221         ;
14222       else if (unformat (line_input, "fib-id %d", &fib_id))
14223         ;
14224       else
14225         break;
14226     }
14227
14228   if (sw_if_index == ~0)
14229     {
14230       errmsg ("missing interface name or sw_if_index");
14231       return -99;
14232     }
14233
14234   /* Construct the API message */
14235   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14236   mp->sw_if_index = ntohl (sw_if_index);
14237   mp->fib_id = ntohl (fib_id);
14238   mp->ip4 = ip4;
14239   mp->ip6 = ip6;
14240   mp->default_cop = default_cop;
14241
14242   /* send it... */
14243   S (mp);
14244   /* Wait for the reply */
14245   W (ret);
14246   return ret;
14247 }
14248
14249 static int
14250 api_get_node_graph (vat_main_t * vam)
14251 {
14252   vl_api_get_node_graph_t *mp;
14253   int ret;
14254
14255   M (GET_NODE_GRAPH, mp);
14256
14257   /* send it... */
14258   S (mp);
14259   /* Wait for the reply */
14260   W (ret);
14261   return ret;
14262 }
14263
14264 /* *INDENT-OFF* */
14265 /** Used for parsing LISP eids */
14266 typedef CLIB_PACKED(struct{
14267   u8 addr[16];   /**< eid address */
14268   u32 len;       /**< prefix length if IP */
14269   u8 type;      /**< type of eid */
14270 }) lisp_eid_vat_t;
14271 /* *INDENT-ON* */
14272
14273 static uword
14274 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14275 {
14276   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14277
14278   memset (a, 0, sizeof (a[0]));
14279
14280   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14281     {
14282       a->type = 0;              /* ipv4 type */
14283     }
14284   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14285     {
14286       a->type = 1;              /* ipv6 type */
14287     }
14288   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14289     {
14290       a->type = 2;              /* mac type */
14291     }
14292   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14293     {
14294       a->type = 3;              /* NSH type */
14295       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14296       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14297     }
14298   else
14299     {
14300       return 0;
14301     }
14302
14303   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14304     {
14305       return 0;
14306     }
14307
14308   return 1;
14309 }
14310
14311 static int
14312 lisp_eid_size_vat (u8 type)
14313 {
14314   switch (type)
14315     {
14316     case 0:
14317       return 4;
14318     case 1:
14319       return 16;
14320     case 2:
14321       return 6;
14322     case 3:
14323       return 5;
14324     }
14325   return 0;
14326 }
14327
14328 static void
14329 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14330 {
14331   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14332 }
14333
14334 static int
14335 api_one_add_del_locator_set (vat_main_t * vam)
14336 {
14337   unformat_input_t *input = vam->input;
14338   vl_api_one_add_del_locator_set_t *mp;
14339   u8 is_add = 1;
14340   u8 *locator_set_name = NULL;
14341   u8 locator_set_name_set = 0;
14342   vl_api_local_locator_t locator, *locators = 0;
14343   u32 sw_if_index, priority, weight;
14344   u32 data_len = 0;
14345
14346   int ret;
14347   /* Parse args required to build the message */
14348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14349     {
14350       if (unformat (input, "del"))
14351         {
14352           is_add = 0;
14353         }
14354       else if (unformat (input, "locator-set %s", &locator_set_name))
14355         {
14356           locator_set_name_set = 1;
14357         }
14358       else if (unformat (input, "sw_if_index %u p %u w %u",
14359                          &sw_if_index, &priority, &weight))
14360         {
14361           locator.sw_if_index = htonl (sw_if_index);
14362           locator.priority = priority;
14363           locator.weight = weight;
14364           vec_add1 (locators, locator);
14365         }
14366       else
14367         if (unformat
14368             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14369              &sw_if_index, &priority, &weight))
14370         {
14371           locator.sw_if_index = htonl (sw_if_index);
14372           locator.priority = priority;
14373           locator.weight = weight;
14374           vec_add1 (locators, locator);
14375         }
14376       else
14377         break;
14378     }
14379
14380   if (locator_set_name_set == 0)
14381     {
14382       errmsg ("missing locator-set name");
14383       vec_free (locators);
14384       return -99;
14385     }
14386
14387   if (vec_len (locator_set_name) > 64)
14388     {
14389       errmsg ("locator-set name too long");
14390       vec_free (locator_set_name);
14391       vec_free (locators);
14392       return -99;
14393     }
14394   vec_add1 (locator_set_name, 0);
14395
14396   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14397
14398   /* Construct the API message */
14399   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14400
14401   mp->is_add = is_add;
14402   clib_memcpy (mp->locator_set_name, locator_set_name,
14403                vec_len (locator_set_name));
14404   vec_free (locator_set_name);
14405
14406   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14407   if (locators)
14408     clib_memcpy (mp->locators, locators, data_len);
14409   vec_free (locators);
14410
14411   /* send it... */
14412   S (mp);
14413
14414   /* Wait for a reply... */
14415   W (ret);
14416   return ret;
14417 }
14418
14419 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14420
14421 static int
14422 api_one_add_del_locator (vat_main_t * vam)
14423 {
14424   unformat_input_t *input = vam->input;
14425   vl_api_one_add_del_locator_t *mp;
14426   u32 tmp_if_index = ~0;
14427   u32 sw_if_index = ~0;
14428   u8 sw_if_index_set = 0;
14429   u8 sw_if_index_if_name_set = 0;
14430   u32 priority = ~0;
14431   u8 priority_set = 0;
14432   u32 weight = ~0;
14433   u8 weight_set = 0;
14434   u8 is_add = 1;
14435   u8 *locator_set_name = NULL;
14436   u8 locator_set_name_set = 0;
14437   int ret;
14438
14439   /* Parse args required to build the message */
14440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14441     {
14442       if (unformat (input, "del"))
14443         {
14444           is_add = 0;
14445         }
14446       else if (unformat (input, "locator-set %s", &locator_set_name))
14447         {
14448           locator_set_name_set = 1;
14449         }
14450       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14451                          &tmp_if_index))
14452         {
14453           sw_if_index_if_name_set = 1;
14454           sw_if_index = tmp_if_index;
14455         }
14456       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14457         {
14458           sw_if_index_set = 1;
14459           sw_if_index = tmp_if_index;
14460         }
14461       else if (unformat (input, "p %d", &priority))
14462         {
14463           priority_set = 1;
14464         }
14465       else if (unformat (input, "w %d", &weight))
14466         {
14467           weight_set = 1;
14468         }
14469       else
14470         break;
14471     }
14472
14473   if (locator_set_name_set == 0)
14474     {
14475       errmsg ("missing locator-set name");
14476       return -99;
14477     }
14478
14479   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14480     {
14481       errmsg ("missing sw_if_index");
14482       vec_free (locator_set_name);
14483       return -99;
14484     }
14485
14486   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14487     {
14488       errmsg ("cannot use both params interface name and sw_if_index");
14489       vec_free (locator_set_name);
14490       return -99;
14491     }
14492
14493   if (priority_set == 0)
14494     {
14495       errmsg ("missing locator-set priority");
14496       vec_free (locator_set_name);
14497       return -99;
14498     }
14499
14500   if (weight_set == 0)
14501     {
14502       errmsg ("missing locator-set weight");
14503       vec_free (locator_set_name);
14504       return -99;
14505     }
14506
14507   if (vec_len (locator_set_name) > 64)
14508     {
14509       errmsg ("locator-set name too long");
14510       vec_free (locator_set_name);
14511       return -99;
14512     }
14513   vec_add1 (locator_set_name, 0);
14514
14515   /* Construct the API message */
14516   M (ONE_ADD_DEL_LOCATOR, mp);
14517
14518   mp->is_add = is_add;
14519   mp->sw_if_index = ntohl (sw_if_index);
14520   mp->priority = priority;
14521   mp->weight = weight;
14522   clib_memcpy (mp->locator_set_name, locator_set_name,
14523                vec_len (locator_set_name));
14524   vec_free (locator_set_name);
14525
14526   /* send it... */
14527   S (mp);
14528
14529   /* Wait for a reply... */
14530   W (ret);
14531   return ret;
14532 }
14533
14534 #define api_lisp_add_del_locator api_one_add_del_locator
14535
14536 uword
14537 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14538 {
14539   u32 *key_id = va_arg (*args, u32 *);
14540   u8 *s = 0;
14541
14542   if (unformat (input, "%s", &s))
14543     {
14544       if (!strcmp ((char *) s, "sha1"))
14545         key_id[0] = HMAC_SHA_1_96;
14546       else if (!strcmp ((char *) s, "sha256"))
14547         key_id[0] = HMAC_SHA_256_128;
14548       else
14549         {
14550           clib_warning ("invalid key_id: '%s'", s);
14551           key_id[0] = HMAC_NO_KEY;
14552         }
14553     }
14554   else
14555     return 0;
14556
14557   vec_free (s);
14558   return 1;
14559 }
14560
14561 static int
14562 api_one_add_del_local_eid (vat_main_t * vam)
14563 {
14564   unformat_input_t *input = vam->input;
14565   vl_api_one_add_del_local_eid_t *mp;
14566   u8 is_add = 1;
14567   u8 eid_set = 0;
14568   lisp_eid_vat_t _eid, *eid = &_eid;
14569   u8 *locator_set_name = 0;
14570   u8 locator_set_name_set = 0;
14571   u32 vni = 0;
14572   u16 key_id = 0;
14573   u8 *key = 0;
14574   int ret;
14575
14576   /* Parse args required to build the message */
14577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14578     {
14579       if (unformat (input, "del"))
14580         {
14581           is_add = 0;
14582         }
14583       else if (unformat (input, "vni %d", &vni))
14584         {
14585           ;
14586         }
14587       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14588         {
14589           eid_set = 1;
14590         }
14591       else if (unformat (input, "locator-set %s", &locator_set_name))
14592         {
14593           locator_set_name_set = 1;
14594         }
14595       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14596         ;
14597       else if (unformat (input, "secret-key %_%v%_", &key))
14598         ;
14599       else
14600         break;
14601     }
14602
14603   if (locator_set_name_set == 0)
14604     {
14605       errmsg ("missing locator-set name");
14606       return -99;
14607     }
14608
14609   if (0 == eid_set)
14610     {
14611       errmsg ("EID address not set!");
14612       vec_free (locator_set_name);
14613       return -99;
14614     }
14615
14616   if (key && (0 == key_id))
14617     {
14618       errmsg ("invalid key_id!");
14619       return -99;
14620     }
14621
14622   if (vec_len (key) > 64)
14623     {
14624       errmsg ("key too long");
14625       vec_free (key);
14626       return -99;
14627     }
14628
14629   if (vec_len (locator_set_name) > 64)
14630     {
14631       errmsg ("locator-set name too long");
14632       vec_free (locator_set_name);
14633       return -99;
14634     }
14635   vec_add1 (locator_set_name, 0);
14636
14637   /* Construct the API message */
14638   M (ONE_ADD_DEL_LOCAL_EID, mp);
14639
14640   mp->is_add = is_add;
14641   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14642   mp->eid_type = eid->type;
14643   mp->prefix_len = eid->len;
14644   mp->vni = clib_host_to_net_u32 (vni);
14645   mp->key_id = clib_host_to_net_u16 (key_id);
14646   clib_memcpy (mp->locator_set_name, locator_set_name,
14647                vec_len (locator_set_name));
14648   clib_memcpy (mp->key, key, vec_len (key));
14649
14650   vec_free (locator_set_name);
14651   vec_free (key);
14652
14653   /* send it... */
14654   S (mp);
14655
14656   /* Wait for a reply... */
14657   W (ret);
14658   return ret;
14659 }
14660
14661 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14662
14663 static int
14664 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14665 {
14666   u32 dp_table = 0, vni = 0;;
14667   unformat_input_t *input = vam->input;
14668   vl_api_gpe_add_del_fwd_entry_t *mp;
14669   u8 is_add = 1;
14670   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14671   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14672   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14673   u32 action = ~0, w;
14674   ip4_address_t rmt_rloc4, lcl_rloc4;
14675   ip6_address_t rmt_rloc6, lcl_rloc6;
14676   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14677   int ret;
14678
14679   memset (&rloc, 0, sizeof (rloc));
14680
14681   /* Parse args required to build the message */
14682   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14683     {
14684       if (unformat (input, "del"))
14685         is_add = 0;
14686       else if (unformat (input, "add"))
14687         is_add = 1;
14688       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14689         {
14690           rmt_eid_set = 1;
14691         }
14692       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14693         {
14694           lcl_eid_set = 1;
14695         }
14696       else if (unformat (input, "vrf %d", &dp_table))
14697         ;
14698       else if (unformat (input, "bd %d", &dp_table))
14699         ;
14700       else if (unformat (input, "vni %d", &vni))
14701         ;
14702       else if (unformat (input, "w %d", &w))
14703         {
14704           if (!curr_rloc)
14705             {
14706               errmsg ("No RLOC configured for setting priority/weight!");
14707               return -99;
14708             }
14709           curr_rloc->weight = w;
14710         }
14711       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14712                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14713         {
14714           rloc.is_ip4 = 1;
14715
14716           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14717           rloc.weight = 0;
14718           vec_add1 (lcl_locs, rloc);
14719
14720           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14721           vec_add1 (rmt_locs, rloc);
14722           /* weight saved in rmt loc */
14723           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14724         }
14725       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14726                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14727         {
14728           rloc.is_ip4 = 0;
14729           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14730           rloc.weight = 0;
14731           vec_add1 (lcl_locs, rloc);
14732
14733           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14734           vec_add1 (rmt_locs, rloc);
14735           /* weight saved in rmt loc */
14736           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14737         }
14738       else if (unformat (input, "action %d", &action))
14739         {
14740           ;
14741         }
14742       else
14743         {
14744           clib_warning ("parse error '%U'", format_unformat_error, input);
14745           return -99;
14746         }
14747     }
14748
14749   if (!rmt_eid_set)
14750     {
14751       errmsg ("remote eid addresses not set");
14752       return -99;
14753     }
14754
14755   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14756     {
14757       errmsg ("eid types don't match");
14758       return -99;
14759     }
14760
14761   if (0 == rmt_locs && (u32) ~ 0 == action)
14762     {
14763       errmsg ("action not set for negative mapping");
14764       return -99;
14765     }
14766
14767   /* Construct the API message */
14768   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14769       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14770
14771   mp->is_add = is_add;
14772   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14773   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14774   mp->eid_type = rmt_eid->type;
14775   mp->dp_table = clib_host_to_net_u32 (dp_table);
14776   mp->vni = clib_host_to_net_u32 (vni);
14777   mp->rmt_len = rmt_eid->len;
14778   mp->lcl_len = lcl_eid->len;
14779   mp->action = action;
14780
14781   if (0 != rmt_locs && 0 != lcl_locs)
14782     {
14783       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14784       clib_memcpy (mp->locs, lcl_locs,
14785                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14786
14787       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14788       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14789                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14790     }
14791   vec_free (lcl_locs);
14792   vec_free (rmt_locs);
14793
14794   /* send it... */
14795   S (mp);
14796
14797   /* Wait for a reply... */
14798   W (ret);
14799   return ret;
14800 }
14801
14802 static int
14803 api_one_add_del_map_server (vat_main_t * vam)
14804 {
14805   unformat_input_t *input = vam->input;
14806   vl_api_one_add_del_map_server_t *mp;
14807   u8 is_add = 1;
14808   u8 ipv4_set = 0;
14809   u8 ipv6_set = 0;
14810   ip4_address_t ipv4;
14811   ip6_address_t ipv6;
14812   int ret;
14813
14814   /* Parse args required to build the message */
14815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14816     {
14817       if (unformat (input, "del"))
14818         {
14819           is_add = 0;
14820         }
14821       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14822         {
14823           ipv4_set = 1;
14824         }
14825       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14826         {
14827           ipv6_set = 1;
14828         }
14829       else
14830         break;
14831     }
14832
14833   if (ipv4_set && ipv6_set)
14834     {
14835       errmsg ("both eid v4 and v6 addresses set");
14836       return -99;
14837     }
14838
14839   if (!ipv4_set && !ipv6_set)
14840     {
14841       errmsg ("eid addresses not set");
14842       return -99;
14843     }
14844
14845   /* Construct the API message */
14846   M (ONE_ADD_DEL_MAP_SERVER, mp);
14847
14848   mp->is_add = is_add;
14849   if (ipv6_set)
14850     {
14851       mp->is_ipv6 = 1;
14852       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14853     }
14854   else
14855     {
14856       mp->is_ipv6 = 0;
14857       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14858     }
14859
14860   /* send it... */
14861   S (mp);
14862
14863   /* Wait for a reply... */
14864   W (ret);
14865   return ret;
14866 }
14867
14868 #define api_lisp_add_del_map_server api_one_add_del_map_server
14869
14870 static int
14871 api_one_add_del_map_resolver (vat_main_t * vam)
14872 {
14873   unformat_input_t *input = vam->input;
14874   vl_api_one_add_del_map_resolver_t *mp;
14875   u8 is_add = 1;
14876   u8 ipv4_set = 0;
14877   u8 ipv6_set = 0;
14878   ip4_address_t ipv4;
14879   ip6_address_t ipv6;
14880   int ret;
14881
14882   /* Parse args required to build the message */
14883   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14884     {
14885       if (unformat (input, "del"))
14886         {
14887           is_add = 0;
14888         }
14889       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14890         {
14891           ipv4_set = 1;
14892         }
14893       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14894         {
14895           ipv6_set = 1;
14896         }
14897       else
14898         break;
14899     }
14900
14901   if (ipv4_set && ipv6_set)
14902     {
14903       errmsg ("both eid v4 and v6 addresses set");
14904       return -99;
14905     }
14906
14907   if (!ipv4_set && !ipv6_set)
14908     {
14909       errmsg ("eid addresses not set");
14910       return -99;
14911     }
14912
14913   /* Construct the API message */
14914   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14915
14916   mp->is_add = is_add;
14917   if (ipv6_set)
14918     {
14919       mp->is_ipv6 = 1;
14920       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14921     }
14922   else
14923     {
14924       mp->is_ipv6 = 0;
14925       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14926     }
14927
14928   /* send it... */
14929   S (mp);
14930
14931   /* Wait for a reply... */
14932   W (ret);
14933   return ret;
14934 }
14935
14936 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14937
14938 static int
14939 api_lisp_gpe_enable_disable (vat_main_t * vam)
14940 {
14941   unformat_input_t *input = vam->input;
14942   vl_api_gpe_enable_disable_t *mp;
14943   u8 is_set = 0;
14944   u8 is_en = 1;
14945   int ret;
14946
14947   /* Parse args required to build the message */
14948   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14949     {
14950       if (unformat (input, "enable"))
14951         {
14952           is_set = 1;
14953           is_en = 1;
14954         }
14955       else if (unformat (input, "disable"))
14956         {
14957           is_set = 1;
14958           is_en = 0;
14959         }
14960       else
14961         break;
14962     }
14963
14964   if (is_set == 0)
14965     {
14966       errmsg ("Value not set");
14967       return -99;
14968     }
14969
14970   /* Construct the API message */
14971   M (GPE_ENABLE_DISABLE, mp);
14972
14973   mp->is_en = is_en;
14974
14975   /* send it... */
14976   S (mp);
14977
14978   /* Wait for a reply... */
14979   W (ret);
14980   return ret;
14981 }
14982
14983 static int
14984 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14985 {
14986   unformat_input_t *input = vam->input;
14987   vl_api_one_rloc_probe_enable_disable_t *mp;
14988   u8 is_set = 0;
14989   u8 is_en = 0;
14990   int ret;
14991
14992   /* Parse args required to build the message */
14993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14994     {
14995       if (unformat (input, "enable"))
14996         {
14997           is_set = 1;
14998           is_en = 1;
14999         }
15000       else if (unformat (input, "disable"))
15001         is_set = 1;
15002       else
15003         break;
15004     }
15005
15006   if (!is_set)
15007     {
15008       errmsg ("Value not set");
15009       return -99;
15010     }
15011
15012   /* Construct the API message */
15013   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15014
15015   mp->is_enabled = is_en;
15016
15017   /* send it... */
15018   S (mp);
15019
15020   /* Wait for a reply... */
15021   W (ret);
15022   return ret;
15023 }
15024
15025 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15026
15027 static int
15028 api_one_map_register_enable_disable (vat_main_t * vam)
15029 {
15030   unformat_input_t *input = vam->input;
15031   vl_api_one_map_register_enable_disable_t *mp;
15032   u8 is_set = 0;
15033   u8 is_en = 0;
15034   int ret;
15035
15036   /* Parse args required to build the message */
15037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15038     {
15039       if (unformat (input, "enable"))
15040         {
15041           is_set = 1;
15042           is_en = 1;
15043         }
15044       else if (unformat (input, "disable"))
15045         is_set = 1;
15046       else
15047         break;
15048     }
15049
15050   if (!is_set)
15051     {
15052       errmsg ("Value not set");
15053       return -99;
15054     }
15055
15056   /* Construct the API message */
15057   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15058
15059   mp->is_enabled = is_en;
15060
15061   /* send it... */
15062   S (mp);
15063
15064   /* Wait for a reply... */
15065   W (ret);
15066   return ret;
15067 }
15068
15069 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15070
15071 static int
15072 api_one_enable_disable (vat_main_t * vam)
15073 {
15074   unformat_input_t *input = vam->input;
15075   vl_api_one_enable_disable_t *mp;
15076   u8 is_set = 0;
15077   u8 is_en = 0;
15078   int ret;
15079
15080   /* Parse args required to build the message */
15081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15082     {
15083       if (unformat (input, "enable"))
15084         {
15085           is_set = 1;
15086           is_en = 1;
15087         }
15088       else if (unformat (input, "disable"))
15089         {
15090           is_set = 1;
15091         }
15092       else
15093         break;
15094     }
15095
15096   if (!is_set)
15097     {
15098       errmsg ("Value not set");
15099       return -99;
15100     }
15101
15102   /* Construct the API message */
15103   M (ONE_ENABLE_DISABLE, mp);
15104
15105   mp->is_en = is_en;
15106
15107   /* send it... */
15108   S (mp);
15109
15110   /* Wait for a reply... */
15111   W (ret);
15112   return ret;
15113 }
15114
15115 #define api_lisp_enable_disable api_one_enable_disable
15116
15117 static int
15118 api_show_one_map_register_state (vat_main_t * vam)
15119 {
15120   vl_api_show_one_map_register_state_t *mp;
15121   int ret;
15122
15123   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15124
15125   /* send */
15126   S (mp);
15127
15128   /* wait for reply */
15129   W (ret);
15130   return ret;
15131 }
15132
15133 #define api_show_lisp_map_register_state api_show_one_map_register_state
15134
15135 static int
15136 api_show_one_rloc_probe_state (vat_main_t * vam)
15137 {
15138   vl_api_show_one_rloc_probe_state_t *mp;
15139   int ret;
15140
15141   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15142
15143   /* send */
15144   S (mp);
15145
15146   /* wait for reply */
15147   W (ret);
15148   return ret;
15149 }
15150
15151 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15152
15153 static int
15154 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15155 {
15156   vl_api_one_add_del_l2_arp_entry_t *mp;
15157   unformat_input_t *input = vam->input;
15158   u8 is_add = 1;
15159   u8 mac_set = 0;
15160   u8 bd_set = 0;
15161   u8 ip_set = 0;
15162   u8 mac[6] = { 0, };
15163   u32 ip4 = 0, bd = ~0;
15164   int ret;
15165
15166   /* Parse args required to build the message */
15167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15168     {
15169       if (unformat (input, "del"))
15170         is_add = 0;
15171       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15172         mac_set = 1;
15173       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15174         ip_set = 1;
15175       else if (unformat (input, "bd %d", &bd))
15176         bd_set = 1;
15177       else
15178         {
15179           errmsg ("parse error '%U'", format_unformat_error, input);
15180           return -99;
15181         }
15182     }
15183
15184   if (!bd_set || !ip_set || (!mac_set && is_add))
15185     {
15186       errmsg ("Missing BD, IP or MAC!");
15187       return -99;
15188     }
15189
15190   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15191   mp->is_add = is_add;
15192   clib_memcpy (mp->mac, mac, 6);
15193   mp->bd = clib_host_to_net_u32 (bd);
15194   mp->ip4 = ip4;
15195
15196   /* send */
15197   S (mp);
15198
15199   /* wait for reply */
15200   W (ret);
15201   return ret;
15202 }
15203
15204 static int
15205 api_one_l2_arp_bd_get (vat_main_t * vam)
15206 {
15207   vl_api_one_l2_arp_bd_get_t *mp;
15208   int ret;
15209
15210   M (ONE_L2_ARP_BD_GET, mp);
15211
15212   /* send */
15213   S (mp);
15214
15215   /* wait for reply */
15216   W (ret);
15217   return ret;
15218 }
15219
15220 static int
15221 api_one_l2_arp_entries_get (vat_main_t * vam)
15222 {
15223   vl_api_one_l2_arp_entries_get_t *mp;
15224   unformat_input_t *input = vam->input;
15225   u8 bd_set = 0;
15226   u32 bd = ~0;
15227   int ret;
15228
15229   /* Parse args required to build the message */
15230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15231     {
15232       if (unformat (input, "bd %d", &bd))
15233         bd_set = 1;
15234       else
15235         {
15236           errmsg ("parse error '%U'", format_unformat_error, input);
15237           return -99;
15238         }
15239     }
15240
15241   if (!bd_set)
15242     {
15243       errmsg ("Expected bridge domain!");
15244       return -99;
15245     }
15246
15247   M (ONE_L2_ARP_ENTRIES_GET, mp);
15248   mp->bd = clib_host_to_net_u32 (bd);
15249
15250   /* send */
15251   S (mp);
15252
15253   /* wait for reply */
15254   W (ret);
15255   return ret;
15256 }
15257
15258 static int
15259 api_one_stats_enable_disable (vat_main_t * vam)
15260 {
15261   vl_api_one_stats_enable_disable_t *mp;
15262   unformat_input_t *input = vam->input;
15263   u8 is_set = 0;
15264   u8 is_en = 0;
15265   int ret;
15266
15267   /* Parse args required to build the message */
15268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15269     {
15270       if (unformat (input, "enable"))
15271         {
15272           is_set = 1;
15273           is_en = 1;
15274         }
15275       else if (unformat (input, "disable"))
15276         {
15277           is_set = 1;
15278         }
15279       else
15280         break;
15281     }
15282
15283   if (!is_set)
15284     {
15285       errmsg ("Value not set");
15286       return -99;
15287     }
15288
15289   M (ONE_STATS_ENABLE_DISABLE, mp);
15290   mp->is_en = is_en;
15291
15292   /* send */
15293   S (mp);
15294
15295   /* wait for reply */
15296   W (ret);
15297   return ret;
15298 }
15299
15300 static int
15301 api_show_one_stats_enable_disable (vat_main_t * vam)
15302 {
15303   vl_api_show_one_stats_enable_disable_t *mp;
15304   int ret;
15305
15306   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15307
15308   /* send */
15309   S (mp);
15310
15311   /* wait for reply */
15312   W (ret);
15313   return ret;
15314 }
15315
15316 static int
15317 api_show_one_map_request_mode (vat_main_t * vam)
15318 {
15319   vl_api_show_one_map_request_mode_t *mp;
15320   int ret;
15321
15322   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15323
15324   /* send */
15325   S (mp);
15326
15327   /* wait for reply */
15328   W (ret);
15329   return ret;
15330 }
15331
15332 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15333
15334 static int
15335 api_one_map_request_mode (vat_main_t * vam)
15336 {
15337   unformat_input_t *input = vam->input;
15338   vl_api_one_map_request_mode_t *mp;
15339   u8 mode = 0;
15340   int ret;
15341
15342   /* Parse args required to build the message */
15343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15344     {
15345       if (unformat (input, "dst-only"))
15346         mode = 0;
15347       else if (unformat (input, "src-dst"))
15348         mode = 1;
15349       else
15350         {
15351           errmsg ("parse error '%U'", format_unformat_error, input);
15352           return -99;
15353         }
15354     }
15355
15356   M (ONE_MAP_REQUEST_MODE, mp);
15357
15358   mp->mode = mode;
15359
15360   /* send */
15361   S (mp);
15362
15363   /* wait for reply */
15364   W (ret);
15365   return ret;
15366 }
15367
15368 #define api_lisp_map_request_mode api_one_map_request_mode
15369
15370 /**
15371  * Enable/disable ONE proxy ITR.
15372  *
15373  * @param vam vpp API test context
15374  * @return return code
15375  */
15376 static int
15377 api_one_pitr_set_locator_set (vat_main_t * vam)
15378 {
15379   u8 ls_name_set = 0;
15380   unformat_input_t *input = vam->input;
15381   vl_api_one_pitr_set_locator_set_t *mp;
15382   u8 is_add = 1;
15383   u8 *ls_name = 0;
15384   int ret;
15385
15386   /* Parse args required to build the message */
15387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15388     {
15389       if (unformat (input, "del"))
15390         is_add = 0;
15391       else if (unformat (input, "locator-set %s", &ls_name))
15392         ls_name_set = 1;
15393       else
15394         {
15395           errmsg ("parse error '%U'", format_unformat_error, input);
15396           return -99;
15397         }
15398     }
15399
15400   if (!ls_name_set)
15401     {
15402       errmsg ("locator-set name not set!");
15403       return -99;
15404     }
15405
15406   M (ONE_PITR_SET_LOCATOR_SET, mp);
15407
15408   mp->is_add = is_add;
15409   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15410   vec_free (ls_name);
15411
15412   /* send */
15413   S (mp);
15414
15415   /* wait for reply */
15416   W (ret);
15417   return ret;
15418 }
15419
15420 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15421
15422 static int
15423 api_one_nsh_set_locator_set (vat_main_t * vam)
15424 {
15425   u8 ls_name_set = 0;
15426   unformat_input_t *input = vam->input;
15427   vl_api_one_nsh_set_locator_set_t *mp;
15428   u8 is_add = 1;
15429   u8 *ls_name = 0;
15430   int ret;
15431
15432   /* Parse args required to build the message */
15433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15434     {
15435       if (unformat (input, "del"))
15436         is_add = 0;
15437       else if (unformat (input, "ls %s", &ls_name))
15438         ls_name_set = 1;
15439       else
15440         {
15441           errmsg ("parse error '%U'", format_unformat_error, input);
15442           return -99;
15443         }
15444     }
15445
15446   if (!ls_name_set && is_add)
15447     {
15448       errmsg ("locator-set name not set!");
15449       return -99;
15450     }
15451
15452   M (ONE_NSH_SET_LOCATOR_SET, mp);
15453
15454   mp->is_add = is_add;
15455   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15456   vec_free (ls_name);
15457
15458   /* send */
15459   S (mp);
15460
15461   /* wait for reply */
15462   W (ret);
15463   return ret;
15464 }
15465
15466 static int
15467 api_show_one_pitr (vat_main_t * vam)
15468 {
15469   vl_api_show_one_pitr_t *mp;
15470   int ret;
15471
15472   if (!vam->json_output)
15473     {
15474       print (vam->ofp, "%=20s", "lisp status:");
15475     }
15476
15477   M (SHOW_ONE_PITR, mp);
15478   /* send it... */
15479   S (mp);
15480
15481   /* Wait for a reply... */
15482   W (ret);
15483   return ret;
15484 }
15485
15486 #define api_show_lisp_pitr api_show_one_pitr
15487
15488 static int
15489 api_one_use_petr (vat_main_t * vam)
15490 {
15491   unformat_input_t *input = vam->input;
15492   vl_api_one_use_petr_t *mp;
15493   u8 is_add = 0;
15494   ip_address_t ip;
15495   int ret;
15496
15497   memset (&ip, 0, sizeof (ip));
15498
15499   /* Parse args required to build the message */
15500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15501     {
15502       if (unformat (input, "disable"))
15503         is_add = 0;
15504       else
15505         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15506         {
15507           is_add = 1;
15508           ip_addr_version (&ip) = IP4;
15509         }
15510       else
15511         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15512         {
15513           is_add = 1;
15514           ip_addr_version (&ip) = IP6;
15515         }
15516       else
15517         {
15518           errmsg ("parse error '%U'", format_unformat_error, input);
15519           return -99;
15520         }
15521     }
15522
15523   M (ONE_USE_PETR, mp);
15524
15525   mp->is_add = is_add;
15526   if (is_add)
15527     {
15528       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15529       if (mp->is_ip4)
15530         clib_memcpy (mp->address, &ip, 4);
15531       else
15532         clib_memcpy (mp->address, &ip, 16);
15533     }
15534
15535   /* send */
15536   S (mp);
15537
15538   /* wait for reply */
15539   W (ret);
15540   return ret;
15541 }
15542
15543 #define api_lisp_use_petr api_one_use_petr
15544
15545 static int
15546 api_show_one_nsh_mapping (vat_main_t * vam)
15547 {
15548   vl_api_show_one_use_petr_t *mp;
15549   int ret;
15550
15551   if (!vam->json_output)
15552     {
15553       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15554     }
15555
15556   M (SHOW_ONE_NSH_MAPPING, mp);
15557   /* send it... */
15558   S (mp);
15559
15560   /* Wait for a reply... */
15561   W (ret);
15562   return ret;
15563 }
15564
15565 static int
15566 api_show_one_use_petr (vat_main_t * vam)
15567 {
15568   vl_api_show_one_use_petr_t *mp;
15569   int ret;
15570
15571   if (!vam->json_output)
15572     {
15573       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15574     }
15575
15576   M (SHOW_ONE_USE_PETR, mp);
15577   /* send it... */
15578   S (mp);
15579
15580   /* Wait for a reply... */
15581   W (ret);
15582   return ret;
15583 }
15584
15585 #define api_show_lisp_use_petr api_show_one_use_petr
15586
15587 /**
15588  * Add/delete mapping between vni and vrf
15589  */
15590 static int
15591 api_one_eid_table_add_del_map (vat_main_t * vam)
15592 {
15593   unformat_input_t *input = vam->input;
15594   vl_api_one_eid_table_add_del_map_t *mp;
15595   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15596   u32 vni, vrf, bd_index;
15597   int ret;
15598
15599   /* Parse args required to build the message */
15600   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15601     {
15602       if (unformat (input, "del"))
15603         is_add = 0;
15604       else if (unformat (input, "vrf %d", &vrf))
15605         vrf_set = 1;
15606       else if (unformat (input, "bd_index %d", &bd_index))
15607         bd_index_set = 1;
15608       else if (unformat (input, "vni %d", &vni))
15609         vni_set = 1;
15610       else
15611         break;
15612     }
15613
15614   if (!vni_set || (!vrf_set && !bd_index_set))
15615     {
15616       errmsg ("missing arguments!");
15617       return -99;
15618     }
15619
15620   if (vrf_set && bd_index_set)
15621     {
15622       errmsg ("error: both vrf and bd entered!");
15623       return -99;
15624     }
15625
15626   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15627
15628   mp->is_add = is_add;
15629   mp->vni = htonl (vni);
15630   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15631   mp->is_l2 = bd_index_set;
15632
15633   /* send */
15634   S (mp);
15635
15636   /* wait for reply */
15637   W (ret);
15638   return ret;
15639 }
15640
15641 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15642
15643 uword
15644 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15645 {
15646   u32 *action = va_arg (*args, u32 *);
15647   u8 *s = 0;
15648
15649   if (unformat (input, "%s", &s))
15650     {
15651       if (!strcmp ((char *) s, "no-action"))
15652         action[0] = 0;
15653       else if (!strcmp ((char *) s, "natively-forward"))
15654         action[0] = 1;
15655       else if (!strcmp ((char *) s, "send-map-request"))
15656         action[0] = 2;
15657       else if (!strcmp ((char *) s, "drop"))
15658         action[0] = 3;
15659       else
15660         {
15661           clib_warning ("invalid action: '%s'", s);
15662           action[0] = 3;
15663         }
15664     }
15665   else
15666     return 0;
15667
15668   vec_free (s);
15669   return 1;
15670 }
15671
15672 /**
15673  * Add/del remote mapping to/from ONE control plane
15674  *
15675  * @param vam vpp API test context
15676  * @return return code
15677  */
15678 static int
15679 api_one_add_del_remote_mapping (vat_main_t * vam)
15680 {
15681   unformat_input_t *input = vam->input;
15682   vl_api_one_add_del_remote_mapping_t *mp;
15683   u32 vni = 0;
15684   lisp_eid_vat_t _eid, *eid = &_eid;
15685   lisp_eid_vat_t _seid, *seid = &_seid;
15686   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15687   u32 action = ~0, p, w, data_len;
15688   ip4_address_t rloc4;
15689   ip6_address_t rloc6;
15690   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15691   int ret;
15692
15693   memset (&rloc, 0, sizeof (rloc));
15694
15695   /* Parse args required to build the message */
15696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15697     {
15698       if (unformat (input, "del-all"))
15699         {
15700           del_all = 1;
15701         }
15702       else if (unformat (input, "del"))
15703         {
15704           is_add = 0;
15705         }
15706       else if (unformat (input, "add"))
15707         {
15708           is_add = 1;
15709         }
15710       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15711         {
15712           eid_set = 1;
15713         }
15714       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15715         {
15716           seid_set = 1;
15717         }
15718       else if (unformat (input, "vni %d", &vni))
15719         {
15720           ;
15721         }
15722       else if (unformat (input, "p %d w %d", &p, &w))
15723         {
15724           if (!curr_rloc)
15725             {
15726               errmsg ("No RLOC configured for setting priority/weight!");
15727               return -99;
15728             }
15729           curr_rloc->priority = p;
15730           curr_rloc->weight = w;
15731         }
15732       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15733         {
15734           rloc.is_ip4 = 1;
15735           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15736           vec_add1 (rlocs, rloc);
15737           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15738         }
15739       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15740         {
15741           rloc.is_ip4 = 0;
15742           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15743           vec_add1 (rlocs, rloc);
15744           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15745         }
15746       else if (unformat (input, "action %U",
15747                          unformat_negative_mapping_action, &action))
15748         {
15749           ;
15750         }
15751       else
15752         {
15753           clib_warning ("parse error '%U'", format_unformat_error, input);
15754           return -99;
15755         }
15756     }
15757
15758   if (0 == eid_set)
15759     {
15760       errmsg ("missing params!");
15761       return -99;
15762     }
15763
15764   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15765     {
15766       errmsg ("no action set for negative map-reply!");
15767       return -99;
15768     }
15769
15770   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15771
15772   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15773   mp->is_add = is_add;
15774   mp->vni = htonl (vni);
15775   mp->action = (u8) action;
15776   mp->is_src_dst = seid_set;
15777   mp->eid_len = eid->len;
15778   mp->seid_len = seid->len;
15779   mp->del_all = del_all;
15780   mp->eid_type = eid->type;
15781   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15782   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15783
15784   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15785   clib_memcpy (mp->rlocs, rlocs, data_len);
15786   vec_free (rlocs);
15787
15788   /* send it... */
15789   S (mp);
15790
15791   /* Wait for a reply... */
15792   W (ret);
15793   return ret;
15794 }
15795
15796 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15797
15798 /**
15799  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15800  * forwarding entries in data-plane accordingly.
15801  *
15802  * @param vam vpp API test context
15803  * @return return code
15804  */
15805 static int
15806 api_one_add_del_adjacency (vat_main_t * vam)
15807 {
15808   unformat_input_t *input = vam->input;
15809   vl_api_one_add_del_adjacency_t *mp;
15810   u32 vni = 0;
15811   ip4_address_t leid4, reid4;
15812   ip6_address_t leid6, reid6;
15813   u8 reid_mac[6] = { 0 };
15814   u8 leid_mac[6] = { 0 };
15815   u8 reid_type, leid_type;
15816   u32 leid_len = 0, reid_len = 0, len;
15817   u8 is_add = 1;
15818   int ret;
15819
15820   leid_type = reid_type = (u8) ~ 0;
15821
15822   /* Parse args required to build the message */
15823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15824     {
15825       if (unformat (input, "del"))
15826         {
15827           is_add = 0;
15828         }
15829       else if (unformat (input, "add"))
15830         {
15831           is_add = 1;
15832         }
15833       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15834                          &reid4, &len))
15835         {
15836           reid_type = 0;        /* ipv4 */
15837           reid_len = len;
15838         }
15839       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15840                          &reid6, &len))
15841         {
15842           reid_type = 1;        /* ipv6 */
15843           reid_len = len;
15844         }
15845       else if (unformat (input, "reid %U", unformat_ethernet_address,
15846                          reid_mac))
15847         {
15848           reid_type = 2;        /* mac */
15849         }
15850       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15851                          &leid4, &len))
15852         {
15853           leid_type = 0;        /* ipv4 */
15854           leid_len = len;
15855         }
15856       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15857                          &leid6, &len))
15858         {
15859           leid_type = 1;        /* ipv6 */
15860           leid_len = len;
15861         }
15862       else if (unformat (input, "leid %U", unformat_ethernet_address,
15863                          leid_mac))
15864         {
15865           leid_type = 2;        /* mac */
15866         }
15867       else if (unformat (input, "vni %d", &vni))
15868         {
15869           ;
15870         }
15871       else
15872         {
15873           errmsg ("parse error '%U'", format_unformat_error, input);
15874           return -99;
15875         }
15876     }
15877
15878   if ((u8) ~ 0 == reid_type)
15879     {
15880       errmsg ("missing params!");
15881       return -99;
15882     }
15883
15884   if (leid_type != reid_type)
15885     {
15886       errmsg ("remote and local EIDs are of different types!");
15887       return -99;
15888     }
15889
15890   M (ONE_ADD_DEL_ADJACENCY, mp);
15891   mp->is_add = is_add;
15892   mp->vni = htonl (vni);
15893   mp->leid_len = leid_len;
15894   mp->reid_len = reid_len;
15895   mp->eid_type = reid_type;
15896
15897   switch (mp->eid_type)
15898     {
15899     case 0:
15900       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15901       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15902       break;
15903     case 1:
15904       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15905       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15906       break;
15907     case 2:
15908       clib_memcpy (mp->leid, leid_mac, 6);
15909       clib_memcpy (mp->reid, reid_mac, 6);
15910       break;
15911     default:
15912       errmsg ("unknown EID type %d!", mp->eid_type);
15913       return 0;
15914     }
15915
15916   /* send it... */
15917   S (mp);
15918
15919   /* Wait for a reply... */
15920   W (ret);
15921   return ret;
15922 }
15923
15924 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15925
15926 uword
15927 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15928 {
15929   u32 *mode = va_arg (*args, u32 *);
15930
15931   if (unformat (input, "lisp"))
15932     *mode = 0;
15933   else if (unformat (input, "vxlan"))
15934     *mode = 1;
15935   else
15936     return 0;
15937
15938   return 1;
15939 }
15940
15941 static int
15942 api_gpe_get_encap_mode (vat_main_t * vam)
15943 {
15944   vl_api_gpe_get_encap_mode_t *mp;
15945   int ret;
15946
15947   /* Construct the API message */
15948   M (GPE_GET_ENCAP_MODE, mp);
15949
15950   /* send it... */
15951   S (mp);
15952
15953   /* Wait for a reply... */
15954   W (ret);
15955   return ret;
15956 }
15957
15958 static int
15959 api_gpe_set_encap_mode (vat_main_t * vam)
15960 {
15961   unformat_input_t *input = vam->input;
15962   vl_api_gpe_set_encap_mode_t *mp;
15963   int ret;
15964   u32 mode = 0;
15965
15966   /* Parse args required to build the message */
15967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15968     {
15969       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15970         ;
15971       else
15972         break;
15973     }
15974
15975   /* Construct the API message */
15976   M (GPE_SET_ENCAP_MODE, mp);
15977
15978   mp->mode = mode;
15979
15980   /* send it... */
15981   S (mp);
15982
15983   /* Wait for a reply... */
15984   W (ret);
15985   return ret;
15986 }
15987
15988 static int
15989 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15990 {
15991   unformat_input_t *input = vam->input;
15992   vl_api_gpe_add_del_iface_t *mp;
15993   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15994   u32 dp_table = 0, vni = 0;
15995   int ret;
15996
15997   /* Parse args required to build the message */
15998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15999     {
16000       if (unformat (input, "up"))
16001         {
16002           action_set = 1;
16003           is_add = 1;
16004         }
16005       else if (unformat (input, "down"))
16006         {
16007           action_set = 1;
16008           is_add = 0;
16009         }
16010       else if (unformat (input, "table_id %d", &dp_table))
16011         {
16012           dp_table_set = 1;
16013         }
16014       else if (unformat (input, "bd_id %d", &dp_table))
16015         {
16016           dp_table_set = 1;
16017           is_l2 = 1;
16018         }
16019       else if (unformat (input, "vni %d", &vni))
16020         {
16021           vni_set = 1;
16022         }
16023       else
16024         break;
16025     }
16026
16027   if (action_set == 0)
16028     {
16029       errmsg ("Action not set");
16030       return -99;
16031     }
16032   if (dp_table_set == 0 || vni_set == 0)
16033     {
16034       errmsg ("vni and dp_table must be set");
16035       return -99;
16036     }
16037
16038   /* Construct the API message */
16039   M (GPE_ADD_DEL_IFACE, mp);
16040
16041   mp->is_add = is_add;
16042   mp->dp_table = clib_host_to_net_u32 (dp_table);
16043   mp->is_l2 = is_l2;
16044   mp->vni = clib_host_to_net_u32 (vni);
16045
16046   /* send it... */
16047   S (mp);
16048
16049   /* Wait for a reply... */
16050   W (ret);
16051   return ret;
16052 }
16053
16054 /**
16055  * Add/del map request itr rlocs from ONE control plane and updates
16056  *
16057  * @param vam vpp API test context
16058  * @return return code
16059  */
16060 static int
16061 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16062 {
16063   unformat_input_t *input = vam->input;
16064   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16065   u8 *locator_set_name = 0;
16066   u8 locator_set_name_set = 0;
16067   u8 is_add = 1;
16068   int ret;
16069
16070   /* Parse args required to build the message */
16071   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16072     {
16073       if (unformat (input, "del"))
16074         {
16075           is_add = 0;
16076         }
16077       else if (unformat (input, "%_%v%_", &locator_set_name))
16078         {
16079           locator_set_name_set = 1;
16080         }
16081       else
16082         {
16083           clib_warning ("parse error '%U'", format_unformat_error, input);
16084           return -99;
16085         }
16086     }
16087
16088   if (is_add && !locator_set_name_set)
16089     {
16090       errmsg ("itr-rloc is not set!");
16091       return -99;
16092     }
16093
16094   if (is_add && vec_len (locator_set_name) > 64)
16095     {
16096       errmsg ("itr-rloc locator-set name too long");
16097       vec_free (locator_set_name);
16098       return -99;
16099     }
16100
16101   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16102   mp->is_add = is_add;
16103   if (is_add)
16104     {
16105       clib_memcpy (mp->locator_set_name, locator_set_name,
16106                    vec_len (locator_set_name));
16107     }
16108   else
16109     {
16110       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16111     }
16112   vec_free (locator_set_name);
16113
16114   /* send it... */
16115   S (mp);
16116
16117   /* Wait for a reply... */
16118   W (ret);
16119   return ret;
16120 }
16121
16122 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16123
16124 static int
16125 api_one_locator_dump (vat_main_t * vam)
16126 {
16127   unformat_input_t *input = vam->input;
16128   vl_api_one_locator_dump_t *mp;
16129   vl_api_control_ping_t *mp_ping;
16130   u8 is_index_set = 0, is_name_set = 0;
16131   u8 *ls_name = 0;
16132   u32 ls_index = ~0;
16133   int ret;
16134
16135   /* Parse args required to build the message */
16136   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16137     {
16138       if (unformat (input, "ls_name %_%v%_", &ls_name))
16139         {
16140           is_name_set = 1;
16141         }
16142       else if (unformat (input, "ls_index %d", &ls_index))
16143         {
16144           is_index_set = 1;
16145         }
16146       else
16147         {
16148           errmsg ("parse error '%U'", format_unformat_error, input);
16149           return -99;
16150         }
16151     }
16152
16153   if (!is_index_set && !is_name_set)
16154     {
16155       errmsg ("error: expected one of index or name!");
16156       return -99;
16157     }
16158
16159   if (is_index_set && is_name_set)
16160     {
16161       errmsg ("error: only one param expected!");
16162       return -99;
16163     }
16164
16165   if (vec_len (ls_name) > 62)
16166     {
16167       errmsg ("error: locator set name too long!");
16168       return -99;
16169     }
16170
16171   if (!vam->json_output)
16172     {
16173       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16174     }
16175
16176   M (ONE_LOCATOR_DUMP, mp);
16177   mp->is_index_set = is_index_set;
16178
16179   if (is_index_set)
16180     mp->ls_index = clib_host_to_net_u32 (ls_index);
16181   else
16182     {
16183       vec_add1 (ls_name, 0);
16184       strncpy ((char *) mp->ls_name, (char *) ls_name,
16185                sizeof (mp->ls_name) - 1);
16186     }
16187
16188   /* send it... */
16189   S (mp);
16190
16191   /* Use a control ping for synchronization */
16192   M (CONTROL_PING, mp_ping);
16193   S (mp_ping);
16194
16195   /* Wait for a reply... */
16196   W (ret);
16197   return ret;
16198 }
16199
16200 #define api_lisp_locator_dump api_one_locator_dump
16201
16202 static int
16203 api_one_locator_set_dump (vat_main_t * vam)
16204 {
16205   vl_api_one_locator_set_dump_t *mp;
16206   vl_api_control_ping_t *mp_ping;
16207   unformat_input_t *input = vam->input;
16208   u8 filter = 0;
16209   int ret;
16210
16211   /* Parse args required to build the message */
16212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16213     {
16214       if (unformat (input, "local"))
16215         {
16216           filter = 1;
16217         }
16218       else if (unformat (input, "remote"))
16219         {
16220           filter = 2;
16221         }
16222       else
16223         {
16224           errmsg ("parse error '%U'", format_unformat_error, input);
16225           return -99;
16226         }
16227     }
16228
16229   if (!vam->json_output)
16230     {
16231       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16232     }
16233
16234   M (ONE_LOCATOR_SET_DUMP, mp);
16235
16236   mp->filter = filter;
16237
16238   /* send it... */
16239   S (mp);
16240
16241   /* Use a control ping for synchronization */
16242   M (CONTROL_PING, mp_ping);
16243   S (mp_ping);
16244
16245   /* Wait for a reply... */
16246   W (ret);
16247   return ret;
16248 }
16249
16250 #define api_lisp_locator_set_dump api_one_locator_set_dump
16251
16252 static int
16253 api_one_eid_table_map_dump (vat_main_t * vam)
16254 {
16255   u8 is_l2 = 0;
16256   u8 mode_set = 0;
16257   unformat_input_t *input = vam->input;
16258   vl_api_one_eid_table_map_dump_t *mp;
16259   vl_api_control_ping_t *mp_ping;
16260   int ret;
16261
16262   /* Parse args required to build the message */
16263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16264     {
16265       if (unformat (input, "l2"))
16266         {
16267           is_l2 = 1;
16268           mode_set = 1;
16269         }
16270       else if (unformat (input, "l3"))
16271         {
16272           is_l2 = 0;
16273           mode_set = 1;
16274         }
16275       else
16276         {
16277           errmsg ("parse error '%U'", format_unformat_error, input);
16278           return -99;
16279         }
16280     }
16281
16282   if (!mode_set)
16283     {
16284       errmsg ("expected one of 'l2' or 'l3' parameter!");
16285       return -99;
16286     }
16287
16288   if (!vam->json_output)
16289     {
16290       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16291     }
16292
16293   M (ONE_EID_TABLE_MAP_DUMP, mp);
16294   mp->is_l2 = is_l2;
16295
16296   /* send it... */
16297   S (mp);
16298
16299   /* Use a control ping for synchronization */
16300   M (CONTROL_PING, mp_ping);
16301   S (mp_ping);
16302
16303   /* Wait for a reply... */
16304   W (ret);
16305   return ret;
16306 }
16307
16308 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16309
16310 static int
16311 api_one_eid_table_vni_dump (vat_main_t * vam)
16312 {
16313   vl_api_one_eid_table_vni_dump_t *mp;
16314   vl_api_control_ping_t *mp_ping;
16315   int ret;
16316
16317   if (!vam->json_output)
16318     {
16319       print (vam->ofp, "VNI");
16320     }
16321
16322   M (ONE_EID_TABLE_VNI_DUMP, mp);
16323
16324   /* send it... */
16325   S (mp);
16326
16327   /* Use a control ping for synchronization */
16328   M (CONTROL_PING, mp_ping);
16329   S (mp_ping);
16330
16331   /* Wait for a reply... */
16332   W (ret);
16333   return ret;
16334 }
16335
16336 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16337
16338 static int
16339 api_one_eid_table_dump (vat_main_t * vam)
16340 {
16341   unformat_input_t *i = vam->input;
16342   vl_api_one_eid_table_dump_t *mp;
16343   vl_api_control_ping_t *mp_ping;
16344   struct in_addr ip4;
16345   struct in6_addr ip6;
16346   u8 mac[6];
16347   u8 eid_type = ~0, eid_set = 0;
16348   u32 prefix_length = ~0, t, vni = 0;
16349   u8 filter = 0;
16350   int ret;
16351   lisp_nsh_api_t nsh;
16352
16353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16354     {
16355       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16356         {
16357           eid_set = 1;
16358           eid_type = 0;
16359           prefix_length = t;
16360         }
16361       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16362         {
16363           eid_set = 1;
16364           eid_type = 1;
16365           prefix_length = t;
16366         }
16367       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16368         {
16369           eid_set = 1;
16370           eid_type = 2;
16371         }
16372       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16373         {
16374           eid_set = 1;
16375           eid_type = 3;
16376         }
16377       else if (unformat (i, "vni %d", &t))
16378         {
16379           vni = t;
16380         }
16381       else if (unformat (i, "local"))
16382         {
16383           filter = 1;
16384         }
16385       else if (unformat (i, "remote"))
16386         {
16387           filter = 2;
16388         }
16389       else
16390         {
16391           errmsg ("parse error '%U'", format_unformat_error, i);
16392           return -99;
16393         }
16394     }
16395
16396   if (!vam->json_output)
16397     {
16398       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16399              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16400     }
16401
16402   M (ONE_EID_TABLE_DUMP, mp);
16403
16404   mp->filter = filter;
16405   if (eid_set)
16406     {
16407       mp->eid_set = 1;
16408       mp->vni = htonl (vni);
16409       mp->eid_type = eid_type;
16410       switch (eid_type)
16411         {
16412         case 0:
16413           mp->prefix_length = prefix_length;
16414           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16415           break;
16416         case 1:
16417           mp->prefix_length = prefix_length;
16418           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16419           break;
16420         case 2:
16421           clib_memcpy (mp->eid, mac, sizeof (mac));
16422           break;
16423         case 3:
16424           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16425           break;
16426         default:
16427           errmsg ("unknown EID type %d!", eid_type);
16428           return -99;
16429         }
16430     }
16431
16432   /* send it... */
16433   S (mp);
16434
16435   /* Use a control ping for synchronization */
16436   M (CONTROL_PING, mp_ping);
16437   S (mp_ping);
16438
16439   /* Wait for a reply... */
16440   W (ret);
16441   return ret;
16442 }
16443
16444 #define api_lisp_eid_table_dump api_one_eid_table_dump
16445
16446 static int
16447 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16448 {
16449   unformat_input_t *i = vam->input;
16450   vl_api_gpe_fwd_entries_get_t *mp;
16451   u8 vni_set = 0;
16452   u32 vni = ~0;
16453   int ret;
16454
16455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16456     {
16457       if (unformat (i, "vni %d", &vni))
16458         {
16459           vni_set = 1;
16460         }
16461       else
16462         {
16463           errmsg ("parse error '%U'", format_unformat_error, i);
16464           return -99;
16465         }
16466     }
16467
16468   if (!vni_set)
16469     {
16470       errmsg ("vni not set!");
16471       return -99;
16472     }
16473
16474   if (!vam->json_output)
16475     {
16476       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16477              "leid", "reid");
16478     }
16479
16480   M (GPE_FWD_ENTRIES_GET, mp);
16481   mp->vni = clib_host_to_net_u32 (vni);
16482
16483   /* send it... */
16484   S (mp);
16485
16486   /* Wait for a reply... */
16487   W (ret);
16488   return ret;
16489 }
16490
16491 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16492 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16493 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16494 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16495 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16496 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16497 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16498 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16499
16500 static int
16501 api_one_adjacencies_get (vat_main_t * vam)
16502 {
16503   unformat_input_t *i = vam->input;
16504   vl_api_one_adjacencies_get_t *mp;
16505   u8 vni_set = 0;
16506   u32 vni = ~0;
16507   int ret;
16508
16509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16510     {
16511       if (unformat (i, "vni %d", &vni))
16512         {
16513           vni_set = 1;
16514         }
16515       else
16516         {
16517           errmsg ("parse error '%U'", format_unformat_error, i);
16518           return -99;
16519         }
16520     }
16521
16522   if (!vni_set)
16523     {
16524       errmsg ("vni not set!");
16525       return -99;
16526     }
16527
16528   if (!vam->json_output)
16529     {
16530       print (vam->ofp, "%s %40s", "leid", "reid");
16531     }
16532
16533   M (ONE_ADJACENCIES_GET, mp);
16534   mp->vni = clib_host_to_net_u32 (vni);
16535
16536   /* send it... */
16537   S (mp);
16538
16539   /* Wait for a reply... */
16540   W (ret);
16541   return ret;
16542 }
16543
16544 #define api_lisp_adjacencies_get api_one_adjacencies_get
16545
16546 static int
16547 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16548 {
16549   unformat_input_t *i = vam->input;
16550   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16551   int ret;
16552   u8 ip_family_set = 0, is_ip4 = 1;
16553
16554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16555     {
16556       if (unformat (i, "ip4"))
16557         {
16558           ip_family_set = 1;
16559           is_ip4 = 1;
16560         }
16561       else if (unformat (i, "ip6"))
16562         {
16563           ip_family_set = 1;
16564           is_ip4 = 0;
16565         }
16566       else
16567         {
16568           errmsg ("parse error '%U'", format_unformat_error, i);
16569           return -99;
16570         }
16571     }
16572
16573   if (!ip_family_set)
16574     {
16575       errmsg ("ip family not set!");
16576       return -99;
16577     }
16578
16579   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16580   mp->is_ip4 = is_ip4;
16581
16582   /* send it... */
16583   S (mp);
16584
16585   /* Wait for a reply... */
16586   W (ret);
16587   return ret;
16588 }
16589
16590 static int
16591 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16592 {
16593   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16594   int ret;
16595
16596   if (!vam->json_output)
16597     {
16598       print (vam->ofp, "VNIs");
16599     }
16600
16601   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16602
16603   /* send it... */
16604   S (mp);
16605
16606   /* Wait for a reply... */
16607   W (ret);
16608   return ret;
16609 }
16610
16611 static int
16612 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16613 {
16614   unformat_input_t *i = vam->input;
16615   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16616   int ret = 0;
16617   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16618   struct in_addr ip4;
16619   struct in6_addr ip6;
16620   u32 table_id = 0, nh_sw_if_index = ~0;
16621
16622   memset (&ip4, 0, sizeof (ip4));
16623   memset (&ip6, 0, sizeof (ip6));
16624
16625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16626     {
16627       if (unformat (i, "del"))
16628         is_add = 0;
16629       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16630                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16631         {
16632           ip_set = 1;
16633           is_ip4 = 1;
16634         }
16635       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16636                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16637         {
16638           ip_set = 1;
16639           is_ip4 = 0;
16640         }
16641       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16642         {
16643           ip_set = 1;
16644           is_ip4 = 1;
16645           nh_sw_if_index = ~0;
16646         }
16647       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16648         {
16649           ip_set = 1;
16650           is_ip4 = 0;
16651           nh_sw_if_index = ~0;
16652         }
16653       else if (unformat (i, "table %d", &table_id))
16654         ;
16655       else
16656         {
16657           errmsg ("parse error '%U'", format_unformat_error, i);
16658           return -99;
16659         }
16660     }
16661
16662   if (!ip_set)
16663     {
16664       errmsg ("nh addr not set!");
16665       return -99;
16666     }
16667
16668   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16669   mp->is_add = is_add;
16670   mp->table_id = clib_host_to_net_u32 (table_id);
16671   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16672   mp->is_ip4 = is_ip4;
16673   if (is_ip4)
16674     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16675   else
16676     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16677
16678   /* send it... */
16679   S (mp);
16680
16681   /* Wait for a reply... */
16682   W (ret);
16683   return ret;
16684 }
16685
16686 static int
16687 api_one_map_server_dump (vat_main_t * vam)
16688 {
16689   vl_api_one_map_server_dump_t *mp;
16690   vl_api_control_ping_t *mp_ping;
16691   int ret;
16692
16693   if (!vam->json_output)
16694     {
16695       print (vam->ofp, "%=20s", "Map server");
16696     }
16697
16698   M (ONE_MAP_SERVER_DUMP, mp);
16699   /* send it... */
16700   S (mp);
16701
16702   /* Use a control ping for synchronization */
16703   M (CONTROL_PING, mp_ping);
16704   S (mp_ping);
16705
16706   /* Wait for a reply... */
16707   W (ret);
16708   return ret;
16709 }
16710
16711 #define api_lisp_map_server_dump api_one_map_server_dump
16712
16713 static int
16714 api_one_map_resolver_dump (vat_main_t * vam)
16715 {
16716   vl_api_one_map_resolver_dump_t *mp;
16717   vl_api_control_ping_t *mp_ping;
16718   int ret;
16719
16720   if (!vam->json_output)
16721     {
16722       print (vam->ofp, "%=20s", "Map resolver");
16723     }
16724
16725   M (ONE_MAP_RESOLVER_DUMP, mp);
16726   /* send it... */
16727   S (mp);
16728
16729   /* Use a control ping for synchronization */
16730   M (CONTROL_PING, mp_ping);
16731   S (mp_ping);
16732
16733   /* Wait for a reply... */
16734   W (ret);
16735   return ret;
16736 }
16737
16738 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16739
16740 static int
16741 api_one_stats_flush (vat_main_t * vam)
16742 {
16743   vl_api_one_stats_flush_t *mp;
16744   int ret = 0;
16745
16746   M (ONE_STATS_FLUSH, mp);
16747   S (mp);
16748   W (ret);
16749   return ret;
16750 }
16751
16752 static int
16753 api_one_stats_dump (vat_main_t * vam)
16754 {
16755   vl_api_one_stats_dump_t *mp;
16756   vl_api_control_ping_t *mp_ping;
16757   int ret;
16758
16759   M (ONE_STATS_DUMP, mp);
16760   /* send it... */
16761   S (mp);
16762
16763   /* Use a control ping for synchronization */
16764   M (CONTROL_PING, mp_ping);
16765   S (mp_ping);
16766
16767   /* Wait for a reply... */
16768   W (ret);
16769   return ret;
16770 }
16771
16772 static int
16773 api_show_one_status (vat_main_t * vam)
16774 {
16775   vl_api_show_one_status_t *mp;
16776   int ret;
16777
16778   if (!vam->json_output)
16779     {
16780       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16781     }
16782
16783   M (SHOW_ONE_STATUS, mp);
16784   /* send it... */
16785   S (mp);
16786   /* Wait for a reply... */
16787   W (ret);
16788   return ret;
16789 }
16790
16791 #define api_show_lisp_status api_show_one_status
16792
16793 static int
16794 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16795 {
16796   vl_api_gpe_fwd_entry_path_dump_t *mp;
16797   vl_api_control_ping_t *mp_ping;
16798   unformat_input_t *i = vam->input;
16799   u32 fwd_entry_index = ~0;
16800   int ret;
16801
16802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16803     {
16804       if (unformat (i, "index %d", &fwd_entry_index))
16805         ;
16806       else
16807         break;
16808     }
16809
16810   if (~0 == fwd_entry_index)
16811     {
16812       errmsg ("no index specified!");
16813       return -99;
16814     }
16815
16816   if (!vam->json_output)
16817     {
16818       print (vam->ofp, "first line");
16819     }
16820
16821   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16822
16823   /* send it... */
16824   S (mp);
16825   /* Use a control ping for synchronization */
16826   M (CONTROL_PING, mp_ping);
16827   S (mp_ping);
16828
16829   /* Wait for a reply... */
16830   W (ret);
16831   return ret;
16832 }
16833
16834 static int
16835 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16836 {
16837   vl_api_one_get_map_request_itr_rlocs_t *mp;
16838   int ret;
16839
16840   if (!vam->json_output)
16841     {
16842       print (vam->ofp, "%=20s", "itr-rlocs:");
16843     }
16844
16845   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16846   /* send it... */
16847   S (mp);
16848   /* Wait for a reply... */
16849   W (ret);
16850   return ret;
16851 }
16852
16853 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16854
16855 static int
16856 api_af_packet_create (vat_main_t * vam)
16857 {
16858   unformat_input_t *i = vam->input;
16859   vl_api_af_packet_create_t *mp;
16860   u8 *host_if_name = 0;
16861   u8 hw_addr[6];
16862   u8 random_hw_addr = 1;
16863   int ret;
16864
16865   memset (hw_addr, 0, sizeof (hw_addr));
16866
16867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16868     {
16869       if (unformat (i, "name %s", &host_if_name))
16870         vec_add1 (host_if_name, 0);
16871       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16872         random_hw_addr = 0;
16873       else
16874         break;
16875     }
16876
16877   if (!vec_len (host_if_name))
16878     {
16879       errmsg ("host-interface name must be specified");
16880       return -99;
16881     }
16882
16883   if (vec_len (host_if_name) > 64)
16884     {
16885       errmsg ("host-interface name too long");
16886       return -99;
16887     }
16888
16889   M (AF_PACKET_CREATE, mp);
16890
16891   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16892   clib_memcpy (mp->hw_addr, hw_addr, 6);
16893   mp->use_random_hw_addr = random_hw_addr;
16894   vec_free (host_if_name);
16895
16896   S (mp);
16897
16898   /* *INDENT-OFF* */
16899   W2 (ret,
16900       ({
16901         if (ret == 0)
16902           fprintf (vam->ofp ? vam->ofp : stderr,
16903                    " new sw_if_index = %d\n", vam->sw_if_index);
16904       }));
16905   /* *INDENT-ON* */
16906   return ret;
16907 }
16908
16909 static int
16910 api_af_packet_delete (vat_main_t * vam)
16911 {
16912   unformat_input_t *i = vam->input;
16913   vl_api_af_packet_delete_t *mp;
16914   u8 *host_if_name = 0;
16915   int ret;
16916
16917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16918     {
16919       if (unformat (i, "name %s", &host_if_name))
16920         vec_add1 (host_if_name, 0);
16921       else
16922         break;
16923     }
16924
16925   if (!vec_len (host_if_name))
16926     {
16927       errmsg ("host-interface name must be specified");
16928       return -99;
16929     }
16930
16931   if (vec_len (host_if_name) > 64)
16932     {
16933       errmsg ("host-interface name too long");
16934       return -99;
16935     }
16936
16937   M (AF_PACKET_DELETE, mp);
16938
16939   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16940   vec_free (host_if_name);
16941
16942   S (mp);
16943   W (ret);
16944   return ret;
16945 }
16946
16947 static int
16948 api_policer_add_del (vat_main_t * vam)
16949 {
16950   unformat_input_t *i = vam->input;
16951   vl_api_policer_add_del_t *mp;
16952   u8 is_add = 1;
16953   u8 *name = 0;
16954   u32 cir = 0;
16955   u32 eir = 0;
16956   u64 cb = 0;
16957   u64 eb = 0;
16958   u8 rate_type = 0;
16959   u8 round_type = 0;
16960   u8 type = 0;
16961   u8 color_aware = 0;
16962   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16963   int ret;
16964
16965   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16966   conform_action.dscp = 0;
16967   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16968   exceed_action.dscp = 0;
16969   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16970   violate_action.dscp = 0;
16971
16972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16973     {
16974       if (unformat (i, "del"))
16975         is_add = 0;
16976       else if (unformat (i, "name %s", &name))
16977         vec_add1 (name, 0);
16978       else if (unformat (i, "cir %u", &cir))
16979         ;
16980       else if (unformat (i, "eir %u", &eir))
16981         ;
16982       else if (unformat (i, "cb %u", &cb))
16983         ;
16984       else if (unformat (i, "eb %u", &eb))
16985         ;
16986       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16987                          &rate_type))
16988         ;
16989       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16990                          &round_type))
16991         ;
16992       else if (unformat (i, "type %U", unformat_policer_type, &type))
16993         ;
16994       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16995                          &conform_action))
16996         ;
16997       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16998                          &exceed_action))
16999         ;
17000       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17001                          &violate_action))
17002         ;
17003       else if (unformat (i, "color-aware"))
17004         color_aware = 1;
17005       else
17006         break;
17007     }
17008
17009   if (!vec_len (name))
17010     {
17011       errmsg ("policer name must be specified");
17012       return -99;
17013     }
17014
17015   if (vec_len (name) > 64)
17016     {
17017       errmsg ("policer name too long");
17018       return -99;
17019     }
17020
17021   M (POLICER_ADD_DEL, mp);
17022
17023   clib_memcpy (mp->name, name, vec_len (name));
17024   vec_free (name);
17025   mp->is_add = is_add;
17026   mp->cir = cir;
17027   mp->eir = eir;
17028   mp->cb = cb;
17029   mp->eb = eb;
17030   mp->rate_type = rate_type;
17031   mp->round_type = round_type;
17032   mp->type = type;
17033   mp->conform_action_type = conform_action.action_type;
17034   mp->conform_dscp = conform_action.dscp;
17035   mp->exceed_action_type = exceed_action.action_type;
17036   mp->exceed_dscp = exceed_action.dscp;
17037   mp->violate_action_type = violate_action.action_type;
17038   mp->violate_dscp = violate_action.dscp;
17039   mp->color_aware = color_aware;
17040
17041   S (mp);
17042   W (ret);
17043   return ret;
17044 }
17045
17046 static int
17047 api_policer_dump (vat_main_t * vam)
17048 {
17049   unformat_input_t *i = vam->input;
17050   vl_api_policer_dump_t *mp;
17051   vl_api_control_ping_t *mp_ping;
17052   u8 *match_name = 0;
17053   u8 match_name_valid = 0;
17054   int ret;
17055
17056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17057     {
17058       if (unformat (i, "name %s", &match_name))
17059         {
17060           vec_add1 (match_name, 0);
17061           match_name_valid = 1;
17062         }
17063       else
17064         break;
17065     }
17066
17067   M (POLICER_DUMP, mp);
17068   mp->match_name_valid = match_name_valid;
17069   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17070   vec_free (match_name);
17071   /* send it... */
17072   S (mp);
17073
17074   /* Use a control ping for synchronization */
17075   M (CONTROL_PING, mp_ping);
17076   S (mp_ping);
17077
17078   /* Wait for a reply... */
17079   W (ret);
17080   return ret;
17081 }
17082
17083 static int
17084 api_policer_classify_set_interface (vat_main_t * vam)
17085 {
17086   unformat_input_t *i = vam->input;
17087   vl_api_policer_classify_set_interface_t *mp;
17088   u32 sw_if_index;
17089   int sw_if_index_set;
17090   u32 ip4_table_index = ~0;
17091   u32 ip6_table_index = ~0;
17092   u32 l2_table_index = ~0;
17093   u8 is_add = 1;
17094   int ret;
17095
17096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17097     {
17098       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17099         sw_if_index_set = 1;
17100       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17101         sw_if_index_set = 1;
17102       else if (unformat (i, "del"))
17103         is_add = 0;
17104       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17105         ;
17106       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17107         ;
17108       else if (unformat (i, "l2-table %d", &l2_table_index))
17109         ;
17110       else
17111         {
17112           clib_warning ("parse error '%U'", format_unformat_error, i);
17113           return -99;
17114         }
17115     }
17116
17117   if (sw_if_index_set == 0)
17118     {
17119       errmsg ("missing interface name or sw_if_index");
17120       return -99;
17121     }
17122
17123   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17124
17125   mp->sw_if_index = ntohl (sw_if_index);
17126   mp->ip4_table_index = ntohl (ip4_table_index);
17127   mp->ip6_table_index = ntohl (ip6_table_index);
17128   mp->l2_table_index = ntohl (l2_table_index);
17129   mp->is_add = is_add;
17130
17131   S (mp);
17132   W (ret);
17133   return ret;
17134 }
17135
17136 static int
17137 api_policer_classify_dump (vat_main_t * vam)
17138 {
17139   unformat_input_t *i = vam->input;
17140   vl_api_policer_classify_dump_t *mp;
17141   vl_api_control_ping_t *mp_ping;
17142   u8 type = POLICER_CLASSIFY_N_TABLES;
17143   int ret;
17144
17145   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17146     ;
17147   else
17148     {
17149       errmsg ("classify table type must be specified");
17150       return -99;
17151     }
17152
17153   if (!vam->json_output)
17154     {
17155       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17156     }
17157
17158   M (POLICER_CLASSIFY_DUMP, mp);
17159   mp->type = type;
17160   /* send it... */
17161   S (mp);
17162
17163   /* Use a control ping for synchronization */
17164   M (CONTROL_PING, mp_ping);
17165   S (mp_ping);
17166
17167   /* Wait for a reply... */
17168   W (ret);
17169   return ret;
17170 }
17171
17172 static int
17173 api_netmap_create (vat_main_t * vam)
17174 {
17175   unformat_input_t *i = vam->input;
17176   vl_api_netmap_create_t *mp;
17177   u8 *if_name = 0;
17178   u8 hw_addr[6];
17179   u8 random_hw_addr = 1;
17180   u8 is_pipe = 0;
17181   u8 is_master = 0;
17182   int ret;
17183
17184   memset (hw_addr, 0, sizeof (hw_addr));
17185
17186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17187     {
17188       if (unformat (i, "name %s", &if_name))
17189         vec_add1 (if_name, 0);
17190       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17191         random_hw_addr = 0;
17192       else if (unformat (i, "pipe"))
17193         is_pipe = 1;
17194       else if (unformat (i, "master"))
17195         is_master = 1;
17196       else if (unformat (i, "slave"))
17197         is_master = 0;
17198       else
17199         break;
17200     }
17201
17202   if (!vec_len (if_name))
17203     {
17204       errmsg ("interface name must be specified");
17205       return -99;
17206     }
17207
17208   if (vec_len (if_name) > 64)
17209     {
17210       errmsg ("interface name too long");
17211       return -99;
17212     }
17213
17214   M (NETMAP_CREATE, mp);
17215
17216   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17217   clib_memcpy (mp->hw_addr, hw_addr, 6);
17218   mp->use_random_hw_addr = random_hw_addr;
17219   mp->is_pipe = is_pipe;
17220   mp->is_master = is_master;
17221   vec_free (if_name);
17222
17223   S (mp);
17224   W (ret);
17225   return ret;
17226 }
17227
17228 static int
17229 api_netmap_delete (vat_main_t * vam)
17230 {
17231   unformat_input_t *i = vam->input;
17232   vl_api_netmap_delete_t *mp;
17233   u8 *if_name = 0;
17234   int ret;
17235
17236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17237     {
17238       if (unformat (i, "name %s", &if_name))
17239         vec_add1 (if_name, 0);
17240       else
17241         break;
17242     }
17243
17244   if (!vec_len (if_name))
17245     {
17246       errmsg ("interface name must be specified");
17247       return -99;
17248     }
17249
17250   if (vec_len (if_name) > 64)
17251     {
17252       errmsg ("interface name too long");
17253       return -99;
17254     }
17255
17256   M (NETMAP_DELETE, mp);
17257
17258   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17259   vec_free (if_name);
17260
17261   S (mp);
17262   W (ret);
17263   return ret;
17264 }
17265
17266 static void
17267 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17268 {
17269   if (fp->afi == IP46_TYPE_IP6)
17270     print (vam->ofp,
17271            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17272            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17273            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17274            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17275            format_ip6_address, fp->next_hop);
17276   else if (fp->afi == IP46_TYPE_IP4)
17277     print (vam->ofp,
17278            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17279            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17280            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17281            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17282            format_ip4_address, fp->next_hop);
17283 }
17284
17285 static void
17286 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17287                                  vl_api_fib_path2_t * fp)
17288 {
17289   struct in_addr ip4;
17290   struct in6_addr ip6;
17291
17292   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17293   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17294   vat_json_object_add_uint (node, "is_local", fp->is_local);
17295   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17296   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17297   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17298   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17299   if (fp->afi == IP46_TYPE_IP4)
17300     {
17301       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17302       vat_json_object_add_ip4 (node, "next_hop", ip4);
17303     }
17304   else if (fp->afi == IP46_TYPE_IP6)
17305     {
17306       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17307       vat_json_object_add_ip6 (node, "next_hop", ip6);
17308     }
17309 }
17310
17311 static void
17312 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17313 {
17314   vat_main_t *vam = &vat_main;
17315   int count = ntohl (mp->mt_count);
17316   vl_api_fib_path2_t *fp;
17317   i32 i;
17318
17319   print (vam->ofp, "[%d]: sw_if_index %d via:",
17320          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17321   fp = mp->mt_paths;
17322   for (i = 0; i < count; i++)
17323     {
17324       vl_api_mpls_fib_path_print (vam, fp);
17325       fp++;
17326     }
17327
17328   print (vam->ofp, "");
17329 }
17330
17331 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17332 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17333
17334 static void
17335 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17336 {
17337   vat_main_t *vam = &vat_main;
17338   vat_json_node_t *node = NULL;
17339   int count = ntohl (mp->mt_count);
17340   vl_api_fib_path2_t *fp;
17341   i32 i;
17342
17343   if (VAT_JSON_ARRAY != vam->json_tree.type)
17344     {
17345       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17346       vat_json_init_array (&vam->json_tree);
17347     }
17348   node = vat_json_array_add (&vam->json_tree);
17349
17350   vat_json_init_object (node);
17351   vat_json_object_add_uint (node, "tunnel_index",
17352                             ntohl (mp->mt_tunnel_index));
17353   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17354
17355   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17356
17357   fp = mp->mt_paths;
17358   for (i = 0; i < count; i++)
17359     {
17360       vl_api_mpls_fib_path_json_print (node, fp);
17361       fp++;
17362     }
17363 }
17364
17365 static int
17366 api_mpls_tunnel_dump (vat_main_t * vam)
17367 {
17368   vl_api_mpls_tunnel_dump_t *mp;
17369   vl_api_control_ping_t *mp_ping;
17370   i32 index = -1;
17371   int ret;
17372
17373   /* Parse args required to build the message */
17374   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17375     {
17376       if (!unformat (vam->input, "tunnel_index %d", &index))
17377         {
17378           index = -1;
17379           break;
17380         }
17381     }
17382
17383   print (vam->ofp, "  tunnel_index %d", index);
17384
17385   M (MPLS_TUNNEL_DUMP, mp);
17386   mp->tunnel_index = htonl (index);
17387   S (mp);
17388
17389   /* Use a control ping for synchronization */
17390   M (CONTROL_PING, mp_ping);
17391   S (mp_ping);
17392
17393   W (ret);
17394   return ret;
17395 }
17396
17397 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17398 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17399
17400
17401 static void
17402 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17403 {
17404   vat_main_t *vam = &vat_main;
17405   int count = ntohl (mp->count);
17406   vl_api_fib_path2_t *fp;
17407   int i;
17408
17409   print (vam->ofp,
17410          "table-id %d, label %u, ess_bit %u",
17411          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17412   fp = mp->path;
17413   for (i = 0; i < count; i++)
17414     {
17415       vl_api_mpls_fib_path_print (vam, fp);
17416       fp++;
17417     }
17418 }
17419
17420 static void vl_api_mpls_fib_details_t_handler_json
17421   (vl_api_mpls_fib_details_t * mp)
17422 {
17423   vat_main_t *vam = &vat_main;
17424   int count = ntohl (mp->count);
17425   vat_json_node_t *node = NULL;
17426   vl_api_fib_path2_t *fp;
17427   int i;
17428
17429   if (VAT_JSON_ARRAY != vam->json_tree.type)
17430     {
17431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17432       vat_json_init_array (&vam->json_tree);
17433     }
17434   node = vat_json_array_add (&vam->json_tree);
17435
17436   vat_json_init_object (node);
17437   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17438   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17439   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17440   vat_json_object_add_uint (node, "path_count", count);
17441   fp = mp->path;
17442   for (i = 0; i < count; i++)
17443     {
17444       vl_api_mpls_fib_path_json_print (node, fp);
17445       fp++;
17446     }
17447 }
17448
17449 static int
17450 api_mpls_fib_dump (vat_main_t * vam)
17451 {
17452   vl_api_mpls_fib_dump_t *mp;
17453   vl_api_control_ping_t *mp_ping;
17454   int ret;
17455
17456   M (MPLS_FIB_DUMP, mp);
17457   S (mp);
17458
17459   /* Use a control ping for synchronization */
17460   M (CONTROL_PING, mp_ping);
17461   S (mp_ping);
17462
17463   W (ret);
17464   return ret;
17465 }
17466
17467 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17468 #define vl_api_ip_fib_details_t_print vl_noop_handler
17469
17470 static void
17471 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17472 {
17473   vat_main_t *vam = &vat_main;
17474   int count = ntohl (mp->count);
17475   vl_api_fib_path_t *fp;
17476   int i;
17477
17478   print (vam->ofp,
17479          "table-id %d, prefix %U/%d",
17480          ntohl (mp->table_id), format_ip4_address, mp->address,
17481          mp->address_length);
17482   fp = mp->path;
17483   for (i = 0; i < count; i++)
17484     {
17485       if (fp->afi == IP46_TYPE_IP6)
17486         print (vam->ofp,
17487                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17488                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17489                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17490                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17491                format_ip6_address, fp->next_hop);
17492       else if (fp->afi == IP46_TYPE_IP4)
17493         print (vam->ofp,
17494                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17495                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17496                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17497                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17498                format_ip4_address, fp->next_hop);
17499       fp++;
17500     }
17501 }
17502
17503 static void vl_api_ip_fib_details_t_handler_json
17504   (vl_api_ip_fib_details_t * mp)
17505 {
17506   vat_main_t *vam = &vat_main;
17507   int count = ntohl (mp->count);
17508   vat_json_node_t *node = NULL;
17509   struct in_addr ip4;
17510   struct in6_addr ip6;
17511   vl_api_fib_path_t *fp;
17512   int i;
17513
17514   if (VAT_JSON_ARRAY != vam->json_tree.type)
17515     {
17516       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17517       vat_json_init_array (&vam->json_tree);
17518     }
17519   node = vat_json_array_add (&vam->json_tree);
17520
17521   vat_json_init_object (node);
17522   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17523   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17524   vat_json_object_add_ip4 (node, "prefix", ip4);
17525   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17526   vat_json_object_add_uint (node, "path_count", count);
17527   fp = mp->path;
17528   for (i = 0; i < count; i++)
17529     {
17530       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17531       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17532       vat_json_object_add_uint (node, "is_local", fp->is_local);
17533       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17534       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17535       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17536       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17537       if (fp->afi == IP46_TYPE_IP4)
17538         {
17539           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17540           vat_json_object_add_ip4 (node, "next_hop", ip4);
17541         }
17542       else if (fp->afi == IP46_TYPE_IP6)
17543         {
17544           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17545           vat_json_object_add_ip6 (node, "next_hop", ip6);
17546         }
17547     }
17548 }
17549
17550 static int
17551 api_ip_fib_dump (vat_main_t * vam)
17552 {
17553   vl_api_ip_fib_dump_t *mp;
17554   vl_api_control_ping_t *mp_ping;
17555   int ret;
17556
17557   M (IP_FIB_DUMP, mp);
17558   S (mp);
17559
17560   /* Use a control ping for synchronization */
17561   M (CONTROL_PING, mp_ping);
17562   S (mp_ping);
17563
17564   W (ret);
17565   return ret;
17566 }
17567
17568 static int
17569 api_ip_mfib_dump (vat_main_t * vam)
17570 {
17571   vl_api_ip_mfib_dump_t *mp;
17572   vl_api_control_ping_t *mp_ping;
17573   int ret;
17574
17575   M (IP_MFIB_DUMP, mp);
17576   S (mp);
17577
17578   /* Use a control ping for synchronization */
17579   M (CONTROL_PING, mp_ping);
17580   S (mp_ping);
17581
17582   W (ret);
17583   return ret;
17584 }
17585
17586 static void vl_api_ip_neighbor_details_t_handler
17587   (vl_api_ip_neighbor_details_t * mp)
17588 {
17589   vat_main_t *vam = &vat_main;
17590
17591   print (vam->ofp, "%c %U %U",
17592          (mp->is_static) ? 'S' : 'D',
17593          format_ethernet_address, &mp->mac_address,
17594          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17595          &mp->ip_address);
17596 }
17597
17598 static void vl_api_ip_neighbor_details_t_handler_json
17599   (vl_api_ip_neighbor_details_t * mp)
17600 {
17601
17602   vat_main_t *vam = &vat_main;
17603   vat_json_node_t *node;
17604   struct in_addr ip4;
17605   struct in6_addr ip6;
17606
17607   if (VAT_JSON_ARRAY != vam->json_tree.type)
17608     {
17609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17610       vat_json_init_array (&vam->json_tree);
17611     }
17612   node = vat_json_array_add (&vam->json_tree);
17613
17614   vat_json_init_object (node);
17615   vat_json_object_add_string_copy (node, "flag",
17616                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17617                                    "dynamic");
17618
17619   vat_json_object_add_string_copy (node, "link_layer",
17620                                    format (0, "%U", format_ethernet_address,
17621                                            &mp->mac_address));
17622
17623   if (mp->is_ipv6)
17624     {
17625       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17626       vat_json_object_add_ip6 (node, "ip_address", ip6);
17627     }
17628   else
17629     {
17630       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17631       vat_json_object_add_ip4 (node, "ip_address", ip4);
17632     }
17633 }
17634
17635 static int
17636 api_ip_neighbor_dump (vat_main_t * vam)
17637 {
17638   unformat_input_t *i = vam->input;
17639   vl_api_ip_neighbor_dump_t *mp;
17640   vl_api_control_ping_t *mp_ping;
17641   u8 is_ipv6 = 0;
17642   u32 sw_if_index = ~0;
17643   int ret;
17644
17645   /* Parse args required to build the message */
17646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17647     {
17648       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17649         ;
17650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17651         ;
17652       else if (unformat (i, "ip6"))
17653         is_ipv6 = 1;
17654       else
17655         break;
17656     }
17657
17658   if (sw_if_index == ~0)
17659     {
17660       errmsg ("missing interface name or sw_if_index");
17661       return -99;
17662     }
17663
17664   M (IP_NEIGHBOR_DUMP, mp);
17665   mp->is_ipv6 = (u8) is_ipv6;
17666   mp->sw_if_index = ntohl (sw_if_index);
17667   S (mp);
17668
17669   /* Use a control ping for synchronization */
17670   M (CONTROL_PING, mp_ping);
17671   S (mp_ping);
17672
17673   W (ret);
17674   return ret;
17675 }
17676
17677 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17678 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17679
17680 static void
17681 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17682 {
17683   vat_main_t *vam = &vat_main;
17684   int count = ntohl (mp->count);
17685   vl_api_fib_path_t *fp;
17686   int i;
17687
17688   print (vam->ofp,
17689          "table-id %d, prefix %U/%d",
17690          ntohl (mp->table_id), format_ip6_address, mp->address,
17691          mp->address_length);
17692   fp = mp->path;
17693   for (i = 0; i < count; i++)
17694     {
17695       if (fp->afi == IP46_TYPE_IP6)
17696         print (vam->ofp,
17697                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17698                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17699                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17700                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17701                format_ip6_address, fp->next_hop);
17702       else if (fp->afi == IP46_TYPE_IP4)
17703         print (vam->ofp,
17704                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17705                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17706                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17707                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17708                format_ip4_address, fp->next_hop);
17709       fp++;
17710     }
17711 }
17712
17713 static void vl_api_ip6_fib_details_t_handler_json
17714   (vl_api_ip6_fib_details_t * mp)
17715 {
17716   vat_main_t *vam = &vat_main;
17717   int count = ntohl (mp->count);
17718   vat_json_node_t *node = NULL;
17719   struct in_addr ip4;
17720   struct in6_addr ip6;
17721   vl_api_fib_path_t *fp;
17722   int i;
17723
17724   if (VAT_JSON_ARRAY != vam->json_tree.type)
17725     {
17726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17727       vat_json_init_array (&vam->json_tree);
17728     }
17729   node = vat_json_array_add (&vam->json_tree);
17730
17731   vat_json_init_object (node);
17732   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17733   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17734   vat_json_object_add_ip6 (node, "prefix", ip6);
17735   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17736   vat_json_object_add_uint (node, "path_count", count);
17737   fp = mp->path;
17738   for (i = 0; i < count; i++)
17739     {
17740       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17741       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17742       vat_json_object_add_uint (node, "is_local", fp->is_local);
17743       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17744       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17745       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17746       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17747       if (fp->afi == IP46_TYPE_IP4)
17748         {
17749           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17750           vat_json_object_add_ip4 (node, "next_hop", ip4);
17751         }
17752       else if (fp->afi == IP46_TYPE_IP6)
17753         {
17754           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17755           vat_json_object_add_ip6 (node, "next_hop", ip6);
17756         }
17757     }
17758 }
17759
17760 static int
17761 api_ip6_fib_dump (vat_main_t * vam)
17762 {
17763   vl_api_ip6_fib_dump_t *mp;
17764   vl_api_control_ping_t *mp_ping;
17765   int ret;
17766
17767   M (IP6_FIB_DUMP, mp);
17768   S (mp);
17769
17770   /* Use a control ping for synchronization */
17771   M (CONTROL_PING, mp_ping);
17772   S (mp_ping);
17773
17774   W (ret);
17775   return ret;
17776 }
17777
17778 static int
17779 api_ip6_mfib_dump (vat_main_t * vam)
17780 {
17781   vl_api_ip6_mfib_dump_t *mp;
17782   vl_api_control_ping_t *mp_ping;
17783   int ret;
17784
17785   M (IP6_MFIB_DUMP, mp);
17786   S (mp);
17787
17788   /* Use a control ping for synchronization */
17789   M (CONTROL_PING, mp_ping);
17790   S (mp_ping);
17791
17792   W (ret);
17793   return ret;
17794 }
17795
17796 int
17797 api_classify_table_ids (vat_main_t * vam)
17798 {
17799   vl_api_classify_table_ids_t *mp;
17800   int ret;
17801
17802   /* Construct the API message */
17803   M (CLASSIFY_TABLE_IDS, mp);
17804   mp->context = 0;
17805
17806   S (mp);
17807   W (ret);
17808   return ret;
17809 }
17810
17811 int
17812 api_classify_table_by_interface (vat_main_t * vam)
17813 {
17814   unformat_input_t *input = vam->input;
17815   vl_api_classify_table_by_interface_t *mp;
17816
17817   u32 sw_if_index = ~0;
17818   int ret;
17819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17820     {
17821       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17822         ;
17823       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17824         ;
17825       else
17826         break;
17827     }
17828   if (sw_if_index == ~0)
17829     {
17830       errmsg ("missing interface name or sw_if_index");
17831       return -99;
17832     }
17833
17834   /* Construct the API message */
17835   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17836   mp->context = 0;
17837   mp->sw_if_index = ntohl (sw_if_index);
17838
17839   S (mp);
17840   W (ret);
17841   return ret;
17842 }
17843
17844 int
17845 api_classify_table_info (vat_main_t * vam)
17846 {
17847   unformat_input_t *input = vam->input;
17848   vl_api_classify_table_info_t *mp;
17849
17850   u32 table_id = ~0;
17851   int ret;
17852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17853     {
17854       if (unformat (input, "table_id %d", &table_id))
17855         ;
17856       else
17857         break;
17858     }
17859   if (table_id == ~0)
17860     {
17861       errmsg ("missing table id");
17862       return -99;
17863     }
17864
17865   /* Construct the API message */
17866   M (CLASSIFY_TABLE_INFO, mp);
17867   mp->context = 0;
17868   mp->table_id = ntohl (table_id);
17869
17870   S (mp);
17871   W (ret);
17872   return ret;
17873 }
17874
17875 int
17876 api_classify_session_dump (vat_main_t * vam)
17877 {
17878   unformat_input_t *input = vam->input;
17879   vl_api_classify_session_dump_t *mp;
17880   vl_api_control_ping_t *mp_ping;
17881
17882   u32 table_id = ~0;
17883   int ret;
17884   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17885     {
17886       if (unformat (input, "table_id %d", &table_id))
17887         ;
17888       else
17889         break;
17890     }
17891   if (table_id == ~0)
17892     {
17893       errmsg ("missing table id");
17894       return -99;
17895     }
17896
17897   /* Construct the API message */
17898   M (CLASSIFY_SESSION_DUMP, mp);
17899   mp->context = 0;
17900   mp->table_id = ntohl (table_id);
17901   S (mp);
17902
17903   /* Use a control ping for synchronization */
17904   M (CONTROL_PING, mp_ping);
17905   S (mp_ping);
17906
17907   W (ret);
17908   return ret;
17909 }
17910
17911 static void
17912 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17913 {
17914   vat_main_t *vam = &vat_main;
17915
17916   print (vam->ofp, "collector_address %U, collector_port %d, "
17917          "src_address %U, vrf_id %d, path_mtu %u, "
17918          "template_interval %u, udp_checksum %d",
17919          format_ip4_address, mp->collector_address,
17920          ntohs (mp->collector_port),
17921          format_ip4_address, mp->src_address,
17922          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17923          ntohl (mp->template_interval), mp->udp_checksum);
17924
17925   vam->retval = 0;
17926   vam->result_ready = 1;
17927 }
17928
17929 static void
17930   vl_api_ipfix_exporter_details_t_handler_json
17931   (vl_api_ipfix_exporter_details_t * mp)
17932 {
17933   vat_main_t *vam = &vat_main;
17934   vat_json_node_t node;
17935   struct in_addr collector_address;
17936   struct in_addr src_address;
17937
17938   vat_json_init_object (&node);
17939   clib_memcpy (&collector_address, &mp->collector_address,
17940                sizeof (collector_address));
17941   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17942   vat_json_object_add_uint (&node, "collector_port",
17943                             ntohs (mp->collector_port));
17944   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17945   vat_json_object_add_ip4 (&node, "src_address", src_address);
17946   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17947   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17948   vat_json_object_add_uint (&node, "template_interval",
17949                             ntohl (mp->template_interval));
17950   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17951
17952   vat_json_print (vam->ofp, &node);
17953   vat_json_free (&node);
17954   vam->retval = 0;
17955   vam->result_ready = 1;
17956 }
17957
17958 int
17959 api_ipfix_exporter_dump (vat_main_t * vam)
17960 {
17961   vl_api_ipfix_exporter_dump_t *mp;
17962   int ret;
17963
17964   /* Construct the API message */
17965   M (IPFIX_EXPORTER_DUMP, mp);
17966   mp->context = 0;
17967
17968   S (mp);
17969   W (ret);
17970   return ret;
17971 }
17972
17973 static int
17974 api_ipfix_classify_stream_dump (vat_main_t * vam)
17975 {
17976   vl_api_ipfix_classify_stream_dump_t *mp;
17977   int ret;
17978
17979   /* Construct the API message */
17980   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17981   mp->context = 0;
17982
17983   S (mp);
17984   W (ret);
17985   return ret;
17986   /* NOTREACHED */
17987   return 0;
17988 }
17989
17990 static void
17991   vl_api_ipfix_classify_stream_details_t_handler
17992   (vl_api_ipfix_classify_stream_details_t * mp)
17993 {
17994   vat_main_t *vam = &vat_main;
17995   print (vam->ofp, "domain_id %d, src_port %d",
17996          ntohl (mp->domain_id), ntohs (mp->src_port));
17997   vam->retval = 0;
17998   vam->result_ready = 1;
17999 }
18000
18001 static void
18002   vl_api_ipfix_classify_stream_details_t_handler_json
18003   (vl_api_ipfix_classify_stream_details_t * mp)
18004 {
18005   vat_main_t *vam = &vat_main;
18006   vat_json_node_t node;
18007
18008   vat_json_init_object (&node);
18009   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18010   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18011
18012   vat_json_print (vam->ofp, &node);
18013   vat_json_free (&node);
18014   vam->retval = 0;
18015   vam->result_ready = 1;
18016 }
18017
18018 static int
18019 api_ipfix_classify_table_dump (vat_main_t * vam)
18020 {
18021   vl_api_ipfix_classify_table_dump_t *mp;
18022   vl_api_control_ping_t *mp_ping;
18023   int ret;
18024
18025   if (!vam->json_output)
18026     {
18027       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18028              "transport_protocol");
18029     }
18030
18031   /* Construct the API message */
18032   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18033
18034   /* send it... */
18035   S (mp);
18036
18037   /* Use a control ping for synchronization */
18038   M (CONTROL_PING, mp_ping);
18039   S (mp_ping);
18040
18041   W (ret);
18042   return ret;
18043 }
18044
18045 static void
18046   vl_api_ipfix_classify_table_details_t_handler
18047   (vl_api_ipfix_classify_table_details_t * mp)
18048 {
18049   vat_main_t *vam = &vat_main;
18050   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18051          mp->transport_protocol);
18052 }
18053
18054 static void
18055   vl_api_ipfix_classify_table_details_t_handler_json
18056   (vl_api_ipfix_classify_table_details_t * mp)
18057 {
18058   vat_json_node_t *node = NULL;
18059   vat_main_t *vam = &vat_main;
18060
18061   if (VAT_JSON_ARRAY != vam->json_tree.type)
18062     {
18063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18064       vat_json_init_array (&vam->json_tree);
18065     }
18066
18067   node = vat_json_array_add (&vam->json_tree);
18068   vat_json_init_object (node);
18069
18070   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18071   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18072   vat_json_object_add_uint (node, "transport_protocol",
18073                             mp->transport_protocol);
18074 }
18075
18076 static int
18077 api_sw_interface_span_enable_disable (vat_main_t * vam)
18078 {
18079   unformat_input_t *i = vam->input;
18080   vl_api_sw_interface_span_enable_disable_t *mp;
18081   u32 src_sw_if_index = ~0;
18082   u32 dst_sw_if_index = ~0;
18083   u8 state = 3;
18084   int ret;
18085   u8 is_l2 = 0;
18086
18087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18088     {
18089       if (unformat
18090           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18091         ;
18092       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18093         ;
18094       else
18095         if (unformat
18096             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18097         ;
18098       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18099         ;
18100       else if (unformat (i, "disable"))
18101         state = 0;
18102       else if (unformat (i, "rx"))
18103         state = 1;
18104       else if (unformat (i, "tx"))
18105         state = 2;
18106       else if (unformat (i, "both"))
18107         state = 3;
18108       else if (unformat (i, "l2"))
18109         is_l2 = 1;
18110       else
18111         break;
18112     }
18113
18114   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18115
18116   mp->sw_if_index_from = htonl (src_sw_if_index);
18117   mp->sw_if_index_to = htonl (dst_sw_if_index);
18118   mp->state = state;
18119   mp->is_l2 = is_l2;
18120
18121   S (mp);
18122   W (ret);
18123   return ret;
18124 }
18125
18126 static void
18127 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18128                                             * mp)
18129 {
18130   vat_main_t *vam = &vat_main;
18131   u8 *sw_if_from_name = 0;
18132   u8 *sw_if_to_name = 0;
18133   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18134   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18135   char *states[] = { "none", "rx", "tx", "both" };
18136   hash_pair_t *p;
18137
18138   /* *INDENT-OFF* */
18139   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18140   ({
18141     if ((u32) p->value[0] == sw_if_index_from)
18142       {
18143         sw_if_from_name = (u8 *)(p->key);
18144         if (sw_if_to_name)
18145           break;
18146       }
18147     if ((u32) p->value[0] == sw_if_index_to)
18148       {
18149         sw_if_to_name = (u8 *)(p->key);
18150         if (sw_if_from_name)
18151           break;
18152       }
18153   }));
18154   /* *INDENT-ON* */
18155   print (vam->ofp, "%20s => %20s (%s)",
18156          sw_if_from_name, sw_if_to_name, states[mp->state]);
18157 }
18158
18159 static void
18160   vl_api_sw_interface_span_details_t_handler_json
18161   (vl_api_sw_interface_span_details_t * mp)
18162 {
18163   vat_main_t *vam = &vat_main;
18164   vat_json_node_t *node = NULL;
18165   u8 *sw_if_from_name = 0;
18166   u8 *sw_if_to_name = 0;
18167   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18168   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18169   hash_pair_t *p;
18170
18171   /* *INDENT-OFF* */
18172   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18173   ({
18174     if ((u32) p->value[0] == sw_if_index_from)
18175       {
18176         sw_if_from_name = (u8 *)(p->key);
18177         if (sw_if_to_name)
18178           break;
18179       }
18180     if ((u32) p->value[0] == sw_if_index_to)
18181       {
18182         sw_if_to_name = (u8 *)(p->key);
18183         if (sw_if_from_name)
18184           break;
18185       }
18186   }));
18187   /* *INDENT-ON* */
18188
18189   if (VAT_JSON_ARRAY != vam->json_tree.type)
18190     {
18191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18192       vat_json_init_array (&vam->json_tree);
18193     }
18194   node = vat_json_array_add (&vam->json_tree);
18195
18196   vat_json_init_object (node);
18197   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18198   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18199   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18200   if (0 != sw_if_to_name)
18201     {
18202       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18203     }
18204   vat_json_object_add_uint (node, "state", mp->state);
18205 }
18206
18207 static int
18208 api_sw_interface_span_dump (vat_main_t * vam)
18209 {
18210   unformat_input_t *input = vam->input;
18211   vl_api_sw_interface_span_dump_t *mp;
18212   vl_api_control_ping_t *mp_ping;
18213   u8 is_l2 = 0;
18214   int ret;
18215
18216   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18217     {
18218       if (unformat (input, "l2"))
18219         is_l2 = 1;
18220       else
18221         break;
18222     }
18223
18224   M (SW_INTERFACE_SPAN_DUMP, mp);
18225   mp->is_l2 = is_l2;
18226   S (mp);
18227
18228   /* Use a control ping for synchronization */
18229   M (CONTROL_PING, mp_ping);
18230   S (mp_ping);
18231
18232   W (ret);
18233   return ret;
18234 }
18235
18236 int
18237 api_pg_create_interface (vat_main_t * vam)
18238 {
18239   unformat_input_t *input = vam->input;
18240   vl_api_pg_create_interface_t *mp;
18241
18242   u32 if_id = ~0;
18243   int ret;
18244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18245     {
18246       if (unformat (input, "if_id %d", &if_id))
18247         ;
18248       else
18249         break;
18250     }
18251   if (if_id == ~0)
18252     {
18253       errmsg ("missing pg interface index");
18254       return -99;
18255     }
18256
18257   /* Construct the API message */
18258   M (PG_CREATE_INTERFACE, mp);
18259   mp->context = 0;
18260   mp->interface_id = ntohl (if_id);
18261
18262   S (mp);
18263   W (ret);
18264   return ret;
18265 }
18266
18267 int
18268 api_pg_capture (vat_main_t * vam)
18269 {
18270   unformat_input_t *input = vam->input;
18271   vl_api_pg_capture_t *mp;
18272
18273   u32 if_id = ~0;
18274   u8 enable = 1;
18275   u32 count = 1;
18276   u8 pcap_file_set = 0;
18277   u8 *pcap_file = 0;
18278   int ret;
18279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18280     {
18281       if (unformat (input, "if_id %d", &if_id))
18282         ;
18283       else if (unformat (input, "pcap %s", &pcap_file))
18284         pcap_file_set = 1;
18285       else if (unformat (input, "count %d", &count))
18286         ;
18287       else if (unformat (input, "disable"))
18288         enable = 0;
18289       else
18290         break;
18291     }
18292   if (if_id == ~0)
18293     {
18294       errmsg ("missing pg interface index");
18295       return -99;
18296     }
18297   if (pcap_file_set > 0)
18298     {
18299       if (vec_len (pcap_file) > 255)
18300         {
18301           errmsg ("pcap file name is too long");
18302           return -99;
18303         }
18304     }
18305
18306   u32 name_len = vec_len (pcap_file);
18307   /* Construct the API message */
18308   M (PG_CAPTURE, mp);
18309   mp->context = 0;
18310   mp->interface_id = ntohl (if_id);
18311   mp->is_enabled = enable;
18312   mp->count = ntohl (count);
18313   mp->pcap_name_length = ntohl (name_len);
18314   if (pcap_file_set != 0)
18315     {
18316       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18317     }
18318   vec_free (pcap_file);
18319
18320   S (mp);
18321   W (ret);
18322   return ret;
18323 }
18324
18325 int
18326 api_pg_enable_disable (vat_main_t * vam)
18327 {
18328   unformat_input_t *input = vam->input;
18329   vl_api_pg_enable_disable_t *mp;
18330
18331   u8 enable = 1;
18332   u8 stream_name_set = 0;
18333   u8 *stream_name = 0;
18334   int ret;
18335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18336     {
18337       if (unformat (input, "stream %s", &stream_name))
18338         stream_name_set = 1;
18339       else if (unformat (input, "disable"))
18340         enable = 0;
18341       else
18342         break;
18343     }
18344
18345   if (stream_name_set > 0)
18346     {
18347       if (vec_len (stream_name) > 255)
18348         {
18349           errmsg ("stream name too long");
18350           return -99;
18351         }
18352     }
18353
18354   u32 name_len = vec_len (stream_name);
18355   /* Construct the API message */
18356   M (PG_ENABLE_DISABLE, mp);
18357   mp->context = 0;
18358   mp->is_enabled = enable;
18359   if (stream_name_set != 0)
18360     {
18361       mp->stream_name_length = ntohl (name_len);
18362       clib_memcpy (mp->stream_name, stream_name, name_len);
18363     }
18364   vec_free (stream_name);
18365
18366   S (mp);
18367   W (ret);
18368   return ret;
18369 }
18370
18371 int
18372 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18373 {
18374   unformat_input_t *input = vam->input;
18375   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18376
18377   u16 *low_ports = 0;
18378   u16 *high_ports = 0;
18379   u16 this_low;
18380   u16 this_hi;
18381   ip4_address_t ip4_addr;
18382   ip6_address_t ip6_addr;
18383   u32 length;
18384   u32 tmp, tmp2;
18385   u8 prefix_set = 0;
18386   u32 vrf_id = ~0;
18387   u8 is_add = 1;
18388   u8 is_ipv6 = 0;
18389   int ret;
18390
18391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18392     {
18393       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18394         {
18395           prefix_set = 1;
18396         }
18397       else
18398         if (unformat
18399             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18400         {
18401           prefix_set = 1;
18402           is_ipv6 = 1;
18403         }
18404       else if (unformat (input, "vrf %d", &vrf_id))
18405         ;
18406       else if (unformat (input, "del"))
18407         is_add = 0;
18408       else if (unformat (input, "port %d", &tmp))
18409         {
18410           if (tmp == 0 || tmp > 65535)
18411             {
18412               errmsg ("port %d out of range", tmp);
18413               return -99;
18414             }
18415           this_low = tmp;
18416           this_hi = this_low + 1;
18417           vec_add1 (low_ports, this_low);
18418           vec_add1 (high_ports, this_hi);
18419         }
18420       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18421         {
18422           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18423             {
18424               errmsg ("incorrect range parameters");
18425               return -99;
18426             }
18427           this_low = tmp;
18428           /* Note: in debug CLI +1 is added to high before
18429              passing to real fn that does "the work"
18430              (ip_source_and_port_range_check_add_del).
18431              This fn is a wrapper around the binary API fn a
18432              control plane will call, which expects this increment
18433              to have occurred. Hence letting the binary API control
18434              plane fn do the increment for consistency between VAT
18435              and other control planes.
18436            */
18437           this_hi = tmp2;
18438           vec_add1 (low_ports, this_low);
18439           vec_add1 (high_ports, this_hi);
18440         }
18441       else
18442         break;
18443     }
18444
18445   if (prefix_set == 0)
18446     {
18447       errmsg ("<address>/<mask> not specified");
18448       return -99;
18449     }
18450
18451   if (vrf_id == ~0)
18452     {
18453       errmsg ("VRF ID required, not specified");
18454       return -99;
18455     }
18456
18457   if (vrf_id == 0)
18458     {
18459       errmsg
18460         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18461       return -99;
18462     }
18463
18464   if (vec_len (low_ports) == 0)
18465     {
18466       errmsg ("At least one port or port range required");
18467       return -99;
18468     }
18469
18470   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18471
18472   mp->is_add = is_add;
18473
18474   if (is_ipv6)
18475     {
18476       mp->is_ipv6 = 1;
18477       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18478     }
18479   else
18480     {
18481       mp->is_ipv6 = 0;
18482       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18483     }
18484
18485   mp->mask_length = length;
18486   mp->number_of_ranges = vec_len (low_ports);
18487
18488   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18489   vec_free (low_ports);
18490
18491   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18492   vec_free (high_ports);
18493
18494   mp->vrf_id = ntohl (vrf_id);
18495
18496   S (mp);
18497   W (ret);
18498   return ret;
18499 }
18500
18501 int
18502 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18503 {
18504   unformat_input_t *input = vam->input;
18505   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18506   u32 sw_if_index = ~0;
18507   int vrf_set = 0;
18508   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18509   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18510   u8 is_add = 1;
18511   int ret;
18512
18513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18514     {
18515       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18516         ;
18517       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18518         ;
18519       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18520         vrf_set = 1;
18521       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18522         vrf_set = 1;
18523       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18524         vrf_set = 1;
18525       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18526         vrf_set = 1;
18527       else if (unformat (input, "del"))
18528         is_add = 0;
18529       else
18530         break;
18531     }
18532
18533   if (sw_if_index == ~0)
18534     {
18535       errmsg ("Interface required but not specified");
18536       return -99;
18537     }
18538
18539   if (vrf_set == 0)
18540     {
18541       errmsg ("VRF ID required but not specified");
18542       return -99;
18543     }
18544
18545   if (tcp_out_vrf_id == 0
18546       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18547     {
18548       errmsg
18549         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18550       return -99;
18551     }
18552
18553   /* Construct the API message */
18554   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18555
18556   mp->sw_if_index = ntohl (sw_if_index);
18557   mp->is_add = is_add;
18558   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18559   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18560   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18561   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18562
18563   /* send it... */
18564   S (mp);
18565
18566   /* Wait for a reply... */
18567   W (ret);
18568   return ret;
18569 }
18570
18571 static int
18572 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18573 {
18574   unformat_input_t *i = vam->input;
18575   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18576   u32 local_sa_id = 0;
18577   u32 remote_sa_id = 0;
18578   ip4_address_t src_address;
18579   ip4_address_t dst_address;
18580   u8 is_add = 1;
18581   int ret;
18582
18583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18584     {
18585       if (unformat (i, "local_sa %d", &local_sa_id))
18586         ;
18587       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18588         ;
18589       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18590         ;
18591       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18592         ;
18593       else if (unformat (i, "del"))
18594         is_add = 0;
18595       else
18596         {
18597           clib_warning ("parse error '%U'", format_unformat_error, i);
18598           return -99;
18599         }
18600     }
18601
18602   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18603
18604   mp->local_sa_id = ntohl (local_sa_id);
18605   mp->remote_sa_id = ntohl (remote_sa_id);
18606   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18607   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18608   mp->is_add = is_add;
18609
18610   S (mp);
18611   W (ret);
18612   return ret;
18613 }
18614
18615 static int
18616 api_punt (vat_main_t * vam)
18617 {
18618   unformat_input_t *i = vam->input;
18619   vl_api_punt_t *mp;
18620   u32 ipv = ~0;
18621   u32 protocol = ~0;
18622   u32 port = ~0;
18623   int is_add = 1;
18624   int ret;
18625
18626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18627     {
18628       if (unformat (i, "ip %d", &ipv))
18629         ;
18630       else if (unformat (i, "protocol %d", &protocol))
18631         ;
18632       else if (unformat (i, "port %d", &port))
18633         ;
18634       else if (unformat (i, "del"))
18635         is_add = 0;
18636       else
18637         {
18638           clib_warning ("parse error '%U'", format_unformat_error, i);
18639           return -99;
18640         }
18641     }
18642
18643   M (PUNT, mp);
18644
18645   mp->is_add = (u8) is_add;
18646   mp->ipv = (u8) ipv;
18647   mp->l4_protocol = (u8) protocol;
18648   mp->l4_port = htons ((u16) port);
18649
18650   S (mp);
18651   W (ret);
18652   return ret;
18653 }
18654
18655 static void vl_api_ipsec_gre_tunnel_details_t_handler
18656   (vl_api_ipsec_gre_tunnel_details_t * mp)
18657 {
18658   vat_main_t *vam = &vat_main;
18659
18660   print (vam->ofp, "%11d%15U%15U%14d%14d",
18661          ntohl (mp->sw_if_index),
18662          format_ip4_address, &mp->src_address,
18663          format_ip4_address, &mp->dst_address,
18664          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18665 }
18666
18667 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18668   (vl_api_ipsec_gre_tunnel_details_t * mp)
18669 {
18670   vat_main_t *vam = &vat_main;
18671   vat_json_node_t *node = NULL;
18672   struct in_addr ip4;
18673
18674   if (VAT_JSON_ARRAY != vam->json_tree.type)
18675     {
18676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18677       vat_json_init_array (&vam->json_tree);
18678     }
18679   node = vat_json_array_add (&vam->json_tree);
18680
18681   vat_json_init_object (node);
18682   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18683   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18684   vat_json_object_add_ip4 (node, "src_address", ip4);
18685   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18686   vat_json_object_add_ip4 (node, "dst_address", ip4);
18687   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18688   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18689 }
18690
18691 static int
18692 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18693 {
18694   unformat_input_t *i = vam->input;
18695   vl_api_ipsec_gre_tunnel_dump_t *mp;
18696   vl_api_control_ping_t *mp_ping;
18697   u32 sw_if_index;
18698   u8 sw_if_index_set = 0;
18699   int ret;
18700
18701   /* Parse args required to build the message */
18702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18703     {
18704       if (unformat (i, "sw_if_index %d", &sw_if_index))
18705         sw_if_index_set = 1;
18706       else
18707         break;
18708     }
18709
18710   if (sw_if_index_set == 0)
18711     {
18712       sw_if_index = ~0;
18713     }
18714
18715   if (!vam->json_output)
18716     {
18717       print (vam->ofp, "%11s%15s%15s%14s%14s",
18718              "sw_if_index", "src_address", "dst_address",
18719              "local_sa_id", "remote_sa_id");
18720     }
18721
18722   /* Get list of gre-tunnel interfaces */
18723   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18724
18725   mp->sw_if_index = htonl (sw_if_index);
18726
18727   S (mp);
18728
18729   /* Use a control ping for synchronization */
18730   M (CONTROL_PING, mp_ping);
18731   S (mp_ping);
18732
18733   W (ret);
18734   return ret;
18735 }
18736
18737 static int
18738 api_delete_subif (vat_main_t * vam)
18739 {
18740   unformat_input_t *i = vam->input;
18741   vl_api_delete_subif_t *mp;
18742   u32 sw_if_index = ~0;
18743   int ret;
18744
18745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18746     {
18747       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18748         ;
18749       if (unformat (i, "sw_if_index %d", &sw_if_index))
18750         ;
18751       else
18752         break;
18753     }
18754
18755   if (sw_if_index == ~0)
18756     {
18757       errmsg ("missing sw_if_index");
18758       return -99;
18759     }
18760
18761   /* Construct the API message */
18762   M (DELETE_SUBIF, mp);
18763   mp->sw_if_index = ntohl (sw_if_index);
18764
18765   S (mp);
18766   W (ret);
18767   return ret;
18768 }
18769
18770 #define foreach_pbb_vtr_op      \
18771 _("disable",  L2_VTR_DISABLED)  \
18772 _("pop",  L2_VTR_POP_2)         \
18773 _("push",  L2_VTR_PUSH_2)
18774
18775 static int
18776 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18777 {
18778   unformat_input_t *i = vam->input;
18779   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18780   u32 sw_if_index = ~0, vtr_op = ~0;
18781   u16 outer_tag = ~0;
18782   u8 dmac[6], smac[6];
18783   u8 dmac_set = 0, smac_set = 0;
18784   u16 vlanid = 0;
18785   u32 sid = ~0;
18786   u32 tmp;
18787   int ret;
18788
18789   /* Shut up coverity */
18790   memset (dmac, 0, sizeof (dmac));
18791   memset (smac, 0, sizeof (smac));
18792
18793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18794     {
18795       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18796         ;
18797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18798         ;
18799       else if (unformat (i, "vtr_op %d", &vtr_op))
18800         ;
18801 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18802       foreach_pbb_vtr_op
18803 #undef _
18804         else if (unformat (i, "translate_pbb_stag"))
18805         {
18806           if (unformat (i, "%d", &tmp))
18807             {
18808               vtr_op = L2_VTR_TRANSLATE_2_1;
18809               outer_tag = tmp;
18810             }
18811           else
18812             {
18813               errmsg
18814                 ("translate_pbb_stag operation requires outer tag definition");
18815               return -99;
18816             }
18817         }
18818       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18819         dmac_set++;
18820       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18821         smac_set++;
18822       else if (unformat (i, "sid %d", &sid))
18823         ;
18824       else if (unformat (i, "vlanid %d", &tmp))
18825         vlanid = tmp;
18826       else
18827         {
18828           clib_warning ("parse error '%U'", format_unformat_error, i);
18829           return -99;
18830         }
18831     }
18832
18833   if ((sw_if_index == ~0) || (vtr_op == ~0))
18834     {
18835       errmsg ("missing sw_if_index or vtr operation");
18836       return -99;
18837     }
18838   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18839       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18840     {
18841       errmsg
18842         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18843       return -99;
18844     }
18845
18846   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18847   mp->sw_if_index = ntohl (sw_if_index);
18848   mp->vtr_op = ntohl (vtr_op);
18849   mp->outer_tag = ntohs (outer_tag);
18850   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18851   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18852   mp->b_vlanid = ntohs (vlanid);
18853   mp->i_sid = ntohl (sid);
18854
18855   S (mp);
18856   W (ret);
18857   return ret;
18858 }
18859
18860 static int
18861 api_flow_classify_set_interface (vat_main_t * vam)
18862 {
18863   unformat_input_t *i = vam->input;
18864   vl_api_flow_classify_set_interface_t *mp;
18865   u32 sw_if_index;
18866   int sw_if_index_set;
18867   u32 ip4_table_index = ~0;
18868   u32 ip6_table_index = ~0;
18869   u8 is_add = 1;
18870   int ret;
18871
18872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18873     {
18874       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18875         sw_if_index_set = 1;
18876       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18877         sw_if_index_set = 1;
18878       else if (unformat (i, "del"))
18879         is_add = 0;
18880       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18881         ;
18882       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18883         ;
18884       else
18885         {
18886           clib_warning ("parse error '%U'", format_unformat_error, i);
18887           return -99;
18888         }
18889     }
18890
18891   if (sw_if_index_set == 0)
18892     {
18893       errmsg ("missing interface name or sw_if_index");
18894       return -99;
18895     }
18896
18897   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18898
18899   mp->sw_if_index = ntohl (sw_if_index);
18900   mp->ip4_table_index = ntohl (ip4_table_index);
18901   mp->ip6_table_index = ntohl (ip6_table_index);
18902   mp->is_add = is_add;
18903
18904   S (mp);
18905   W (ret);
18906   return ret;
18907 }
18908
18909 static int
18910 api_flow_classify_dump (vat_main_t * vam)
18911 {
18912   unformat_input_t *i = vam->input;
18913   vl_api_flow_classify_dump_t *mp;
18914   vl_api_control_ping_t *mp_ping;
18915   u8 type = FLOW_CLASSIFY_N_TABLES;
18916   int ret;
18917
18918   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18919     ;
18920   else
18921     {
18922       errmsg ("classify table type must be specified");
18923       return -99;
18924     }
18925
18926   if (!vam->json_output)
18927     {
18928       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18929     }
18930
18931   M (FLOW_CLASSIFY_DUMP, mp);
18932   mp->type = type;
18933   /* send it... */
18934   S (mp);
18935
18936   /* Use a control ping for synchronization */
18937   M (CONTROL_PING, mp_ping);
18938   S (mp_ping);
18939
18940   /* Wait for a reply... */
18941   W (ret);
18942   return ret;
18943 }
18944
18945 static int
18946 api_feature_enable_disable (vat_main_t * vam)
18947 {
18948   unformat_input_t *i = vam->input;
18949   vl_api_feature_enable_disable_t *mp;
18950   u8 *arc_name = 0;
18951   u8 *feature_name = 0;
18952   u32 sw_if_index = ~0;
18953   u8 enable = 1;
18954   int ret;
18955
18956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18957     {
18958       if (unformat (i, "arc_name %s", &arc_name))
18959         ;
18960       else if (unformat (i, "feature_name %s", &feature_name))
18961         ;
18962       else
18963         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18964         ;
18965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18966         ;
18967       else if (unformat (i, "disable"))
18968         enable = 0;
18969       else
18970         break;
18971     }
18972
18973   if (arc_name == 0)
18974     {
18975       errmsg ("missing arc name");
18976       return -99;
18977     }
18978   if (vec_len (arc_name) > 63)
18979     {
18980       errmsg ("arc name too long");
18981     }
18982
18983   if (feature_name == 0)
18984     {
18985       errmsg ("missing feature name");
18986       return -99;
18987     }
18988   if (vec_len (feature_name) > 63)
18989     {
18990       errmsg ("feature name too long");
18991     }
18992
18993   if (sw_if_index == ~0)
18994     {
18995       errmsg ("missing interface name or sw_if_index");
18996       return -99;
18997     }
18998
18999   /* Construct the API message */
19000   M (FEATURE_ENABLE_DISABLE, mp);
19001   mp->sw_if_index = ntohl (sw_if_index);
19002   mp->enable = enable;
19003   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19004   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19005   vec_free (arc_name);
19006   vec_free (feature_name);
19007
19008   S (mp);
19009   W (ret);
19010   return ret;
19011 }
19012
19013 static int
19014 api_sw_interface_tag_add_del (vat_main_t * vam)
19015 {
19016   unformat_input_t *i = vam->input;
19017   vl_api_sw_interface_tag_add_del_t *mp;
19018   u32 sw_if_index = ~0;
19019   u8 *tag = 0;
19020   u8 enable = 1;
19021   int ret;
19022
19023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19024     {
19025       if (unformat (i, "tag %s", &tag))
19026         ;
19027       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19028         ;
19029       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19030         ;
19031       else if (unformat (i, "del"))
19032         enable = 0;
19033       else
19034         break;
19035     }
19036
19037   if (sw_if_index == ~0)
19038     {
19039       errmsg ("missing interface name or sw_if_index");
19040       return -99;
19041     }
19042
19043   if (enable && (tag == 0))
19044     {
19045       errmsg ("no tag specified");
19046       return -99;
19047     }
19048
19049   /* Construct the API message */
19050   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19051   mp->sw_if_index = ntohl (sw_if_index);
19052   mp->is_add = enable;
19053   if (enable)
19054     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19055   vec_free (tag);
19056
19057   S (mp);
19058   W (ret);
19059   return ret;
19060 }
19061
19062 static void vl_api_l2_xconnect_details_t_handler
19063   (vl_api_l2_xconnect_details_t * mp)
19064 {
19065   vat_main_t *vam = &vat_main;
19066
19067   print (vam->ofp, "%15d%15d",
19068          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19069 }
19070
19071 static void vl_api_l2_xconnect_details_t_handler_json
19072   (vl_api_l2_xconnect_details_t * mp)
19073 {
19074   vat_main_t *vam = &vat_main;
19075   vat_json_node_t *node = NULL;
19076
19077   if (VAT_JSON_ARRAY != vam->json_tree.type)
19078     {
19079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19080       vat_json_init_array (&vam->json_tree);
19081     }
19082   node = vat_json_array_add (&vam->json_tree);
19083
19084   vat_json_init_object (node);
19085   vat_json_object_add_uint (node, "rx_sw_if_index",
19086                             ntohl (mp->rx_sw_if_index));
19087   vat_json_object_add_uint (node, "tx_sw_if_index",
19088                             ntohl (mp->tx_sw_if_index));
19089 }
19090
19091 static int
19092 api_l2_xconnect_dump (vat_main_t * vam)
19093 {
19094   vl_api_l2_xconnect_dump_t *mp;
19095   vl_api_control_ping_t *mp_ping;
19096   int ret;
19097
19098   if (!vam->json_output)
19099     {
19100       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19101     }
19102
19103   M (L2_XCONNECT_DUMP, mp);
19104
19105   S (mp);
19106
19107   /* Use a control ping for synchronization */
19108   M (CONTROL_PING, mp_ping);
19109   S (mp_ping);
19110
19111   W (ret);
19112   return ret;
19113 }
19114
19115 static int
19116 api_sw_interface_set_mtu (vat_main_t * vam)
19117 {
19118   unformat_input_t *i = vam->input;
19119   vl_api_sw_interface_set_mtu_t *mp;
19120   u32 sw_if_index = ~0;
19121   u32 mtu = 0;
19122   int ret;
19123
19124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19125     {
19126       if (unformat (i, "mtu %d", &mtu))
19127         ;
19128       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19129         ;
19130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19131         ;
19132       else
19133         break;
19134     }
19135
19136   if (sw_if_index == ~0)
19137     {
19138       errmsg ("missing interface name or sw_if_index");
19139       return -99;
19140     }
19141
19142   if (mtu == 0)
19143     {
19144       errmsg ("no mtu specified");
19145       return -99;
19146     }
19147
19148   /* Construct the API message */
19149   M (SW_INTERFACE_SET_MTU, mp);
19150   mp->sw_if_index = ntohl (sw_if_index);
19151   mp->mtu = ntohs ((u16) mtu);
19152
19153   S (mp);
19154   W (ret);
19155   return ret;
19156 }
19157
19158 static int
19159 api_p2p_ethernet_add (vat_main_t * vam)
19160 {
19161   unformat_input_t *i = vam->input;
19162   vl_api_p2p_ethernet_add_t *mp;
19163   u32 parent_if_index = ~0;
19164   u32 sub_id = ~0;
19165   u8 remote_mac[6];
19166   u8 mac_set = 0;
19167   int ret;
19168
19169   memset (remote_mac, 0, sizeof (remote_mac));
19170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19171     {
19172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19173         ;
19174       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19175         ;
19176       else
19177         if (unformat
19178             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19179         mac_set++;
19180       else if (unformat (i, "sub_id %d", &sub_id))
19181         ;
19182       else
19183         {
19184           clib_warning ("parse error '%U'", format_unformat_error, i);
19185           return -99;
19186         }
19187     }
19188
19189   if (parent_if_index == ~0)
19190     {
19191       errmsg ("missing interface name or sw_if_index");
19192       return -99;
19193     }
19194   if (mac_set == 0)
19195     {
19196       errmsg ("missing remote mac address");
19197       return -99;
19198     }
19199   if (sub_id == ~0)
19200     {
19201       errmsg ("missing sub-interface id");
19202       return -99;
19203     }
19204
19205   M (P2P_ETHERNET_ADD, mp);
19206   mp->parent_if_index = ntohl (parent_if_index);
19207   mp->subif_id = ntohl (sub_id);
19208   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19209
19210   S (mp);
19211   W (ret);
19212   return ret;
19213 }
19214
19215 static int
19216 api_p2p_ethernet_del (vat_main_t * vam)
19217 {
19218   unformat_input_t *i = vam->input;
19219   vl_api_p2p_ethernet_del_t *mp;
19220   u32 parent_if_index = ~0;
19221   u8 remote_mac[6];
19222   u8 mac_set = 0;
19223   int ret;
19224
19225   memset (remote_mac, 0, sizeof (remote_mac));
19226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19227     {
19228       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19229         ;
19230       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19231         ;
19232       else
19233         if (unformat
19234             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19235         mac_set++;
19236       else
19237         {
19238           clib_warning ("parse error '%U'", format_unformat_error, i);
19239           return -99;
19240         }
19241     }
19242
19243   if (parent_if_index == ~0)
19244     {
19245       errmsg ("missing interface name or sw_if_index");
19246       return -99;
19247     }
19248   if (mac_set == 0)
19249     {
19250       errmsg ("missing remote mac address");
19251       return -99;
19252     }
19253
19254   M (P2P_ETHERNET_DEL, mp);
19255   mp->parent_if_index = ntohl (parent_if_index);
19256   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19257
19258   S (mp);
19259   W (ret);
19260   return ret;
19261 }
19262
19263 static int
19264 api_lldp_config (vat_main_t * vam)
19265 {
19266   unformat_input_t *i = vam->input;
19267   vl_api_lldp_config_t *mp;
19268   int tx_hold = 0;
19269   int tx_interval = 0;
19270   u8 *sys_name = NULL;
19271   int ret;
19272
19273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19274     {
19275       if (unformat (i, "system-name %s", &sys_name))
19276         ;
19277       else if (unformat (i, "tx-hold %d", &tx_hold))
19278         ;
19279       else if (unformat (i, "tx-interval %d", &tx_interval))
19280         ;
19281       else
19282         {
19283           clib_warning ("parse error '%U'", format_unformat_error, i);
19284           return -99;
19285         }
19286     }
19287
19288   vec_add1 (sys_name, 0);
19289
19290   M (LLDP_CONFIG, mp);
19291   mp->tx_hold = htonl (tx_hold);
19292   mp->tx_interval = htonl (tx_interval);
19293   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19294   vec_free (sys_name);
19295
19296   S (mp);
19297   W (ret);
19298   return ret;
19299 }
19300
19301 static int
19302 api_sw_interface_set_lldp (vat_main_t * vam)
19303 {
19304   unformat_input_t *i = vam->input;
19305   vl_api_sw_interface_set_lldp_t *mp;
19306   u32 sw_if_index = ~0;
19307   u32 enable = 1;
19308   u8 *port_desc = NULL;
19309   int ret;
19310
19311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19312     {
19313       if (unformat (i, "disable"))
19314         enable = 0;
19315       else
19316         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19317         ;
19318       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19319         ;
19320       else if (unformat (i, "port-desc %s", &port_desc))
19321         ;
19322       else
19323         break;
19324     }
19325
19326   if (sw_if_index == ~0)
19327     {
19328       errmsg ("missing interface name or sw_if_index");
19329       return -99;
19330     }
19331
19332   /* Construct the API message */
19333   vec_add1 (port_desc, 0);
19334   M (SW_INTERFACE_SET_LLDP, mp);
19335   mp->sw_if_index = ntohl (sw_if_index);
19336   mp->enable = enable;
19337   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19338   vec_free (port_desc);
19339
19340   S (mp);
19341   W (ret);
19342   return ret;
19343 }
19344
19345 static int
19346 q_or_quit (vat_main_t * vam)
19347 {
19348 #if VPP_API_TEST_BUILTIN == 0
19349   longjmp (vam->jump_buf, 1);
19350 #endif
19351   return 0;                     /* not so much */
19352 }
19353
19354 static int
19355 q (vat_main_t * vam)
19356 {
19357   return q_or_quit (vam);
19358 }
19359
19360 static int
19361 quit (vat_main_t * vam)
19362 {
19363   return q_or_quit (vam);
19364 }
19365
19366 static int
19367 comment (vat_main_t * vam)
19368 {
19369   return 0;
19370 }
19371
19372 static int
19373 cmd_cmp (void *a1, void *a2)
19374 {
19375   u8 **c1 = a1;
19376   u8 **c2 = a2;
19377
19378   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19379 }
19380
19381 static int
19382 help (vat_main_t * vam)
19383 {
19384   u8 **cmds = 0;
19385   u8 *name = 0;
19386   hash_pair_t *p;
19387   unformat_input_t *i = vam->input;
19388   int j;
19389
19390   if (unformat (i, "%s", &name))
19391     {
19392       uword *hs;
19393
19394       vec_add1 (name, 0);
19395
19396       hs = hash_get_mem (vam->help_by_name, name);
19397       if (hs)
19398         print (vam->ofp, "usage: %s %s", name, hs[0]);
19399       else
19400         print (vam->ofp, "No such msg / command '%s'", name);
19401       vec_free (name);
19402       return 0;
19403     }
19404
19405   print (vam->ofp, "Help is available for the following:");
19406
19407     /* *INDENT-OFF* */
19408     hash_foreach_pair (p, vam->function_by_name,
19409     ({
19410       vec_add1 (cmds, (u8 *)(p->key));
19411     }));
19412     /* *INDENT-ON* */
19413
19414   vec_sort_with_function (cmds, cmd_cmp);
19415
19416   for (j = 0; j < vec_len (cmds); j++)
19417     print (vam->ofp, "%s", cmds[j]);
19418
19419   vec_free (cmds);
19420   return 0;
19421 }
19422
19423 static int
19424 set (vat_main_t * vam)
19425 {
19426   u8 *name = 0, *value = 0;
19427   unformat_input_t *i = vam->input;
19428
19429   if (unformat (i, "%s", &name))
19430     {
19431       /* The input buffer is a vector, not a string. */
19432       value = vec_dup (i->buffer);
19433       vec_delete (value, i->index, 0);
19434       /* Almost certainly has a trailing newline */
19435       if (value[vec_len (value) - 1] == '\n')
19436         value[vec_len (value) - 1] = 0;
19437       /* Make sure it's a proper string, one way or the other */
19438       vec_add1 (value, 0);
19439       (void) clib_macro_set_value (&vam->macro_main,
19440                                    (char *) name, (char *) value);
19441     }
19442   else
19443     errmsg ("usage: set <name> <value>");
19444
19445   vec_free (name);
19446   vec_free (value);
19447   return 0;
19448 }
19449
19450 static int
19451 unset (vat_main_t * vam)
19452 {
19453   u8 *name = 0;
19454
19455   if (unformat (vam->input, "%s", &name))
19456     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19457       errmsg ("unset: %s wasn't set", name);
19458   vec_free (name);
19459   return 0;
19460 }
19461
19462 typedef struct
19463 {
19464   u8 *name;
19465   u8 *value;
19466 } macro_sort_t;
19467
19468
19469 static int
19470 macro_sort_cmp (void *a1, void *a2)
19471 {
19472   macro_sort_t *s1 = a1;
19473   macro_sort_t *s2 = a2;
19474
19475   return strcmp ((char *) (s1->name), (char *) (s2->name));
19476 }
19477
19478 static int
19479 dump_macro_table (vat_main_t * vam)
19480 {
19481   macro_sort_t *sort_me = 0, *sm;
19482   int i;
19483   hash_pair_t *p;
19484
19485     /* *INDENT-OFF* */
19486     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19487     ({
19488       vec_add2 (sort_me, sm, 1);
19489       sm->name = (u8 *)(p->key);
19490       sm->value = (u8 *) (p->value[0]);
19491     }));
19492     /* *INDENT-ON* */
19493
19494   vec_sort_with_function (sort_me, macro_sort_cmp);
19495
19496   if (vec_len (sort_me))
19497     print (vam->ofp, "%-15s%s", "Name", "Value");
19498   else
19499     print (vam->ofp, "The macro table is empty...");
19500
19501   for (i = 0; i < vec_len (sort_me); i++)
19502     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19503   return 0;
19504 }
19505
19506 static int
19507 dump_node_table (vat_main_t * vam)
19508 {
19509   int i, j;
19510   vlib_node_t *node, *next_node;
19511
19512   if (vec_len (vam->graph_nodes) == 0)
19513     {
19514       print (vam->ofp, "Node table empty, issue get_node_graph...");
19515       return 0;
19516     }
19517
19518   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19519     {
19520       node = vam->graph_nodes[i];
19521       print (vam->ofp, "[%d] %s", i, node->name);
19522       for (j = 0; j < vec_len (node->next_nodes); j++)
19523         {
19524           if (node->next_nodes[j] != ~0)
19525             {
19526               next_node = vam->graph_nodes[node->next_nodes[j]];
19527               print (vam->ofp, "  [%d] %s", j, next_node->name);
19528             }
19529         }
19530     }
19531   return 0;
19532 }
19533
19534 static int
19535 value_sort_cmp (void *a1, void *a2)
19536 {
19537   name_sort_t *n1 = a1;
19538   name_sort_t *n2 = a2;
19539
19540   if (n1->value < n2->value)
19541     return -1;
19542   if (n1->value > n2->value)
19543     return 1;
19544   return 0;
19545 }
19546
19547
19548 static int
19549 dump_msg_api_table (vat_main_t * vam)
19550 {
19551   api_main_t *am = &api_main;
19552   name_sort_t *nses = 0, *ns;
19553   hash_pair_t *hp;
19554   int i;
19555
19556   /* *INDENT-OFF* */
19557   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19558   ({
19559     vec_add2 (nses, ns, 1);
19560     ns->name = (u8 *)(hp->key);
19561     ns->value = (u32) hp->value[0];
19562   }));
19563   /* *INDENT-ON* */
19564
19565   vec_sort_with_function (nses, value_sort_cmp);
19566
19567   for (i = 0; i < vec_len (nses); i++)
19568     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19569   vec_free (nses);
19570   return 0;
19571 }
19572
19573 static int
19574 get_msg_id (vat_main_t * vam)
19575 {
19576   u8 *name_and_crc;
19577   u32 message_index;
19578
19579   if (unformat (vam->input, "%s", &name_and_crc))
19580     {
19581       message_index = vl_api_get_msg_index (name_and_crc);
19582       if (message_index == ~0)
19583         {
19584           print (vam->ofp, " '%s' not found", name_and_crc);
19585           return 0;
19586         }
19587       print (vam->ofp, " '%s' has message index %d",
19588              name_and_crc, message_index);
19589       return 0;
19590     }
19591   errmsg ("name_and_crc required...");
19592   return 0;
19593 }
19594
19595 static int
19596 search_node_table (vat_main_t * vam)
19597 {
19598   unformat_input_t *line_input = vam->input;
19599   u8 *node_to_find;
19600   int j;
19601   vlib_node_t *node, *next_node;
19602   uword *p;
19603
19604   if (vam->graph_node_index_by_name == 0)
19605     {
19606       print (vam->ofp, "Node table empty, issue get_node_graph...");
19607       return 0;
19608     }
19609
19610   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19611     {
19612       if (unformat (line_input, "%s", &node_to_find))
19613         {
19614           vec_add1 (node_to_find, 0);
19615           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19616           if (p == 0)
19617             {
19618               print (vam->ofp, "%s not found...", node_to_find);
19619               goto out;
19620             }
19621           node = vam->graph_nodes[p[0]];
19622           print (vam->ofp, "[%d] %s", p[0], node->name);
19623           for (j = 0; j < vec_len (node->next_nodes); j++)
19624             {
19625               if (node->next_nodes[j] != ~0)
19626                 {
19627                   next_node = vam->graph_nodes[node->next_nodes[j]];
19628                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19629                 }
19630             }
19631         }
19632
19633       else
19634         {
19635           clib_warning ("parse error '%U'", format_unformat_error,
19636                         line_input);
19637           return -99;
19638         }
19639
19640     out:
19641       vec_free (node_to_find);
19642
19643     }
19644
19645   return 0;
19646 }
19647
19648
19649 static int
19650 script (vat_main_t * vam)
19651 {
19652 #if (VPP_API_TEST_BUILTIN==0)
19653   u8 *s = 0;
19654   char *save_current_file;
19655   unformat_input_t save_input;
19656   jmp_buf save_jump_buf;
19657   u32 save_line_number;
19658
19659   FILE *new_fp, *save_ifp;
19660
19661   if (unformat (vam->input, "%s", &s))
19662     {
19663       new_fp = fopen ((char *) s, "r");
19664       if (new_fp == 0)
19665         {
19666           errmsg ("Couldn't open script file %s", s);
19667           vec_free (s);
19668           return -99;
19669         }
19670     }
19671   else
19672     {
19673       errmsg ("Missing script name");
19674       return -99;
19675     }
19676
19677   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19678   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19679   save_ifp = vam->ifp;
19680   save_line_number = vam->input_line_number;
19681   save_current_file = (char *) vam->current_file;
19682
19683   vam->input_line_number = 0;
19684   vam->ifp = new_fp;
19685   vam->current_file = s;
19686   do_one_file (vam);
19687
19688   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19689   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19690   vam->ifp = save_ifp;
19691   vam->input_line_number = save_line_number;
19692   vam->current_file = (u8 *) save_current_file;
19693   vec_free (s);
19694
19695   return 0;
19696 #else
19697   clib_warning ("use the exec command...");
19698   return -99;
19699 #endif
19700 }
19701
19702 static int
19703 echo (vat_main_t * vam)
19704 {
19705   print (vam->ofp, "%v", vam->input->buffer);
19706   return 0;
19707 }
19708
19709 /* List of API message constructors, CLI names map to api_xxx */
19710 #define foreach_vpe_api_msg                                             \
19711 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19712 _(sw_interface_dump,"")                                                 \
19713 _(sw_interface_set_flags,                                               \
19714   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19715 _(sw_interface_add_del_address,                                         \
19716   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19717 _(sw_interface_set_table,                                               \
19718   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19719 _(sw_interface_set_mpls_enable,                                         \
19720   "<intfc> | sw_if_index [disable | dis]")                              \
19721 _(sw_interface_set_vpath,                                               \
19722   "<intfc> | sw_if_index <id> enable | disable")                        \
19723 _(sw_interface_set_vxlan_bypass,                                        \
19724   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19725 _(sw_interface_set_l2_xconnect,                                         \
19726   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19727   "enable | disable")                                                   \
19728 _(sw_interface_set_l2_bridge,                                           \
19729   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19730   "[shg <split-horizon-group>] [bvi]\n"                                 \
19731   "enable | disable")                                                   \
19732 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19733 _(bridge_domain_add_del,                                                \
19734   "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") \
19735 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19736 _(l2fib_add_del,                                                        \
19737   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19738 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19739 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19740 _(l2_flags,                                                             \
19741   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
19742 _(bridge_flags,                                                         \
19743   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19744 _(tap_connect,                                                          \
19745   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19746 _(tap_modify,                                                           \
19747   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
19748 _(tap_delete,                                                           \
19749   "<vpp-if-name> | sw_if_index <id>")                                   \
19750 _(sw_interface_tap_dump, "")                                            \
19751 _(ip_add_del_route,                                                     \
19752   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
19753   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19754   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19755   "[multipath] [count <n>]")                                            \
19756 _(ip_mroute_add_del,                                                    \
19757   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
19758   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
19759 _(mpls_route_add_del,                                                   \
19760   "<label> <eos> via <addr> [table-id <n>]\n"                           \
19761   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19762   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19763   "[multipath] [count <n>]")                                            \
19764 _(mpls_ip_bind_unbind,                                                  \
19765   "<label> <addr/len>")                                                 \
19766 _(mpls_tunnel_add_del,                                                  \
19767   " via <addr> [table-id <n>]\n"                                        \
19768   "sw_if_index <id>] [l2]  [del]")                                      \
19769 _(proxy_arp_add_del,                                                    \
19770   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
19771 _(proxy_arp_intfc_enable_disable,                                       \
19772   "<intfc> | sw_if_index <id> enable | disable")                        \
19773 _(sw_interface_set_unnumbered,                                          \
19774   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
19775 _(ip_neighbor_add_del,                                                  \
19776   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
19777   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
19778 _(reset_vrf, "vrf <id> [ipv6]")                                         \
19779 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
19780 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
19781   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
19782   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
19783   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
19784 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
19785 _(reset_fib, "vrf <n> [ipv6]")                                          \
19786 _(dhcp_proxy_config,                                                    \
19787   "svr <v46-address> src <v46-address>\n"                               \
19788    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
19789 _(dhcp_proxy_set_vss,                                                   \
19790   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
19791 _(dhcp_proxy_dump, "ip6")                                               \
19792 _(dhcp_client_config,                                                   \
19793   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
19794 _(set_ip_flow_hash,                                                     \
19795   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
19796 _(sw_interface_ip6_enable_disable,                                      \
19797   "<intfc> | sw_if_index <id> enable | disable")                        \
19798 _(sw_interface_ip6_set_link_local_address,                              \
19799   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
19800 _(ip6nd_proxy_add_del,                                                  \
19801   "<intfc> | sw_if_index <id> <ip6-address>")                           \
19802 _(ip6nd_proxy_dump, "")                                                 \
19803 _(sw_interface_ip6nd_ra_prefix,                                         \
19804   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
19805   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
19806   "[nolink] [isno]")                                                    \
19807 _(sw_interface_ip6nd_ra_config,                                         \
19808   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
19809   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
19810   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
19811 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
19812 _(l2_patch_add_del,                                                     \
19813   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19814   "enable | disable")                                                   \
19815 _(sr_localsid_add_del,                                                  \
19816   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
19817   "fib-table <num> (end.psp) sw_if_index <num>")                        \
19818 _(classify_add_del_table,                                               \
19819   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
19820   " [del] [del-chain] mask <mask-value>\n"                              \
19821   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
19822   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
19823 _(classify_add_del_session,                                             \
19824   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
19825   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
19826   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
19827   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
19828 _(classify_set_interface_ip_table,                                      \
19829   "<intfc> | sw_if_index <nn> table <nn>")                              \
19830 _(classify_set_interface_l2_tables,                                     \
19831   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19832   "  [other-table <nn>]")                                               \
19833 _(get_node_index, "node <node-name")                                    \
19834 _(add_node_next, "node <node-name> next <next-node-name>")              \
19835 _(l2tpv3_create_tunnel,                                                 \
19836   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
19837   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
19838   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
19839 _(l2tpv3_set_tunnel_cookies,                                            \
19840   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
19841   "[new_remote_cookie <nn>]\n")                                         \
19842 _(l2tpv3_interface_enable_disable,                                      \
19843   "<intfc> | sw_if_index <nn> enable | disable")                        \
19844 _(l2tpv3_set_lookup_key,                                                \
19845   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
19846 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
19847 _(vxlan_add_del_tunnel,                                                 \
19848   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
19849   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19850   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
19851 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
19852 _(gre_add_del_tunnel,                                                   \
19853   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
19854 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
19855 _(l2_fib_clear_table, "")                                               \
19856 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
19857 _(l2_interface_vlan_tag_rewrite,                                        \
19858   "<intfc> | sw_if_index <nn> \n"                                       \
19859   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
19860   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
19861 _(create_vhost_user_if,                                                 \
19862         "socket <filename> [server] [renumber <dev_instance>] "         \
19863         "[mac <mac_address>]")                                          \
19864 _(modify_vhost_user_if,                                                 \
19865         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
19866         "[server] [renumber <dev_instance>]")                           \
19867 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
19868 _(sw_interface_vhost_user_dump, "")                                     \
19869 _(show_version, "")                                                     \
19870 _(vxlan_gpe_add_del_tunnel,                                             \
19871   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
19872   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19873   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
19874   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
19875 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
19876 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
19877 _(interface_name_renumber,                                              \
19878   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
19879 _(input_acl_set_interface,                                              \
19880   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19881   "  [l2-table <nn>] [del]")                                            \
19882 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
19883 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
19884 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
19885 _(ip_dump, "ipv4 | ipv6")                                               \
19886 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
19887 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
19888   "  spid_id <n> ")                                                     \
19889 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
19890   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
19891   "  integ_alg <alg> integ_key <hex>")                                  \
19892 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
19893   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
19894   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19895   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19896 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
19897 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
19898   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19899   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
19900   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
19901 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
19902 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
19903   "(auth_data 0x<data> | auth_data <data>)")                            \
19904 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
19905   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
19906 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
19907   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
19908   "(local|remote)")                                                     \
19909 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
19910 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
19911 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19912 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19913 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
19914 _(ikev2_initiate_sa_init, "<profile_name>")                             \
19915 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
19916 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
19917 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
19918 _(delete_loopback,"sw_if_index <nn>")                                   \
19919 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19920 _(map_add_domain,                                                       \
19921   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
19922   "ip6-src <ip6addr> "                                                  \
19923   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
19924 _(map_del_domain, "index <n>")                                          \
19925 _(map_add_del_rule,                                                     \
19926   "index <n> psid <n> dst <ip6addr> [del]")                             \
19927 _(map_domain_dump, "")                                                  \
19928 _(map_rule_dump, "index <map-domain>")                                  \
19929 _(want_interface_events,  "enable|disable")                             \
19930 _(want_stats,"enable|disable")                                          \
19931 _(get_first_msg_id, "client <name>")                                    \
19932 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19933 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19934   "fib-id <nn> [ip4][ip6][default]")                                    \
19935 _(get_node_graph, " ")                                                  \
19936 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19937 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19938 _(ioam_disable, "")                                                     \
19939 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19940                             " sw_if_index <sw_if_index> p <priority> "  \
19941                             "w <weight>] [del]")                        \
19942 _(one_add_del_locator, "locator-set <locator_name> "                    \
19943                         "iface <intf> | sw_if_index <sw_if_index> "     \
19944                         "p <priority> w <weight> [del]")                \
19945 _(one_add_del_local_eid,"vni <vni> eid "                                \
19946                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19947                          "locator-set <locator_name> [del]"             \
19948                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19949 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19950 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19951 _(one_enable_disable, "enable|disable")                                 \
19952 _(one_map_register_enable_disable, "enable|disable")                    \
19953 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19954 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19955                                "[seid <seid>] "                         \
19956                                "rloc <locator> p <prio> "               \
19957                                "w <weight> [rloc <loc> ... ] "          \
19958                                "action <action> [del-all]")             \
19959 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19960                           "<local-eid>")                                \
19961 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19962 _(one_use_petr, "ip-address> | disable")                                \
19963 _(one_map_request_mode, "src-dst|dst-only")                             \
19964 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19965 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19966 _(one_locator_set_dump, "[local | remote]")                             \
19967 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19968 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19969                        "[local] | [remote]")                            \
19970 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
19971 _(one_l2_arp_bd_get, "")                                                \
19972 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
19973 _(one_stats_enable_disable, "enable|disalbe")                           \
19974 _(show_one_stats_enable_disable, "")                                    \
19975 _(one_eid_table_vni_dump, "")                                           \
19976 _(one_eid_table_map_dump, "l2|l3")                                      \
19977 _(one_map_resolver_dump, "")                                            \
19978 _(one_map_server_dump, "")                                              \
19979 _(one_adjacencies_get, "vni <vni>")                                     \
19980 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
19981 _(show_one_rloc_probe_state, "")                                        \
19982 _(show_one_map_register_state, "")                                      \
19983 _(show_one_status, "")                                                  \
19984 _(one_stats_dump, "")                                                   \
19985 _(one_stats_flush, "")                                                  \
19986 _(one_get_map_request_itr_rlocs, "")                                    \
19987 _(show_one_nsh_mapping, "")                                             \
19988 _(show_one_pitr, "")                                                    \
19989 _(show_one_use_petr, "")                                                \
19990 _(show_one_map_request_mode, "")                                        \
19991 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19992                             " sw_if_index <sw_if_index> p <priority> "  \
19993                             "w <weight>] [del]")                        \
19994 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19995                         "iface <intf> | sw_if_index <sw_if_index> "     \
19996                         "p <priority> w <weight> [del]")                \
19997 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19998                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19999                          "locator-set <locator_name> [del]"             \
20000                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20001 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20002 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20003 _(lisp_enable_disable, "enable|disable")                                \
20004 _(lisp_map_register_enable_disable, "enable|disable")                   \
20005 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20006 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20007                                "[seid <seid>] "                         \
20008                                "rloc <locator> p <prio> "               \
20009                                "w <weight> [rloc <loc> ... ] "          \
20010                                "action <action> [del-all]")             \
20011 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20012                           "<local-eid>")                                \
20013 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20014 _(lisp_use_petr, "<ip-address> | disable")                              \
20015 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20016 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20017 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20018 _(lisp_locator_set_dump, "[local | remote]")                            \
20019 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20020 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20021                        "[local] | [remote]")                            \
20022 _(lisp_eid_table_vni_dump, "")                                          \
20023 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20024 _(lisp_map_resolver_dump, "")                                           \
20025 _(lisp_map_server_dump, "")                                             \
20026 _(lisp_adjacencies_get, "vni <vni>")                                    \
20027 _(gpe_fwd_entry_vnis_get, "")                                           \
20028 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20029 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20030                                 "[table <table-id>]")                   \
20031 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20032 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20033 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20034 _(gpe_get_encap_mode, "")                                               \
20035 _(lisp_gpe_add_del_iface, "up|down")                                    \
20036 _(lisp_gpe_enable_disable, "enable|disable")                            \
20037 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20038   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20039 _(show_lisp_rloc_probe_state, "")                                       \
20040 _(show_lisp_map_register_state, "")                                     \
20041 _(show_lisp_status, "")                                                 \
20042 _(lisp_get_map_request_itr_rlocs, "")                                   \
20043 _(show_lisp_pitr, "")                                                   \
20044 _(show_lisp_use_petr, "")                                               \
20045 _(show_lisp_map_request_mode, "")                                       \
20046 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20047 _(af_packet_delete, "name <host interface name>")                       \
20048 _(policer_add_del, "name <policer name> <params> [del]")                \
20049 _(policer_dump, "[name <policer name>]")                                \
20050 _(policer_classify_set_interface,                                       \
20051   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20052   "  [l2-table <nn>] [del]")                                            \
20053 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20054 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20055     "[master|slave]")                                                   \
20056 _(netmap_delete, "name <interface name>")                               \
20057 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20058 _(mpls_fib_dump, "")                                                    \
20059 _(classify_table_ids, "")                                               \
20060 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20061 _(classify_table_info, "table_id <nn>")                                 \
20062 _(classify_session_dump, "table_id <nn>")                               \
20063 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20064     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20065     "[template_interval <nn>] [udp_checksum]")                          \
20066 _(ipfix_exporter_dump, "")                                              \
20067 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20068 _(ipfix_classify_stream_dump, "")                                       \
20069 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20070 _(ipfix_classify_table_dump, "")                                        \
20071 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20072 _(sw_interface_span_dump, "[l2]")                                           \
20073 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20074 _(pg_create_interface, "if_id <nn>")                                    \
20075 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20076 _(pg_enable_disable, "[stream <id>] disable")                           \
20077 _(ip_source_and_port_range_check_add_del,                               \
20078   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20079 _(ip_source_and_port_range_check_interface_add_del,                     \
20080   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20081   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20082 _(ipsec_gre_add_del_tunnel,                                             \
20083   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20084 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20085 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20086 _(l2_interface_pbb_tag_rewrite,                                         \
20087   "<intfc> | sw_if_index <nn> \n"                                       \
20088   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20089   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20090 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20091 _(flow_classify_set_interface,                                          \
20092   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20093 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20094 _(ip_fib_dump, "")                                                      \
20095 _(ip_mfib_dump, "")                                                     \
20096 _(ip6_fib_dump, "")                                                     \
20097 _(ip6_mfib_dump, "")                                                    \
20098 _(feature_enable_disable, "arc_name <arc_name> "                        \
20099   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20100 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20101 "[disable]")                                                            \
20102 _(l2_xconnect_dump, "")                                                 \
20103 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20104 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20105 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20106 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20107 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20108 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20109 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]")
20110
20111 /* List of command functions, CLI names map directly to functions */
20112 #define foreach_cli_function                                    \
20113 _(comment, "usage: comment <ignore-rest-of-line>")              \
20114 _(dump_interface_table, "usage: dump_interface_table")          \
20115 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20116 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20117 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20118 _(dump_stats_table, "usage: dump_stats_table")                  \
20119 _(dump_macro_table, "usage: dump_macro_table ")                 \
20120 _(dump_node_table, "usage: dump_node_table")                    \
20121 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20122 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20123 _(echo, "usage: echo <message>")                                \
20124 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20125 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20126 _(help, "usage: help")                                          \
20127 _(q, "usage: quit")                                             \
20128 _(quit, "usage: quit")                                          \
20129 _(search_node_table, "usage: search_node_table <name>...")      \
20130 _(set, "usage: set <variable-name> <value>")                    \
20131 _(script, "usage: script <file-name>")                          \
20132 _(unset, "usage: unset <variable-name>")
20133 #define _(N,n)                                  \
20134     static void vl_api_##n##_t_handler_uni      \
20135     (vl_api_##n##_t * mp)                       \
20136     {                                           \
20137         vat_main_t * vam = &vat_main;           \
20138         if (vam->json_output) {                 \
20139             vl_api_##n##_t_handler_json(mp);    \
20140         } else {                                \
20141             vl_api_##n##_t_handler(mp);         \
20142         }                                       \
20143     }
20144 foreach_vpe_api_reply_msg;
20145 #if VPP_API_TEST_BUILTIN == 0
20146 foreach_standalone_reply_msg;
20147 #endif
20148 #undef _
20149
20150 void
20151 vat_api_hookup (vat_main_t * vam)
20152 {
20153 #define _(N,n)                                                  \
20154     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20155                            vl_api_##n##_t_handler_uni,          \
20156                            vl_noop_handler,                     \
20157                            vl_api_##n##_t_endian,               \
20158                            vl_api_##n##_t_print,                \
20159                            sizeof(vl_api_##n##_t), 1);
20160   foreach_vpe_api_reply_msg;
20161 #if VPP_API_TEST_BUILTIN == 0
20162   foreach_standalone_reply_msg;
20163 #endif
20164 #undef _
20165
20166 #if (VPP_API_TEST_BUILTIN==0)
20167   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20168
20169   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20170
20171   vam->function_by_name = hash_create_string (0, sizeof (uword));
20172
20173   vam->help_by_name = hash_create_string (0, sizeof (uword));
20174 #endif
20175
20176   /* API messages we can send */
20177 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20178   foreach_vpe_api_msg;
20179 #undef _
20180
20181   /* Help strings */
20182 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20183   foreach_vpe_api_msg;
20184 #undef _
20185
20186   /* CLI functions */
20187 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20188   foreach_cli_function;
20189 #undef _
20190
20191   /* Help strings */
20192 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20193   foreach_cli_function;
20194 #undef _
20195 }
20196
20197 #if VPP_API_TEST_BUILTIN
20198 static clib_error_t *
20199 vat_api_hookup_shim (vlib_main_t * vm)
20200 {
20201   vat_api_hookup (&vat_main);
20202   return 0;
20203 }
20204
20205 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20206 #endif
20207
20208 /*
20209  * fd.io coding-style-patch-verification: ON
20210  *
20211  * Local Variables:
20212  * eval: (c-set-style "gnu")
20213  * End:
20214  */