Fix pid field endian in ARP/ND/DHCP event related API messages
[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 #define VHOST_USER_POLLING_MODE   0
407 #define VHOST_USER_INTERRUPT_MODE 1
408 #define VHOST_USER_ADAPTIVE_MODE  2
409
410 static u8 *
411 api_format_vhost_user_operation_mode (u8 * s, va_list * va)
412 {
413   int operation_mode = va_arg (*va, int);
414
415   switch (operation_mode)
416     {
417     case VHOST_USER_POLLING_MODE:
418       s = format (s, "%-9s", "polling");
419       break;
420     case VHOST_USER_INTERRUPT_MODE:
421       s = format (s, "%-9s", "interrupt");
422       break;
423     default:
424       s = format (s, "%-9s", "invalid");
425     }
426   return s;
427 }
428
429 static uword
430 api_unformat_vhost_user_operation_mode (unformat_input_t * input,
431                                         va_list * args)
432 {
433   u8 *operation_mode = va_arg (*args, u8 *);
434   uword rc = 1;
435
436   if (unformat (input, "interrupt"))
437     *operation_mode = VHOST_USER_INTERRUPT_MODE;
438   else if (unformat (input, "polling"))
439     *operation_mode = VHOST_USER_POLLING_MODE;
440   else
441     rc = 0;
442
443   return rc;
444 }
445
446 static uword
447 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
448 {
449   u8 *r = va_arg (*args, u8 *);
450
451   if (unformat (input, "kbps"))
452     *r = SSE2_QOS_RATE_KBPS;
453   else if (unformat (input, "pps"))
454     *r = SSE2_QOS_RATE_PPS;
455   else
456     return 0;
457   return 1;
458 }
459
460 static uword
461 unformat_policer_round_type (unformat_input_t * input, va_list * args)
462 {
463   u8 *r = va_arg (*args, u8 *);
464
465   if (unformat (input, "closest"))
466     *r = SSE2_QOS_ROUND_TO_CLOSEST;
467   else if (unformat (input, "up"))
468     *r = SSE2_QOS_ROUND_TO_UP;
469   else if (unformat (input, "down"))
470     *r = SSE2_QOS_ROUND_TO_DOWN;
471   else
472     return 0;
473   return 1;
474 }
475
476 static uword
477 unformat_policer_type (unformat_input_t * input, va_list * args)
478 {
479   u8 *r = va_arg (*args, u8 *);
480
481   if (unformat (input, "1r2c"))
482     *r = SSE2_QOS_POLICER_TYPE_1R2C;
483   else if (unformat (input, "1r3c"))
484     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
485   else if (unformat (input, "2r3c-2698"))
486     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
487   else if (unformat (input, "2r3c-4115"))
488     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
489   else if (unformat (input, "2r3c-mef5cf1"))
490     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
491   else
492     return 0;
493   return 1;
494 }
495
496 static uword
497 unformat_dscp (unformat_input_t * input, va_list * va)
498 {
499   u8 *r = va_arg (*va, u8 *);
500
501   if (0);
502 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
503   foreach_vnet_dscp
504 #undef _
505     else
506     return 0;
507   return 1;
508 }
509
510 static uword
511 unformat_policer_action_type (unformat_input_t * input, va_list * va)
512 {
513   sse2_qos_pol_action_params_st *a
514     = va_arg (*va, sse2_qos_pol_action_params_st *);
515
516   if (unformat (input, "drop"))
517     a->action_type = SSE2_QOS_ACTION_DROP;
518   else if (unformat (input, "transmit"))
519     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
520   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
521     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
522   else
523     return 0;
524   return 1;
525 }
526
527 static uword
528 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
529 {
530   u32 *r = va_arg (*va, u32 *);
531   u32 tid;
532
533   if (unformat (input, "ip4"))
534     tid = POLICER_CLASSIFY_TABLE_IP4;
535   else if (unformat (input, "ip6"))
536     tid = POLICER_CLASSIFY_TABLE_IP6;
537   else if (unformat (input, "l2"))
538     tid = POLICER_CLASSIFY_TABLE_L2;
539   else
540     return 0;
541
542   *r = tid;
543   return 1;
544 }
545
546 static uword
547 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
548 {
549   u32 *r = va_arg (*va, u32 *);
550   u32 tid;
551
552   if (unformat (input, "ip4"))
553     tid = FLOW_CLASSIFY_TABLE_IP4;
554   else if (unformat (input, "ip6"))
555     tid = FLOW_CLASSIFY_TABLE_IP6;
556   else
557     return 0;
558
559   *r = tid;
560   return 1;
561 }
562
563 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
564 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
565 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
566 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
567
568 #if (VPP_API_TEST_BUILTIN==0)
569 uword
570 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
571 {
572   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
573   mfib_itf_attribute_t attr;
574
575   old = *iflags;
576   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
577   {
578     if (unformat (input, mfib_itf_flag_long_names[attr]))
579       *iflags |= (1 << attr);
580   }
581   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582   {
583     if (unformat (input, mfib_itf_flag_names[attr]))
584       *iflags |= (1 << attr);
585   }
586
587   return (old == *iflags ? 0 : 1);
588 }
589
590 uword
591 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
592 {
593   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
594   mfib_entry_attribute_t attr;
595
596   old = *eflags;
597   FOR_EACH_MFIB_ATTRIBUTE (attr)
598   {
599     if (unformat (input, mfib_flag_long_names[attr]))
600       *eflags |= (1 << attr);
601   }
602   FOR_EACH_MFIB_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_flag_names[attr]))
605       *eflags |= (1 << attr);
606   }
607
608   return (old == *eflags ? 0 : 1);
609 }
610
611 u8 *
612 format_ip4_address (u8 * s, va_list * args)
613 {
614   u8 *a = va_arg (*args, u8 *);
615   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
616 }
617
618 u8 *
619 format_ip6_address (u8 * s, va_list * args)
620 {
621   ip6_address_t *a = va_arg (*args, ip6_address_t *);
622   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
623
624   i_max_n_zero = ARRAY_LEN (a->as_u16);
625   max_n_zeros = 0;
626   i_first_zero = i_max_n_zero;
627   n_zeros = 0;
628   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
629     {
630       u32 is_zero = a->as_u16[i] == 0;
631       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
632         {
633           i_first_zero = i;
634           n_zeros = 0;
635         }
636       n_zeros += is_zero;
637       if ((!is_zero && n_zeros > max_n_zeros)
638           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
639         {
640           i_max_n_zero = i_first_zero;
641           max_n_zeros = n_zeros;
642           i_first_zero = ARRAY_LEN (a->as_u16);
643           n_zeros = 0;
644         }
645     }
646
647   last_double_colon = 0;
648   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
649     {
650       if (i == i_max_n_zero && max_n_zeros > 1)
651         {
652           s = format (s, "::");
653           i += max_n_zeros - 1;
654           last_double_colon = 1;
655         }
656       else
657         {
658           s = format (s, "%s%x",
659                       (last_double_colon || i == 0) ? "" : ":",
660                       clib_net_to_host_u16 (a->as_u16[i]));
661           last_double_colon = 0;
662         }
663     }
664
665   return s;
666 }
667
668 /* Format an IP46 address. */
669 u8 *
670 format_ip46_address (u8 * s, va_list * args)
671 {
672   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
673   ip46_type_t type = va_arg (*args, ip46_type_t);
674   int is_ip4 = 1;
675
676   switch (type)
677     {
678     case IP46_TYPE_ANY:
679       is_ip4 = ip46_address_is_ip4 (ip46);
680       break;
681     case IP46_TYPE_IP4:
682       is_ip4 = 1;
683       break;
684     case IP46_TYPE_IP6:
685       is_ip4 = 0;
686       break;
687     }
688
689   return is_ip4 ?
690     format (s, "%U", format_ip4_address, &ip46->ip4) :
691     format (s, "%U", format_ip6_address, &ip46->ip6);
692 }
693
694 u8 *
695 format_ethernet_address (u8 * s, va_list * args)
696 {
697   u8 *a = va_arg (*args, u8 *);
698
699   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
700                  a[0], a[1], a[2], a[3], a[4], a[5]);
701 }
702 #endif
703
704 static void
705 increment_v4_address (ip4_address_t * a)
706 {
707   u32 v;
708
709   v = ntohl (a->as_u32) + 1;
710   a->as_u32 = ntohl (v);
711 }
712
713 static void
714 increment_v6_address (ip6_address_t * a)
715 {
716   u64 v0, v1;
717
718   v0 = clib_net_to_host_u64 (a->as_u64[0]);
719   v1 = clib_net_to_host_u64 (a->as_u64[1]);
720
721   v1 += 1;
722   if (v1 == 0)
723     v0 += 1;
724   a->as_u64[0] = clib_net_to_host_u64 (v0);
725   a->as_u64[1] = clib_net_to_host_u64 (v1);
726 }
727
728 static void
729 increment_mac_address (u64 * mac)
730 {
731   u64 tmp = *mac;
732
733   tmp = clib_net_to_host_u64 (tmp);
734   tmp += 1 << 16;               /* skip unused (least significant) octets */
735   tmp = clib_host_to_net_u64 (tmp);
736   *mac = tmp;
737 }
738
739 static void vl_api_create_loopback_reply_t_handler
740   (vl_api_create_loopback_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   i32 retval = ntohl (mp->retval);
744
745   vam->retval = retval;
746   vam->regenerate_interface_table = 1;
747   vam->sw_if_index = ntohl (mp->sw_if_index);
748   vam->result_ready = 1;
749 }
750
751 static void vl_api_create_loopback_reply_t_handler_json
752   (vl_api_create_loopback_reply_t * mp)
753 {
754   vat_main_t *vam = &vat_main;
755   vat_json_node_t node;
756
757   vat_json_init_object (&node);
758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
759   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
760
761   vat_json_print (vam->ofp, &node);
762   vat_json_free (&node);
763   vam->retval = ntohl (mp->retval);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_create_loopback_instance_reply_t_handler
768   (vl_api_create_loopback_instance_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   i32 retval = ntohl (mp->retval);
772
773   vam->retval = retval;
774   vam->regenerate_interface_table = 1;
775   vam->sw_if_index = ntohl (mp->sw_if_index);
776   vam->result_ready = 1;
777 }
778
779 static void vl_api_create_loopback_instance_reply_t_handler_json
780   (vl_api_create_loopback_instance_reply_t * mp)
781 {
782   vat_main_t *vam = &vat_main;
783   vat_json_node_t node;
784
785   vat_json_init_object (&node);
786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
787   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
788
789   vat_json_print (vam->ofp, &node);
790   vat_json_free (&node);
791   vam->retval = ntohl (mp->retval);
792   vam->result_ready = 1;
793 }
794
795 static void vl_api_af_packet_create_reply_t_handler
796   (vl_api_af_packet_create_reply_t * mp)
797 {
798   vat_main_t *vam = &vat_main;
799   i32 retval = ntohl (mp->retval);
800
801   vam->retval = retval;
802   vam->regenerate_interface_table = 1;
803   vam->sw_if_index = ntohl (mp->sw_if_index);
804   vam->result_ready = 1;
805 }
806
807 static void vl_api_af_packet_create_reply_t_handler_json
808   (vl_api_af_packet_create_reply_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t node;
812
813   vat_json_init_object (&node);
814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
815   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
816
817   vat_json_print (vam->ofp, &node);
818   vat_json_free (&node);
819
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_create_vlan_subif_reply_t_handler
825   (vl_api_create_vlan_subif_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_create_vlan_subif_reply_t_handler_json
837   (vl_api_create_vlan_subif_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848
849   vam->retval = ntohl (mp->retval);
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_create_subif_reply_t_handler
854   (vl_api_create_subif_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   i32 retval = ntohl (mp->retval);
858
859   vam->retval = retval;
860   vam->regenerate_interface_table = 1;
861   vam->sw_if_index = ntohl (mp->sw_if_index);
862   vam->result_ready = 1;
863 }
864
865 static void vl_api_create_subif_reply_t_handler_json
866   (vl_api_create_subif_reply_t * mp)
867 {
868   vat_main_t *vam = &vat_main;
869   vat_json_node_t node;
870
871   vat_json_init_object (&node);
872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
873   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
874
875   vat_json_print (vam->ofp, &node);
876   vat_json_free (&node);
877
878   vam->retval = ntohl (mp->retval);
879   vam->result_ready = 1;
880 }
881
882 static void vl_api_interface_name_renumber_reply_t_handler
883   (vl_api_interface_name_renumber_reply_t * mp)
884 {
885   vat_main_t *vam = &vat_main;
886   i32 retval = ntohl (mp->retval);
887
888   vam->retval = retval;
889   vam->regenerate_interface_table = 1;
890   vam->result_ready = 1;
891 }
892
893 static void vl_api_interface_name_renumber_reply_t_handler_json
894   (vl_api_interface_name_renumber_reply_t * mp)
895 {
896   vat_main_t *vam = &vat_main;
897   vat_json_node_t node;
898
899   vat_json_init_object (&node);
900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 /*
910  * Special-case: build the interface table, maintain
911  * the next loopback sw_if_index vbl.
912  */
913 static void vl_api_sw_interface_details_t_handler
914   (vl_api_sw_interface_details_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   u8 *s = format (0, "%s%c", mp->interface_name, 0);
918
919   hash_set_mem (vam->sw_if_index_by_interface_name, s,
920                 ntohl (mp->sw_if_index));
921
922   /* In sub interface case, fill the sub interface table entry */
923   if (mp->sw_if_index != mp->sup_sw_if_index)
924     {
925       sw_interface_subif_t *sub = NULL;
926
927       vec_add2 (vam->sw_if_subif_table, sub, 1);
928
929       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
930       strncpy ((char *) sub->interface_name, (char *) s,
931                vec_len (sub->interface_name));
932       sub->sw_if_index = ntohl (mp->sw_if_index);
933       sub->sub_id = ntohl (mp->sub_id);
934
935       sub->sub_dot1ad = mp->sub_dot1ad;
936       sub->sub_number_of_tags = mp->sub_number_of_tags;
937       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
938       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
939       sub->sub_exact_match = mp->sub_exact_match;
940       sub->sub_default = mp->sub_default;
941       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
942       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
943
944       /* vlan tag rewrite */
945       sub->vtr_op = ntohl (mp->vtr_op);
946       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
947       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
948       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
949     }
950 }
951
952 static void vl_api_sw_interface_details_t_handler_json
953   (vl_api_sw_interface_details_t * mp)
954 {
955   vat_main_t *vam = &vat_main;
956   vat_json_node_t *node = NULL;
957
958   if (VAT_JSON_ARRAY != vam->json_tree.type)
959     {
960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
961       vat_json_init_array (&vam->json_tree);
962     }
963   node = vat_json_array_add (&vam->json_tree);
964
965   vat_json_init_object (node);
966   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
967   vat_json_object_add_uint (node, "sup_sw_if_index",
968                             ntohl (mp->sup_sw_if_index));
969   vat_json_object_add_uint (node, "l2_address_length",
970                             ntohl (mp->l2_address_length));
971   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
972                              sizeof (mp->l2_address));
973   vat_json_object_add_string_copy (node, "interface_name",
974                                    mp->interface_name);
975   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
976   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
977   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
978   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
979   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
980   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
981   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
982   vat_json_object_add_uint (node, "sub_number_of_tags",
983                             mp->sub_number_of_tags);
984   vat_json_object_add_uint (node, "sub_outer_vlan_id",
985                             ntohs (mp->sub_outer_vlan_id));
986   vat_json_object_add_uint (node, "sub_inner_vlan_id",
987                             ntohs (mp->sub_inner_vlan_id));
988   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
989   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
990   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
991                             mp->sub_outer_vlan_id_any);
992   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
993                             mp->sub_inner_vlan_id_any);
994   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
995   vat_json_object_add_uint (node, "vtr_push_dot1q",
996                             ntohl (mp->vtr_push_dot1q));
997   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
998   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
999   if (mp->sub_dot1ah)
1000     {
1001       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1002                                        format (0, "%U",
1003                                                format_ethernet_address,
1004                                                &mp->b_dmac));
1005       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1006                                        format (0, "%U",
1007                                                format_ethernet_address,
1008                                                &mp->b_smac));
1009       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1010       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1011     }
1012 }
1013
1014 #if VPP_API_TEST_BUILTIN == 0
1015 static void vl_api_sw_interface_set_flags_t_handler
1016   (vl_api_sw_interface_set_flags_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   if (vam->interface_event_display)
1020     errmsg ("interface flags: sw_if_index %d %s %s",
1021             ntohl (mp->sw_if_index),
1022             mp->admin_up_down ? "admin-up" : "admin-down",
1023             mp->link_up_down ? "link-up" : "link-down");
1024 }
1025 #endif
1026
1027 static void vl_api_sw_interface_set_flags_t_handler_json
1028   (vl_api_sw_interface_set_flags_t * mp)
1029 {
1030   /* JSON output not supported */
1031 }
1032
1033 static void
1034 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   i32 retval = ntohl (mp->retval);
1038
1039   vam->retval = retval;
1040   vam->shmem_result = (u8 *) mp->reply_in_shmem;
1041   vam->result_ready = 1;
1042 }
1043
1044 static void
1045 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049   api_main_t *am = &api_main;
1050   void *oldheap;
1051   u8 *reply;
1052
1053   vat_json_init_object (&node);
1054   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1055   vat_json_object_add_uint (&node, "reply_in_shmem",
1056                             ntohl (mp->reply_in_shmem));
1057   /* Toss the shared-memory original... */
1058   pthread_mutex_lock (&am->vlib_rp->mutex);
1059   oldheap = svm_push_data_heap (am->vlib_rp);
1060
1061   reply = (u8 *) (mp->reply_in_shmem);
1062   vec_free (reply);
1063
1064   svm_pop_heap (oldheap);
1065   pthread_mutex_unlock (&am->vlib_rp->mutex);
1066
1067   vat_json_print (vam->ofp, &node);
1068   vat_json_free (&node);
1069
1070   vam->retval = ntohl (mp->retval);
1071   vam->result_ready = 1;
1072 }
1073
1074 static void
1075 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1076 {
1077   vat_main_t *vam = &vat_main;
1078   i32 retval = ntohl (mp->retval);
1079
1080   vam->retval = retval;
1081   vam->cmd_reply = mp->reply;
1082   vam->result_ready = 1;
1083 }
1084
1085 static void
1086 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vat_json_init_object (&node);
1092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1093   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1094
1095   vat_json_print (vam->ofp, &node);
1096   vat_json_free (&node);
1097
1098   vam->retval = ntohl (mp->retval);
1099   vam->result_ready = 1;
1100 }
1101
1102 static void vl_api_classify_add_del_table_reply_t_handler
1103   (vl_api_classify_add_del_table_reply_t * mp)
1104 {
1105   vat_main_t *vam = &vat_main;
1106   i32 retval = ntohl (mp->retval);
1107   if (vam->async_mode)
1108     {
1109       vam->async_errors += (retval < 0);
1110     }
1111   else
1112     {
1113       vam->retval = retval;
1114       if (retval == 0 &&
1115           ((mp->new_table_index != 0xFFFFFFFF) ||
1116            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1117            (mp->match_n_vectors != 0xFFFFFFFF)))
1118         /*
1119          * Note: this is just barely thread-safe, depends on
1120          * the main thread spinning waiting for an answer...
1121          */
1122         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1123                 ntohl (mp->new_table_index),
1124                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_classify_add_del_table_reply_t_handler_json
1130   (vl_api_classify_add_del_table_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, "new_table_index",
1138                             ntohl (mp->new_table_index));
1139   vat_json_object_add_uint (&node, "skip_n_vectors",
1140                             ntohl (mp->skip_n_vectors));
1141   vat_json_object_add_uint (&node, "match_n_vectors",
1142                             ntohl (mp->match_n_vectors));
1143
1144   vat_json_print (vam->ofp, &node);
1145   vat_json_free (&node);
1146
1147   vam->retval = ntohl (mp->retval);
1148   vam->result_ready = 1;
1149 }
1150
1151 static void vl_api_get_node_index_reply_t_handler
1152   (vl_api_get_node_index_reply_t * mp)
1153 {
1154   vat_main_t *vam = &vat_main;
1155   i32 retval = ntohl (mp->retval);
1156   if (vam->async_mode)
1157     {
1158       vam->async_errors += (retval < 0);
1159     }
1160   else
1161     {
1162       vam->retval = retval;
1163       if (retval == 0)
1164         errmsg ("node index %d", ntohl (mp->node_index));
1165       vam->result_ready = 1;
1166     }
1167 }
1168
1169 static void vl_api_get_node_index_reply_t_handler_json
1170   (vl_api_get_node_index_reply_t * mp)
1171 {
1172   vat_main_t *vam = &vat_main;
1173   vat_json_node_t node;
1174
1175   vat_json_init_object (&node);
1176   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1177   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1178
1179   vat_json_print (vam->ofp, &node);
1180   vat_json_free (&node);
1181
1182   vam->retval = ntohl (mp->retval);
1183   vam->result_ready = 1;
1184 }
1185
1186 static void vl_api_get_next_index_reply_t_handler
1187   (vl_api_get_next_index_reply_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   i32 retval = ntohl (mp->retval);
1191   if (vam->async_mode)
1192     {
1193       vam->async_errors += (retval < 0);
1194     }
1195   else
1196     {
1197       vam->retval = retval;
1198       if (retval == 0)
1199         errmsg ("next node index %d", ntohl (mp->next_index));
1200       vam->result_ready = 1;
1201     }
1202 }
1203
1204 static void vl_api_get_next_index_reply_t_handler_json
1205   (vl_api_get_next_index_reply_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t node;
1209
1210   vat_json_init_object (&node);
1211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1212   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1213
1214   vat_json_print (vam->ofp, &node);
1215   vat_json_free (&node);
1216
1217   vam->retval = ntohl (mp->retval);
1218   vam->result_ready = 1;
1219 }
1220
1221 static void vl_api_add_node_next_reply_t_handler
1222   (vl_api_add_node_next_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   i32 retval = ntohl (mp->retval);
1226   if (vam->async_mode)
1227     {
1228       vam->async_errors += (retval < 0);
1229     }
1230   else
1231     {
1232       vam->retval = retval;
1233       if (retval == 0)
1234         errmsg ("next index %d", ntohl (mp->next_index));
1235       vam->result_ready = 1;
1236     }
1237 }
1238
1239 static void vl_api_add_node_next_reply_t_handler_json
1240   (vl_api_add_node_next_reply_t * mp)
1241 {
1242   vat_main_t *vam = &vat_main;
1243   vat_json_node_t node;
1244
1245   vat_json_init_object (&node);
1246   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1247   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1248
1249   vat_json_print (vam->ofp, &node);
1250   vat_json_free (&node);
1251
1252   vam->retval = ntohl (mp->retval);
1253   vam->result_ready = 1;
1254 }
1255
1256 static void vl_api_show_version_reply_t_handler
1257   (vl_api_show_version_reply_t * mp)
1258 {
1259   vat_main_t *vam = &vat_main;
1260   i32 retval = ntohl (mp->retval);
1261
1262   if (retval >= 0)
1263     {
1264       errmsg ("        program: %s", mp->program);
1265       errmsg ("        version: %s", mp->version);
1266       errmsg ("     build date: %s", mp->build_date);
1267       errmsg ("build directory: %s", mp->build_directory);
1268     }
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_show_version_reply_t_handler_json
1274   (vl_api_show_version_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   vat_json_node_t node;
1278
1279   vat_json_init_object (&node);
1280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1281   vat_json_object_add_string_copy (&node, "program", mp->program);
1282   vat_json_object_add_string_copy (&node, "version", mp->version);
1283   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1284   vat_json_object_add_string_copy (&node, "build_directory",
1285                                    mp->build_directory);
1286
1287   vat_json_print (vam->ofp, &node);
1288   vat_json_free (&node);
1289
1290   vam->retval = ntohl (mp->retval);
1291   vam->result_ready = 1;
1292 }
1293
1294 static void
1295 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1296 {
1297   u32 sw_if_index = ntohl (mp->sw_if_index);
1298   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1299           mp->mac_ip ? "mac/ip binding" : "address resolution",
1300           ntohl (mp->pid), format_ip4_address, &mp->address,
1301           format_ethernet_address, mp->new_mac, sw_if_index);
1302 }
1303
1304 static void
1305 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 static void
1311 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1312 {
1313   u32 sw_if_index = ntohl (mp->sw_if_index);
1314   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1315           mp->mac_ip ? "mac/ip binding" : "address resolution",
1316           ntohl (mp->pid), format_ip6_address, mp->address,
1317           format_ethernet_address, mp->new_mac, sw_if_index);
1318 }
1319
1320 static void
1321 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1322 {
1323   /* JSON output not supported */
1324 }
1325
1326 /*
1327  * Special-case: build the bridge domain table, maintain
1328  * the next bd id vbl.
1329  */
1330 static void vl_api_bridge_domain_details_t_handler
1331   (vl_api_bridge_domain_details_t * mp)
1332 {
1333   vat_main_t *vam = &vat_main;
1334   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1335
1336   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1337          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1338
1339   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1340          ntohl (mp->bd_id), mp->learn, mp->forward,
1341          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1342
1343   if (n_sw_ifs)
1344     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1345 }
1346
1347 static void vl_api_bridge_domain_details_t_handler_json
1348   (vl_api_bridge_domain_details_t * mp)
1349 {
1350   vat_main_t *vam = &vat_main;
1351   vat_json_node_t *node, *array = NULL;
1352
1353   if (VAT_JSON_ARRAY != vam->json_tree.type)
1354     {
1355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1356       vat_json_init_array (&vam->json_tree);
1357     }
1358   node = vat_json_array_add (&vam->json_tree);
1359
1360   vat_json_init_object (node);
1361   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1362   vat_json_object_add_uint (node, "flood", mp->flood);
1363   vat_json_object_add_uint (node, "forward", mp->forward);
1364   vat_json_object_add_uint (node, "learn", mp->learn);
1365   vat_json_object_add_uint (node, "bvi_sw_if_index",
1366                             ntohl (mp->bvi_sw_if_index));
1367   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1368   array = vat_json_object_add (node, "sw_if");
1369   vat_json_init_array (array);
1370 }
1371
1372 /*
1373  * Special-case: build the bridge domain sw if table.
1374  */
1375 static void vl_api_bridge_domain_sw_if_details_t_handler
1376   (vl_api_bridge_domain_sw_if_details_t * mp)
1377 {
1378   vat_main_t *vam = &vat_main;
1379   hash_pair_t *p;
1380   u8 *sw_if_name = 0;
1381   u32 sw_if_index;
1382
1383   sw_if_index = ntohl (mp->sw_if_index);
1384   /* *INDENT-OFF* */
1385   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1386   ({
1387     if ((u32) p->value[0] == sw_if_index)
1388       {
1389         sw_if_name = (u8 *)(p->key);
1390         break;
1391       }
1392   }));
1393   /* *INDENT-ON* */
1394
1395   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1396          mp->shg, sw_if_name ? (char *) sw_if_name :
1397          "sw_if_index not found!");
1398 }
1399
1400 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1401   (vl_api_bridge_domain_sw_if_details_t * mp)
1402 {
1403   vat_main_t *vam = &vat_main;
1404   vat_json_node_t *node = NULL;
1405   uword last_index = 0;
1406
1407   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1408   ASSERT (vec_len (vam->json_tree.array) >= 1);
1409   last_index = vec_len (vam->json_tree.array) - 1;
1410   node = &vam->json_tree.array[last_index];
1411   node = vat_json_object_get_element (node, "sw_if");
1412   ASSERT (NULL != node);
1413   node = vat_json_array_add (node);
1414
1415   vat_json_init_object (node);
1416   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1418   vat_json_object_add_uint (node, "shg", mp->shg);
1419 }
1420
1421 static void vl_api_control_ping_reply_t_handler
1422   (vl_api_control_ping_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   i32 retval = ntohl (mp->retval);
1426   if (vam->async_mode)
1427     {
1428       vam->async_errors += (retval < 0);
1429     }
1430   else
1431     {
1432       vam->retval = retval;
1433       vam->result_ready = 1;
1434     }
1435 }
1436
1437 static void vl_api_control_ping_reply_t_handler_json
1438   (vl_api_control_ping_reply_t * mp)
1439 {
1440   vat_main_t *vam = &vat_main;
1441   i32 retval = ntohl (mp->retval);
1442
1443   if (VAT_JSON_NONE != vam->json_tree.type)
1444     {
1445       vat_json_print (vam->ofp, &vam->json_tree);
1446       vat_json_free (&vam->json_tree);
1447       vam->json_tree.type = VAT_JSON_NONE;
1448     }
1449   else
1450     {
1451       /* just print [] */
1452       vat_json_init_array (&vam->json_tree);
1453       vat_json_print (vam->ofp, &vam->json_tree);
1454       vam->json_tree.type = VAT_JSON_NONE;
1455     }
1456
1457   vam->retval = retval;
1458   vam->result_ready = 1;
1459 }
1460
1461 static void
1462 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1463 {
1464   vat_main_t *vam = &vat_main;
1465   i32 retval = ntohl (mp->retval);
1466   if (vam->async_mode)
1467     {
1468       vam->async_errors += (retval < 0);
1469     }
1470   else
1471     {
1472       vam->retval = retval;
1473       vam->result_ready = 1;
1474     }
1475 }
1476
1477 static void vl_api_l2_flags_reply_t_handler_json
1478   (vl_api_l2_flags_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   vat_json_node_t node;
1482
1483   vat_json_init_object (&node);
1484   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1485   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1486                             ntohl (mp->resulting_feature_bitmap));
1487
1488   vat_json_print (vam->ofp, &node);
1489   vat_json_free (&node);
1490
1491   vam->retval = ntohl (mp->retval);
1492   vam->result_ready = 1;
1493 }
1494
1495 static void vl_api_bridge_flags_reply_t_handler
1496   (vl_api_bridge_flags_reply_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   i32 retval = ntohl (mp->retval);
1500   if (vam->async_mode)
1501     {
1502       vam->async_errors += (retval < 0);
1503     }
1504   else
1505     {
1506       vam->retval = retval;
1507       vam->result_ready = 1;
1508     }
1509 }
1510
1511 static void vl_api_bridge_flags_reply_t_handler_json
1512   (vl_api_bridge_flags_reply_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t node;
1516
1517   vat_json_init_object (&node);
1518   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1519   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1520                             ntohl (mp->resulting_feature_bitmap));
1521
1522   vat_json_print (vam->ofp, &node);
1523   vat_json_free (&node);
1524
1525   vam->retval = ntohl (mp->retval);
1526   vam->result_ready = 1;
1527 }
1528
1529 static void vl_api_tap_connect_reply_t_handler
1530   (vl_api_tap_connect_reply_t * mp)
1531 {
1532   vat_main_t *vam = &vat_main;
1533   i32 retval = ntohl (mp->retval);
1534   if (vam->async_mode)
1535     {
1536       vam->async_errors += (retval < 0);
1537     }
1538   else
1539     {
1540       vam->retval = retval;
1541       vam->sw_if_index = ntohl (mp->sw_if_index);
1542       vam->result_ready = 1;
1543     }
1544
1545 }
1546
1547 static void vl_api_tap_connect_reply_t_handler_json
1548   (vl_api_tap_connect_reply_t * mp)
1549 {
1550   vat_main_t *vam = &vat_main;
1551   vat_json_node_t node;
1552
1553   vat_json_init_object (&node);
1554   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1555   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1556
1557   vat_json_print (vam->ofp, &node);
1558   vat_json_free (&node);
1559
1560   vam->retval = ntohl (mp->retval);
1561   vam->result_ready = 1;
1562
1563 }
1564
1565 static void
1566 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1567 {
1568   vat_main_t *vam = &vat_main;
1569   i32 retval = ntohl (mp->retval);
1570   if (vam->async_mode)
1571     {
1572       vam->async_errors += (retval < 0);
1573     }
1574   else
1575     {
1576       vam->retval = retval;
1577       vam->sw_if_index = ntohl (mp->sw_if_index);
1578       vam->result_ready = 1;
1579     }
1580 }
1581
1582 static void vl_api_tap_modify_reply_t_handler_json
1583   (vl_api_tap_modify_reply_t * mp)
1584 {
1585   vat_main_t *vam = &vat_main;
1586   vat_json_node_t node;
1587
1588   vat_json_init_object (&node);
1589   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1590   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1591
1592   vat_json_print (vam->ofp, &node);
1593   vat_json_free (&node);
1594
1595   vam->retval = ntohl (mp->retval);
1596   vam->result_ready = 1;
1597 }
1598
1599 static void
1600 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1601 {
1602   vat_main_t *vam = &vat_main;
1603   i32 retval = ntohl (mp->retval);
1604   if (vam->async_mode)
1605     {
1606       vam->async_errors += (retval < 0);
1607     }
1608   else
1609     {
1610       vam->retval = retval;
1611       vam->result_ready = 1;
1612     }
1613 }
1614
1615 static void vl_api_tap_delete_reply_t_handler_json
1616   (vl_api_tap_delete_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   vat_json_node_t node;
1620
1621   vat_json_init_object (&node);
1622   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1623
1624   vat_json_print (vam->ofp, &node);
1625   vat_json_free (&node);
1626
1627   vam->retval = ntohl (mp->retval);
1628   vam->result_ready = 1;
1629 }
1630
1631 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1632   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1648   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1656                             ntohl (mp->sw_if_index));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1666   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->sw_if_index = ntohl (mp->sw_if_index);
1678       vam->result_ready = 1;
1679     }
1680 }
1681
1682 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1683   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1684 {
1685   vat_main_t *vam = &vat_main;
1686   vat_json_node_t node;
1687
1688   vat_json_init_object (&node);
1689   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1690   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1691
1692   vat_json_print (vam->ofp, &node);
1693   vat_json_free (&node);
1694
1695   vam->retval = ntohl (mp->retval);
1696   vam->result_ready = 1;
1697 }
1698
1699
1700 static void vl_api_one_add_del_locator_set_reply_t_handler
1701   (vl_api_one_add_del_locator_set_reply_t * mp)
1702 {
1703   vat_main_t *vam = &vat_main;
1704   i32 retval = ntohl (mp->retval);
1705   if (vam->async_mode)
1706     {
1707       vam->async_errors += (retval < 0);
1708     }
1709   else
1710     {
1711       vam->retval = retval;
1712       vam->result_ready = 1;
1713     }
1714 }
1715
1716 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1717   (vl_api_one_add_del_locator_set_reply_t * mp)
1718 {
1719   vat_main_t *vam = &vat_main;
1720   vat_json_node_t node;
1721
1722   vat_json_init_object (&node);
1723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1724   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1725
1726   vat_json_print (vam->ofp, &node);
1727   vat_json_free (&node);
1728
1729   vam->retval = ntohl (mp->retval);
1730   vam->result_ready = 1;
1731 }
1732
1733 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1734   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->sw_if_index = ntohl (mp->sw_if_index);
1746       vam->result_ready = 1;
1747     }
1748 }
1749
1750 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1751   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1752 {
1753   vat_main_t *vam = &vat_main;
1754   vat_json_node_t node;
1755
1756   vat_json_init_object (&node);
1757   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1758   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765 }
1766
1767 static void vl_api_gre_add_del_tunnel_reply_t_handler
1768   (vl_api_gre_add_del_tunnel_reply_t * mp)
1769 {
1770   vat_main_t *vam = &vat_main;
1771   i32 retval = ntohl (mp->retval);
1772   if (vam->async_mode)
1773     {
1774       vam->async_errors += (retval < 0);
1775     }
1776   else
1777     {
1778       vam->retval = retval;
1779       vam->sw_if_index = ntohl (mp->sw_if_index);
1780       vam->result_ready = 1;
1781     }
1782 }
1783
1784 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1785   (vl_api_gre_add_del_tunnel_reply_t * mp)
1786 {
1787   vat_main_t *vam = &vat_main;
1788   vat_json_node_t node;
1789
1790   vat_json_init_object (&node);
1791   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1792   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1793
1794   vat_json_print (vam->ofp, &node);
1795   vat_json_free (&node);
1796
1797   vam->retval = ntohl (mp->retval);
1798   vam->result_ready = 1;
1799 }
1800
1801 static void vl_api_create_vhost_user_if_reply_t_handler
1802   (vl_api_create_vhost_user_if_reply_t * mp)
1803 {
1804   vat_main_t *vam = &vat_main;
1805   i32 retval = ntohl (mp->retval);
1806   if (vam->async_mode)
1807     {
1808       vam->async_errors += (retval < 0);
1809     }
1810   else
1811     {
1812       vam->retval = retval;
1813       vam->sw_if_index = ntohl (mp->sw_if_index);
1814       vam->result_ready = 1;
1815     }
1816 }
1817
1818 static void vl_api_create_vhost_user_if_reply_t_handler_json
1819   (vl_api_create_vhost_user_if_reply_t * mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822   vat_json_node_t node;
1823
1824   vat_json_init_object (&node);
1825   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1826   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1827
1828   vat_json_print (vam->ofp, &node);
1829   vat_json_free (&node);
1830
1831   vam->retval = ntohl (mp->retval);
1832   vam->result_ready = 1;
1833 }
1834
1835 static void vl_api_ip_address_details_t_handler
1836   (vl_api_ip_address_details_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   static ip_address_details_t empty_ip_address_details = { {0} };
1840   ip_address_details_t *address = NULL;
1841   ip_details_t *current_ip_details = NULL;
1842   ip_details_t *details = NULL;
1843
1844   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1845
1846   if (!details || vam->current_sw_if_index >= vec_len (details)
1847       || !details[vam->current_sw_if_index].present)
1848     {
1849       errmsg ("ip address details arrived but not stored");
1850       errmsg ("ip_dump should be called first");
1851       return;
1852     }
1853
1854   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1855
1856 #define addresses (current_ip_details->addr)
1857
1858   vec_validate_init_empty (addresses, vec_len (addresses),
1859                            empty_ip_address_details);
1860
1861   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1862
1863   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1864   address->prefix_length = mp->prefix_length;
1865 #undef addresses
1866 }
1867
1868 static void vl_api_ip_address_details_t_handler_json
1869   (vl_api_ip_address_details_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   vat_json_node_t *node = NULL;
1873   struct in6_addr ip6;
1874   struct in_addr ip4;
1875
1876   if (VAT_JSON_ARRAY != vam->json_tree.type)
1877     {
1878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1879       vat_json_init_array (&vam->json_tree);
1880     }
1881   node = vat_json_array_add (&vam->json_tree);
1882
1883   vat_json_init_object (node);
1884   if (vam->is_ipv6)
1885     {
1886       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1887       vat_json_object_add_ip6 (node, "ip", ip6);
1888     }
1889   else
1890     {
1891       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1892       vat_json_object_add_ip4 (node, "ip", ip4);
1893     }
1894   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1895 }
1896
1897 static void
1898 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   static ip_details_t empty_ip_details = { 0 };
1902   ip_details_t *ip = NULL;
1903   u32 sw_if_index = ~0;
1904
1905   sw_if_index = ntohl (mp->sw_if_index);
1906
1907   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1908                            sw_if_index, empty_ip_details);
1909
1910   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1911                          sw_if_index);
1912
1913   ip->present = 1;
1914 }
1915
1916 static void
1917 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920
1921   if (VAT_JSON_ARRAY != vam->json_tree.type)
1922     {
1923       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1924       vat_json_init_array (&vam->json_tree);
1925     }
1926   vat_json_array_add_uint (&vam->json_tree,
1927                            clib_net_to_host_u32 (mp->sw_if_index));
1928 }
1929
1930 static void vl_api_map_domain_details_t_handler_json
1931   (vl_api_map_domain_details_t * mp)
1932 {
1933   vat_json_node_t *node = NULL;
1934   vat_main_t *vam = &vat_main;
1935   struct in6_addr ip6;
1936   struct in_addr ip4;
1937
1938   if (VAT_JSON_ARRAY != vam->json_tree.type)
1939     {
1940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1941       vat_json_init_array (&vam->json_tree);
1942     }
1943
1944   node = vat_json_array_add (&vam->json_tree);
1945   vat_json_init_object (node);
1946
1947   vat_json_object_add_uint (node, "domain_index",
1948                             clib_net_to_host_u32 (mp->domain_index));
1949   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1950   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1951   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1952   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1953   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1954   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1955   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1956   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1957   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1958   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1959   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1960   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1961   vat_json_object_add_uint (node, "flags", mp->flags);
1962   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1963   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1964 }
1965
1966 static void vl_api_map_domain_details_t_handler
1967   (vl_api_map_domain_details_t * mp)
1968 {
1969   vat_main_t *vam = &vat_main;
1970
1971   if (mp->is_translation)
1972     {
1973       print (vam->ofp,
1974              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1975              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1976              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1977              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1978              clib_net_to_host_u32 (mp->domain_index));
1979     }
1980   else
1981     {
1982       print (vam->ofp,
1983              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1984              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1985              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1986              format_ip6_address, mp->ip6_src,
1987              clib_net_to_host_u32 (mp->domain_index));
1988     }
1989   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1990          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1991          mp->is_translation ? "map-t" : "");
1992 }
1993
1994 static void vl_api_map_rule_details_t_handler_json
1995   (vl_api_map_rule_details_t * mp)
1996 {
1997   struct in6_addr ip6;
1998   vat_json_node_t *node = NULL;
1999   vat_main_t *vam = &vat_main;
2000
2001   if (VAT_JSON_ARRAY != vam->json_tree.type)
2002     {
2003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2004       vat_json_init_array (&vam->json_tree);
2005     }
2006
2007   node = vat_json_array_add (&vam->json_tree);
2008   vat_json_init_object (node);
2009
2010   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2011   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2012   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2013 }
2014
2015 static void
2016 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2017 {
2018   vat_main_t *vam = &vat_main;
2019   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2020          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2021 }
2022
2023 static void
2024 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2025 {
2026   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2027           "router_addr %U host_mac %U",
2028           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2029           format_ip4_address, &mp->host_address,
2030           format_ip4_address, &mp->router_address,
2031           format_ethernet_address, mp->host_mac);
2032 }
2033
2034 static void vl_api_dhcp_compl_event_t_handler_json
2035   (vl_api_dhcp_compl_event_t * mp)
2036 {
2037   /* JSON output not supported */
2038 }
2039
2040 static void
2041 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2042                               u32 counter)
2043 {
2044   vat_main_t *vam = &vat_main;
2045   static u64 default_counter = 0;
2046
2047   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2048                            NULL);
2049   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2050                            sw_if_index, default_counter);
2051   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2052 }
2053
2054 static void
2055 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2056                                 interface_counter_t counter)
2057 {
2058   vat_main_t *vam = &vat_main;
2059   static interface_counter_t default_counter = { 0, };
2060
2061   vec_validate_init_empty (vam->combined_interface_counters,
2062                            vnet_counter_type, NULL);
2063   vec_validate_init_empty (vam->combined_interface_counters
2064                            [vnet_counter_type], sw_if_index, default_counter);
2065   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2066 }
2067
2068 static void vl_api_vnet_interface_counters_t_handler
2069   (vl_api_vnet_interface_counters_t * mp)
2070 {
2071   /* not supported */
2072 }
2073
2074 static void vl_api_vnet_interface_counters_t_handler_json
2075   (vl_api_vnet_interface_counters_t * mp)
2076 {
2077   interface_counter_t counter;
2078   vlib_counter_t *v;
2079   u64 *v_packets;
2080   u64 packets;
2081   u32 count;
2082   u32 first_sw_if_index;
2083   int i;
2084
2085   count = ntohl (mp->count);
2086   first_sw_if_index = ntohl (mp->first_sw_if_index);
2087
2088   if (!mp->is_combined)
2089     {
2090       v_packets = (u64 *) & mp->data;
2091       for (i = 0; i < count; i++)
2092         {
2093           packets =
2094             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2095           set_simple_interface_counter (mp->vnet_counter_type,
2096                                         first_sw_if_index + i, packets);
2097           v_packets++;
2098         }
2099     }
2100   else
2101     {
2102       v = (vlib_counter_t *) & mp->data;
2103       for (i = 0; i < count; i++)
2104         {
2105           counter.packets =
2106             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2107           counter.bytes =
2108             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2109           set_combined_interface_counter (mp->vnet_counter_type,
2110                                           first_sw_if_index + i, counter);
2111           v++;
2112         }
2113     }
2114 }
2115
2116 static u32
2117 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2118 {
2119   vat_main_t *vam = &vat_main;
2120   u32 i;
2121
2122   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2123     {
2124       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2125         {
2126           return i;
2127         }
2128     }
2129   return ~0;
2130 }
2131
2132 static u32
2133 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2134 {
2135   vat_main_t *vam = &vat_main;
2136   u32 i;
2137
2138   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2139     {
2140       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2141         {
2142           return i;
2143         }
2144     }
2145   return ~0;
2146 }
2147
2148 static void vl_api_vnet_ip4_fib_counters_t_handler
2149   (vl_api_vnet_ip4_fib_counters_t * mp)
2150 {
2151   /* not supported */
2152 }
2153
2154 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2155   (vl_api_vnet_ip4_fib_counters_t * mp)
2156 {
2157   vat_main_t *vam = &vat_main;
2158   vl_api_ip4_fib_counter_t *v;
2159   ip4_fib_counter_t *counter;
2160   struct in_addr ip4;
2161   u32 vrf_id;
2162   u32 vrf_index;
2163   u32 count;
2164   int i;
2165
2166   vrf_id = ntohl (mp->vrf_id);
2167   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2168   if (~0 == vrf_index)
2169     {
2170       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2171       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2172       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2173       vec_validate (vam->ip4_fib_counters, vrf_index);
2174       vam->ip4_fib_counters[vrf_index] = NULL;
2175     }
2176
2177   vec_free (vam->ip4_fib_counters[vrf_index]);
2178   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2179   count = ntohl (mp->count);
2180   for (i = 0; i < count; i++)
2181     {
2182       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2183       counter = &vam->ip4_fib_counters[vrf_index][i];
2184       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2185       counter->address = ip4;
2186       counter->address_length = v->address_length;
2187       counter->packets = clib_net_to_host_u64 (v->packets);
2188       counter->bytes = clib_net_to_host_u64 (v->bytes);
2189       v++;
2190     }
2191 }
2192
2193 static void vl_api_vnet_ip4_nbr_counters_t_handler
2194   (vl_api_vnet_ip4_nbr_counters_t * mp)
2195 {
2196   /* not supported */
2197 }
2198
2199 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2200   (vl_api_vnet_ip4_nbr_counters_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   vl_api_ip4_nbr_counter_t *v;
2204   ip4_nbr_counter_t *counter;
2205   u32 sw_if_index;
2206   u32 count;
2207   int i;
2208
2209   sw_if_index = ntohl (mp->sw_if_index);
2210   count = ntohl (mp->count);
2211   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2212
2213   if (mp->begin)
2214     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2215
2216   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2217   for (i = 0; i < count; i++)
2218     {
2219       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2220       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2221       counter->address.s_addr = v->address;
2222       counter->packets = clib_net_to_host_u64 (v->packets);
2223       counter->bytes = clib_net_to_host_u64 (v->bytes);
2224       counter->linkt = v->link_type;
2225       v++;
2226     }
2227 }
2228
2229 static void vl_api_vnet_ip6_fib_counters_t_handler
2230   (vl_api_vnet_ip6_fib_counters_t * mp)
2231 {
2232   /* not supported */
2233 }
2234
2235 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2236   (vl_api_vnet_ip6_fib_counters_t * mp)
2237 {
2238   vat_main_t *vam = &vat_main;
2239   vl_api_ip6_fib_counter_t *v;
2240   ip6_fib_counter_t *counter;
2241   struct in6_addr ip6;
2242   u32 vrf_id;
2243   u32 vrf_index;
2244   u32 count;
2245   int i;
2246
2247   vrf_id = ntohl (mp->vrf_id);
2248   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2249   if (~0 == vrf_index)
2250     {
2251       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2252       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2253       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2254       vec_validate (vam->ip6_fib_counters, vrf_index);
2255       vam->ip6_fib_counters[vrf_index] = NULL;
2256     }
2257
2258   vec_free (vam->ip6_fib_counters[vrf_index]);
2259   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2260   count = ntohl (mp->count);
2261   for (i = 0; i < count; i++)
2262     {
2263       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2264       counter = &vam->ip6_fib_counters[vrf_index][i];
2265       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2266       counter->address = ip6;
2267       counter->address_length = v->address_length;
2268       counter->packets = clib_net_to_host_u64 (v->packets);
2269       counter->bytes = clib_net_to_host_u64 (v->bytes);
2270       v++;
2271     }
2272 }
2273
2274 static void vl_api_vnet_ip6_nbr_counters_t_handler
2275   (vl_api_vnet_ip6_nbr_counters_t * mp)
2276 {
2277   /* not supported */
2278 }
2279
2280 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2281   (vl_api_vnet_ip6_nbr_counters_t * mp)
2282 {
2283   vat_main_t *vam = &vat_main;
2284   vl_api_ip6_nbr_counter_t *v;
2285   ip6_nbr_counter_t *counter;
2286   struct in6_addr ip6;
2287   u32 sw_if_index;
2288   u32 count;
2289   int i;
2290
2291   sw_if_index = ntohl (mp->sw_if_index);
2292   count = ntohl (mp->count);
2293   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2294
2295   if (mp->begin)
2296     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2297
2298   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2299   for (i = 0; i < count; i++)
2300     {
2301       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2302       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2303       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2304       counter->address = ip6;
2305       counter->packets = clib_net_to_host_u64 (v->packets);
2306       counter->bytes = clib_net_to_host_u64 (v->bytes);
2307       v++;
2308     }
2309 }
2310
2311 static void vl_api_get_first_msg_id_reply_t_handler
2312   (vl_api_get_first_msg_id_reply_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   i32 retval = ntohl (mp->retval);
2316
2317   if (vam->async_mode)
2318     {
2319       vam->async_errors += (retval < 0);
2320     }
2321   else
2322     {
2323       vam->retval = retval;
2324       vam->result_ready = 1;
2325     }
2326   if (retval >= 0)
2327     {
2328       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2329     }
2330 }
2331
2332 static void vl_api_get_first_msg_id_reply_t_handler_json
2333   (vl_api_get_first_msg_id_reply_t * mp)
2334 {
2335   vat_main_t *vam = &vat_main;
2336   vat_json_node_t node;
2337
2338   vat_json_init_object (&node);
2339   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2340   vat_json_object_add_uint (&node, "first_msg_id",
2341                             (uint) ntohs (mp->first_msg_id));
2342
2343   vat_json_print (vam->ofp, &node);
2344   vat_json_free (&node);
2345
2346   vam->retval = ntohl (mp->retval);
2347   vam->result_ready = 1;
2348 }
2349
2350 static void vl_api_get_node_graph_reply_t_handler
2351   (vl_api_get_node_graph_reply_t * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   api_main_t *am = &api_main;
2355   i32 retval = ntohl (mp->retval);
2356   u8 *pvt_copy, *reply;
2357   void *oldheap;
2358   vlib_node_t *node;
2359   int i;
2360
2361   if (vam->async_mode)
2362     {
2363       vam->async_errors += (retval < 0);
2364     }
2365   else
2366     {
2367       vam->retval = retval;
2368       vam->result_ready = 1;
2369     }
2370
2371   /* "Should never happen..." */
2372   if (retval != 0)
2373     return;
2374
2375   reply = (u8 *) (mp->reply_in_shmem);
2376   pvt_copy = vec_dup (reply);
2377
2378   /* Toss the shared-memory original... */
2379   pthread_mutex_lock (&am->vlib_rp->mutex);
2380   oldheap = svm_push_data_heap (am->vlib_rp);
2381
2382   vec_free (reply);
2383
2384   svm_pop_heap (oldheap);
2385   pthread_mutex_unlock (&am->vlib_rp->mutex);
2386
2387   if (vam->graph_nodes)
2388     {
2389       hash_free (vam->graph_node_index_by_name);
2390
2391       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2392         {
2393           node = vam->graph_nodes[i];
2394           vec_free (node->name);
2395           vec_free (node->next_nodes);
2396           vec_free (node);
2397         }
2398       vec_free (vam->graph_nodes);
2399     }
2400
2401   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2402   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2403   vec_free (pvt_copy);
2404
2405   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2406     {
2407       node = vam->graph_nodes[i];
2408       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2409     }
2410 }
2411
2412 static void vl_api_get_node_graph_reply_t_handler_json
2413   (vl_api_get_node_graph_reply_t * mp)
2414 {
2415   vat_main_t *vam = &vat_main;
2416   api_main_t *am = &api_main;
2417   void *oldheap;
2418   vat_json_node_t node;
2419   u8 *reply;
2420
2421   /* $$$$ make this real? */
2422   vat_json_init_object (&node);
2423   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2424   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2425
2426   reply = (u8 *) (mp->reply_in_shmem);
2427
2428   /* Toss the shared-memory original... */
2429   pthread_mutex_lock (&am->vlib_rp->mutex);
2430   oldheap = svm_push_data_heap (am->vlib_rp);
2431
2432   vec_free (reply);
2433
2434   svm_pop_heap (oldheap);
2435   pthread_mutex_unlock (&am->vlib_rp->mutex);
2436
2437   vat_json_print (vam->ofp, &node);
2438   vat_json_free (&node);
2439
2440   vam->retval = ntohl (mp->retval);
2441   vam->result_ready = 1;
2442 }
2443
2444 static void
2445 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2446 {
2447   vat_main_t *vam = &vat_main;
2448   u8 *s = 0;
2449
2450   if (mp->local)
2451     {
2452       s = format (s, "%=16d%=16d%=16d",
2453                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2454     }
2455   else
2456     {
2457       s = format (s, "%=16U%=16d%=16d",
2458                   mp->is_ipv6 ? format_ip6_address :
2459                   format_ip4_address,
2460                   mp->ip_address, mp->priority, mp->weight);
2461     }
2462
2463   print (vam->ofp, "%v", s);
2464   vec_free (s);
2465 }
2466
2467 static void
2468 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2469 {
2470   vat_main_t *vam = &vat_main;
2471   vat_json_node_t *node = NULL;
2472   struct in6_addr ip6;
2473   struct in_addr ip4;
2474
2475   if (VAT_JSON_ARRAY != vam->json_tree.type)
2476     {
2477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2478       vat_json_init_array (&vam->json_tree);
2479     }
2480   node = vat_json_array_add (&vam->json_tree);
2481   vat_json_init_object (node);
2482
2483   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2484   vat_json_object_add_uint (node, "priority", mp->priority);
2485   vat_json_object_add_uint (node, "weight", mp->weight);
2486
2487   if (mp->local)
2488     vat_json_object_add_uint (node, "sw_if_index",
2489                               clib_net_to_host_u32 (mp->sw_if_index));
2490   else
2491     {
2492       if (mp->is_ipv6)
2493         {
2494           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2495           vat_json_object_add_ip6 (node, "address", ip6);
2496         }
2497       else
2498         {
2499           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2500           vat_json_object_add_ip4 (node, "address", ip4);
2501         }
2502     }
2503 }
2504
2505 static void
2506 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2507                                           mp)
2508 {
2509   vat_main_t *vam = &vat_main;
2510   u8 *ls_name = 0;
2511
2512   ls_name = format (0, "%s", mp->ls_name);
2513
2514   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2515          ls_name);
2516   vec_free (ls_name);
2517 }
2518
2519 static void
2520   vl_api_one_locator_set_details_t_handler_json
2521   (vl_api_one_locator_set_details_t * mp)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   vat_json_node_t *node = 0;
2525   u8 *ls_name = 0;
2526
2527   ls_name = format (0, "%s", mp->ls_name);
2528   vec_add1 (ls_name, 0);
2529
2530   if (VAT_JSON_ARRAY != vam->json_tree.type)
2531     {
2532       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2533       vat_json_init_array (&vam->json_tree);
2534     }
2535   node = vat_json_array_add (&vam->json_tree);
2536
2537   vat_json_init_object (node);
2538   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2539   vat_json_object_add_uint (node, "ls_index",
2540                             clib_net_to_host_u32 (mp->ls_index));
2541   vec_free (ls_name);
2542 }
2543
2544 static u8 *
2545 format_lisp_flat_eid (u8 * s, va_list * args)
2546 {
2547   u32 type = va_arg (*args, u32);
2548   u8 *eid = va_arg (*args, u8 *);
2549   u32 eid_len = va_arg (*args, u32);
2550
2551   switch (type)
2552     {
2553     case 0:
2554       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2555     case 1:
2556       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2557     case 2:
2558       return format (s, "%U", format_ethernet_address, eid);
2559     }
2560   return 0;
2561 }
2562
2563 static u8 *
2564 format_lisp_eid_vat (u8 * s, va_list * args)
2565 {
2566   u32 type = va_arg (*args, u32);
2567   u8 *eid = va_arg (*args, u8 *);
2568   u32 eid_len = va_arg (*args, u32);
2569   u8 *seid = va_arg (*args, u8 *);
2570   u32 seid_len = va_arg (*args, u32);
2571   u32 is_src_dst = va_arg (*args, u32);
2572
2573   if (is_src_dst)
2574     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2575
2576   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2577
2578   return s;
2579 }
2580
2581 static void
2582 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   u8 *s = 0, *eid = 0;
2586
2587   if (~0 == mp->locator_set_index)
2588     s = format (0, "action: %d", mp->action);
2589   else
2590     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2591
2592   eid = format (0, "%U", format_lisp_eid_vat,
2593                 mp->eid_type,
2594                 mp->eid,
2595                 mp->eid_prefix_len,
2596                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2597   vec_add1 (eid, 0);
2598
2599   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2600          clib_net_to_host_u32 (mp->vni),
2601          eid,
2602          mp->is_local ? "local" : "remote",
2603          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2604          clib_net_to_host_u16 (mp->key_id), mp->key);
2605
2606   vec_free (s);
2607   vec_free (eid);
2608 }
2609
2610 static void
2611 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2612                                              * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   vat_json_node_t *node = 0;
2616   u8 *eid = 0;
2617
2618   if (VAT_JSON_ARRAY != vam->json_tree.type)
2619     {
2620       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2621       vat_json_init_array (&vam->json_tree);
2622     }
2623   node = vat_json_array_add (&vam->json_tree);
2624
2625   vat_json_init_object (node);
2626   if (~0 == mp->locator_set_index)
2627     vat_json_object_add_uint (node, "action", mp->action);
2628   else
2629     vat_json_object_add_uint (node, "locator_set_index",
2630                               clib_net_to_host_u32 (mp->locator_set_index));
2631
2632   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2633   eid = format (0, "%U", format_lisp_eid_vat,
2634                 mp->eid_type,
2635                 mp->eid,
2636                 mp->eid_prefix_len,
2637                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2638   vec_add1 (eid, 0);
2639   vat_json_object_add_string_copy (node, "eid", eid);
2640   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2641   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2642   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2643
2644   if (mp->key_id)
2645     {
2646       vat_json_object_add_uint (node, "key_id",
2647                                 clib_net_to_host_u16 (mp->key_id));
2648       vat_json_object_add_string_copy (node, "key", mp->key);
2649     }
2650   vec_free (eid);
2651 }
2652
2653 static void
2654 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2655 {
2656   vat_main_t *vam = &vat_main;
2657   u8 *seid = 0, *deid = 0;
2658   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2659
2660   deid = format (0, "%U", format_lisp_eid_vat,
2661                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2662
2663   seid = format (0, "%U", format_lisp_eid_vat,
2664                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2665
2666   vec_add1 (deid, 0);
2667   vec_add1 (seid, 0);
2668
2669   if (mp->is_ip4)
2670     format_ip_address_fcn = format_ip4_address;
2671   else
2672     format_ip_address_fcn = format_ip6_address;
2673
2674
2675   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2676          clib_net_to_host_u32 (mp->vni),
2677          seid, deid,
2678          format_ip_address_fcn, mp->lloc,
2679          format_ip_address_fcn, mp->rloc,
2680          clib_net_to_host_u32 (mp->pkt_count),
2681          clib_net_to_host_u32 (mp->bytes));
2682
2683   vec_free (deid);
2684   vec_free (seid);
2685 }
2686
2687 static void
2688 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2689 {
2690   struct in6_addr ip6;
2691   struct in_addr ip4;
2692   vat_main_t *vam = &vat_main;
2693   vat_json_node_t *node = 0;
2694   u8 *deid = 0, *seid = 0;
2695
2696   if (VAT_JSON_ARRAY != vam->json_tree.type)
2697     {
2698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2699       vat_json_init_array (&vam->json_tree);
2700     }
2701   node = vat_json_array_add (&vam->json_tree);
2702
2703   vat_json_init_object (node);
2704   deid = format (0, "%U", format_lisp_eid_vat,
2705                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2706
2707   seid = format (0, "%U", format_lisp_eid_vat,
2708                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2709
2710   vec_add1 (deid, 0);
2711   vec_add1 (seid, 0);
2712
2713   vat_json_object_add_string_copy (node, "seid", seid);
2714   vat_json_object_add_string_copy (node, "deid", deid);
2715   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2716
2717   if (mp->is_ip4)
2718     {
2719       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2720       vat_json_object_add_ip4 (node, "lloc", ip4);
2721       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2722       vat_json_object_add_ip4 (node, "rloc", ip4);
2723     }
2724   else
2725     {
2726       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2727       vat_json_object_add_ip6 (node, "lloc", ip6);
2728       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2729       vat_json_object_add_ip6 (node, "rloc", ip6);
2730     }
2731   vat_json_object_add_uint (node, "pkt_count",
2732                             clib_net_to_host_u32 (mp->pkt_count));
2733   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2734
2735   vec_free (deid);
2736   vec_free (seid);
2737 }
2738
2739 static void
2740   vl_api_one_eid_table_map_details_t_handler
2741   (vl_api_one_eid_table_map_details_t * mp)
2742 {
2743   vat_main_t *vam = &vat_main;
2744
2745   u8 *line = format (0, "%=10d%=10d",
2746                      clib_net_to_host_u32 (mp->vni),
2747                      clib_net_to_host_u32 (mp->dp_table));
2748   print (vam->ofp, "%v", line);
2749   vec_free (line);
2750 }
2751
2752 static void
2753   vl_api_one_eid_table_map_details_t_handler_json
2754   (vl_api_one_eid_table_map_details_t * mp)
2755 {
2756   vat_main_t *vam = &vat_main;
2757   vat_json_node_t *node = NULL;
2758
2759   if (VAT_JSON_ARRAY != vam->json_tree.type)
2760     {
2761       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2762       vat_json_init_array (&vam->json_tree);
2763     }
2764   node = vat_json_array_add (&vam->json_tree);
2765   vat_json_init_object (node);
2766   vat_json_object_add_uint (node, "dp_table",
2767                             clib_net_to_host_u32 (mp->dp_table));
2768   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2769 }
2770
2771 static void
2772   vl_api_one_eid_table_vni_details_t_handler
2773   (vl_api_one_eid_table_vni_details_t * mp)
2774 {
2775   vat_main_t *vam = &vat_main;
2776
2777   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2778   print (vam->ofp, "%v", line);
2779   vec_free (line);
2780 }
2781
2782 static void
2783   vl_api_one_eid_table_vni_details_t_handler_json
2784   (vl_api_one_eid_table_vni_details_t * mp)
2785 {
2786   vat_main_t *vam = &vat_main;
2787   vat_json_node_t *node = NULL;
2788
2789   if (VAT_JSON_ARRAY != vam->json_tree.type)
2790     {
2791       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2792       vat_json_init_array (&vam->json_tree);
2793     }
2794   node = vat_json_array_add (&vam->json_tree);
2795   vat_json_init_object (node);
2796   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2797 }
2798
2799 static void
2800   vl_api_show_one_map_register_state_reply_t_handler
2801   (vl_api_show_one_map_register_state_reply_t * mp)
2802 {
2803   vat_main_t *vam = &vat_main;
2804   int retval = clib_net_to_host_u32 (mp->retval);
2805
2806   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2807
2808   vam->retval = retval;
2809   vam->result_ready = 1;
2810 }
2811
2812 static void
2813   vl_api_show_one_map_register_state_reply_t_handler_json
2814   (vl_api_show_one_map_register_state_reply_t * mp)
2815 {
2816   vat_main_t *vam = &vat_main;
2817   vat_json_node_t _node, *node = &_node;
2818   int retval = clib_net_to_host_u32 (mp->retval);
2819
2820   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2821
2822   vat_json_init_object (node);
2823   vat_json_object_add_string_copy (node, "state", s);
2824
2825   vat_json_print (vam->ofp, node);
2826   vat_json_free (node);
2827
2828   vam->retval = retval;
2829   vam->result_ready = 1;
2830   vec_free (s);
2831 }
2832
2833 static void
2834   vl_api_show_one_rloc_probe_state_reply_t_handler
2835   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2836 {
2837   vat_main_t *vam = &vat_main;
2838   int retval = clib_net_to_host_u32 (mp->retval);
2839
2840   if (retval)
2841     goto end;
2842
2843   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2844 end:
2845   vam->retval = retval;
2846   vam->result_ready = 1;
2847 }
2848
2849 static void
2850   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2851   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2852 {
2853   vat_main_t *vam = &vat_main;
2854   vat_json_node_t _node, *node = &_node;
2855   int retval = clib_net_to_host_u32 (mp->retval);
2856
2857   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2858   vat_json_init_object (node);
2859   vat_json_object_add_string_copy (node, "state", s);
2860
2861   vat_json_print (vam->ofp, node);
2862   vat_json_free (node);
2863
2864   vam->retval = retval;
2865   vam->result_ready = 1;
2866   vec_free (s);
2867 }
2868
2869 static void
2870   vl_api_show_one_stats_enable_disable_reply_t_handler
2871   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2872 {
2873   vat_main_t *vam = &vat_main;
2874   int retval = clib_net_to_host_u32 (mp->retval);
2875
2876   if (retval)
2877     goto end;
2878
2879   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2880 end:
2881   vam->retval = retval;
2882   vam->result_ready = 1;
2883 }
2884
2885 static void
2886   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2887   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2888 {
2889   vat_main_t *vam = &vat_main;
2890   vat_json_node_t _node, *node = &_node;
2891   int retval = clib_net_to_host_u32 (mp->retval);
2892
2893   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2894   vat_json_init_object (node);
2895   vat_json_object_add_string_copy (node, "state", s);
2896
2897   vat_json_print (vam->ofp, node);
2898   vat_json_free (node);
2899
2900   vam->retval = retval;
2901   vam->result_ready = 1;
2902   vec_free (s);
2903 }
2904
2905 static void
2906 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2907 {
2908   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2909   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2910 }
2911
2912 static void
2913   gpe_fwd_entries_get_reply_t_net_to_host
2914   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2915 {
2916   u32 i;
2917
2918   mp->count = clib_net_to_host_u32 (mp->count);
2919   for (i = 0; i < mp->count; i++)
2920     {
2921       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2922     }
2923 }
2924
2925 static u8 *
2926 format_gpe_encap_mode (u8 * s, va_list * args)
2927 {
2928   u32 mode = va_arg (*args, u32);
2929
2930   switch (mode)
2931     {
2932     case 0:
2933       return format (s, "lisp");
2934     case 1:
2935       return format (s, "vxlan");
2936     }
2937   return 0;
2938 }
2939
2940 static void
2941   vl_api_gpe_get_encap_mode_reply_t_handler
2942   (vl_api_gpe_get_encap_mode_reply_t * mp)
2943 {
2944   vat_main_t *vam = &vat_main;
2945
2946   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2947   vam->retval = ntohl (mp->retval);
2948   vam->result_ready = 1;
2949 }
2950
2951 static void
2952   vl_api_gpe_get_encap_mode_reply_t_handler_json
2953   (vl_api_gpe_get_encap_mode_reply_t * mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956   vat_json_node_t node;
2957
2958   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2959   vec_add1 (encap_mode, 0);
2960
2961   vat_json_init_object (&node);
2962   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2963
2964   vec_free (encap_mode);
2965   vat_json_print (vam->ofp, &node);
2966   vat_json_free (&node);
2967
2968   vam->retval = ntohl (mp->retval);
2969   vam->result_ready = 1;
2970 }
2971
2972 static void
2973   vl_api_gpe_fwd_entry_path_details_t_handler
2974   (vl_api_gpe_fwd_entry_path_details_t * mp)
2975 {
2976   vat_main_t *vam = &vat_main;
2977   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2978
2979   if (mp->lcl_loc.is_ip4)
2980     format_ip_address_fcn = format_ip4_address;
2981   else
2982     format_ip_address_fcn = format_ip6_address;
2983
2984   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2985          format_ip_address_fcn, &mp->lcl_loc,
2986          format_ip_address_fcn, &mp->rmt_loc);
2987 }
2988
2989 static void
2990 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2991 {
2992   struct in6_addr ip6;
2993   struct in_addr ip4;
2994
2995   if (loc->is_ip4)
2996     {
2997       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2998       vat_json_object_add_ip4 (n, "address", ip4);
2999     }
3000   else
3001     {
3002       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3003       vat_json_object_add_ip6 (n, "address", ip6);
3004     }
3005   vat_json_object_add_uint (n, "weight", loc->weight);
3006 }
3007
3008 static void
3009   vl_api_gpe_fwd_entry_path_details_t_handler_json
3010   (vl_api_gpe_fwd_entry_path_details_t * mp)
3011 {
3012   vat_main_t *vam = &vat_main;
3013   vat_json_node_t *node = NULL;
3014   vat_json_node_t *loc_node;
3015
3016   if (VAT_JSON_ARRAY != vam->json_tree.type)
3017     {
3018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3019       vat_json_init_array (&vam->json_tree);
3020     }
3021   node = vat_json_array_add (&vam->json_tree);
3022   vat_json_init_object (node);
3023
3024   loc_node = vat_json_object_add (node, "local_locator");
3025   vat_json_init_object (loc_node);
3026   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3027
3028   loc_node = vat_json_object_add (node, "remote_locator");
3029   vat_json_init_object (loc_node);
3030   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3031 }
3032
3033 static void
3034   vl_api_gpe_fwd_entries_get_reply_t_handler
3035   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3036 {
3037   vat_main_t *vam = &vat_main;
3038   u32 i;
3039   int retval = clib_net_to_host_u32 (mp->retval);
3040   vl_api_gpe_fwd_entry_t *e;
3041
3042   if (retval)
3043     goto end;
3044
3045   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3046
3047   for (i = 0; i < mp->count; i++)
3048     {
3049       e = &mp->entries[i];
3050       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3051              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3052              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3053     }
3054
3055 end:
3056   vam->retval = retval;
3057   vam->result_ready = 1;
3058 }
3059
3060 static void
3061   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3062   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3063 {
3064   u8 *s = 0;
3065   vat_main_t *vam = &vat_main;
3066   vat_json_node_t *e = 0, root;
3067   u32 i;
3068   int retval = clib_net_to_host_u32 (mp->retval);
3069   vl_api_gpe_fwd_entry_t *fwd;
3070
3071   if (retval)
3072     goto end;
3073
3074   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3075   vat_json_init_array (&root);
3076
3077   for (i = 0; i < mp->count; i++)
3078     {
3079       e = vat_json_array_add (&root);
3080       fwd = &mp->entries[i];
3081
3082       vat_json_init_object (e);
3083       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3084       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3085
3086       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3087                   fwd->leid_prefix_len);
3088       vec_add1 (s, 0);
3089       vat_json_object_add_string_copy (e, "leid", s);
3090       vec_free (s);
3091
3092       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3093                   fwd->reid_prefix_len);
3094       vec_add1 (s, 0);
3095       vat_json_object_add_string_copy (e, "reid", s);
3096       vec_free (s);
3097     }
3098
3099   vat_json_print (vam->ofp, &root);
3100   vat_json_free (&root);
3101
3102 end:
3103   vam->retval = retval;
3104   vam->result_ready = 1;
3105 }
3106
3107 static void
3108   vl_api_one_adjacencies_get_reply_t_handler
3109   (vl_api_one_adjacencies_get_reply_t * mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112   u32 i, n;
3113   int retval = clib_net_to_host_u32 (mp->retval);
3114   vl_api_one_adjacency_t *a;
3115
3116   if (retval)
3117     goto end;
3118
3119   n = clib_net_to_host_u32 (mp->count);
3120
3121   for (i = 0; i < n; i++)
3122     {
3123       a = &mp->adjacencies[i];
3124       print (vam->ofp, "%U %40U",
3125              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3126              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3127     }
3128
3129 end:
3130   vam->retval = retval;
3131   vam->result_ready = 1;
3132 }
3133
3134 static void
3135   vl_api_one_adjacencies_get_reply_t_handler_json
3136   (vl_api_one_adjacencies_get_reply_t * mp)
3137 {
3138   u8 *s = 0;
3139   vat_main_t *vam = &vat_main;
3140   vat_json_node_t *e = 0, root;
3141   u32 i, n;
3142   int retval = clib_net_to_host_u32 (mp->retval);
3143   vl_api_one_adjacency_t *a;
3144
3145   if (retval)
3146     goto end;
3147
3148   n = clib_net_to_host_u32 (mp->count);
3149   vat_json_init_array (&root);
3150
3151   for (i = 0; i < n; i++)
3152     {
3153       e = vat_json_array_add (&root);
3154       a = &mp->adjacencies[i];
3155
3156       vat_json_init_object (e);
3157       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3158                   a->leid_prefix_len);
3159       vec_add1 (s, 0);
3160       vat_json_object_add_string_copy (e, "leid", s);
3161       vec_free (s);
3162
3163       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3164                   a->reid_prefix_len);
3165       vec_add1 (s, 0);
3166       vat_json_object_add_string_copy (e, "reid", s);
3167       vec_free (s);
3168     }
3169
3170   vat_json_print (vam->ofp, &root);
3171   vat_json_free (&root);
3172
3173 end:
3174   vam->retval = retval;
3175   vam->result_ready = 1;
3176 }
3177
3178 static void
3179 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3180 {
3181   vat_main_t *vam = &vat_main;
3182
3183   print (vam->ofp, "%=20U",
3184          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3185          mp->ip_address);
3186 }
3187
3188 static void
3189   vl_api_one_map_server_details_t_handler_json
3190   (vl_api_one_map_server_details_t * mp)
3191 {
3192   vat_main_t *vam = &vat_main;
3193   vat_json_node_t *node = NULL;
3194   struct in6_addr ip6;
3195   struct in_addr ip4;
3196
3197   if (VAT_JSON_ARRAY != vam->json_tree.type)
3198     {
3199       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3200       vat_json_init_array (&vam->json_tree);
3201     }
3202   node = vat_json_array_add (&vam->json_tree);
3203
3204   vat_json_init_object (node);
3205   if (mp->is_ipv6)
3206     {
3207       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3208       vat_json_object_add_ip6 (node, "map-server", ip6);
3209     }
3210   else
3211     {
3212       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3213       vat_json_object_add_ip4 (node, "map-server", ip4);
3214     }
3215 }
3216
3217 static void
3218 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3219                                            * mp)
3220 {
3221   vat_main_t *vam = &vat_main;
3222
3223   print (vam->ofp, "%=20U",
3224          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3225          mp->ip_address);
3226 }
3227
3228 static void
3229   vl_api_one_map_resolver_details_t_handler_json
3230   (vl_api_one_map_resolver_details_t * mp)
3231 {
3232   vat_main_t *vam = &vat_main;
3233   vat_json_node_t *node = NULL;
3234   struct in6_addr ip6;
3235   struct in_addr ip4;
3236
3237   if (VAT_JSON_ARRAY != vam->json_tree.type)
3238     {
3239       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3240       vat_json_init_array (&vam->json_tree);
3241     }
3242   node = vat_json_array_add (&vam->json_tree);
3243
3244   vat_json_init_object (node);
3245   if (mp->is_ipv6)
3246     {
3247       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3248       vat_json_object_add_ip6 (node, "map resolver", ip6);
3249     }
3250   else
3251     {
3252       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3253       vat_json_object_add_ip4 (node, "map resolver", ip4);
3254     }
3255 }
3256
3257 static void
3258 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3259 {
3260   vat_main_t *vam = &vat_main;
3261   i32 retval = ntohl (mp->retval);
3262
3263   if (0 <= retval)
3264     {
3265       print (vam->ofp, "feature: %s\ngpe: %s",
3266              mp->feature_status ? "enabled" : "disabled",
3267              mp->gpe_status ? "enabled" : "disabled");
3268     }
3269
3270   vam->retval = retval;
3271   vam->result_ready = 1;
3272 }
3273
3274 static void
3275   vl_api_show_one_status_reply_t_handler_json
3276   (vl_api_show_one_status_reply_t * mp)
3277 {
3278   vat_main_t *vam = &vat_main;
3279   vat_json_node_t node;
3280   u8 *gpe_status = NULL;
3281   u8 *feature_status = NULL;
3282
3283   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3284   feature_status = format (0, "%s",
3285                            mp->feature_status ? "enabled" : "disabled");
3286   vec_add1 (gpe_status, 0);
3287   vec_add1 (feature_status, 0);
3288
3289   vat_json_init_object (&node);
3290   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3291   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3292
3293   vec_free (gpe_status);
3294   vec_free (feature_status);
3295
3296   vat_json_print (vam->ofp, &node);
3297   vat_json_free (&node);
3298
3299   vam->retval = ntohl (mp->retval);
3300   vam->result_ready = 1;
3301 }
3302
3303 static void
3304   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3305   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3306 {
3307   vat_main_t *vam = &vat_main;
3308   i32 retval = ntohl (mp->retval);
3309
3310   if (retval >= 0)
3311     {
3312       print (vam->ofp, "%=20s", mp->locator_set_name);
3313     }
3314
3315   vam->retval = retval;
3316   vam->result_ready = 1;
3317 }
3318
3319 static void
3320   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3321   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3322 {
3323   vat_main_t *vam = &vat_main;
3324   vat_json_node_t *node = NULL;
3325
3326   if (VAT_JSON_ARRAY != vam->json_tree.type)
3327     {
3328       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3329       vat_json_init_array (&vam->json_tree);
3330     }
3331   node = vat_json_array_add (&vam->json_tree);
3332
3333   vat_json_init_object (node);
3334   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3335
3336   vat_json_print (vam->ofp, node);
3337   vat_json_free (node);
3338
3339   vam->retval = ntohl (mp->retval);
3340   vam->result_ready = 1;
3341 }
3342
3343 static u8 *
3344 format_lisp_map_request_mode (u8 * s, va_list * args)
3345 {
3346   u32 mode = va_arg (*args, u32);
3347
3348   switch (mode)
3349     {
3350     case 0:
3351       return format (0, "dst-only");
3352     case 1:
3353       return format (0, "src-dst");
3354     }
3355   return 0;
3356 }
3357
3358 static void
3359   vl_api_show_one_map_request_mode_reply_t_handler
3360   (vl_api_show_one_map_request_mode_reply_t * mp)
3361 {
3362   vat_main_t *vam = &vat_main;
3363   i32 retval = ntohl (mp->retval);
3364
3365   if (0 <= retval)
3366     {
3367       u32 mode = mp->mode;
3368       print (vam->ofp, "map_request_mode: %U",
3369              format_lisp_map_request_mode, mode);
3370     }
3371
3372   vam->retval = retval;
3373   vam->result_ready = 1;
3374 }
3375
3376 static void
3377   vl_api_show_one_map_request_mode_reply_t_handler_json
3378   (vl_api_show_one_map_request_mode_reply_t * mp)
3379 {
3380   vat_main_t *vam = &vat_main;
3381   vat_json_node_t node;
3382   u8 *s = 0;
3383   u32 mode;
3384
3385   mode = mp->mode;
3386   s = format (0, "%U", format_lisp_map_request_mode, mode);
3387   vec_add1 (s, 0);
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3391   vat_json_print (vam->ofp, &node);
3392   vat_json_free (&node);
3393
3394   vec_free (s);
3395   vam->retval = ntohl (mp->retval);
3396   vam->result_ready = 1;
3397 }
3398
3399 static void
3400   vl_api_show_one_use_petr_reply_t_handler
3401   (vl_api_show_one_use_petr_reply_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404   i32 retval = ntohl (mp->retval);
3405
3406   if (0 <= retval)
3407     {
3408       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3409       if (mp->status)
3410         {
3411           print (vam->ofp, "Proxy-ETR address; %U",
3412                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3413                  mp->address);
3414         }
3415     }
3416
3417   vam->retval = retval;
3418   vam->result_ready = 1;
3419 }
3420
3421 static void
3422   vl_api_show_one_use_petr_reply_t_handler_json
3423   (vl_api_show_one_use_petr_reply_t * mp)
3424 {
3425   vat_main_t *vam = &vat_main;
3426   vat_json_node_t node;
3427   u8 *status = 0;
3428   struct in_addr ip4;
3429   struct in6_addr ip6;
3430
3431   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3432   vec_add1 (status, 0);
3433
3434   vat_json_init_object (&node);
3435   vat_json_object_add_string_copy (&node, "status", status);
3436   if (mp->status)
3437     {
3438       if (mp->is_ip4)
3439         {
3440           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3441           vat_json_object_add_ip6 (&node, "address", ip6);
3442         }
3443       else
3444         {
3445           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3446           vat_json_object_add_ip4 (&node, "address", ip4);
3447         }
3448     }
3449
3450   vec_free (status);
3451
3452   vat_json_print (vam->ofp, &node);
3453   vat_json_free (&node);
3454
3455   vam->retval = ntohl (mp->retval);
3456   vam->result_ready = 1;
3457 }
3458
3459 static void
3460 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3461 {
3462   vat_main_t *vam = &vat_main;
3463   i32 retval = ntohl (mp->retval);
3464
3465   if (0 <= retval)
3466     {
3467       print (vam->ofp, "%-20s%-16s",
3468              mp->status ? "enabled" : "disabled",
3469              mp->status ? (char *) mp->locator_set_name : "");
3470     }
3471
3472   vam->retval = retval;
3473   vam->result_ready = 1;
3474 }
3475
3476 static void
3477 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3478 {
3479   vat_main_t *vam = &vat_main;
3480   vat_json_node_t node;
3481   u8 *status = 0;
3482
3483   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3484   vec_add1 (status, 0);
3485
3486   vat_json_init_object (&node);
3487   vat_json_object_add_string_copy (&node, "status", status);
3488   if (mp->status)
3489     {
3490       vat_json_object_add_string_copy (&node, "locator_set",
3491                                        mp->locator_set_name);
3492     }
3493
3494   vec_free (status);
3495
3496   vat_json_print (vam->ofp, &node);
3497   vat_json_free (&node);
3498
3499   vam->retval = ntohl (mp->retval);
3500   vam->result_ready = 1;
3501 }
3502
3503 static u8 *
3504 format_policer_type (u8 * s, va_list * va)
3505 {
3506   u32 i = va_arg (*va, u32);
3507
3508   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3509     s = format (s, "1r2c");
3510   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3511     s = format (s, "1r3c");
3512   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3513     s = format (s, "2r3c-2698");
3514   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3515     s = format (s, "2r3c-4115");
3516   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3517     s = format (s, "2r3c-mef5cf1");
3518   else
3519     s = format (s, "ILLEGAL");
3520   return s;
3521 }
3522
3523 static u8 *
3524 format_policer_rate_type (u8 * s, va_list * va)
3525 {
3526   u32 i = va_arg (*va, u32);
3527
3528   if (i == SSE2_QOS_RATE_KBPS)
3529     s = format (s, "kbps");
3530   else if (i == SSE2_QOS_RATE_PPS)
3531     s = format (s, "pps");
3532   else
3533     s = format (s, "ILLEGAL");
3534   return s;
3535 }
3536
3537 static u8 *
3538 format_policer_round_type (u8 * s, va_list * va)
3539 {
3540   u32 i = va_arg (*va, u32);
3541
3542   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3543     s = format (s, "closest");
3544   else if (i == SSE2_QOS_ROUND_TO_UP)
3545     s = format (s, "up");
3546   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3547     s = format (s, "down");
3548   else
3549     s = format (s, "ILLEGAL");
3550   return s;
3551 }
3552
3553 static u8 *
3554 format_policer_action_type (u8 * s, va_list * va)
3555 {
3556   u32 i = va_arg (*va, u32);
3557
3558   if (i == SSE2_QOS_ACTION_DROP)
3559     s = format (s, "drop");
3560   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3561     s = format (s, "transmit");
3562   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3563     s = format (s, "mark-and-transmit");
3564   else
3565     s = format (s, "ILLEGAL");
3566   return s;
3567 }
3568
3569 static u8 *
3570 format_dscp (u8 * s, va_list * va)
3571 {
3572   u32 i = va_arg (*va, u32);
3573   char *t = 0;
3574
3575   switch (i)
3576     {
3577 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3578       foreach_vnet_dscp
3579 #undef _
3580     default:
3581       return format (s, "ILLEGAL");
3582     }
3583   s = format (s, "%s", t);
3584   return s;
3585 }
3586
3587 static void
3588 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3589 {
3590   vat_main_t *vam = &vat_main;
3591   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3592
3593   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3594     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3595   else
3596     conform_dscp_str = format (0, "");
3597
3598   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3599     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3600   else
3601     exceed_dscp_str = format (0, "");
3602
3603   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3604     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3605   else
3606     violate_dscp_str = format (0, "");
3607
3608   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3609          "rate type %U, round type %U, %s rate, %s color-aware, "
3610          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3611          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3612          "conform action %U%s, exceed action %U%s, violate action %U%s",
3613          mp->name,
3614          format_policer_type, mp->type,
3615          ntohl (mp->cir),
3616          ntohl (mp->eir),
3617          clib_net_to_host_u64 (mp->cb),
3618          clib_net_to_host_u64 (mp->eb),
3619          format_policer_rate_type, mp->rate_type,
3620          format_policer_round_type, mp->round_type,
3621          mp->single_rate ? "single" : "dual",
3622          mp->color_aware ? "is" : "not",
3623          ntohl (mp->cir_tokens_per_period),
3624          ntohl (mp->pir_tokens_per_period),
3625          ntohl (mp->scale),
3626          ntohl (mp->current_limit),
3627          ntohl (mp->current_bucket),
3628          ntohl (mp->extended_limit),
3629          ntohl (mp->extended_bucket),
3630          clib_net_to_host_u64 (mp->last_update_time),
3631          format_policer_action_type, mp->conform_action_type,
3632          conform_dscp_str,
3633          format_policer_action_type, mp->exceed_action_type,
3634          exceed_dscp_str,
3635          format_policer_action_type, mp->violate_action_type,
3636          violate_dscp_str);
3637
3638   vec_free (conform_dscp_str);
3639   vec_free (exceed_dscp_str);
3640   vec_free (violate_dscp_str);
3641 }
3642
3643 static void vl_api_policer_details_t_handler_json
3644   (vl_api_policer_details_t * mp)
3645 {
3646   vat_main_t *vam = &vat_main;
3647   vat_json_node_t *node;
3648   u8 *rate_type_str, *round_type_str, *type_str;
3649   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3650
3651   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3652   round_type_str =
3653     format (0, "%U", format_policer_round_type, mp->round_type);
3654   type_str = format (0, "%U", format_policer_type, mp->type);
3655   conform_action_str = format (0, "%U", format_policer_action_type,
3656                                mp->conform_action_type);
3657   exceed_action_str = format (0, "%U", format_policer_action_type,
3658                               mp->exceed_action_type);
3659   violate_action_str = format (0, "%U", format_policer_action_type,
3660                                mp->violate_action_type);
3661
3662   if (VAT_JSON_ARRAY != vam->json_tree.type)
3663     {
3664       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3665       vat_json_init_array (&vam->json_tree);
3666     }
3667   node = vat_json_array_add (&vam->json_tree);
3668
3669   vat_json_init_object (node);
3670   vat_json_object_add_string_copy (node, "name", mp->name);
3671   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3672   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3673   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3674   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3675   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3676   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3677   vat_json_object_add_string_copy (node, "type", type_str);
3678   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3679   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3680   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3681   vat_json_object_add_uint (node, "cir_tokens_per_period",
3682                             ntohl (mp->cir_tokens_per_period));
3683   vat_json_object_add_uint (node, "eir_tokens_per_period",
3684                             ntohl (mp->pir_tokens_per_period));
3685   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3686   vat_json_object_add_uint (node, "current_bucket",
3687                             ntohl (mp->current_bucket));
3688   vat_json_object_add_uint (node, "extended_limit",
3689                             ntohl (mp->extended_limit));
3690   vat_json_object_add_uint (node, "extended_bucket",
3691                             ntohl (mp->extended_bucket));
3692   vat_json_object_add_uint (node, "last_update_time",
3693                             ntohl (mp->last_update_time));
3694   vat_json_object_add_string_copy (node, "conform_action",
3695                                    conform_action_str);
3696   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3697     {
3698       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3699       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3700       vec_free (dscp_str);
3701     }
3702   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3703   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3704     {
3705       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3706       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3707       vec_free (dscp_str);
3708     }
3709   vat_json_object_add_string_copy (node, "violate_action",
3710                                    violate_action_str);
3711   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3712     {
3713       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3714       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3715       vec_free (dscp_str);
3716     }
3717
3718   vec_free (rate_type_str);
3719   vec_free (round_type_str);
3720   vec_free (type_str);
3721   vec_free (conform_action_str);
3722   vec_free (exceed_action_str);
3723   vec_free (violate_action_str);
3724 }
3725
3726 static void
3727 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3728                                            mp)
3729 {
3730   vat_main_t *vam = &vat_main;
3731   int i, count = ntohl (mp->count);
3732
3733   if (count > 0)
3734     print (vam->ofp, "classify table ids (%d) : ", count);
3735   for (i = 0; i < count; i++)
3736     {
3737       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3738       print (vam->ofp, (i < count - 1) ? "," : "");
3739     }
3740   vam->retval = ntohl (mp->retval);
3741   vam->result_ready = 1;
3742 }
3743
3744 static void
3745   vl_api_classify_table_ids_reply_t_handler_json
3746   (vl_api_classify_table_ids_reply_t * mp)
3747 {
3748   vat_main_t *vam = &vat_main;
3749   int i, count = ntohl (mp->count);
3750
3751   if (count > 0)
3752     {
3753       vat_json_node_t node;
3754
3755       vat_json_init_object (&node);
3756       for (i = 0; i < count; i++)
3757         {
3758           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3759         }
3760       vat_json_print (vam->ofp, &node);
3761       vat_json_free (&node);
3762     }
3763   vam->retval = ntohl (mp->retval);
3764   vam->result_ready = 1;
3765 }
3766
3767 static void
3768   vl_api_classify_table_by_interface_reply_t_handler
3769   (vl_api_classify_table_by_interface_reply_t * mp)
3770 {
3771   vat_main_t *vam = &vat_main;
3772   u32 table_id;
3773
3774   table_id = ntohl (mp->l2_table_id);
3775   if (table_id != ~0)
3776     print (vam->ofp, "l2 table id : %d", table_id);
3777   else
3778     print (vam->ofp, "l2 table id : No input ACL tables configured");
3779   table_id = ntohl (mp->ip4_table_id);
3780   if (table_id != ~0)
3781     print (vam->ofp, "ip4 table id : %d", table_id);
3782   else
3783     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3784   table_id = ntohl (mp->ip6_table_id);
3785   if (table_id != ~0)
3786     print (vam->ofp, "ip6 table id : %d", table_id);
3787   else
3788     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3789   vam->retval = ntohl (mp->retval);
3790   vam->result_ready = 1;
3791 }
3792
3793 static void
3794   vl_api_classify_table_by_interface_reply_t_handler_json
3795   (vl_api_classify_table_by_interface_reply_t * mp)
3796 {
3797   vat_main_t *vam = &vat_main;
3798   vat_json_node_t node;
3799
3800   vat_json_init_object (&node);
3801
3802   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3803   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3804   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3805
3806   vat_json_print (vam->ofp, &node);
3807   vat_json_free (&node);
3808
3809   vam->retval = ntohl (mp->retval);
3810   vam->result_ready = 1;
3811 }
3812
3813 static void vl_api_policer_add_del_reply_t_handler
3814   (vl_api_policer_add_del_reply_t * mp)
3815 {
3816   vat_main_t *vam = &vat_main;
3817   i32 retval = ntohl (mp->retval);
3818   if (vam->async_mode)
3819     {
3820       vam->async_errors += (retval < 0);
3821     }
3822   else
3823     {
3824       vam->retval = retval;
3825       vam->result_ready = 1;
3826       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3827         /*
3828          * Note: this is just barely thread-safe, depends on
3829          * the main thread spinning waiting for an answer...
3830          */
3831         errmsg ("policer index %d", ntohl (mp->policer_index));
3832     }
3833 }
3834
3835 static void vl_api_policer_add_del_reply_t_handler_json
3836   (vl_api_policer_add_del_reply_t * mp)
3837 {
3838   vat_main_t *vam = &vat_main;
3839   vat_json_node_t node;
3840
3841   vat_json_init_object (&node);
3842   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3843   vat_json_object_add_uint (&node, "policer_index",
3844                             ntohl (mp->policer_index));
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 /* Format hex dump. */
3854 u8 *
3855 format_hex_bytes (u8 * s, va_list * va)
3856 {
3857   u8 *bytes = va_arg (*va, u8 *);
3858   int n_bytes = va_arg (*va, int);
3859   uword i;
3860
3861   /* Print short or long form depending on byte count. */
3862   uword short_form = n_bytes <= 32;
3863   uword indent = format_get_indent (s);
3864
3865   if (n_bytes == 0)
3866     return s;
3867
3868   for (i = 0; i < n_bytes; i++)
3869     {
3870       if (!short_form && (i % 32) == 0)
3871         s = format (s, "%08x: ", i);
3872       s = format (s, "%02x", bytes[i]);
3873       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3874         s = format (s, "\n%U", format_white_space, indent);
3875     }
3876
3877   return s;
3878 }
3879
3880 static void
3881 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3882                                             * mp)
3883 {
3884   vat_main_t *vam = &vat_main;
3885   i32 retval = ntohl (mp->retval);
3886   if (retval == 0)
3887     {
3888       print (vam->ofp, "classify table info :");
3889       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3890              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3891              ntohl (mp->miss_next_index));
3892       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3893              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3894              ntohl (mp->match_n_vectors));
3895       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3896              ntohl (mp->mask_length));
3897     }
3898   vam->retval = retval;
3899   vam->result_ready = 1;
3900 }
3901
3902 static void
3903   vl_api_classify_table_info_reply_t_handler_json
3904   (vl_api_classify_table_info_reply_t * mp)
3905 {
3906   vat_main_t *vam = &vat_main;
3907   vat_json_node_t node;
3908
3909   i32 retval = ntohl (mp->retval);
3910   if (retval == 0)
3911     {
3912       vat_json_init_object (&node);
3913
3914       vat_json_object_add_int (&node, "sessions",
3915                                ntohl (mp->active_sessions));
3916       vat_json_object_add_int (&node, "nexttbl",
3917                                ntohl (mp->next_table_index));
3918       vat_json_object_add_int (&node, "nextnode",
3919                                ntohl (mp->miss_next_index));
3920       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3921       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3922       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3923       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3924                       ntohl (mp->mask_length), 0);
3925       vat_json_object_add_string_copy (&node, "mask", s);
3926
3927       vat_json_print (vam->ofp, &node);
3928       vat_json_free (&node);
3929     }
3930   vam->retval = ntohl (mp->retval);
3931   vam->result_ready = 1;
3932 }
3933
3934 static void
3935 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3936                                            mp)
3937 {
3938   vat_main_t *vam = &vat_main;
3939
3940   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3941          ntohl (mp->hit_next_index), ntohl (mp->advance),
3942          ntohl (mp->opaque_index));
3943   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3944          ntohl (mp->match_length));
3945 }
3946
3947 static void
3948   vl_api_classify_session_details_t_handler_json
3949   (vl_api_classify_session_details_t * mp)
3950 {
3951   vat_main_t *vam = &vat_main;
3952   vat_json_node_t *node = NULL;
3953
3954   if (VAT_JSON_ARRAY != vam->json_tree.type)
3955     {
3956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3957       vat_json_init_array (&vam->json_tree);
3958     }
3959   node = vat_json_array_add (&vam->json_tree);
3960
3961   vat_json_init_object (node);
3962   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3963   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3964   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3965   u8 *s =
3966     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3967             0);
3968   vat_json_object_add_string_copy (node, "match", s);
3969 }
3970
3971 static void vl_api_pg_create_interface_reply_t_handler
3972   (vl_api_pg_create_interface_reply_t * mp)
3973 {
3974   vat_main_t *vam = &vat_main;
3975
3976   vam->retval = ntohl (mp->retval);
3977   vam->result_ready = 1;
3978 }
3979
3980 static void vl_api_pg_create_interface_reply_t_handler_json
3981   (vl_api_pg_create_interface_reply_t * mp)
3982 {
3983   vat_main_t *vam = &vat_main;
3984   vat_json_node_t node;
3985
3986   i32 retval = ntohl (mp->retval);
3987   if (retval == 0)
3988     {
3989       vat_json_init_object (&node);
3990
3991       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3992
3993       vat_json_print (vam->ofp, &node);
3994       vat_json_free (&node);
3995     }
3996   vam->retval = ntohl (mp->retval);
3997   vam->result_ready = 1;
3998 }
3999
4000 static void vl_api_policer_classify_details_t_handler
4001   (vl_api_policer_classify_details_t * mp)
4002 {
4003   vat_main_t *vam = &vat_main;
4004
4005   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4006          ntohl (mp->table_index));
4007 }
4008
4009 static void vl_api_policer_classify_details_t_handler_json
4010   (vl_api_policer_classify_details_t * mp)
4011 {
4012   vat_main_t *vam = &vat_main;
4013   vat_json_node_t *node;
4014
4015   if (VAT_JSON_ARRAY != vam->json_tree.type)
4016     {
4017       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4018       vat_json_init_array (&vam->json_tree);
4019     }
4020   node = vat_json_array_add (&vam->json_tree);
4021
4022   vat_json_init_object (node);
4023   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4024   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4025 }
4026
4027 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4028   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4029 {
4030   vat_main_t *vam = &vat_main;
4031   i32 retval = ntohl (mp->retval);
4032   if (vam->async_mode)
4033     {
4034       vam->async_errors += (retval < 0);
4035     }
4036   else
4037     {
4038       vam->retval = retval;
4039       vam->sw_if_index = ntohl (mp->sw_if_index);
4040       vam->result_ready = 1;
4041     }
4042 }
4043
4044 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4045   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   vat_json_node_t node;
4049
4050   vat_json_init_object (&node);
4051   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4052   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4053
4054   vat_json_print (vam->ofp, &node);
4055   vat_json_free (&node);
4056
4057   vam->retval = ntohl (mp->retval);
4058   vam->result_ready = 1;
4059 }
4060
4061 static void vl_api_flow_classify_details_t_handler
4062   (vl_api_flow_classify_details_t * mp)
4063 {
4064   vat_main_t *vam = &vat_main;
4065
4066   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4067          ntohl (mp->table_index));
4068 }
4069
4070 static void vl_api_flow_classify_details_t_handler_json
4071   (vl_api_flow_classify_details_t * mp)
4072 {
4073   vat_main_t *vam = &vat_main;
4074   vat_json_node_t *node;
4075
4076   if (VAT_JSON_ARRAY != vam->json_tree.type)
4077     {
4078       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4079       vat_json_init_array (&vam->json_tree);
4080     }
4081   node = vat_json_array_add (&vam->json_tree);
4082
4083   vat_json_init_object (node);
4084   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4085   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4086 }
4087
4088
4089
4090 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4091 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4092 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4093 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4094 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4095 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4096 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4097 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4098 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4099 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4100
4101 /*
4102  * Generate boilerplate reply handlers, which
4103  * dig the return value out of the xxx_reply_t API message,
4104  * stick it into vam->retval, and set vam->result_ready
4105  *
4106  * Could also do this by pointing N message decode slots at
4107  * a single function, but that could break in subtle ways.
4108  */
4109
4110 #define foreach_standard_reply_retval_handler           \
4111 _(sw_interface_set_flags_reply)                         \
4112 _(sw_interface_add_del_address_reply)                   \
4113 _(sw_interface_set_table_reply)                         \
4114 _(sw_interface_set_mpls_enable_reply)                   \
4115 _(sw_interface_set_vpath_reply)                         \
4116 _(sw_interface_set_vxlan_bypass_reply)                  \
4117 _(sw_interface_set_l2_bridge_reply)                     \
4118 _(bridge_domain_add_del_reply)                          \
4119 _(sw_interface_set_l2_xconnect_reply)                   \
4120 _(l2fib_add_del_reply)                                  \
4121 _(ip_add_del_route_reply)                               \
4122 _(ip_mroute_add_del_reply)                              \
4123 _(mpls_route_add_del_reply)                             \
4124 _(mpls_ip_bind_unbind_reply)                            \
4125 _(proxy_arp_add_del_reply)                              \
4126 _(proxy_arp_intfc_enable_disable_reply)                 \
4127 _(sw_interface_set_unnumbered_reply)                    \
4128 _(ip_neighbor_add_del_reply)                            \
4129 _(reset_vrf_reply)                                      \
4130 _(oam_add_del_reply)                                    \
4131 _(reset_fib_reply)                                      \
4132 _(dhcp_proxy_config_reply)                              \
4133 _(dhcp_proxy_set_vss_reply)                             \
4134 _(dhcp_client_config_reply)                             \
4135 _(set_ip_flow_hash_reply)                               \
4136 _(sw_interface_ip6_enable_disable_reply)                \
4137 _(sw_interface_ip6_set_link_local_address_reply)        \
4138 _(ip6nd_proxy_add_del_reply)                            \
4139 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4140 _(sw_interface_ip6nd_ra_config_reply)                   \
4141 _(set_arp_neighbor_limit_reply)                         \
4142 _(l2_patch_add_del_reply)                               \
4143 _(sr_policy_add_reply)                                  \
4144 _(sr_policy_mod_reply)                                  \
4145 _(sr_policy_del_reply)                                  \
4146 _(sr_localsid_add_del_reply)                            \
4147 _(sr_steering_add_del_reply)                            \
4148 _(classify_add_del_session_reply)                       \
4149 _(classify_set_interface_ip_table_reply)                \
4150 _(classify_set_interface_l2_tables_reply)               \
4151 _(l2tpv3_set_tunnel_cookies_reply)                      \
4152 _(l2tpv3_interface_enable_disable_reply)                \
4153 _(l2tpv3_set_lookup_key_reply)                          \
4154 _(l2_fib_clear_table_reply)                             \
4155 _(l2_interface_efp_filter_reply)                        \
4156 _(l2_interface_vlan_tag_rewrite_reply)                  \
4157 _(modify_vhost_user_if_reply)                           \
4158 _(delete_vhost_user_if_reply)                           \
4159 _(want_ip4_arp_events_reply)                            \
4160 _(want_ip6_nd_events_reply)                             \
4161 _(input_acl_set_interface_reply)                        \
4162 _(ipsec_spd_add_del_reply)                              \
4163 _(ipsec_interface_add_del_spd_reply)                    \
4164 _(ipsec_spd_add_del_entry_reply)                        \
4165 _(ipsec_sad_add_del_entry_reply)                        \
4166 _(ipsec_sa_set_key_reply)                               \
4167 _(ikev2_profile_add_del_reply)                          \
4168 _(ikev2_profile_set_auth_reply)                         \
4169 _(ikev2_profile_set_id_reply)                           \
4170 _(ikev2_profile_set_ts_reply)                           \
4171 _(ikev2_set_local_key_reply)                            \
4172 _(ikev2_set_responder_reply)                            \
4173 _(ikev2_set_ike_transforms_reply)                       \
4174 _(ikev2_set_esp_transforms_reply)                       \
4175 _(ikev2_set_sa_lifetime_reply)                          \
4176 _(ikev2_initiate_sa_init_reply)                         \
4177 _(ikev2_initiate_del_ike_sa_reply)                      \
4178 _(ikev2_initiate_del_child_sa_reply)                    \
4179 _(ikev2_initiate_rekey_child_sa_reply)                  \
4180 _(delete_loopback_reply)                                \
4181 _(bd_ip_mac_add_del_reply)                              \
4182 _(map_del_domain_reply)                                 \
4183 _(map_add_del_rule_reply)                               \
4184 _(want_interface_events_reply)                          \
4185 _(want_stats_reply)                                     \
4186 _(cop_interface_enable_disable_reply)                   \
4187 _(cop_whitelist_enable_disable_reply)                   \
4188 _(sw_interface_clear_stats_reply)                       \
4189 _(ioam_enable_reply)                              \
4190 _(ioam_disable_reply)                              \
4191 _(one_add_del_locator_reply)                            \
4192 _(one_add_del_local_eid_reply)                          \
4193 _(one_add_del_remote_mapping_reply)                     \
4194 _(one_add_del_adjacency_reply)                          \
4195 _(one_add_del_map_resolver_reply)                       \
4196 _(one_add_del_map_server_reply)                         \
4197 _(one_enable_disable_reply)                             \
4198 _(one_rloc_probe_enable_disable_reply)                  \
4199 _(one_map_register_enable_disable_reply)                \
4200 _(one_pitr_set_locator_set_reply)                       \
4201 _(one_map_request_mode_reply)                           \
4202 _(one_add_del_map_request_itr_rlocs_reply)              \
4203 _(one_eid_table_add_del_map_reply)                      \
4204 _(one_use_petr_reply)                                   \
4205 _(one_stats_enable_disable_reply)                       \
4206 _(gpe_add_del_fwd_entry_reply)                          \
4207 _(gpe_enable_disable_reply)                             \
4208 _(gpe_set_encap_mode_reply)                             \
4209 _(gpe_add_del_iface_reply)                              \
4210 _(vxlan_gpe_add_del_tunnel_reply)                       \
4211 _(af_packet_delete_reply)                               \
4212 _(policer_classify_set_interface_reply)                 \
4213 _(netmap_create_reply)                                  \
4214 _(netmap_delete_reply)                                  \
4215 _(set_ipfix_exporter_reply)                             \
4216 _(set_ipfix_classify_stream_reply)                      \
4217 _(ipfix_classify_table_add_del_reply)                   \
4218 _(flow_classify_set_interface_reply)                    \
4219 _(sw_interface_span_enable_disable_reply)               \
4220 _(pg_capture_reply)                                     \
4221 _(pg_enable_disable_reply)                              \
4222 _(ip_source_and_port_range_check_add_del_reply)         \
4223 _(ip_source_and_port_range_check_interface_add_del_reply)\
4224 _(delete_subif_reply)                                   \
4225 _(l2_interface_pbb_tag_rewrite_reply)                   \
4226 _(punt_reply)                                           \
4227 _(feature_enable_disable_reply)                         \
4228 _(sw_interface_tag_add_del_reply)                       \
4229 _(sw_interface_set_mtu_reply)
4230
4231 #define _(n)                                    \
4232     static void vl_api_##n##_t_handler          \
4233     (vl_api_##n##_t * mp)                       \
4234     {                                           \
4235         vat_main_t * vam = &vat_main;           \
4236         i32 retval = ntohl(mp->retval);         \
4237         if (vam->async_mode) {                  \
4238             vam->async_errors += (retval < 0);  \
4239         } else {                                \
4240             vam->retval = retval;               \
4241             vam->result_ready = 1;              \
4242         }                                       \
4243     }
4244 foreach_standard_reply_retval_handler;
4245 #undef _
4246
4247 #define _(n)                                    \
4248     static void vl_api_##n##_t_handler_json     \
4249     (vl_api_##n##_t * mp)                       \
4250     {                                           \
4251         vat_main_t * vam = &vat_main;           \
4252         vat_json_node_t node;                   \
4253         vat_json_init_object(&node);            \
4254         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4255         vat_json_print(vam->ofp, &node);        \
4256         vam->retval = ntohl(mp->retval);        \
4257         vam->result_ready = 1;                  \
4258     }
4259 foreach_standard_reply_retval_handler;
4260 #undef _
4261
4262 /*
4263  * Table of message reply handlers, must include boilerplate handlers
4264  * we just generated
4265  */
4266
4267 #define foreach_vpe_api_reply_msg                                       \
4268 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4269 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4270 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4271 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4272 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4273 _(CLI_REPLY, cli_reply)                                                 \
4274 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4275 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4276   sw_interface_add_del_address_reply)                                   \
4277 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4278 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4279 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4280 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4281 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4282   sw_interface_set_l2_xconnect_reply)                                   \
4283 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4284   sw_interface_set_l2_bridge_reply)                                     \
4285 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4286 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4287 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4288 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4289 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4290 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4291 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4292 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4293 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4294 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4295 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4296 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4297 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4298 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4299 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4300 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4301   proxy_arp_intfc_enable_disable_reply)                                 \
4302 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4303 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4304   sw_interface_set_unnumbered_reply)                                    \
4305 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4306 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4307 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4308 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4309 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4310 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4311 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4312 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4313 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4314 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4315 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4316 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4317   sw_interface_ip6_enable_disable_reply)                                \
4318 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4319   sw_interface_ip6_set_link_local_address_reply)                        \
4320 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4321 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4322 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4323   sw_interface_ip6nd_ra_prefix_reply)                                   \
4324 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4325   sw_interface_ip6nd_ra_config_reply)                                   \
4326 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4327 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4328 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4329 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4330 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4331 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4332 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4333 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4334 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4335 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4336 classify_set_interface_ip_table_reply)                                  \
4337 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4338   classify_set_interface_l2_tables_reply)                               \
4339 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4340 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4341 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4342 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4343 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4344   l2tpv3_interface_enable_disable_reply)                                \
4345 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4346 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4347 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4348 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4349 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4350 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4351 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4352 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4353 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4354 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4355 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4356 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4357 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4358 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4359 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4360 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4361 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4362 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4363 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4364 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4365 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4366 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4367 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4368 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4369 _(IP_DETAILS, ip_details)                                               \
4370 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4371 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4372 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4373 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4374 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4375 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4376 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4377 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4378 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4379 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4380 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4381 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4382 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4383 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4384 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4385 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4386 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4387 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4388 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4389 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4390 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4391 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4392 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4393 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4394 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4395 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4396 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4397 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4398 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4399 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4400 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4401 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4402 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4403 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4404 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4405 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4406 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4407 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4408 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4409 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4410 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4411 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4412 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4413 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4414   one_map_register_enable_disable_reply)                                \
4415 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4416   one_rloc_probe_enable_disable_reply)                                  \
4417 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4418 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4419 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4420 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4421 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4422 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4423 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4424 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4425 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4426 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4427 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4428 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4429 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4430 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4431 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4432   show_one_stats_enable_disable_reply)                                  \
4433 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4434 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4435 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4436 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4437 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4438 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4439 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4440   gpe_fwd_entry_path_details)                                           \
4441 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4442 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4443   one_add_del_map_request_itr_rlocs_reply)                              \
4444 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4445   one_get_map_request_itr_rlocs_reply)                                  \
4446 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4447 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4448 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4449 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4450 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4451   show_one_map_register_state_reply)                                    \
4452 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4453 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4454 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4455 _(POLICER_DETAILS, policer_details)                                     \
4456 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4457 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4458 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4459 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4460 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4461 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4462 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4463 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4464 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4465 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4466 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4467 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4468 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4469 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4470 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4471 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4472 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4473 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4474 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4475 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4476 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4477 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4478 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4479 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4480 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4481  ip_source_and_port_range_check_add_del_reply)                          \
4482 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4483  ip_source_and_port_range_check_interface_add_del_reply)                \
4484 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4485 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4486 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4487 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4488 _(PUNT_REPLY, punt_reply)                                               \
4489 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4490 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4491 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4492 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4493 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4494 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4495 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4496 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4497
4498 #define foreach_standalone_reply_msg                                    \
4499 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4500 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4501 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4502 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4503 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4504 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4505
4506 typedef struct
4507 {
4508   u8 *name;
4509   u32 value;
4510 } name_sort_t;
4511
4512
4513 #define STR_VTR_OP_CASE(op)     \
4514     case L2_VTR_ ## op:         \
4515         return "" # op;
4516
4517 static const char *
4518 str_vtr_op (u32 vtr_op)
4519 {
4520   switch (vtr_op)
4521     {
4522       STR_VTR_OP_CASE (DISABLED);
4523       STR_VTR_OP_CASE (PUSH_1);
4524       STR_VTR_OP_CASE (PUSH_2);
4525       STR_VTR_OP_CASE (POP_1);
4526       STR_VTR_OP_CASE (POP_2);
4527       STR_VTR_OP_CASE (TRANSLATE_1_1);
4528       STR_VTR_OP_CASE (TRANSLATE_1_2);
4529       STR_VTR_OP_CASE (TRANSLATE_2_1);
4530       STR_VTR_OP_CASE (TRANSLATE_2_2);
4531     }
4532
4533   return "UNKNOWN";
4534 }
4535
4536 static int
4537 dump_sub_interface_table (vat_main_t * vam)
4538 {
4539   const sw_interface_subif_t *sub = NULL;
4540
4541   if (vam->json_output)
4542     {
4543       clib_warning
4544         ("JSON output supported only for VPE API calls and dump_stats_table");
4545       return -99;
4546     }
4547
4548   print (vam->ofp,
4549          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4550          "Interface", "sw_if_index",
4551          "sub id", "dot1ad", "tags", "outer id",
4552          "inner id", "exact", "default", "outer any", "inner any");
4553
4554   vec_foreach (sub, vam->sw_if_subif_table)
4555   {
4556     print (vam->ofp,
4557            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4558            sub->interface_name,
4559            sub->sw_if_index,
4560            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4561            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4562            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4563            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4564     if (sub->vtr_op != L2_VTR_DISABLED)
4565       {
4566         print (vam->ofp,
4567                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4568                "tag1: %d tag2: %d ]",
4569                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4570                sub->vtr_tag1, sub->vtr_tag2);
4571       }
4572   }
4573
4574   return 0;
4575 }
4576
4577 static int
4578 name_sort_cmp (void *a1, void *a2)
4579 {
4580   name_sort_t *n1 = a1;
4581   name_sort_t *n2 = a2;
4582
4583   return strcmp ((char *) n1->name, (char *) n2->name);
4584 }
4585
4586 static int
4587 dump_interface_table (vat_main_t * vam)
4588 {
4589   hash_pair_t *p;
4590   name_sort_t *nses = 0, *ns;
4591
4592   if (vam->json_output)
4593     {
4594       clib_warning
4595         ("JSON output supported only for VPE API calls and dump_stats_table");
4596       return -99;
4597     }
4598
4599   /* *INDENT-OFF* */
4600   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4601   ({
4602     vec_add2 (nses, ns, 1);
4603     ns->name = (u8 *)(p->key);
4604     ns->value = (u32) p->value[0];
4605   }));
4606   /* *INDENT-ON* */
4607
4608   vec_sort_with_function (nses, name_sort_cmp);
4609
4610   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4611   vec_foreach (ns, nses)
4612   {
4613     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4614   }
4615   vec_free (nses);
4616   return 0;
4617 }
4618
4619 static int
4620 dump_ip_table (vat_main_t * vam, int is_ipv6)
4621 {
4622   const ip_details_t *det = NULL;
4623   const ip_address_details_t *address = NULL;
4624   u32 i = ~0;
4625
4626   print (vam->ofp, "%-12s", "sw_if_index");
4627
4628   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4629   {
4630     i++;
4631     if (!det->present)
4632       {
4633         continue;
4634       }
4635     print (vam->ofp, "%-12d", i);
4636     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4637     if (!det->addr)
4638       {
4639         continue;
4640       }
4641     vec_foreach (address, det->addr)
4642     {
4643       print (vam->ofp,
4644              "            %-30U%-13d",
4645              is_ipv6 ? format_ip6_address : format_ip4_address,
4646              address->ip, address->prefix_length);
4647     }
4648   }
4649
4650   return 0;
4651 }
4652
4653 static int
4654 dump_ipv4_table (vat_main_t * vam)
4655 {
4656   if (vam->json_output)
4657     {
4658       clib_warning
4659         ("JSON output supported only for VPE API calls and dump_stats_table");
4660       return -99;
4661     }
4662
4663   return dump_ip_table (vam, 0);
4664 }
4665
4666 static int
4667 dump_ipv6_table (vat_main_t * vam)
4668 {
4669   if (vam->json_output)
4670     {
4671       clib_warning
4672         ("JSON output supported only for VPE API calls and dump_stats_table");
4673       return -99;
4674     }
4675
4676   return dump_ip_table (vam, 1);
4677 }
4678
4679 static char *
4680 counter_type_to_str (u8 counter_type, u8 is_combined)
4681 {
4682   if (!is_combined)
4683     {
4684       switch (counter_type)
4685         {
4686         case VNET_INTERFACE_COUNTER_DROP:
4687           return "drop";
4688         case VNET_INTERFACE_COUNTER_PUNT:
4689           return "punt";
4690         case VNET_INTERFACE_COUNTER_IP4:
4691           return "ip4";
4692         case VNET_INTERFACE_COUNTER_IP6:
4693           return "ip6";
4694         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4695           return "rx-no-buf";
4696         case VNET_INTERFACE_COUNTER_RX_MISS:
4697           return "rx-miss";
4698         case VNET_INTERFACE_COUNTER_RX_ERROR:
4699           return "rx-error";
4700         case VNET_INTERFACE_COUNTER_TX_ERROR:
4701           return "tx-error";
4702         default:
4703           return "INVALID-COUNTER-TYPE";
4704         }
4705     }
4706   else
4707     {
4708       switch (counter_type)
4709         {
4710         case VNET_INTERFACE_COUNTER_RX:
4711           return "rx";
4712         case VNET_INTERFACE_COUNTER_TX:
4713           return "tx";
4714         default:
4715           return "INVALID-COUNTER-TYPE";
4716         }
4717     }
4718 }
4719
4720 static int
4721 dump_stats_table (vat_main_t * vam)
4722 {
4723   vat_json_node_t node;
4724   vat_json_node_t *msg_array;
4725   vat_json_node_t *msg;
4726   vat_json_node_t *counter_array;
4727   vat_json_node_t *counter;
4728   interface_counter_t c;
4729   u64 packets;
4730   ip4_fib_counter_t *c4;
4731   ip6_fib_counter_t *c6;
4732   ip4_nbr_counter_t *n4;
4733   ip6_nbr_counter_t *n6;
4734   int i, j;
4735
4736   if (!vam->json_output)
4737     {
4738       clib_warning ("dump_stats_table supported only in JSON format");
4739       return -99;
4740     }
4741
4742   vat_json_init_object (&node);
4743
4744   /* interface counters */
4745   msg_array = vat_json_object_add (&node, "interface_counters");
4746   vat_json_init_array (msg_array);
4747   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4748     {
4749       msg = vat_json_array_add (msg_array);
4750       vat_json_init_object (msg);
4751       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4752                                        (u8 *) counter_type_to_str (i, 0));
4753       vat_json_object_add_int (msg, "is_combined", 0);
4754       counter_array = vat_json_object_add (msg, "data");
4755       vat_json_init_array (counter_array);
4756       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4757         {
4758           packets = vam->simple_interface_counters[i][j];
4759           vat_json_array_add_uint (counter_array, packets);
4760         }
4761     }
4762   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4763     {
4764       msg = vat_json_array_add (msg_array);
4765       vat_json_init_object (msg);
4766       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4767                                        (u8 *) counter_type_to_str (i, 1));
4768       vat_json_object_add_int (msg, "is_combined", 1);
4769       counter_array = vat_json_object_add (msg, "data");
4770       vat_json_init_array (counter_array);
4771       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4772         {
4773           c = vam->combined_interface_counters[i][j];
4774           counter = vat_json_array_add (counter_array);
4775           vat_json_init_object (counter);
4776           vat_json_object_add_uint (counter, "packets", c.packets);
4777           vat_json_object_add_uint (counter, "bytes", c.bytes);
4778         }
4779     }
4780
4781   /* ip4 fib counters */
4782   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4783   vat_json_init_array (msg_array);
4784   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4785     {
4786       msg = vat_json_array_add (msg_array);
4787       vat_json_init_object (msg);
4788       vat_json_object_add_uint (msg, "vrf_id",
4789                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4790       counter_array = vat_json_object_add (msg, "c");
4791       vat_json_init_array (counter_array);
4792       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4793         {
4794           counter = vat_json_array_add (counter_array);
4795           vat_json_init_object (counter);
4796           c4 = &vam->ip4_fib_counters[i][j];
4797           vat_json_object_add_ip4 (counter, "address", c4->address);
4798           vat_json_object_add_uint (counter, "address_length",
4799                                     c4->address_length);
4800           vat_json_object_add_uint (counter, "packets", c4->packets);
4801           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4802         }
4803     }
4804
4805   /* ip6 fib counters */
4806   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4807   vat_json_init_array (msg_array);
4808   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4809     {
4810       msg = vat_json_array_add (msg_array);
4811       vat_json_init_object (msg);
4812       vat_json_object_add_uint (msg, "vrf_id",
4813                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4814       counter_array = vat_json_object_add (msg, "c");
4815       vat_json_init_array (counter_array);
4816       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4817         {
4818           counter = vat_json_array_add (counter_array);
4819           vat_json_init_object (counter);
4820           c6 = &vam->ip6_fib_counters[i][j];
4821           vat_json_object_add_ip6 (counter, "address", c6->address);
4822           vat_json_object_add_uint (counter, "address_length",
4823                                     c6->address_length);
4824           vat_json_object_add_uint (counter, "packets", c6->packets);
4825           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4826         }
4827     }
4828
4829   /* ip4 nbr counters */
4830   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4831   vat_json_init_array (msg_array);
4832   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4833     {
4834       msg = vat_json_array_add (msg_array);
4835       vat_json_init_object (msg);
4836       vat_json_object_add_uint (msg, "sw_if_index", i);
4837       counter_array = vat_json_object_add (msg, "c");
4838       vat_json_init_array (counter_array);
4839       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4840         {
4841           counter = vat_json_array_add (counter_array);
4842           vat_json_init_object (counter);
4843           n4 = &vam->ip4_nbr_counters[i][j];
4844           vat_json_object_add_ip4 (counter, "address", n4->address);
4845           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4846           vat_json_object_add_uint (counter, "packets", n4->packets);
4847           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4848         }
4849     }
4850
4851   /* ip6 nbr counters */
4852   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4853   vat_json_init_array (msg_array);
4854   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4855     {
4856       msg = vat_json_array_add (msg_array);
4857       vat_json_init_object (msg);
4858       vat_json_object_add_uint (msg, "sw_if_index", i);
4859       counter_array = vat_json_object_add (msg, "c");
4860       vat_json_init_array (counter_array);
4861       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4862         {
4863           counter = vat_json_array_add (counter_array);
4864           vat_json_init_object (counter);
4865           n6 = &vam->ip6_nbr_counters[i][j];
4866           vat_json_object_add_ip6 (counter, "address", n6->address);
4867           vat_json_object_add_uint (counter, "packets", n6->packets);
4868           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4869         }
4870     }
4871
4872   vat_json_print (vam->ofp, &node);
4873   vat_json_free (&node);
4874
4875   return 0;
4876 }
4877
4878 int
4879 exec (vat_main_t * vam)
4880 {
4881   api_main_t *am = &api_main;
4882   vl_api_cli_request_t *mp;
4883   f64 timeout;
4884   void *oldheap;
4885   u8 *cmd = 0;
4886   unformat_input_t *i = vam->input;
4887
4888   if (vec_len (i->buffer) == 0)
4889     return -1;
4890
4891   if (vam->exec_mode == 0 && unformat (i, "mode"))
4892     {
4893       vam->exec_mode = 1;
4894       return 0;
4895     }
4896   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4897     {
4898       vam->exec_mode = 0;
4899       return 0;
4900     }
4901
4902
4903   M (CLI_REQUEST, mp);
4904
4905   /*
4906    * Copy cmd into shared memory.
4907    * In order for the CLI command to work, it
4908    * must be a vector ending in \n, not a C-string ending
4909    * in \n\0.
4910    */
4911   pthread_mutex_lock (&am->vlib_rp->mutex);
4912   oldheap = svm_push_data_heap (am->vlib_rp);
4913
4914   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4915   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4916
4917   svm_pop_heap (oldheap);
4918   pthread_mutex_unlock (&am->vlib_rp->mutex);
4919
4920   mp->cmd_in_shmem = (u64) cmd;
4921   S (mp);
4922   timeout = vat_time_now (vam) + 10.0;
4923
4924   while (vat_time_now (vam) < timeout)
4925     {
4926       if (vam->result_ready == 1)
4927         {
4928           u8 *free_me;
4929           if (vam->shmem_result != NULL)
4930             print (vam->ofp, "%s", vam->shmem_result);
4931           pthread_mutex_lock (&am->vlib_rp->mutex);
4932           oldheap = svm_push_data_heap (am->vlib_rp);
4933
4934           free_me = (u8 *) vam->shmem_result;
4935           vec_free (free_me);
4936
4937           svm_pop_heap (oldheap);
4938           pthread_mutex_unlock (&am->vlib_rp->mutex);
4939           return 0;
4940         }
4941     }
4942   return -99;
4943 }
4944
4945 /*
4946  * Future replacement of exec() that passes CLI buffers directly in
4947  * the API messages instead of an additional shared memory area.
4948  */
4949 static int
4950 exec_inband (vat_main_t * vam)
4951 {
4952   vl_api_cli_inband_t *mp;
4953   unformat_input_t *i = vam->input;
4954   int ret;
4955
4956   if (vec_len (i->buffer) == 0)
4957     return -1;
4958
4959   if (vam->exec_mode == 0 && unformat (i, "mode"))
4960     {
4961       vam->exec_mode = 1;
4962       return 0;
4963     }
4964   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4965     {
4966       vam->exec_mode = 0;
4967       return 0;
4968     }
4969
4970   /*
4971    * In order for the CLI command to work, it
4972    * must be a vector ending in \n, not a C-string ending
4973    * in \n\0.
4974    */
4975   u32 len = vec_len (vam->input->buffer);
4976   M2 (CLI_INBAND, mp, len);
4977   clib_memcpy (mp->cmd, vam->input->buffer, len);
4978   mp->length = htonl (len);
4979
4980   S (mp);
4981   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4982   return ret;
4983 }
4984
4985 static int
4986 api_create_loopback (vat_main_t * vam)
4987 {
4988   unformat_input_t *i = vam->input;
4989   vl_api_create_loopback_t *mp;
4990   vl_api_create_loopback_instance_t *mp_lbi;
4991   u8 mac_address[6];
4992   u8 mac_set = 0;
4993   u8 is_specified = 0;
4994   u32 user_instance = 0;
4995   int ret;
4996
4997   memset (mac_address, 0, sizeof (mac_address));
4998
4999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5000     {
5001       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5002         mac_set = 1;
5003       if (unformat (i, "instance %d", &user_instance))
5004         is_specified = 1;
5005       else
5006         break;
5007     }
5008
5009   if (is_specified)
5010     {
5011       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5012       mp_lbi->is_specified = is_specified;
5013       if (is_specified)
5014         mp_lbi->user_instance = htonl (user_instance);
5015       if (mac_set)
5016         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5017       S (mp_lbi);
5018     }
5019   else
5020     {
5021       /* Construct the API message */
5022       M (CREATE_LOOPBACK, mp);
5023       if (mac_set)
5024         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5025       S (mp);
5026     }
5027
5028   W (ret);
5029   return ret;
5030 }
5031
5032 static int
5033 api_delete_loopback (vat_main_t * vam)
5034 {
5035   unformat_input_t *i = vam->input;
5036   vl_api_delete_loopback_t *mp;
5037   u32 sw_if_index = ~0;
5038   int ret;
5039
5040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5041     {
5042       if (unformat (i, "sw_if_index %d", &sw_if_index))
5043         ;
5044       else
5045         break;
5046     }
5047
5048   if (sw_if_index == ~0)
5049     {
5050       errmsg ("missing sw_if_index");
5051       return -99;
5052     }
5053
5054   /* Construct the API message */
5055   M (DELETE_LOOPBACK, mp);
5056   mp->sw_if_index = ntohl (sw_if_index);
5057
5058   S (mp);
5059   W (ret);
5060   return ret;
5061 }
5062
5063 static int
5064 api_want_stats (vat_main_t * vam)
5065 {
5066   unformat_input_t *i = vam->input;
5067   vl_api_want_stats_t *mp;
5068   int enable = -1;
5069   int ret;
5070
5071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5072     {
5073       if (unformat (i, "enable"))
5074         enable = 1;
5075       else if (unformat (i, "disable"))
5076         enable = 0;
5077       else
5078         break;
5079     }
5080
5081   if (enable == -1)
5082     {
5083       errmsg ("missing enable|disable");
5084       return -99;
5085     }
5086
5087   M (WANT_STATS, mp);
5088   mp->enable_disable = enable;
5089
5090   S (mp);
5091   W (ret);
5092   return ret;
5093 }
5094
5095 static int
5096 api_want_interface_events (vat_main_t * vam)
5097 {
5098   unformat_input_t *i = vam->input;
5099   vl_api_want_interface_events_t *mp;
5100   int enable = -1;
5101   int ret;
5102
5103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5104     {
5105       if (unformat (i, "enable"))
5106         enable = 1;
5107       else if (unformat (i, "disable"))
5108         enable = 0;
5109       else
5110         break;
5111     }
5112
5113   if (enable == -1)
5114     {
5115       errmsg ("missing enable|disable");
5116       return -99;
5117     }
5118
5119   M (WANT_INTERFACE_EVENTS, mp);
5120   mp->enable_disable = enable;
5121
5122   vam->interface_event_display = enable;
5123
5124   S (mp);
5125   W (ret);
5126   return ret;
5127 }
5128
5129
5130 /* Note: non-static, called once to set up the initial intfc table */
5131 int
5132 api_sw_interface_dump (vat_main_t * vam)
5133 {
5134   vl_api_sw_interface_dump_t *mp;
5135   vl_api_control_ping_t *mp_ping;
5136   hash_pair_t *p;
5137   name_sort_t *nses = 0, *ns;
5138   sw_interface_subif_t *sub = NULL;
5139   int ret;
5140
5141   /* Toss the old name table */
5142   /* *INDENT-OFF* */
5143   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5144   ({
5145     vec_add2 (nses, ns, 1);
5146     ns->name = (u8 *)(p->key);
5147     ns->value = (u32) p->value[0];
5148   }));
5149   /* *INDENT-ON* */
5150
5151   hash_free (vam->sw_if_index_by_interface_name);
5152
5153   vec_foreach (ns, nses) vec_free (ns->name);
5154
5155   vec_free (nses);
5156
5157   vec_foreach (sub, vam->sw_if_subif_table)
5158   {
5159     vec_free (sub->interface_name);
5160   }
5161   vec_free (vam->sw_if_subif_table);
5162
5163   /* recreate the interface name hash table */
5164   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5165
5166   /* Get list of ethernets */
5167   M (SW_INTERFACE_DUMP, mp);
5168   mp->name_filter_valid = 1;
5169   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5170   S (mp);
5171
5172   /* and local / loopback interfaces */
5173   M (SW_INTERFACE_DUMP, mp);
5174   mp->name_filter_valid = 1;
5175   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5176   S (mp);
5177
5178   /* and packet-generator interfaces */
5179   M (SW_INTERFACE_DUMP, mp);
5180   mp->name_filter_valid = 1;
5181   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5182   S (mp);
5183
5184   /* and vxlan-gpe tunnel interfaces */
5185   M (SW_INTERFACE_DUMP, mp);
5186   mp->name_filter_valid = 1;
5187   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5188            sizeof (mp->name_filter) - 1);
5189   S (mp);
5190
5191   /* and vxlan tunnel interfaces */
5192   M (SW_INTERFACE_DUMP, mp);
5193   mp->name_filter_valid = 1;
5194   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5195   S (mp);
5196
5197   /* and host (af_packet) interfaces */
5198   M (SW_INTERFACE_DUMP, mp);
5199   mp->name_filter_valid = 1;
5200   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5201   S (mp);
5202
5203   /* and l2tpv3 tunnel interfaces */
5204   M (SW_INTERFACE_DUMP, mp);
5205   mp->name_filter_valid = 1;
5206   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5207            sizeof (mp->name_filter) - 1);
5208   S (mp);
5209
5210   /* and GRE tunnel interfaces */
5211   M (SW_INTERFACE_DUMP, mp);
5212   mp->name_filter_valid = 1;
5213   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5214   S (mp);
5215
5216   /* and LISP-GPE interfaces */
5217   M (SW_INTERFACE_DUMP, mp);
5218   mp->name_filter_valid = 1;
5219   strncpy ((char *) mp->name_filter, "lisp_gpe",
5220            sizeof (mp->name_filter) - 1);
5221   S (mp);
5222
5223   /* and IPSEC tunnel interfaces */
5224   M (SW_INTERFACE_DUMP, mp);
5225   mp->name_filter_valid = 1;
5226   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5227   S (mp);
5228
5229   /* Use a control ping for synchronization */
5230   M (CONTROL_PING, mp_ping);
5231   S (mp_ping);
5232
5233   W (ret);
5234   return ret;
5235 }
5236
5237 static int
5238 api_sw_interface_set_flags (vat_main_t * vam)
5239 {
5240   unformat_input_t *i = vam->input;
5241   vl_api_sw_interface_set_flags_t *mp;
5242   u32 sw_if_index;
5243   u8 sw_if_index_set = 0;
5244   u8 admin_up = 0, link_up = 0;
5245   int ret;
5246
5247   /* Parse args required to build the message */
5248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5249     {
5250       if (unformat (i, "admin-up"))
5251         admin_up = 1;
5252       else if (unformat (i, "admin-down"))
5253         admin_up = 0;
5254       else if (unformat (i, "link-up"))
5255         link_up = 1;
5256       else if (unformat (i, "link-down"))
5257         link_up = 0;
5258       else
5259         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5260         sw_if_index_set = 1;
5261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5262         sw_if_index_set = 1;
5263       else
5264         break;
5265     }
5266
5267   if (sw_if_index_set == 0)
5268     {
5269       errmsg ("missing interface name or sw_if_index");
5270       return -99;
5271     }
5272
5273   /* Construct the API message */
5274   M (SW_INTERFACE_SET_FLAGS, mp);
5275   mp->sw_if_index = ntohl (sw_if_index);
5276   mp->admin_up_down = admin_up;
5277   mp->link_up_down = link_up;
5278
5279   /* send it... */
5280   S (mp);
5281
5282   /* Wait for a reply, return the good/bad news... */
5283   W (ret);
5284   return ret;
5285 }
5286
5287 static int
5288 api_sw_interface_clear_stats (vat_main_t * vam)
5289 {
5290   unformat_input_t *i = vam->input;
5291   vl_api_sw_interface_clear_stats_t *mp;
5292   u32 sw_if_index;
5293   u8 sw_if_index_set = 0;
5294   int ret;
5295
5296   /* Parse args required to build the message */
5297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5298     {
5299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5300         sw_if_index_set = 1;
5301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5302         sw_if_index_set = 1;
5303       else
5304         break;
5305     }
5306
5307   /* Construct the API message */
5308   M (SW_INTERFACE_CLEAR_STATS, mp);
5309
5310   if (sw_if_index_set == 1)
5311     mp->sw_if_index = ntohl (sw_if_index);
5312   else
5313     mp->sw_if_index = ~0;
5314
5315   /* send it... */
5316   S (mp);
5317
5318   /* Wait for a reply, return the good/bad news... */
5319   W (ret);
5320   return ret;
5321 }
5322
5323 static int
5324 api_sw_interface_add_del_address (vat_main_t * vam)
5325 {
5326   unformat_input_t *i = vam->input;
5327   vl_api_sw_interface_add_del_address_t *mp;
5328   u32 sw_if_index;
5329   u8 sw_if_index_set = 0;
5330   u8 is_add = 1, del_all = 0;
5331   u32 address_length = 0;
5332   u8 v4_address_set = 0;
5333   u8 v6_address_set = 0;
5334   ip4_address_t v4address;
5335   ip6_address_t v6address;
5336   int ret;
5337
5338   /* Parse args required to build the message */
5339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5340     {
5341       if (unformat (i, "del-all"))
5342         del_all = 1;
5343       else if (unformat (i, "del"))
5344         is_add = 0;
5345       else
5346         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5347         sw_if_index_set = 1;
5348       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5349         sw_if_index_set = 1;
5350       else if (unformat (i, "%U/%d",
5351                          unformat_ip4_address, &v4address, &address_length))
5352         v4_address_set = 1;
5353       else if (unformat (i, "%U/%d",
5354                          unformat_ip6_address, &v6address, &address_length))
5355         v6_address_set = 1;
5356       else
5357         break;
5358     }
5359
5360   if (sw_if_index_set == 0)
5361     {
5362       errmsg ("missing interface name or sw_if_index");
5363       return -99;
5364     }
5365   if (v4_address_set && v6_address_set)
5366     {
5367       errmsg ("both v4 and v6 addresses set");
5368       return -99;
5369     }
5370   if (!v4_address_set && !v6_address_set && !del_all)
5371     {
5372       errmsg ("no addresses set");
5373       return -99;
5374     }
5375
5376   /* Construct the API message */
5377   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5378
5379   mp->sw_if_index = ntohl (sw_if_index);
5380   mp->is_add = is_add;
5381   mp->del_all = del_all;
5382   if (v6_address_set)
5383     {
5384       mp->is_ipv6 = 1;
5385       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5386     }
5387   else
5388     {
5389       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5390     }
5391   mp->address_length = address_length;
5392
5393   /* send it... */
5394   S (mp);
5395
5396   /* Wait for a reply, return good/bad news  */
5397   W (ret);
5398   return ret;
5399 }
5400
5401 static int
5402 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5403 {
5404   unformat_input_t *i = vam->input;
5405   vl_api_sw_interface_set_mpls_enable_t *mp;
5406   u32 sw_if_index;
5407   u8 sw_if_index_set = 0;
5408   u8 enable = 1;
5409   int ret;
5410
5411   /* Parse args required to build the message */
5412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5413     {
5414       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5415         sw_if_index_set = 1;
5416       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5417         sw_if_index_set = 1;
5418       else if (unformat (i, "disable"))
5419         enable = 0;
5420       else if (unformat (i, "dis"))
5421         enable = 0;
5422       else
5423         break;
5424     }
5425
5426   if (sw_if_index_set == 0)
5427     {
5428       errmsg ("missing interface name or sw_if_index");
5429       return -99;
5430     }
5431
5432   /* Construct the API message */
5433   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5434
5435   mp->sw_if_index = ntohl (sw_if_index);
5436   mp->enable = enable;
5437
5438   /* send it... */
5439   S (mp);
5440
5441   /* Wait for a reply... */
5442   W (ret);
5443   return ret;
5444 }
5445
5446 static int
5447 api_sw_interface_set_table (vat_main_t * vam)
5448 {
5449   unformat_input_t *i = vam->input;
5450   vl_api_sw_interface_set_table_t *mp;
5451   u32 sw_if_index, vrf_id = 0;
5452   u8 sw_if_index_set = 0;
5453   u8 is_ipv6 = 0;
5454   int ret;
5455
5456   /* Parse args required to build the message */
5457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5458     {
5459       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5460         sw_if_index_set = 1;
5461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5462         sw_if_index_set = 1;
5463       else if (unformat (i, "vrf %d", &vrf_id))
5464         ;
5465       else if (unformat (i, "ipv6"))
5466         is_ipv6 = 1;
5467       else
5468         break;
5469     }
5470
5471   if (sw_if_index_set == 0)
5472     {
5473       errmsg ("missing interface name or sw_if_index");
5474       return -99;
5475     }
5476
5477   /* Construct the API message */
5478   M (SW_INTERFACE_SET_TABLE, mp);
5479
5480   mp->sw_if_index = ntohl (sw_if_index);
5481   mp->is_ipv6 = is_ipv6;
5482   mp->vrf_id = ntohl (vrf_id);
5483
5484   /* send it... */
5485   S (mp);
5486
5487   /* Wait for a reply... */
5488   W (ret);
5489   return ret;
5490 }
5491
5492 static void vl_api_sw_interface_get_table_reply_t_handler
5493   (vl_api_sw_interface_get_table_reply_t * mp)
5494 {
5495   vat_main_t *vam = &vat_main;
5496
5497   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5498
5499   vam->retval = ntohl (mp->retval);
5500   vam->result_ready = 1;
5501
5502 }
5503
5504 static void vl_api_sw_interface_get_table_reply_t_handler_json
5505   (vl_api_sw_interface_get_table_reply_t * mp)
5506 {
5507   vat_main_t *vam = &vat_main;
5508   vat_json_node_t node;
5509
5510   vat_json_init_object (&node);
5511   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5512   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5513
5514   vat_json_print (vam->ofp, &node);
5515   vat_json_free (&node);
5516
5517   vam->retval = ntohl (mp->retval);
5518   vam->result_ready = 1;
5519 }
5520
5521 static int
5522 api_sw_interface_get_table (vat_main_t * vam)
5523 {
5524   unformat_input_t *i = vam->input;
5525   vl_api_sw_interface_get_table_t *mp;
5526   u32 sw_if_index;
5527   u8 sw_if_index_set = 0;
5528   u8 is_ipv6 = 0;
5529   int ret;
5530
5531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5532     {
5533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5534         sw_if_index_set = 1;
5535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5536         sw_if_index_set = 1;
5537       else if (unformat (i, "ipv6"))
5538         is_ipv6 = 1;
5539       else
5540         break;
5541     }
5542
5543   if (sw_if_index_set == 0)
5544     {
5545       errmsg ("missing interface name or sw_if_index");
5546       return -99;
5547     }
5548
5549   M (SW_INTERFACE_GET_TABLE, mp);
5550   mp->sw_if_index = htonl (sw_if_index);
5551   mp->is_ipv6 = is_ipv6;
5552
5553   S (mp);
5554   W (ret);
5555   return ret;
5556 }
5557
5558 static int
5559 api_sw_interface_set_vpath (vat_main_t * vam)
5560 {
5561   unformat_input_t *i = vam->input;
5562   vl_api_sw_interface_set_vpath_t *mp;
5563   u32 sw_if_index = 0;
5564   u8 sw_if_index_set = 0;
5565   u8 is_enable = 0;
5566   int ret;
5567
5568   /* Parse args required to build the message */
5569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5570     {
5571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5572         sw_if_index_set = 1;
5573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5574         sw_if_index_set = 1;
5575       else if (unformat (i, "enable"))
5576         is_enable = 1;
5577       else if (unformat (i, "disable"))
5578         is_enable = 0;
5579       else
5580         break;
5581     }
5582
5583   if (sw_if_index_set == 0)
5584     {
5585       errmsg ("missing interface name or sw_if_index");
5586       return -99;
5587     }
5588
5589   /* Construct the API message */
5590   M (SW_INTERFACE_SET_VPATH, mp);
5591
5592   mp->sw_if_index = ntohl (sw_if_index);
5593   mp->enable = is_enable;
5594
5595   /* send it... */
5596   S (mp);
5597
5598   /* Wait for a reply... */
5599   W (ret);
5600   return ret;
5601 }
5602
5603 static int
5604 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5605 {
5606   unformat_input_t *i = vam->input;
5607   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5608   u32 sw_if_index = 0;
5609   u8 sw_if_index_set = 0;
5610   u8 is_enable = 1;
5611   u8 is_ipv6 = 0;
5612   int ret;
5613
5614   /* Parse args required to build the message */
5615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5616     {
5617       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5618         sw_if_index_set = 1;
5619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5620         sw_if_index_set = 1;
5621       else if (unformat (i, "enable"))
5622         is_enable = 1;
5623       else if (unformat (i, "disable"))
5624         is_enable = 0;
5625       else if (unformat (i, "ip4"))
5626         is_ipv6 = 0;
5627       else if (unformat (i, "ip6"))
5628         is_ipv6 = 1;
5629       else
5630         break;
5631     }
5632
5633   if (sw_if_index_set == 0)
5634     {
5635       errmsg ("missing interface name or sw_if_index");
5636       return -99;
5637     }
5638
5639   /* Construct the API message */
5640   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5641
5642   mp->sw_if_index = ntohl (sw_if_index);
5643   mp->enable = is_enable;
5644   mp->is_ipv6 = is_ipv6;
5645
5646   /* send it... */
5647   S (mp);
5648
5649   /* Wait for a reply... */
5650   W (ret);
5651   return ret;
5652 }
5653
5654 static int
5655 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5656 {
5657   unformat_input_t *i = vam->input;
5658   vl_api_sw_interface_set_l2_xconnect_t *mp;
5659   u32 rx_sw_if_index;
5660   u8 rx_sw_if_index_set = 0;
5661   u32 tx_sw_if_index;
5662   u8 tx_sw_if_index_set = 0;
5663   u8 enable = 1;
5664   int ret;
5665
5666   /* Parse args required to build the message */
5667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5668     {
5669       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5670         rx_sw_if_index_set = 1;
5671       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5672         tx_sw_if_index_set = 1;
5673       else if (unformat (i, "rx"))
5674         {
5675           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5676             {
5677               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5678                             &rx_sw_if_index))
5679                 rx_sw_if_index_set = 1;
5680             }
5681           else
5682             break;
5683         }
5684       else if (unformat (i, "tx"))
5685         {
5686           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5687             {
5688               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5689                             &tx_sw_if_index))
5690                 tx_sw_if_index_set = 1;
5691             }
5692           else
5693             break;
5694         }
5695       else if (unformat (i, "enable"))
5696         enable = 1;
5697       else if (unformat (i, "disable"))
5698         enable = 0;
5699       else
5700         break;
5701     }
5702
5703   if (rx_sw_if_index_set == 0)
5704     {
5705       errmsg ("missing rx interface name or rx_sw_if_index");
5706       return -99;
5707     }
5708
5709   if (enable && (tx_sw_if_index_set == 0))
5710     {
5711       errmsg ("missing tx interface name or tx_sw_if_index");
5712       return -99;
5713     }
5714
5715   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5716
5717   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5718   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5719   mp->enable = enable;
5720
5721   S (mp);
5722   W (ret);
5723   return ret;
5724 }
5725
5726 static int
5727 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5728 {
5729   unformat_input_t *i = vam->input;
5730   vl_api_sw_interface_set_l2_bridge_t *mp;
5731   u32 rx_sw_if_index;
5732   u8 rx_sw_if_index_set = 0;
5733   u32 bd_id;
5734   u8 bd_id_set = 0;
5735   u8 bvi = 0;
5736   u32 shg = 0;
5737   u8 enable = 1;
5738   int ret;
5739
5740   /* Parse args required to build the message */
5741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5742     {
5743       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5744         rx_sw_if_index_set = 1;
5745       else if (unformat (i, "bd_id %d", &bd_id))
5746         bd_id_set = 1;
5747       else
5748         if (unformat
5749             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5750         rx_sw_if_index_set = 1;
5751       else if (unformat (i, "shg %d", &shg))
5752         ;
5753       else if (unformat (i, "bvi"))
5754         bvi = 1;
5755       else if (unformat (i, "enable"))
5756         enable = 1;
5757       else if (unformat (i, "disable"))
5758         enable = 0;
5759       else
5760         break;
5761     }
5762
5763   if (rx_sw_if_index_set == 0)
5764     {
5765       errmsg ("missing rx interface name or sw_if_index");
5766       return -99;
5767     }
5768
5769   if (enable && (bd_id_set == 0))
5770     {
5771       errmsg ("missing bridge domain");
5772       return -99;
5773     }
5774
5775   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5776
5777   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5778   mp->bd_id = ntohl (bd_id);
5779   mp->shg = (u8) shg;
5780   mp->bvi = bvi;
5781   mp->enable = enable;
5782
5783   S (mp);
5784   W (ret);
5785   return ret;
5786 }
5787
5788 static int
5789 api_bridge_domain_dump (vat_main_t * vam)
5790 {
5791   unformat_input_t *i = vam->input;
5792   vl_api_bridge_domain_dump_t *mp;
5793   vl_api_control_ping_t *mp_ping;
5794   u32 bd_id = ~0;
5795   int ret;
5796
5797   /* Parse args required to build the message */
5798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5799     {
5800       if (unformat (i, "bd_id %d", &bd_id))
5801         ;
5802       else
5803         break;
5804     }
5805
5806   M (BRIDGE_DOMAIN_DUMP, mp);
5807   mp->bd_id = ntohl (bd_id);
5808   S (mp);
5809
5810   /* Use a control ping for synchronization */
5811   M (CONTROL_PING, mp_ping);
5812   S (mp_ping);
5813
5814   W (ret);
5815   return ret;
5816 }
5817
5818 static int
5819 api_bridge_domain_add_del (vat_main_t * vam)
5820 {
5821   unformat_input_t *i = vam->input;
5822   vl_api_bridge_domain_add_del_t *mp;
5823   u32 bd_id = ~0;
5824   u8 is_add = 1;
5825   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5826   u32 mac_age = 0;
5827   int ret;
5828
5829   /* Parse args required to build the message */
5830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5831     {
5832       if (unformat (i, "bd_id %d", &bd_id))
5833         ;
5834       else if (unformat (i, "flood %d", &flood))
5835         ;
5836       else if (unformat (i, "uu-flood %d", &uu_flood))
5837         ;
5838       else if (unformat (i, "forward %d", &forward))
5839         ;
5840       else if (unformat (i, "learn %d", &learn))
5841         ;
5842       else if (unformat (i, "arp-term %d", &arp_term))
5843         ;
5844       else if (unformat (i, "mac-age %d", &mac_age))
5845         ;
5846       else if (unformat (i, "del"))
5847         {
5848           is_add = 0;
5849           flood = uu_flood = forward = learn = 0;
5850         }
5851       else
5852         break;
5853     }
5854
5855   if (bd_id == ~0)
5856     {
5857       errmsg ("missing bridge domain");
5858       return -99;
5859     }
5860
5861   if (mac_age > 255)
5862     {
5863       errmsg ("mac age must be less than 256 ");
5864       return -99;
5865     }
5866
5867   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5868
5869   mp->bd_id = ntohl (bd_id);
5870   mp->flood = flood;
5871   mp->uu_flood = uu_flood;
5872   mp->forward = forward;
5873   mp->learn = learn;
5874   mp->arp_term = arp_term;
5875   mp->is_add = is_add;
5876   mp->mac_age = (u8) mac_age;
5877
5878   S (mp);
5879   W (ret);
5880   return ret;
5881 }
5882
5883 static int
5884 api_l2fib_add_del (vat_main_t * vam)
5885 {
5886   unformat_input_t *i = vam->input;
5887   vl_api_l2fib_add_del_t *mp;
5888   f64 timeout;
5889   u64 mac = 0;
5890   u8 mac_set = 0;
5891   u32 bd_id;
5892   u8 bd_id_set = 0;
5893   u32 sw_if_index = ~0;
5894   u8 sw_if_index_set = 0;
5895   u8 is_add = 1;
5896   u8 static_mac = 0;
5897   u8 filter_mac = 0;
5898   u8 bvi_mac = 0;
5899   int count = 1;
5900   f64 before = 0;
5901   int j;
5902
5903   /* Parse args required to build the message */
5904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5905     {
5906       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5907         mac_set = 1;
5908       else if (unformat (i, "bd_id %d", &bd_id))
5909         bd_id_set = 1;
5910       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5911         sw_if_index_set = 1;
5912       else if (unformat (i, "sw_if"))
5913         {
5914           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5915             {
5916               if (unformat
5917                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5918                 sw_if_index_set = 1;
5919             }
5920           else
5921             break;
5922         }
5923       else if (unformat (i, "static"))
5924         static_mac = 1;
5925       else if (unformat (i, "filter"))
5926         {
5927           filter_mac = 1;
5928           static_mac = 1;
5929         }
5930       else if (unformat (i, "bvi"))
5931         {
5932           bvi_mac = 1;
5933           static_mac = 1;
5934         }
5935       else if (unformat (i, "del"))
5936         is_add = 0;
5937       else if (unformat (i, "count %d", &count))
5938         ;
5939       else
5940         break;
5941     }
5942
5943   if (mac_set == 0)
5944     {
5945       errmsg ("missing mac address");
5946       return -99;
5947     }
5948
5949   if (bd_id_set == 0)
5950     {
5951       errmsg ("missing bridge domain");
5952       return -99;
5953     }
5954
5955   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5956     {
5957       errmsg ("missing interface name or sw_if_index");
5958       return -99;
5959     }
5960
5961   if (count > 1)
5962     {
5963       /* Turn on async mode */
5964       vam->async_mode = 1;
5965       vam->async_errors = 0;
5966       before = vat_time_now (vam);
5967     }
5968
5969   for (j = 0; j < count; j++)
5970     {
5971       M (L2FIB_ADD_DEL, mp);
5972
5973       mp->mac = mac;
5974       mp->bd_id = ntohl (bd_id);
5975       mp->is_add = is_add;
5976
5977       if (is_add)
5978         {
5979           mp->sw_if_index = ntohl (sw_if_index);
5980           mp->static_mac = static_mac;
5981           mp->filter_mac = filter_mac;
5982           mp->bvi_mac = bvi_mac;
5983         }
5984       increment_mac_address (&mac);
5985       /* send it... */
5986       S (mp);
5987     }
5988
5989   if (count > 1)
5990     {
5991       vl_api_control_ping_t *mp_ping;
5992       f64 after;
5993
5994       /* Shut off async mode */
5995       vam->async_mode = 0;
5996
5997       M (CONTROL_PING, mp_ping);
5998       S (mp_ping);
5999
6000       timeout = vat_time_now (vam) + 1.0;
6001       while (vat_time_now (vam) < timeout)
6002         if (vam->result_ready == 1)
6003           goto out;
6004       vam->retval = -99;
6005
6006     out:
6007       if (vam->retval == -99)
6008         errmsg ("timeout");
6009
6010       if (vam->async_errors > 0)
6011         {
6012           errmsg ("%d asynchronous errors", vam->async_errors);
6013           vam->retval = -98;
6014         }
6015       vam->async_errors = 0;
6016       after = vat_time_now (vam);
6017
6018       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6019              count, after - before, count / (after - before));
6020     }
6021   else
6022     {
6023       int ret;
6024
6025       /* Wait for a reply... */
6026       W (ret);
6027       return ret;
6028     }
6029   /* Return the good/bad news */
6030   return (vam->retval);
6031 }
6032
6033 static int
6034 api_l2_flags (vat_main_t * vam)
6035 {
6036   unformat_input_t *i = vam->input;
6037   vl_api_l2_flags_t *mp;
6038   u32 sw_if_index;
6039   u32 feature_bitmap = 0;
6040   u8 sw_if_index_set = 0;
6041   int ret;
6042
6043   /* Parse args required to build the message */
6044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6045     {
6046       if (unformat (i, "sw_if_index %d", &sw_if_index))
6047         sw_if_index_set = 1;
6048       else if (unformat (i, "sw_if"))
6049         {
6050           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6051             {
6052               if (unformat
6053                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6054                 sw_if_index_set = 1;
6055             }
6056           else
6057             break;
6058         }
6059       else if (unformat (i, "learn"))
6060         feature_bitmap |= L2INPUT_FEAT_LEARN;
6061       else if (unformat (i, "forward"))
6062         feature_bitmap |= L2INPUT_FEAT_FWD;
6063       else if (unformat (i, "flood"))
6064         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6065       else if (unformat (i, "uu-flood"))
6066         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6067       else
6068         break;
6069     }
6070
6071   if (sw_if_index_set == 0)
6072     {
6073       errmsg ("missing interface name or sw_if_index");
6074       return -99;
6075     }
6076
6077   M (L2_FLAGS, mp);
6078
6079   mp->sw_if_index = ntohl (sw_if_index);
6080   mp->feature_bitmap = ntohl (feature_bitmap);
6081
6082   S (mp);
6083   W (ret);
6084   return ret;
6085 }
6086
6087 static int
6088 api_bridge_flags (vat_main_t * vam)
6089 {
6090   unformat_input_t *i = vam->input;
6091   vl_api_bridge_flags_t *mp;
6092   u32 bd_id;
6093   u8 bd_id_set = 0;
6094   u8 is_set = 1;
6095   u32 flags = 0;
6096   int ret;
6097
6098   /* Parse args required to build the message */
6099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6100     {
6101       if (unformat (i, "bd_id %d", &bd_id))
6102         bd_id_set = 1;
6103       else if (unformat (i, "learn"))
6104         flags |= L2_LEARN;
6105       else if (unformat (i, "forward"))
6106         flags |= L2_FWD;
6107       else if (unformat (i, "flood"))
6108         flags |= L2_FLOOD;
6109       else if (unformat (i, "uu-flood"))
6110         flags |= L2_UU_FLOOD;
6111       else if (unformat (i, "arp-term"))
6112         flags |= L2_ARP_TERM;
6113       else if (unformat (i, "off"))
6114         is_set = 0;
6115       else if (unformat (i, "disable"))
6116         is_set = 0;
6117       else
6118         break;
6119     }
6120
6121   if (bd_id_set == 0)
6122     {
6123       errmsg ("missing bridge domain");
6124       return -99;
6125     }
6126
6127   M (BRIDGE_FLAGS, mp);
6128
6129   mp->bd_id = ntohl (bd_id);
6130   mp->feature_bitmap = ntohl (flags);
6131   mp->is_set = is_set;
6132
6133   S (mp);
6134   W (ret);
6135   return ret;
6136 }
6137
6138 static int
6139 api_bd_ip_mac_add_del (vat_main_t * vam)
6140 {
6141   unformat_input_t *i = vam->input;
6142   vl_api_bd_ip_mac_add_del_t *mp;
6143   u32 bd_id;
6144   u8 is_ipv6 = 0;
6145   u8 is_add = 1;
6146   u8 bd_id_set = 0;
6147   u8 ip_set = 0;
6148   u8 mac_set = 0;
6149   ip4_address_t v4addr;
6150   ip6_address_t v6addr;
6151   u8 macaddr[6];
6152   int ret;
6153
6154
6155   /* Parse args required to build the message */
6156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6157     {
6158       if (unformat (i, "bd_id %d", &bd_id))
6159         {
6160           bd_id_set++;
6161         }
6162       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6163         {
6164           ip_set++;
6165         }
6166       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6167         {
6168           ip_set++;
6169           is_ipv6++;
6170         }
6171       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6172         {
6173           mac_set++;
6174         }
6175       else if (unformat (i, "del"))
6176         is_add = 0;
6177       else
6178         break;
6179     }
6180
6181   if (bd_id_set == 0)
6182     {
6183       errmsg ("missing bridge domain");
6184       return -99;
6185     }
6186   else if (ip_set == 0)
6187     {
6188       errmsg ("missing IP address");
6189       return -99;
6190     }
6191   else if (mac_set == 0)
6192     {
6193       errmsg ("missing MAC address");
6194       return -99;
6195     }
6196
6197   M (BD_IP_MAC_ADD_DEL, mp);
6198
6199   mp->bd_id = ntohl (bd_id);
6200   mp->is_ipv6 = is_ipv6;
6201   mp->is_add = is_add;
6202   if (is_ipv6)
6203     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6204   else
6205     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6206   clib_memcpy (mp->mac_address, macaddr, 6);
6207   S (mp);
6208   W (ret);
6209   return ret;
6210 }
6211
6212 static int
6213 api_tap_connect (vat_main_t * vam)
6214 {
6215   unformat_input_t *i = vam->input;
6216   vl_api_tap_connect_t *mp;
6217   u8 mac_address[6];
6218   u8 random_mac = 1;
6219   u8 name_set = 0;
6220   u8 *tap_name;
6221   u8 *tag = 0;
6222   ip4_address_t ip4_address;
6223   u32 ip4_mask_width;
6224   int ip4_address_set = 0;
6225   ip6_address_t ip6_address;
6226   u32 ip6_mask_width;
6227   int ip6_address_set = 0;
6228   int ret;
6229
6230   memset (mac_address, 0, sizeof (mac_address));
6231
6232   /* Parse args required to build the message */
6233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6234     {
6235       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6236         {
6237           random_mac = 0;
6238         }
6239       else if (unformat (i, "random-mac"))
6240         random_mac = 1;
6241       else if (unformat (i, "tapname %s", &tap_name))
6242         name_set = 1;
6243       else if (unformat (i, "tag %s", &tag))
6244         ;
6245       else if (unformat (i, "address %U/%d",
6246                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6247         ip4_address_set = 1;
6248       else if (unformat (i, "address %U/%d",
6249                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6250         ip6_address_set = 1;
6251       else
6252         break;
6253     }
6254
6255   if (name_set == 0)
6256     {
6257       errmsg ("missing tap name");
6258       return -99;
6259     }
6260   if (vec_len (tap_name) > 63)
6261     {
6262       errmsg ("tap name too long");
6263       return -99;
6264     }
6265   vec_add1 (tap_name, 0);
6266
6267   if (vec_len (tag) > 63)
6268     {
6269       errmsg ("tag too long");
6270       return -99;
6271     }
6272
6273   /* Construct the API message */
6274   M (TAP_CONNECT, mp);
6275
6276   mp->use_random_mac = random_mac;
6277   clib_memcpy (mp->mac_address, mac_address, 6);
6278   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6279   if (tag)
6280     clib_memcpy (mp->tag, tag, vec_len (tag));
6281
6282   if (ip4_address_set)
6283     {
6284       mp->ip4_address_set = 1;
6285       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6286       mp->ip4_mask_width = ip4_mask_width;
6287     }
6288   if (ip6_address_set)
6289     {
6290       mp->ip6_address_set = 1;
6291       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6292       mp->ip6_mask_width = ip6_mask_width;
6293     }
6294
6295   vec_free (tap_name);
6296   vec_free (tag);
6297
6298   /* send it... */
6299   S (mp);
6300
6301   /* Wait for a reply... */
6302   W (ret);
6303   return ret;
6304 }
6305
6306 static int
6307 api_tap_modify (vat_main_t * vam)
6308 {
6309   unformat_input_t *i = vam->input;
6310   vl_api_tap_modify_t *mp;
6311   u8 mac_address[6];
6312   u8 random_mac = 1;
6313   u8 name_set = 0;
6314   u8 *tap_name;
6315   u32 sw_if_index = ~0;
6316   u8 sw_if_index_set = 0;
6317   int ret;
6318
6319   memset (mac_address, 0, sizeof (mac_address));
6320
6321   /* Parse args required to build the message */
6322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6323     {
6324       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6325         sw_if_index_set = 1;
6326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6327         sw_if_index_set = 1;
6328       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6329         {
6330           random_mac = 0;
6331         }
6332       else if (unformat (i, "random-mac"))
6333         random_mac = 1;
6334       else if (unformat (i, "tapname %s", &tap_name))
6335         name_set = 1;
6336       else
6337         break;
6338     }
6339
6340   if (sw_if_index_set == 0)
6341     {
6342       errmsg ("missing vpp interface name");
6343       return -99;
6344     }
6345   if (name_set == 0)
6346     {
6347       errmsg ("missing tap name");
6348       return -99;
6349     }
6350   if (vec_len (tap_name) > 63)
6351     {
6352       errmsg ("tap name too long");
6353     }
6354   vec_add1 (tap_name, 0);
6355
6356   /* Construct the API message */
6357   M (TAP_MODIFY, mp);
6358
6359   mp->use_random_mac = random_mac;
6360   mp->sw_if_index = ntohl (sw_if_index);
6361   clib_memcpy (mp->mac_address, mac_address, 6);
6362   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6363   vec_free (tap_name);
6364
6365   /* send it... */
6366   S (mp);
6367
6368   /* Wait for a reply... */
6369   W (ret);
6370   return ret;
6371 }
6372
6373 static int
6374 api_tap_delete (vat_main_t * vam)
6375 {
6376   unformat_input_t *i = vam->input;
6377   vl_api_tap_delete_t *mp;
6378   u32 sw_if_index = ~0;
6379   u8 sw_if_index_set = 0;
6380   int ret;
6381
6382   /* Parse args required to build the message */
6383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6384     {
6385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6386         sw_if_index_set = 1;
6387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6388         sw_if_index_set = 1;
6389       else
6390         break;
6391     }
6392
6393   if (sw_if_index_set == 0)
6394     {
6395       errmsg ("missing vpp interface name");
6396       return -99;
6397     }
6398
6399   /* Construct the API message */
6400   M (TAP_DELETE, mp);
6401
6402   mp->sw_if_index = ntohl (sw_if_index);
6403
6404   /* send it... */
6405   S (mp);
6406
6407   /* Wait for a reply... */
6408   W (ret);
6409   return ret;
6410 }
6411
6412 static int
6413 api_ip_add_del_route (vat_main_t * vam)
6414 {
6415   unformat_input_t *i = vam->input;
6416   vl_api_ip_add_del_route_t *mp;
6417   u32 sw_if_index = ~0, vrf_id = 0;
6418   u8 is_ipv6 = 0;
6419   u8 is_local = 0, is_drop = 0;
6420   u8 is_unreach = 0, is_prohibit = 0;
6421   u8 create_vrf_if_needed = 0;
6422   u8 is_add = 1;
6423   u32 next_hop_weight = 1;
6424   u8 not_last = 0;
6425   u8 is_multipath = 0;
6426   u8 address_set = 0;
6427   u8 address_length_set = 0;
6428   u32 next_hop_table_id = 0;
6429   u32 resolve_attempts = 0;
6430   u32 dst_address_length = 0;
6431   u8 next_hop_set = 0;
6432   ip4_address_t v4_dst_address, v4_next_hop_address;
6433   ip6_address_t v6_dst_address, v6_next_hop_address;
6434   int count = 1;
6435   int j;
6436   f64 before = 0;
6437   u32 random_add_del = 0;
6438   u32 *random_vector = 0;
6439   uword *random_hash;
6440   u32 random_seed = 0xdeaddabe;
6441   u32 classify_table_index = ~0;
6442   u8 is_classify = 0;
6443   u8 resolve_host = 0, resolve_attached = 0;
6444   mpls_label_t *next_hop_out_label_stack = NULL;
6445   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6446   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6447
6448   /* Parse args required to build the message */
6449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6450     {
6451       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6452         ;
6453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6454         ;
6455       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6456         {
6457           address_set = 1;
6458           is_ipv6 = 0;
6459         }
6460       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6461         {
6462           address_set = 1;
6463           is_ipv6 = 1;
6464         }
6465       else if (unformat (i, "/%d", &dst_address_length))
6466         {
6467           address_length_set = 1;
6468         }
6469
6470       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6471                                          &v4_next_hop_address))
6472         {
6473           next_hop_set = 1;
6474         }
6475       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6476                                          &v6_next_hop_address))
6477         {
6478           next_hop_set = 1;
6479         }
6480       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6481         ;
6482       else if (unformat (i, "weight %d", &next_hop_weight))
6483         ;
6484       else if (unformat (i, "drop"))
6485         {
6486           is_drop = 1;
6487         }
6488       else if (unformat (i, "null-send-unreach"))
6489         {
6490           is_unreach = 1;
6491         }
6492       else if (unformat (i, "null-send-prohibit"))
6493         {
6494           is_prohibit = 1;
6495         }
6496       else if (unformat (i, "local"))
6497         {
6498           is_local = 1;
6499         }
6500       else if (unformat (i, "classify %d", &classify_table_index))
6501         {
6502           is_classify = 1;
6503         }
6504       else if (unformat (i, "del"))
6505         is_add = 0;
6506       else if (unformat (i, "add"))
6507         is_add = 1;
6508       else if (unformat (i, "not-last"))
6509         not_last = 1;
6510       else if (unformat (i, "resolve-via-host"))
6511         resolve_host = 1;
6512       else if (unformat (i, "resolve-via-attached"))
6513         resolve_attached = 1;
6514       else if (unformat (i, "multipath"))
6515         is_multipath = 1;
6516       else if (unformat (i, "vrf %d", &vrf_id))
6517         ;
6518       else if (unformat (i, "create-vrf"))
6519         create_vrf_if_needed = 1;
6520       else if (unformat (i, "count %d", &count))
6521         ;
6522       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6523         ;
6524       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6525         ;
6526       else if (unformat (i, "out-label %d", &next_hop_out_label))
6527         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6528       else if (unformat (i, "via-label %d", &next_hop_via_label))
6529         ;
6530       else if (unformat (i, "random"))
6531         random_add_del = 1;
6532       else if (unformat (i, "seed %d", &random_seed))
6533         ;
6534       else
6535         {
6536           clib_warning ("parse error '%U'", format_unformat_error, i);
6537           return -99;
6538         }
6539     }
6540
6541   if (!next_hop_set && !is_drop && !is_local &&
6542       !is_classify && !is_unreach && !is_prohibit &&
6543       MPLS_LABEL_INVALID == next_hop_via_label)
6544     {
6545       errmsg
6546         ("next hop / local / drop / unreach / prohibit / classify not set");
6547       return -99;
6548     }
6549
6550   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6551     {
6552       errmsg ("next hop and next-hop via label set");
6553       return -99;
6554     }
6555   if (address_set == 0)
6556     {
6557       errmsg ("missing addresses");
6558       return -99;
6559     }
6560
6561   if (address_length_set == 0)
6562     {
6563       errmsg ("missing address length");
6564       return -99;
6565     }
6566
6567   /* Generate a pile of unique, random routes */
6568   if (random_add_del)
6569     {
6570       u32 this_random_address;
6571       random_hash = hash_create (count, sizeof (uword));
6572
6573       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6574       for (j = 0; j <= count; j++)
6575         {
6576           do
6577             {
6578               this_random_address = random_u32 (&random_seed);
6579               this_random_address =
6580                 clib_host_to_net_u32 (this_random_address);
6581             }
6582           while (hash_get (random_hash, this_random_address));
6583           vec_add1 (random_vector, this_random_address);
6584           hash_set (random_hash, this_random_address, 1);
6585         }
6586       hash_free (random_hash);
6587       v4_dst_address.as_u32 = random_vector[0];
6588     }
6589
6590   if (count > 1)
6591     {
6592       /* Turn on async mode */
6593       vam->async_mode = 1;
6594       vam->async_errors = 0;
6595       before = vat_time_now (vam);
6596     }
6597
6598   for (j = 0; j < count; j++)
6599     {
6600       /* Construct the API message */
6601       M2 (IP_ADD_DEL_ROUTE, mp,
6602           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6603
6604       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6605       mp->table_id = ntohl (vrf_id);
6606       mp->create_vrf_if_needed = create_vrf_if_needed;
6607
6608       mp->is_add = is_add;
6609       mp->is_drop = is_drop;
6610       mp->is_unreach = is_unreach;
6611       mp->is_prohibit = is_prohibit;
6612       mp->is_ipv6 = is_ipv6;
6613       mp->is_local = is_local;
6614       mp->is_classify = is_classify;
6615       mp->is_multipath = is_multipath;
6616       mp->is_resolve_host = resolve_host;
6617       mp->is_resolve_attached = resolve_attached;
6618       mp->not_last = not_last;
6619       mp->next_hop_weight = next_hop_weight;
6620       mp->dst_address_length = dst_address_length;
6621       mp->next_hop_table_id = ntohl (next_hop_table_id);
6622       mp->classify_table_index = ntohl (classify_table_index);
6623       mp->next_hop_via_label = ntohl (next_hop_via_label);
6624       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6625       if (0 != mp->next_hop_n_out_labels)
6626         {
6627           memcpy (mp->next_hop_out_label_stack,
6628                   next_hop_out_label_stack,
6629                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6630           vec_free (next_hop_out_label_stack);
6631         }
6632
6633       if (is_ipv6)
6634         {
6635           clib_memcpy (mp->dst_address, &v6_dst_address,
6636                        sizeof (v6_dst_address));
6637           if (next_hop_set)
6638             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6639                          sizeof (v6_next_hop_address));
6640           increment_v6_address (&v6_dst_address);
6641         }
6642       else
6643         {
6644           clib_memcpy (mp->dst_address, &v4_dst_address,
6645                        sizeof (v4_dst_address));
6646           if (next_hop_set)
6647             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6648                          sizeof (v4_next_hop_address));
6649           if (random_add_del)
6650             v4_dst_address.as_u32 = random_vector[j + 1];
6651           else
6652             increment_v4_address (&v4_dst_address);
6653         }
6654       /* send it... */
6655       S (mp);
6656       /* If we receive SIGTERM, stop now... */
6657       if (vam->do_exit)
6658         break;
6659     }
6660
6661   /* When testing multiple add/del ops, use a control-ping to sync */
6662   if (count > 1)
6663     {
6664       vl_api_control_ping_t *mp_ping;
6665       f64 after;
6666       f64 timeout;
6667
6668       /* Shut off async mode */
6669       vam->async_mode = 0;
6670
6671       M (CONTROL_PING, mp_ping);
6672       S (mp_ping);
6673
6674       timeout = vat_time_now (vam) + 1.0;
6675       while (vat_time_now (vam) < timeout)
6676         if (vam->result_ready == 1)
6677           goto out;
6678       vam->retval = -99;
6679
6680     out:
6681       if (vam->retval == -99)
6682         errmsg ("timeout");
6683
6684       if (vam->async_errors > 0)
6685         {
6686           errmsg ("%d asynchronous errors", vam->async_errors);
6687           vam->retval = -98;
6688         }
6689       vam->async_errors = 0;
6690       after = vat_time_now (vam);
6691
6692       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6693       if (j > 0)
6694         count = j;
6695
6696       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6697              count, after - before, count / (after - before));
6698     }
6699   else
6700     {
6701       int ret;
6702
6703       /* Wait for a reply... */
6704       W (ret);
6705       return ret;
6706     }
6707
6708   /* Return the good/bad news */
6709   return (vam->retval);
6710 }
6711
6712 static int
6713 api_ip_mroute_add_del (vat_main_t * vam)
6714 {
6715   unformat_input_t *i = vam->input;
6716   vl_api_ip_mroute_add_del_t *mp;
6717   u32 sw_if_index = ~0, vrf_id = 0;
6718   u8 is_ipv6 = 0;
6719   u8 is_local = 0;
6720   u8 create_vrf_if_needed = 0;
6721   u8 is_add = 1;
6722   u8 address_set = 0;
6723   u32 grp_address_length = 0;
6724   ip4_address_t v4_grp_address, v4_src_address;
6725   ip6_address_t v6_grp_address, v6_src_address;
6726   mfib_itf_flags_t iflags = 0;
6727   mfib_entry_flags_t eflags = 0;
6728   int ret;
6729
6730   /* Parse args required to build the message */
6731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6732     {
6733       if (unformat (i, "sw_if_index %d", &sw_if_index))
6734         ;
6735       else if (unformat (i, "%U %U",
6736                          unformat_ip4_address, &v4_src_address,
6737                          unformat_ip4_address, &v4_grp_address))
6738         {
6739           grp_address_length = 64;
6740           address_set = 1;
6741           is_ipv6 = 0;
6742         }
6743       else if (unformat (i, "%U %U",
6744                          unformat_ip6_address, &v6_src_address,
6745                          unformat_ip6_address, &v6_grp_address))
6746         {
6747           grp_address_length = 256;
6748           address_set = 1;
6749           is_ipv6 = 1;
6750         }
6751       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6752         {
6753           memset (&v4_src_address, 0, sizeof (v4_src_address));
6754           grp_address_length = 32;
6755           address_set = 1;
6756           is_ipv6 = 0;
6757         }
6758       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6759         {
6760           memset (&v6_src_address, 0, sizeof (v6_src_address));
6761           grp_address_length = 128;
6762           address_set = 1;
6763           is_ipv6 = 1;
6764         }
6765       else if (unformat (i, "/%d", &grp_address_length))
6766         ;
6767       else if (unformat (i, "local"))
6768         {
6769           is_local = 1;
6770         }
6771       else if (unformat (i, "del"))
6772         is_add = 0;
6773       else if (unformat (i, "add"))
6774         is_add = 1;
6775       else if (unformat (i, "vrf %d", &vrf_id))
6776         ;
6777       else if (unformat (i, "create-vrf"))
6778         create_vrf_if_needed = 1;
6779       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6780         ;
6781       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6782         ;
6783       else
6784         {
6785           clib_warning ("parse error '%U'", format_unformat_error, i);
6786           return -99;
6787         }
6788     }
6789
6790   if (address_set == 0)
6791     {
6792       errmsg ("missing addresses\n");
6793       return -99;
6794     }
6795
6796   /* Construct the API message */
6797   M (IP_MROUTE_ADD_DEL, mp);
6798
6799   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6800   mp->table_id = ntohl (vrf_id);
6801   mp->create_vrf_if_needed = create_vrf_if_needed;
6802
6803   mp->is_add = is_add;
6804   mp->is_ipv6 = is_ipv6;
6805   mp->is_local = is_local;
6806   mp->itf_flags = ntohl (iflags);
6807   mp->entry_flags = ntohl (eflags);
6808   mp->grp_address_length = grp_address_length;
6809   mp->grp_address_length = ntohs (mp->grp_address_length);
6810
6811   if (is_ipv6)
6812     {
6813       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6814       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6815     }
6816   else
6817     {
6818       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6819       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6820
6821     }
6822
6823   /* send it... */
6824   S (mp);
6825   /* Wait for a reply... */
6826   W (ret);
6827   return ret;
6828 }
6829
6830 static int
6831 api_mpls_route_add_del (vat_main_t * vam)
6832 {
6833   unformat_input_t *i = vam->input;
6834   vl_api_mpls_route_add_del_t *mp;
6835   u32 sw_if_index = ~0, table_id = 0;
6836   u8 create_table_if_needed = 0;
6837   u8 is_add = 1;
6838   u32 next_hop_weight = 1;
6839   u8 is_multipath = 0;
6840   u32 next_hop_table_id = 0;
6841   u8 next_hop_set = 0;
6842   ip4_address_t v4_next_hop_address = {
6843     .as_u32 = 0,
6844   };
6845   ip6_address_t v6_next_hop_address = { {0} };
6846   int count = 1;
6847   int j;
6848   f64 before = 0;
6849   u32 classify_table_index = ~0;
6850   u8 is_classify = 0;
6851   u8 resolve_host = 0, resolve_attached = 0;
6852   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6853   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6854   mpls_label_t *next_hop_out_label_stack = NULL;
6855   mpls_label_t local_label = MPLS_LABEL_INVALID;
6856   u8 is_eos = 0;
6857   u8 next_hop_proto_is_ip4 = 1;
6858
6859   /* Parse args required to build the message */
6860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6861     {
6862       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6863         ;
6864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6865         ;
6866       else if (unformat (i, "%d", &local_label))
6867         ;
6868       else if (unformat (i, "eos"))
6869         is_eos = 1;
6870       else if (unformat (i, "non-eos"))
6871         is_eos = 0;
6872       else if (unformat (i, "via %U", unformat_ip4_address,
6873                          &v4_next_hop_address))
6874         {
6875           next_hop_set = 1;
6876           next_hop_proto_is_ip4 = 1;
6877         }
6878       else if (unformat (i, "via %U", unformat_ip6_address,
6879                          &v6_next_hop_address))
6880         {
6881           next_hop_set = 1;
6882           next_hop_proto_is_ip4 = 0;
6883         }
6884       else if (unformat (i, "weight %d", &next_hop_weight))
6885         ;
6886       else if (unformat (i, "create-table"))
6887         create_table_if_needed = 1;
6888       else if (unformat (i, "classify %d", &classify_table_index))
6889         {
6890           is_classify = 1;
6891         }
6892       else if (unformat (i, "del"))
6893         is_add = 0;
6894       else if (unformat (i, "add"))
6895         is_add = 1;
6896       else if (unformat (i, "resolve-via-host"))
6897         resolve_host = 1;
6898       else if (unformat (i, "resolve-via-attached"))
6899         resolve_attached = 1;
6900       else if (unformat (i, "multipath"))
6901         is_multipath = 1;
6902       else if (unformat (i, "count %d", &count))
6903         ;
6904       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6905         {
6906           next_hop_set = 1;
6907           next_hop_proto_is_ip4 = 1;
6908         }
6909       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6910         {
6911           next_hop_set = 1;
6912           next_hop_proto_is_ip4 = 0;
6913         }
6914       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6915         ;
6916       else if (unformat (i, "via-label %d", &next_hop_via_label))
6917         ;
6918       else if (unformat (i, "out-label %d", &next_hop_out_label))
6919         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6920       else
6921         {
6922           clib_warning ("parse error '%U'", format_unformat_error, i);
6923           return -99;
6924         }
6925     }
6926
6927   if (!next_hop_set && !is_classify)
6928     {
6929       errmsg ("next hop / classify not set");
6930       return -99;
6931     }
6932
6933   if (MPLS_LABEL_INVALID == local_label)
6934     {
6935       errmsg ("missing label");
6936       return -99;
6937     }
6938
6939   if (count > 1)
6940     {
6941       /* Turn on async mode */
6942       vam->async_mode = 1;
6943       vam->async_errors = 0;
6944       before = vat_time_now (vam);
6945     }
6946
6947   for (j = 0; j < count; j++)
6948     {
6949       /* Construct the API message */
6950       M2 (MPLS_ROUTE_ADD_DEL, mp,
6951           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6952
6953       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6954       mp->mr_table_id = ntohl (table_id);
6955       mp->mr_create_table_if_needed = create_table_if_needed;
6956
6957       mp->mr_is_add = is_add;
6958       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6959       mp->mr_is_classify = is_classify;
6960       mp->mr_is_multipath = is_multipath;
6961       mp->mr_is_resolve_host = resolve_host;
6962       mp->mr_is_resolve_attached = resolve_attached;
6963       mp->mr_next_hop_weight = next_hop_weight;
6964       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6965       mp->mr_classify_table_index = ntohl (classify_table_index);
6966       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6967       mp->mr_label = ntohl (local_label);
6968       mp->mr_eos = is_eos;
6969
6970       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6971       if (0 != mp->mr_next_hop_n_out_labels)
6972         {
6973           memcpy (mp->mr_next_hop_out_label_stack,
6974                   next_hop_out_label_stack,
6975                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6976           vec_free (next_hop_out_label_stack);
6977         }
6978
6979       if (next_hop_set)
6980         {
6981           if (next_hop_proto_is_ip4)
6982             {
6983               clib_memcpy (mp->mr_next_hop,
6984                            &v4_next_hop_address,
6985                            sizeof (v4_next_hop_address));
6986             }
6987           else
6988             {
6989               clib_memcpy (mp->mr_next_hop,
6990                            &v6_next_hop_address,
6991                            sizeof (v6_next_hop_address));
6992             }
6993         }
6994       local_label++;
6995
6996       /* send it... */
6997       S (mp);
6998       /* If we receive SIGTERM, stop now... */
6999       if (vam->do_exit)
7000         break;
7001     }
7002
7003   /* When testing multiple add/del ops, use a control-ping to sync */
7004   if (count > 1)
7005     {
7006       vl_api_control_ping_t *mp_ping;
7007       f64 after;
7008       f64 timeout;
7009
7010       /* Shut off async mode */
7011       vam->async_mode = 0;
7012
7013       M (CONTROL_PING, mp_ping);
7014       S (mp_ping);
7015
7016       timeout = vat_time_now (vam) + 1.0;
7017       while (vat_time_now (vam) < timeout)
7018         if (vam->result_ready == 1)
7019           goto out;
7020       vam->retval = -99;
7021
7022     out:
7023       if (vam->retval == -99)
7024         errmsg ("timeout");
7025
7026       if (vam->async_errors > 0)
7027         {
7028           errmsg ("%d asynchronous errors", vam->async_errors);
7029           vam->retval = -98;
7030         }
7031       vam->async_errors = 0;
7032       after = vat_time_now (vam);
7033
7034       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7035       if (j > 0)
7036         count = j;
7037
7038       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7039              count, after - before, count / (after - before));
7040     }
7041   else
7042     {
7043       int ret;
7044
7045       /* Wait for a reply... */
7046       W (ret);
7047       return ret;
7048     }
7049
7050   /* Return the good/bad news */
7051   return (vam->retval);
7052 }
7053
7054 static int
7055 api_mpls_ip_bind_unbind (vat_main_t * vam)
7056 {
7057   unformat_input_t *i = vam->input;
7058   vl_api_mpls_ip_bind_unbind_t *mp;
7059   u32 ip_table_id = 0;
7060   u8 create_table_if_needed = 0;
7061   u8 is_bind = 1;
7062   u8 is_ip4 = 1;
7063   ip4_address_t v4_address;
7064   ip6_address_t v6_address;
7065   u32 address_length;
7066   u8 address_set = 0;
7067   mpls_label_t local_label = MPLS_LABEL_INVALID;
7068   int ret;
7069
7070   /* Parse args required to build the message */
7071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7072     {
7073       if (unformat (i, "%U/%d", unformat_ip4_address,
7074                     &v4_address, &address_length))
7075         {
7076           is_ip4 = 1;
7077           address_set = 1;
7078         }
7079       else if (unformat (i, "%U/%d", unformat_ip6_address,
7080                          &v6_address, &address_length))
7081         {
7082           is_ip4 = 0;
7083           address_set = 1;
7084         }
7085       else if (unformat (i, "%d", &local_label))
7086         ;
7087       else if (unformat (i, "create-table"))
7088         create_table_if_needed = 1;
7089       else if (unformat (i, "table-id %d", &ip_table_id))
7090         ;
7091       else if (unformat (i, "unbind"))
7092         is_bind = 0;
7093       else if (unformat (i, "bind"))
7094         is_bind = 1;
7095       else
7096         {
7097           clib_warning ("parse error '%U'", format_unformat_error, i);
7098           return -99;
7099         }
7100     }
7101
7102   if (!address_set)
7103     {
7104       errmsg ("IP addres not set");
7105       return -99;
7106     }
7107
7108   if (MPLS_LABEL_INVALID == local_label)
7109     {
7110       errmsg ("missing label");
7111       return -99;
7112     }
7113
7114   /* Construct the API message */
7115   M (MPLS_IP_BIND_UNBIND, mp);
7116
7117   mp->mb_create_table_if_needed = create_table_if_needed;
7118   mp->mb_is_bind = is_bind;
7119   mp->mb_is_ip4 = is_ip4;
7120   mp->mb_ip_table_id = ntohl (ip_table_id);
7121   mp->mb_mpls_table_id = 0;
7122   mp->mb_label = ntohl (local_label);
7123   mp->mb_address_length = address_length;
7124
7125   if (is_ip4)
7126     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7127   else
7128     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7129
7130   /* send it... */
7131   S (mp);
7132
7133   /* Wait for a reply... */
7134   W (ret);
7135   return ret;
7136 }
7137
7138 static int
7139 api_proxy_arp_add_del (vat_main_t * vam)
7140 {
7141   unformat_input_t *i = vam->input;
7142   vl_api_proxy_arp_add_del_t *mp;
7143   u32 vrf_id = 0;
7144   u8 is_add = 1;
7145   ip4_address_t lo, hi;
7146   u8 range_set = 0;
7147   int ret;
7148
7149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7150     {
7151       if (unformat (i, "vrf %d", &vrf_id))
7152         ;
7153       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7154                          unformat_ip4_address, &hi))
7155         range_set = 1;
7156       else if (unformat (i, "del"))
7157         is_add = 0;
7158       else
7159         {
7160           clib_warning ("parse error '%U'", format_unformat_error, i);
7161           return -99;
7162         }
7163     }
7164
7165   if (range_set == 0)
7166     {
7167       errmsg ("address range not set");
7168       return -99;
7169     }
7170
7171   M (PROXY_ARP_ADD_DEL, mp);
7172
7173   mp->vrf_id = ntohl (vrf_id);
7174   mp->is_add = is_add;
7175   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7176   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7177
7178   S (mp);
7179   W (ret);
7180   return ret;
7181 }
7182
7183 static int
7184 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7185 {
7186   unformat_input_t *i = vam->input;
7187   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7188   u32 sw_if_index;
7189   u8 enable = 1;
7190   u8 sw_if_index_set = 0;
7191   int ret;
7192
7193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7194     {
7195       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7196         sw_if_index_set = 1;
7197       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7198         sw_if_index_set = 1;
7199       else if (unformat (i, "enable"))
7200         enable = 1;
7201       else if (unformat (i, "disable"))
7202         enable = 0;
7203       else
7204         {
7205           clib_warning ("parse error '%U'", format_unformat_error, i);
7206           return -99;
7207         }
7208     }
7209
7210   if (sw_if_index_set == 0)
7211     {
7212       errmsg ("missing interface name or sw_if_index");
7213       return -99;
7214     }
7215
7216   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7217
7218   mp->sw_if_index = ntohl (sw_if_index);
7219   mp->enable_disable = enable;
7220
7221   S (mp);
7222   W (ret);
7223   return ret;
7224 }
7225
7226 static int
7227 api_mpls_tunnel_add_del (vat_main_t * vam)
7228 {
7229   unformat_input_t *i = vam->input;
7230   vl_api_mpls_tunnel_add_del_t *mp;
7231
7232   u8 is_add = 1;
7233   u8 l2_only = 0;
7234   u32 sw_if_index = ~0;
7235   u32 next_hop_sw_if_index = ~0;
7236   u32 next_hop_proto_is_ip4 = 1;
7237
7238   u32 next_hop_table_id = 0;
7239   ip4_address_t v4_next_hop_address = {
7240     .as_u32 = 0,
7241   };
7242   ip6_address_t v6_next_hop_address = { {0} };
7243   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7244   int ret;
7245
7246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7247     {
7248       if (unformat (i, "add"))
7249         is_add = 1;
7250       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7251         is_add = 0;
7252       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7253         ;
7254       else if (unformat (i, "via %U",
7255                          unformat_ip4_address, &v4_next_hop_address))
7256         {
7257           next_hop_proto_is_ip4 = 1;
7258         }
7259       else if (unformat (i, "via %U",
7260                          unformat_ip6_address, &v6_next_hop_address))
7261         {
7262           next_hop_proto_is_ip4 = 0;
7263         }
7264       else if (unformat (i, "l2-only"))
7265         l2_only = 1;
7266       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7267         ;
7268       else if (unformat (i, "out-label %d", &next_hop_out_label))
7269         vec_add1 (labels, ntohl (next_hop_out_label));
7270       else
7271         {
7272           clib_warning ("parse error '%U'", format_unformat_error, i);
7273           return -99;
7274         }
7275     }
7276
7277   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7278
7279   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7280   mp->mt_sw_if_index = ntohl (sw_if_index);
7281   mp->mt_is_add = is_add;
7282   mp->mt_l2_only = l2_only;
7283   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7284   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7285
7286   mp->mt_next_hop_n_out_labels = vec_len (labels);
7287
7288   if (0 != mp->mt_next_hop_n_out_labels)
7289     {
7290       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7291                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7292       vec_free (labels);
7293     }
7294
7295   if (next_hop_proto_is_ip4)
7296     {
7297       clib_memcpy (mp->mt_next_hop,
7298                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7299     }
7300   else
7301     {
7302       clib_memcpy (mp->mt_next_hop,
7303                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7304     }
7305
7306   S (mp);
7307   W (ret);
7308   return ret;
7309 }
7310
7311 static int
7312 api_sw_interface_set_unnumbered (vat_main_t * vam)
7313 {
7314   unformat_input_t *i = vam->input;
7315   vl_api_sw_interface_set_unnumbered_t *mp;
7316   u32 sw_if_index;
7317   u32 unnum_sw_index = ~0;
7318   u8 is_add = 1;
7319   u8 sw_if_index_set = 0;
7320   int ret;
7321
7322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7323     {
7324       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7325         sw_if_index_set = 1;
7326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7327         sw_if_index_set = 1;
7328       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7329         ;
7330       else if (unformat (i, "del"))
7331         is_add = 0;
7332       else
7333         {
7334           clib_warning ("parse error '%U'", format_unformat_error, i);
7335           return -99;
7336         }
7337     }
7338
7339   if (sw_if_index_set == 0)
7340     {
7341       errmsg ("missing interface name or sw_if_index");
7342       return -99;
7343     }
7344
7345   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7346
7347   mp->sw_if_index = ntohl (sw_if_index);
7348   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7349   mp->is_add = is_add;
7350
7351   S (mp);
7352   W (ret);
7353   return ret;
7354 }
7355
7356 static int
7357 api_ip_neighbor_add_del (vat_main_t * vam)
7358 {
7359   unformat_input_t *i = vam->input;
7360   vl_api_ip_neighbor_add_del_t *mp;
7361   u32 sw_if_index;
7362   u8 sw_if_index_set = 0;
7363   u8 is_add = 1;
7364   u8 is_static = 0;
7365   u8 is_no_fib_entry = 0;
7366   u8 mac_address[6];
7367   u8 mac_set = 0;
7368   u8 v4_address_set = 0;
7369   u8 v6_address_set = 0;
7370   ip4_address_t v4address;
7371   ip6_address_t v6address;
7372   int ret;
7373
7374   memset (mac_address, 0, sizeof (mac_address));
7375
7376   /* Parse args required to build the message */
7377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7378     {
7379       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7380         {
7381           mac_set = 1;
7382         }
7383       else if (unformat (i, "del"))
7384         is_add = 0;
7385       else
7386         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7387         sw_if_index_set = 1;
7388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7389         sw_if_index_set = 1;
7390       else if (unformat (i, "is_static"))
7391         is_static = 1;
7392       else if (unformat (i, "no-fib-entry"))
7393         is_no_fib_entry = 1;
7394       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7395         v4_address_set = 1;
7396       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7397         v6_address_set = 1;
7398       else
7399         {
7400           clib_warning ("parse error '%U'", format_unformat_error, i);
7401           return -99;
7402         }
7403     }
7404
7405   if (sw_if_index_set == 0)
7406     {
7407       errmsg ("missing interface name or sw_if_index");
7408       return -99;
7409     }
7410   if (v4_address_set && v6_address_set)
7411     {
7412       errmsg ("both v4 and v6 addresses set");
7413       return -99;
7414     }
7415   if (!v4_address_set && !v6_address_set)
7416     {
7417       errmsg ("no address set");
7418       return -99;
7419     }
7420
7421   /* Construct the API message */
7422   M (IP_NEIGHBOR_ADD_DEL, mp);
7423
7424   mp->sw_if_index = ntohl (sw_if_index);
7425   mp->is_add = is_add;
7426   mp->is_static = is_static;
7427   mp->is_no_adj_fib = is_no_fib_entry;
7428   if (mac_set)
7429     clib_memcpy (mp->mac_address, mac_address, 6);
7430   if (v6_address_set)
7431     {
7432       mp->is_ipv6 = 1;
7433       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7434     }
7435   else
7436     {
7437       /* mp->is_ipv6 = 0; via memset in M macro above */
7438       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7439     }
7440
7441   /* send it... */
7442   S (mp);
7443
7444   /* Wait for a reply, return good/bad news  */
7445   W (ret);
7446   return ret;
7447 }
7448
7449 static int
7450 api_reset_vrf (vat_main_t * vam)
7451 {
7452   unformat_input_t *i = vam->input;
7453   vl_api_reset_vrf_t *mp;
7454   u32 vrf_id = 0;
7455   u8 is_ipv6 = 0;
7456   u8 vrf_id_set = 0;
7457   int ret;
7458
7459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7460     {
7461       if (unformat (i, "vrf %d", &vrf_id))
7462         vrf_id_set = 1;
7463       else if (unformat (i, "ipv6"))
7464         is_ipv6 = 1;
7465       else
7466         {
7467           clib_warning ("parse error '%U'", format_unformat_error, i);
7468           return -99;
7469         }
7470     }
7471
7472   if (vrf_id_set == 0)
7473     {
7474       errmsg ("missing vrf id");
7475       return -99;
7476     }
7477
7478   M (RESET_VRF, mp);
7479
7480   mp->vrf_id = ntohl (vrf_id);
7481   mp->is_ipv6 = is_ipv6;
7482
7483   S (mp);
7484   W (ret);
7485   return ret;
7486 }
7487
7488 static int
7489 api_create_vlan_subif (vat_main_t * vam)
7490 {
7491   unformat_input_t *i = vam->input;
7492   vl_api_create_vlan_subif_t *mp;
7493   u32 sw_if_index;
7494   u8 sw_if_index_set = 0;
7495   u32 vlan_id;
7496   u8 vlan_id_set = 0;
7497   int ret;
7498
7499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7500     {
7501       if (unformat (i, "sw_if_index %d", &sw_if_index))
7502         sw_if_index_set = 1;
7503       else
7504         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7505         sw_if_index_set = 1;
7506       else if (unformat (i, "vlan %d", &vlan_id))
7507         vlan_id_set = 1;
7508       else
7509         {
7510           clib_warning ("parse error '%U'", format_unformat_error, i);
7511           return -99;
7512         }
7513     }
7514
7515   if (sw_if_index_set == 0)
7516     {
7517       errmsg ("missing interface name or sw_if_index");
7518       return -99;
7519     }
7520
7521   if (vlan_id_set == 0)
7522     {
7523       errmsg ("missing vlan_id");
7524       return -99;
7525     }
7526   M (CREATE_VLAN_SUBIF, mp);
7527
7528   mp->sw_if_index = ntohl (sw_if_index);
7529   mp->vlan_id = ntohl (vlan_id);
7530
7531   S (mp);
7532   W (ret);
7533   return ret;
7534 }
7535
7536 #define foreach_create_subif_bit                \
7537 _(no_tags)                                      \
7538 _(one_tag)                                      \
7539 _(two_tags)                                     \
7540 _(dot1ad)                                       \
7541 _(exact_match)                                  \
7542 _(default_sub)                                  \
7543 _(outer_vlan_id_any)                            \
7544 _(inner_vlan_id_any)
7545
7546 static int
7547 api_create_subif (vat_main_t * vam)
7548 {
7549   unformat_input_t *i = vam->input;
7550   vl_api_create_subif_t *mp;
7551   u32 sw_if_index;
7552   u8 sw_if_index_set = 0;
7553   u32 sub_id;
7554   u8 sub_id_set = 0;
7555   u32 no_tags = 0;
7556   u32 one_tag = 0;
7557   u32 two_tags = 0;
7558   u32 dot1ad = 0;
7559   u32 exact_match = 0;
7560   u32 default_sub = 0;
7561   u32 outer_vlan_id_any = 0;
7562   u32 inner_vlan_id_any = 0;
7563   u32 tmp;
7564   u16 outer_vlan_id = 0;
7565   u16 inner_vlan_id = 0;
7566   int ret;
7567
7568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7569     {
7570       if (unformat (i, "sw_if_index %d", &sw_if_index))
7571         sw_if_index_set = 1;
7572       else
7573         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7574         sw_if_index_set = 1;
7575       else if (unformat (i, "sub_id %d", &sub_id))
7576         sub_id_set = 1;
7577       else if (unformat (i, "outer_vlan_id %d", &tmp))
7578         outer_vlan_id = tmp;
7579       else if (unformat (i, "inner_vlan_id %d", &tmp))
7580         inner_vlan_id = tmp;
7581
7582 #define _(a) else if (unformat (i, #a)) a = 1 ;
7583       foreach_create_subif_bit
7584 #undef _
7585         else
7586         {
7587           clib_warning ("parse error '%U'", format_unformat_error, i);
7588           return -99;
7589         }
7590     }
7591
7592   if (sw_if_index_set == 0)
7593     {
7594       errmsg ("missing interface name or sw_if_index");
7595       return -99;
7596     }
7597
7598   if (sub_id_set == 0)
7599     {
7600       errmsg ("missing sub_id");
7601       return -99;
7602     }
7603   M (CREATE_SUBIF, mp);
7604
7605   mp->sw_if_index = ntohl (sw_if_index);
7606   mp->sub_id = ntohl (sub_id);
7607
7608 #define _(a) mp->a = a;
7609   foreach_create_subif_bit;
7610 #undef _
7611
7612   mp->outer_vlan_id = ntohs (outer_vlan_id);
7613   mp->inner_vlan_id = ntohs (inner_vlan_id);
7614
7615   S (mp);
7616   W (ret);
7617   return ret;
7618 }
7619
7620 static int
7621 api_oam_add_del (vat_main_t * vam)
7622 {
7623   unformat_input_t *i = vam->input;
7624   vl_api_oam_add_del_t *mp;
7625   u32 vrf_id = 0;
7626   u8 is_add = 1;
7627   ip4_address_t src, dst;
7628   u8 src_set = 0;
7629   u8 dst_set = 0;
7630   int ret;
7631
7632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7633     {
7634       if (unformat (i, "vrf %d", &vrf_id))
7635         ;
7636       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7637         src_set = 1;
7638       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7639         dst_set = 1;
7640       else if (unformat (i, "del"))
7641         is_add = 0;
7642       else
7643         {
7644           clib_warning ("parse error '%U'", format_unformat_error, i);
7645           return -99;
7646         }
7647     }
7648
7649   if (src_set == 0)
7650     {
7651       errmsg ("missing src addr");
7652       return -99;
7653     }
7654
7655   if (dst_set == 0)
7656     {
7657       errmsg ("missing dst addr");
7658       return -99;
7659     }
7660
7661   M (OAM_ADD_DEL, mp);
7662
7663   mp->vrf_id = ntohl (vrf_id);
7664   mp->is_add = is_add;
7665   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7666   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7667
7668   S (mp);
7669   W (ret);
7670   return ret;
7671 }
7672
7673 static int
7674 api_reset_fib (vat_main_t * vam)
7675 {
7676   unformat_input_t *i = vam->input;
7677   vl_api_reset_fib_t *mp;
7678   u32 vrf_id = 0;
7679   u8 is_ipv6 = 0;
7680   u8 vrf_id_set = 0;
7681
7682   int ret;
7683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7684     {
7685       if (unformat (i, "vrf %d", &vrf_id))
7686         vrf_id_set = 1;
7687       else if (unformat (i, "ipv6"))
7688         is_ipv6 = 1;
7689       else
7690         {
7691           clib_warning ("parse error '%U'", format_unformat_error, i);
7692           return -99;
7693         }
7694     }
7695
7696   if (vrf_id_set == 0)
7697     {
7698       errmsg ("missing vrf id");
7699       return -99;
7700     }
7701
7702   M (RESET_FIB, mp);
7703
7704   mp->vrf_id = ntohl (vrf_id);
7705   mp->is_ipv6 = is_ipv6;
7706
7707   S (mp);
7708   W (ret);
7709   return ret;
7710 }
7711
7712 static int
7713 api_dhcp_proxy_config (vat_main_t * vam)
7714 {
7715   unformat_input_t *i = vam->input;
7716   vl_api_dhcp_proxy_config_t *mp;
7717   u32 rx_vrf_id = 0;
7718   u32 server_vrf_id = 0;
7719   u8 is_add = 1;
7720   u8 v4_address_set = 0;
7721   u8 v6_address_set = 0;
7722   ip4_address_t v4address;
7723   ip6_address_t v6address;
7724   u8 v4_src_address_set = 0;
7725   u8 v6_src_address_set = 0;
7726   ip4_address_t v4srcaddress;
7727   ip6_address_t v6srcaddress;
7728   int ret;
7729
7730   /* Parse args required to build the message */
7731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7732     {
7733       if (unformat (i, "del"))
7734         is_add = 0;
7735       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7736         ;
7737       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7738         ;
7739       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7740         v4_address_set = 1;
7741       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7742         v6_address_set = 1;
7743       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7744         v4_src_address_set = 1;
7745       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7746         v6_src_address_set = 1;
7747       else
7748         break;
7749     }
7750
7751   if (v4_address_set && v6_address_set)
7752     {
7753       errmsg ("both v4 and v6 server addresses set");
7754       return -99;
7755     }
7756   if (!v4_address_set && !v6_address_set)
7757     {
7758       errmsg ("no server addresses set");
7759       return -99;
7760     }
7761
7762   if (v4_src_address_set && v6_src_address_set)
7763     {
7764       errmsg ("both v4 and v6  src addresses set");
7765       return -99;
7766     }
7767   if (!v4_src_address_set && !v6_src_address_set)
7768     {
7769       errmsg ("no src addresses set");
7770       return -99;
7771     }
7772
7773   if (!(v4_src_address_set && v4_address_set) &&
7774       !(v6_src_address_set && v6_address_set))
7775     {
7776       errmsg ("no matching server and src addresses set");
7777       return -99;
7778     }
7779
7780   /* Construct the API message */
7781   M (DHCP_PROXY_CONFIG, mp);
7782
7783   mp->is_add = is_add;
7784   mp->rx_vrf_id = ntohl (rx_vrf_id);
7785   mp->server_vrf_id = ntohl (server_vrf_id);
7786   if (v6_address_set)
7787     {
7788       mp->is_ipv6 = 1;
7789       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7790       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7791     }
7792   else
7793     {
7794       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7795       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7796     }
7797
7798   /* send it... */
7799   S (mp);
7800
7801   /* Wait for a reply, return good/bad news  */
7802   W (ret);
7803   return ret;
7804 }
7805
7806 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7807 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7808
7809 static void
7810 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7811 {
7812   vat_main_t *vam = &vat_main;
7813   u32 i, count = mp->count;
7814   vl_api_dhcp_server_t *s;
7815
7816   if (mp->is_ipv6)
7817     print (vam->ofp,
7818            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7819            ntohl (mp->rx_vrf_id),
7820            format_ip6_address, mp->dhcp_src_address,
7821            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7822   else
7823     print (vam->ofp,
7824            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7825            ntohl (mp->rx_vrf_id),
7826            format_ip4_address, mp->dhcp_src_address,
7827            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7828
7829   for (i = 0; i < count; i++)
7830     {
7831       s = &mp->servers[i];
7832
7833       if (mp->is_ipv6)
7834         print (vam->ofp,
7835                " Server Table-ID %d, Server Address %U",
7836                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7837       else
7838         print (vam->ofp,
7839                " Server Table-ID %d, Server Address %U",
7840                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7841     }
7842 }
7843
7844 static void vl_api_dhcp_proxy_details_t_handler_json
7845   (vl_api_dhcp_proxy_details_t * mp)
7846 {
7847   vat_main_t *vam = &vat_main;
7848   vat_json_node_t *node = NULL;
7849   u32 i, count = mp->count;
7850   struct in_addr ip4;
7851   struct in6_addr ip6;
7852   vl_api_dhcp_server_t *s;
7853
7854   if (VAT_JSON_ARRAY != vam->json_tree.type)
7855     {
7856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7857       vat_json_init_array (&vam->json_tree);
7858     }
7859   node = vat_json_array_add (&vam->json_tree);
7860
7861   vat_json_init_object (node);
7862   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7863   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7864   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7865
7866   if (mp->is_ipv6)
7867     {
7868       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7869       vat_json_object_add_ip6 (node, "src_address", ip6);
7870     }
7871   else
7872     {
7873       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7874       vat_json_object_add_ip4 (node, "src_address", ip4);
7875     }
7876
7877   for (i = 0; i < count; i++)
7878     {
7879       s = &mp->servers[i];
7880
7881       vat_json_object_add_uint (node, "server-table-id",
7882                                 ntohl (s->server_vrf_id));
7883
7884       if (mp->is_ipv6)
7885         {
7886           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
7887           vat_json_object_add_ip4 (node, "src_address", ip4);
7888         }
7889       else
7890         {
7891           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
7892           vat_json_object_add_ip6 (node, "server_address", ip6);
7893         }
7894     }
7895 }
7896
7897 static int
7898 api_dhcp_proxy_dump (vat_main_t * vam)
7899 {
7900   unformat_input_t *i = vam->input;
7901   vl_api_control_ping_t *mp_ping;
7902   vl_api_dhcp_proxy_dump_t *mp;
7903   u8 is_ipv6 = 0;
7904   int ret;
7905
7906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7907     {
7908       if (unformat (i, "ipv6"))
7909         is_ipv6 = 1;
7910       else
7911         {
7912           clib_warning ("parse error '%U'", format_unformat_error, i);
7913           return -99;
7914         }
7915     }
7916
7917   M (DHCP_PROXY_DUMP, mp);
7918
7919   mp->is_ip6 = is_ipv6;
7920   S (mp);
7921
7922   /* Use a control ping for synchronization */
7923   M (CONTROL_PING, mp_ping);
7924   S (mp_ping);
7925
7926   W (ret);
7927   return ret;
7928 }
7929
7930 static int
7931 api_dhcp_proxy_set_vss (vat_main_t * vam)
7932 {
7933   unformat_input_t *i = vam->input;
7934   vl_api_dhcp_proxy_set_vss_t *mp;
7935   u8 is_ipv6 = 0;
7936   u8 is_add = 1;
7937   u32 tbl_id;
7938   u8 tbl_id_set = 0;
7939   u32 oui;
7940   u8 oui_set = 0;
7941   u32 fib_id;
7942   u8 fib_id_set = 0;
7943   int ret;
7944
7945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7946     {
7947       if (unformat (i, "tbl_id %d", &tbl_id))
7948         tbl_id_set = 1;
7949       if (unformat (i, "fib_id %d", &fib_id))
7950         fib_id_set = 1;
7951       if (unformat (i, "oui %d", &oui))
7952         oui_set = 1;
7953       else if (unformat (i, "ipv6"))
7954         is_ipv6 = 1;
7955       else if (unformat (i, "del"))
7956         is_add = 0;
7957       else
7958         {
7959           clib_warning ("parse error '%U'", format_unformat_error, i);
7960           return -99;
7961         }
7962     }
7963
7964   if (tbl_id_set == 0)
7965     {
7966       errmsg ("missing tbl id");
7967       return -99;
7968     }
7969
7970   if (fib_id_set == 0)
7971     {
7972       errmsg ("missing fib id");
7973       return -99;
7974     }
7975   if (oui_set == 0)
7976     {
7977       errmsg ("missing oui");
7978       return -99;
7979     }
7980
7981   M (DHCP_PROXY_SET_VSS, mp);
7982   mp->tbl_id = ntohl (tbl_id);
7983   mp->fib_id = ntohl (fib_id);
7984   mp->oui = ntohl (oui);
7985   mp->is_ipv6 = is_ipv6;
7986   mp->is_add = is_add;
7987
7988   S (mp);
7989   W (ret);
7990   return ret;
7991 }
7992
7993 static int
7994 api_dhcp_client_config (vat_main_t * vam)
7995 {
7996   unformat_input_t *i = vam->input;
7997   vl_api_dhcp_client_config_t *mp;
7998   u32 sw_if_index;
7999   u8 sw_if_index_set = 0;
8000   u8 is_add = 1;
8001   u8 *hostname = 0;
8002   u8 disable_event = 0;
8003   int ret;
8004
8005   /* Parse args required to build the message */
8006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8007     {
8008       if (unformat (i, "del"))
8009         is_add = 0;
8010       else
8011         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8012         sw_if_index_set = 1;
8013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8014         sw_if_index_set = 1;
8015       else if (unformat (i, "hostname %s", &hostname))
8016         ;
8017       else if (unformat (i, "disable_event"))
8018         disable_event = 1;
8019       else
8020         break;
8021     }
8022
8023   if (sw_if_index_set == 0)
8024     {
8025       errmsg ("missing interface name or sw_if_index");
8026       return -99;
8027     }
8028
8029   if (vec_len (hostname) > 63)
8030     {
8031       errmsg ("hostname too long");
8032     }
8033   vec_add1 (hostname, 0);
8034
8035   /* Construct the API message */
8036   M (DHCP_CLIENT_CONFIG, mp);
8037
8038   mp->sw_if_index = htonl (sw_if_index);
8039   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8040   vec_free (hostname);
8041   mp->is_add = is_add;
8042   mp->want_dhcp_event = disable_event ? 0 : 1;
8043   mp->pid = htonl (getpid ());
8044
8045   /* send it... */
8046   S (mp);
8047
8048   /* Wait for a reply, return good/bad news  */
8049   W (ret);
8050   return ret;
8051 }
8052
8053 static int
8054 api_set_ip_flow_hash (vat_main_t * vam)
8055 {
8056   unformat_input_t *i = vam->input;
8057   vl_api_set_ip_flow_hash_t *mp;
8058   u32 vrf_id = 0;
8059   u8 is_ipv6 = 0;
8060   u8 vrf_id_set = 0;
8061   u8 src = 0;
8062   u8 dst = 0;
8063   u8 sport = 0;
8064   u8 dport = 0;
8065   u8 proto = 0;
8066   u8 reverse = 0;
8067   int ret;
8068
8069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8070     {
8071       if (unformat (i, "vrf %d", &vrf_id))
8072         vrf_id_set = 1;
8073       else if (unformat (i, "ipv6"))
8074         is_ipv6 = 1;
8075       else if (unformat (i, "src"))
8076         src = 1;
8077       else if (unformat (i, "dst"))
8078         dst = 1;
8079       else if (unformat (i, "sport"))
8080         sport = 1;
8081       else if (unformat (i, "dport"))
8082         dport = 1;
8083       else if (unformat (i, "proto"))
8084         proto = 1;
8085       else if (unformat (i, "reverse"))
8086         reverse = 1;
8087
8088       else
8089         {
8090           clib_warning ("parse error '%U'", format_unformat_error, i);
8091           return -99;
8092         }
8093     }
8094
8095   if (vrf_id_set == 0)
8096     {
8097       errmsg ("missing vrf id");
8098       return -99;
8099     }
8100
8101   M (SET_IP_FLOW_HASH, mp);
8102   mp->src = src;
8103   mp->dst = dst;
8104   mp->sport = sport;
8105   mp->dport = dport;
8106   mp->proto = proto;
8107   mp->reverse = reverse;
8108   mp->vrf_id = ntohl (vrf_id);
8109   mp->is_ipv6 = is_ipv6;
8110
8111   S (mp);
8112   W (ret);
8113   return ret;
8114 }
8115
8116 static int
8117 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8118 {
8119   unformat_input_t *i = vam->input;
8120   vl_api_sw_interface_ip6_enable_disable_t *mp;
8121   u32 sw_if_index;
8122   u8 sw_if_index_set = 0;
8123   u8 enable = 0;
8124   int ret;
8125
8126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8127     {
8128       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8129         sw_if_index_set = 1;
8130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8131         sw_if_index_set = 1;
8132       else if (unformat (i, "enable"))
8133         enable = 1;
8134       else if (unformat (i, "disable"))
8135         enable = 0;
8136       else
8137         {
8138           clib_warning ("parse error '%U'", format_unformat_error, i);
8139           return -99;
8140         }
8141     }
8142
8143   if (sw_if_index_set == 0)
8144     {
8145       errmsg ("missing interface name or sw_if_index");
8146       return -99;
8147     }
8148
8149   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8150
8151   mp->sw_if_index = ntohl (sw_if_index);
8152   mp->enable = enable;
8153
8154   S (mp);
8155   W (ret);
8156   return ret;
8157 }
8158
8159 static int
8160 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8161 {
8162   unformat_input_t *i = vam->input;
8163   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8164   u32 sw_if_index;
8165   u8 sw_if_index_set = 0;
8166   u8 v6_address_set = 0;
8167   ip6_address_t v6address;
8168   int ret;
8169
8170   /* Parse args required to build the message */
8171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8172     {
8173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8174         sw_if_index_set = 1;
8175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8176         sw_if_index_set = 1;
8177       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8178         v6_address_set = 1;
8179       else
8180         break;
8181     }
8182
8183   if (sw_if_index_set == 0)
8184     {
8185       errmsg ("missing interface name or sw_if_index");
8186       return -99;
8187     }
8188   if (!v6_address_set)
8189     {
8190       errmsg ("no address set");
8191       return -99;
8192     }
8193
8194   /* Construct the API message */
8195   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8196
8197   mp->sw_if_index = ntohl (sw_if_index);
8198   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8199
8200   /* send it... */
8201   S (mp);
8202
8203   /* Wait for a reply, return good/bad news  */
8204   W (ret);
8205   return ret;
8206 }
8207
8208 static int
8209 api_ip6nd_proxy_add_del (vat_main_t * vam)
8210 {
8211   unformat_input_t *i = vam->input;
8212   vl_api_ip6nd_proxy_add_del_t *mp;
8213   u32 sw_if_index = ~0;
8214   u8 v6_address_set = 0;
8215   ip6_address_t v6address;
8216   u8 is_del = 0;
8217   int ret;
8218
8219   /* Parse args required to build the message */
8220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8221     {
8222       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8223         ;
8224       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8225         ;
8226       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8227         v6_address_set = 1;
8228       if (unformat (i, "del"))
8229         is_del = 1;
8230       else
8231         {
8232           clib_warning ("parse error '%U'", format_unformat_error, i);
8233           return -99;
8234         }
8235     }
8236
8237   if (sw_if_index == ~0)
8238     {
8239       errmsg ("missing interface name or sw_if_index");
8240       return -99;
8241     }
8242   if (!v6_address_set)
8243     {
8244       errmsg ("no address set");
8245       return -99;
8246     }
8247
8248   /* Construct the API message */
8249   M (IP6ND_PROXY_ADD_DEL, mp);
8250
8251   mp->is_del = is_del;
8252   mp->sw_if_index = ntohl (sw_if_index);
8253   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8254
8255   /* send it... */
8256   S (mp);
8257
8258   /* Wait for a reply, return good/bad news  */
8259   W (ret);
8260   return ret;
8261 }
8262
8263 static int
8264 api_ip6nd_proxy_dump (vat_main_t * vam)
8265 {
8266   vl_api_ip6nd_proxy_dump_t *mp;
8267   vl_api_control_ping_t *mp_ping;
8268   int ret;
8269
8270   M (IP6ND_PROXY_DUMP, mp);
8271
8272   S (mp);
8273
8274   /* Use a control ping for synchronization */
8275   M (CONTROL_PING, mp_ping);
8276   S (mp_ping);
8277
8278   W (ret);
8279   return ret;
8280 }
8281
8282 static void vl_api_ip6nd_proxy_details_t_handler
8283   (vl_api_ip6nd_proxy_details_t * mp)
8284 {
8285   vat_main_t *vam = &vat_main;
8286
8287   print (vam->ofp, "host %U sw_if_index %d",
8288          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8289 }
8290
8291 static void vl_api_ip6nd_proxy_details_t_handler_json
8292   (vl_api_ip6nd_proxy_details_t * mp)
8293 {
8294   vat_main_t *vam = &vat_main;
8295   struct in6_addr ip6;
8296   vat_json_node_t *node = NULL;
8297
8298   if (VAT_JSON_ARRAY != vam->json_tree.type)
8299     {
8300       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8301       vat_json_init_array (&vam->json_tree);
8302     }
8303   node = vat_json_array_add (&vam->json_tree);
8304
8305   vat_json_init_object (node);
8306   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8307
8308   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8309   vat_json_object_add_ip6 (node, "host", ip6);
8310 }
8311
8312 static int
8313 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8314 {
8315   unformat_input_t *i = vam->input;
8316   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8317   u32 sw_if_index;
8318   u8 sw_if_index_set = 0;
8319   u32 address_length = 0;
8320   u8 v6_address_set = 0;
8321   ip6_address_t v6address;
8322   u8 use_default = 0;
8323   u8 no_advertise = 0;
8324   u8 off_link = 0;
8325   u8 no_autoconfig = 0;
8326   u8 no_onlink = 0;
8327   u8 is_no = 0;
8328   u32 val_lifetime = 0;
8329   u32 pref_lifetime = 0;
8330   int ret;
8331
8332   /* Parse args required to build the message */
8333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8334     {
8335       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8336         sw_if_index_set = 1;
8337       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8338         sw_if_index_set = 1;
8339       else if (unformat (i, "%U/%d",
8340                          unformat_ip6_address, &v6address, &address_length))
8341         v6_address_set = 1;
8342       else if (unformat (i, "val_life %d", &val_lifetime))
8343         ;
8344       else if (unformat (i, "pref_life %d", &pref_lifetime))
8345         ;
8346       else if (unformat (i, "def"))
8347         use_default = 1;
8348       else if (unformat (i, "noadv"))
8349         no_advertise = 1;
8350       else if (unformat (i, "offl"))
8351         off_link = 1;
8352       else if (unformat (i, "noauto"))
8353         no_autoconfig = 1;
8354       else if (unformat (i, "nolink"))
8355         no_onlink = 1;
8356       else if (unformat (i, "isno"))
8357         is_no = 1;
8358       else
8359         {
8360           clib_warning ("parse error '%U'", format_unformat_error, i);
8361           return -99;
8362         }
8363     }
8364
8365   if (sw_if_index_set == 0)
8366     {
8367       errmsg ("missing interface name or sw_if_index");
8368       return -99;
8369     }
8370   if (!v6_address_set)
8371     {
8372       errmsg ("no address set");
8373       return -99;
8374     }
8375
8376   /* Construct the API message */
8377   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8378
8379   mp->sw_if_index = ntohl (sw_if_index);
8380   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8381   mp->address_length = address_length;
8382   mp->use_default = use_default;
8383   mp->no_advertise = no_advertise;
8384   mp->off_link = off_link;
8385   mp->no_autoconfig = no_autoconfig;
8386   mp->no_onlink = no_onlink;
8387   mp->is_no = is_no;
8388   mp->val_lifetime = ntohl (val_lifetime);
8389   mp->pref_lifetime = ntohl (pref_lifetime);
8390
8391   /* send it... */
8392   S (mp);
8393
8394   /* Wait for a reply, return good/bad news  */
8395   W (ret);
8396   return ret;
8397 }
8398
8399 static int
8400 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8401 {
8402   unformat_input_t *i = vam->input;
8403   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8404   u32 sw_if_index;
8405   u8 sw_if_index_set = 0;
8406   u8 suppress = 0;
8407   u8 managed = 0;
8408   u8 other = 0;
8409   u8 ll_option = 0;
8410   u8 send_unicast = 0;
8411   u8 cease = 0;
8412   u8 is_no = 0;
8413   u8 default_router = 0;
8414   u32 max_interval = 0;
8415   u32 min_interval = 0;
8416   u32 lifetime = 0;
8417   u32 initial_count = 0;
8418   u32 initial_interval = 0;
8419   int ret;
8420
8421
8422   /* Parse args required to build the message */
8423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8424     {
8425       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8426         sw_if_index_set = 1;
8427       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8428         sw_if_index_set = 1;
8429       else if (unformat (i, "maxint %d", &max_interval))
8430         ;
8431       else if (unformat (i, "minint %d", &min_interval))
8432         ;
8433       else if (unformat (i, "life %d", &lifetime))
8434         ;
8435       else if (unformat (i, "count %d", &initial_count))
8436         ;
8437       else if (unformat (i, "interval %d", &initial_interval))
8438         ;
8439       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8440         suppress = 1;
8441       else if (unformat (i, "managed"))
8442         managed = 1;
8443       else if (unformat (i, "other"))
8444         other = 1;
8445       else if (unformat (i, "ll"))
8446         ll_option = 1;
8447       else if (unformat (i, "send"))
8448         send_unicast = 1;
8449       else if (unformat (i, "cease"))
8450         cease = 1;
8451       else if (unformat (i, "isno"))
8452         is_no = 1;
8453       else if (unformat (i, "def"))
8454         default_router = 1;
8455       else
8456         {
8457           clib_warning ("parse error '%U'", format_unformat_error, i);
8458           return -99;
8459         }
8460     }
8461
8462   if (sw_if_index_set == 0)
8463     {
8464       errmsg ("missing interface name or sw_if_index");
8465       return -99;
8466     }
8467
8468   /* Construct the API message */
8469   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8470
8471   mp->sw_if_index = ntohl (sw_if_index);
8472   mp->max_interval = ntohl (max_interval);
8473   mp->min_interval = ntohl (min_interval);
8474   mp->lifetime = ntohl (lifetime);
8475   mp->initial_count = ntohl (initial_count);
8476   mp->initial_interval = ntohl (initial_interval);
8477   mp->suppress = suppress;
8478   mp->managed = managed;
8479   mp->other = other;
8480   mp->ll_option = ll_option;
8481   mp->send_unicast = send_unicast;
8482   mp->cease = cease;
8483   mp->is_no = is_no;
8484   mp->default_router = default_router;
8485
8486   /* send it... */
8487   S (mp);
8488
8489   /* Wait for a reply, return good/bad news  */
8490   W (ret);
8491   return ret;
8492 }
8493
8494 static int
8495 api_set_arp_neighbor_limit (vat_main_t * vam)
8496 {
8497   unformat_input_t *i = vam->input;
8498   vl_api_set_arp_neighbor_limit_t *mp;
8499   u32 arp_nbr_limit;
8500   u8 limit_set = 0;
8501   u8 is_ipv6 = 0;
8502   int ret;
8503
8504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8505     {
8506       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8507         limit_set = 1;
8508       else if (unformat (i, "ipv6"))
8509         is_ipv6 = 1;
8510       else
8511         {
8512           clib_warning ("parse error '%U'", format_unformat_error, i);
8513           return -99;
8514         }
8515     }
8516
8517   if (limit_set == 0)
8518     {
8519       errmsg ("missing limit value");
8520       return -99;
8521     }
8522
8523   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8524
8525   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8526   mp->is_ipv6 = is_ipv6;
8527
8528   S (mp);
8529   W (ret);
8530   return ret;
8531 }
8532
8533 static int
8534 api_l2_patch_add_del (vat_main_t * vam)
8535 {
8536   unformat_input_t *i = vam->input;
8537   vl_api_l2_patch_add_del_t *mp;
8538   u32 rx_sw_if_index;
8539   u8 rx_sw_if_index_set = 0;
8540   u32 tx_sw_if_index;
8541   u8 tx_sw_if_index_set = 0;
8542   u8 is_add = 1;
8543   int ret;
8544
8545   /* Parse args required to build the message */
8546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8547     {
8548       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8549         rx_sw_if_index_set = 1;
8550       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8551         tx_sw_if_index_set = 1;
8552       else if (unformat (i, "rx"))
8553         {
8554           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8555             {
8556               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8557                             &rx_sw_if_index))
8558                 rx_sw_if_index_set = 1;
8559             }
8560           else
8561             break;
8562         }
8563       else if (unformat (i, "tx"))
8564         {
8565           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8566             {
8567               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8568                             &tx_sw_if_index))
8569                 tx_sw_if_index_set = 1;
8570             }
8571           else
8572             break;
8573         }
8574       else if (unformat (i, "del"))
8575         is_add = 0;
8576       else
8577         break;
8578     }
8579
8580   if (rx_sw_if_index_set == 0)
8581     {
8582       errmsg ("missing rx interface name or rx_sw_if_index");
8583       return -99;
8584     }
8585
8586   if (tx_sw_if_index_set == 0)
8587     {
8588       errmsg ("missing tx interface name or tx_sw_if_index");
8589       return -99;
8590     }
8591
8592   M (L2_PATCH_ADD_DEL, mp);
8593
8594   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8595   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8596   mp->is_add = is_add;
8597
8598   S (mp);
8599   W (ret);
8600   return ret;
8601 }
8602
8603 u8 is_del;
8604 u8 localsid_addr[16];
8605 u8 end_psp;
8606 u8 behavior;
8607 u32 sw_if_index;
8608 u32 vlan_index;
8609 u32 fib_table;
8610 u8 nh_addr[16];
8611
8612 static int
8613 api_sr_localsid_add_del (vat_main_t * vam)
8614 {
8615   unformat_input_t *i = vam->input;
8616   vl_api_sr_localsid_add_del_t *mp;
8617
8618   u8 is_del;
8619   ip6_address_t localsid;
8620   u8 end_psp = 0;
8621   u8 behavior = ~0;
8622   u32 sw_if_index;
8623   u32 fib_table = ~(u32) 0;
8624   ip6_address_t next_hop;
8625
8626   bool nexthop_set = 0;
8627
8628   int ret;
8629
8630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8631     {
8632       if (unformat (i, "del"))
8633         is_del = 1;
8634       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8635       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8636         nexthop_set = 1;
8637       else if (unformat (i, "behavior %u", &behavior));
8638       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8639       else if (unformat (i, "fib-table %u", &fib_table));
8640       else if (unformat (i, "end.psp %u", &behavior));
8641       else
8642         break;
8643     }
8644
8645   M (SR_LOCALSID_ADD_DEL, mp);
8646
8647   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8648   if (nexthop_set)
8649     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8650   mp->behavior = behavior;
8651   mp->sw_if_index = ntohl (sw_if_index);
8652   mp->fib_table = ntohl (fib_table);
8653   mp->end_psp = end_psp;
8654   mp->is_del = is_del;
8655
8656   S (mp);
8657   W (ret);
8658   return ret;
8659 }
8660
8661 static int
8662 api_ioam_enable (vat_main_t * vam)
8663 {
8664   unformat_input_t *input = vam->input;
8665   vl_api_ioam_enable_t *mp;
8666   u32 id = 0;
8667   int has_trace_option = 0;
8668   int has_pot_option = 0;
8669   int has_seqno_option = 0;
8670   int has_analyse_option = 0;
8671   int ret;
8672
8673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8674     {
8675       if (unformat (input, "trace"))
8676         has_trace_option = 1;
8677       else if (unformat (input, "pot"))
8678         has_pot_option = 1;
8679       else if (unformat (input, "seqno"))
8680         has_seqno_option = 1;
8681       else if (unformat (input, "analyse"))
8682         has_analyse_option = 1;
8683       else
8684         break;
8685     }
8686   M (IOAM_ENABLE, mp);
8687   mp->id = htons (id);
8688   mp->seqno = has_seqno_option;
8689   mp->analyse = has_analyse_option;
8690   mp->pot_enable = has_pot_option;
8691   mp->trace_enable = has_trace_option;
8692
8693   S (mp);
8694   W (ret);
8695   return ret;
8696 }
8697
8698
8699 static int
8700 api_ioam_disable (vat_main_t * vam)
8701 {
8702   vl_api_ioam_disable_t *mp;
8703   int ret;
8704
8705   M (IOAM_DISABLE, mp);
8706   S (mp);
8707   W (ret);
8708   return ret;
8709 }
8710
8711 #define foreach_tcp_proto_field                 \
8712 _(src_port)                                     \
8713 _(dst_port)
8714
8715 #define foreach_udp_proto_field                 \
8716 _(src_port)                                     \
8717 _(dst_port)
8718
8719 #define foreach_ip4_proto_field                 \
8720 _(src_address)                                  \
8721 _(dst_address)                                  \
8722 _(tos)                                          \
8723 _(length)                                       \
8724 _(fragment_id)                                  \
8725 _(ttl)                                          \
8726 _(protocol)                                     \
8727 _(checksum)
8728
8729 typedef struct
8730 {
8731   u16 src_port, dst_port;
8732 } tcpudp_header_t;
8733
8734 #if VPP_API_TEST_BUILTIN == 0
8735 uword
8736 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8737 {
8738   u8 **maskp = va_arg (*args, u8 **);
8739   u8 *mask = 0;
8740   u8 found_something = 0;
8741   tcp_header_t *tcp;
8742
8743 #define _(a) u8 a=0;
8744   foreach_tcp_proto_field;
8745 #undef _
8746
8747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8748     {
8749       if (0);
8750 #define _(a) else if (unformat (input, #a)) a=1;
8751       foreach_tcp_proto_field
8752 #undef _
8753         else
8754         break;
8755     }
8756
8757 #define _(a) found_something += a;
8758   foreach_tcp_proto_field;
8759 #undef _
8760
8761   if (found_something == 0)
8762     return 0;
8763
8764   vec_validate (mask, sizeof (*tcp) - 1);
8765
8766   tcp = (tcp_header_t *) mask;
8767
8768 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8769   foreach_tcp_proto_field;
8770 #undef _
8771
8772   *maskp = mask;
8773   return 1;
8774 }
8775
8776 uword
8777 unformat_udp_mask (unformat_input_t * input, va_list * args)
8778 {
8779   u8 **maskp = va_arg (*args, u8 **);
8780   u8 *mask = 0;
8781   u8 found_something = 0;
8782   udp_header_t *udp;
8783
8784 #define _(a) u8 a=0;
8785   foreach_udp_proto_field;
8786 #undef _
8787
8788   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8789     {
8790       if (0);
8791 #define _(a) else if (unformat (input, #a)) a=1;
8792       foreach_udp_proto_field
8793 #undef _
8794         else
8795         break;
8796     }
8797
8798 #define _(a) found_something += a;
8799   foreach_udp_proto_field;
8800 #undef _
8801
8802   if (found_something == 0)
8803     return 0;
8804
8805   vec_validate (mask, sizeof (*udp) - 1);
8806
8807   udp = (udp_header_t *) mask;
8808
8809 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8810   foreach_udp_proto_field;
8811 #undef _
8812
8813   *maskp = mask;
8814   return 1;
8815 }
8816
8817 uword
8818 unformat_l4_mask (unformat_input_t * input, va_list * args)
8819 {
8820   u8 **maskp = va_arg (*args, u8 **);
8821   u16 src_port = 0, dst_port = 0;
8822   tcpudp_header_t *tcpudp;
8823
8824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8825     {
8826       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8827         return 1;
8828       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8829         return 1;
8830       else if (unformat (input, "src_port"))
8831         src_port = 0xFFFF;
8832       else if (unformat (input, "dst_port"))
8833         dst_port = 0xFFFF;
8834       else
8835         return 0;
8836     }
8837
8838   if (!src_port && !dst_port)
8839     return 0;
8840
8841   u8 *mask = 0;
8842   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8843
8844   tcpudp = (tcpudp_header_t *) mask;
8845   tcpudp->src_port = src_port;
8846   tcpudp->dst_port = dst_port;
8847
8848   *maskp = mask;
8849
8850   return 1;
8851 }
8852
8853 uword
8854 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8855 {
8856   u8 **maskp = va_arg (*args, u8 **);
8857   u8 *mask = 0;
8858   u8 found_something = 0;
8859   ip4_header_t *ip;
8860
8861 #define _(a) u8 a=0;
8862   foreach_ip4_proto_field;
8863 #undef _
8864   u8 version = 0;
8865   u8 hdr_length = 0;
8866
8867
8868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8869     {
8870       if (unformat (input, "version"))
8871         version = 1;
8872       else if (unformat (input, "hdr_length"))
8873         hdr_length = 1;
8874       else if (unformat (input, "src"))
8875         src_address = 1;
8876       else if (unformat (input, "dst"))
8877         dst_address = 1;
8878       else if (unformat (input, "proto"))
8879         protocol = 1;
8880
8881 #define _(a) else if (unformat (input, #a)) a=1;
8882       foreach_ip4_proto_field
8883 #undef _
8884         else
8885         break;
8886     }
8887
8888 #define _(a) found_something += a;
8889   foreach_ip4_proto_field;
8890 #undef _
8891
8892   if (found_something == 0)
8893     return 0;
8894
8895   vec_validate (mask, sizeof (*ip) - 1);
8896
8897   ip = (ip4_header_t *) mask;
8898
8899 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8900   foreach_ip4_proto_field;
8901 #undef _
8902
8903   ip->ip_version_and_header_length = 0;
8904
8905   if (version)
8906     ip->ip_version_and_header_length |= 0xF0;
8907
8908   if (hdr_length)
8909     ip->ip_version_and_header_length |= 0x0F;
8910
8911   *maskp = mask;
8912   return 1;
8913 }
8914
8915 #define foreach_ip6_proto_field                 \
8916 _(src_address)                                  \
8917 _(dst_address)                                  \
8918 _(payload_length)                               \
8919 _(hop_limit)                                    \
8920 _(protocol)
8921
8922 uword
8923 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8924 {
8925   u8 **maskp = va_arg (*args, u8 **);
8926   u8 *mask = 0;
8927   u8 found_something = 0;
8928   ip6_header_t *ip;
8929   u32 ip_version_traffic_class_and_flow_label;
8930
8931 #define _(a) u8 a=0;
8932   foreach_ip6_proto_field;
8933 #undef _
8934   u8 version = 0;
8935   u8 traffic_class = 0;
8936   u8 flow_label = 0;
8937
8938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8939     {
8940       if (unformat (input, "version"))
8941         version = 1;
8942       else if (unformat (input, "traffic-class"))
8943         traffic_class = 1;
8944       else if (unformat (input, "flow-label"))
8945         flow_label = 1;
8946       else if (unformat (input, "src"))
8947         src_address = 1;
8948       else if (unformat (input, "dst"))
8949         dst_address = 1;
8950       else if (unformat (input, "proto"))
8951         protocol = 1;
8952
8953 #define _(a) else if (unformat (input, #a)) a=1;
8954       foreach_ip6_proto_field
8955 #undef _
8956         else
8957         break;
8958     }
8959
8960 #define _(a) found_something += a;
8961   foreach_ip6_proto_field;
8962 #undef _
8963
8964   if (found_something == 0)
8965     return 0;
8966
8967   vec_validate (mask, sizeof (*ip) - 1);
8968
8969   ip = (ip6_header_t *) mask;
8970
8971 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8972   foreach_ip6_proto_field;
8973 #undef _
8974
8975   ip_version_traffic_class_and_flow_label = 0;
8976
8977   if (version)
8978     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8979
8980   if (traffic_class)
8981     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8982
8983   if (flow_label)
8984     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8985
8986   ip->ip_version_traffic_class_and_flow_label =
8987     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8988
8989   *maskp = mask;
8990   return 1;
8991 }
8992
8993 uword
8994 unformat_l3_mask (unformat_input_t * input, va_list * args)
8995 {
8996   u8 **maskp = va_arg (*args, u8 **);
8997
8998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8999     {
9000       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9001         return 1;
9002       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9003         return 1;
9004       else
9005         break;
9006     }
9007   return 0;
9008 }
9009
9010 uword
9011 unformat_l2_mask (unformat_input_t * input, va_list * args)
9012 {
9013   u8 **maskp = va_arg (*args, u8 **);
9014   u8 *mask = 0;
9015   u8 src = 0;
9016   u8 dst = 0;
9017   u8 proto = 0;
9018   u8 tag1 = 0;
9019   u8 tag2 = 0;
9020   u8 ignore_tag1 = 0;
9021   u8 ignore_tag2 = 0;
9022   u8 cos1 = 0;
9023   u8 cos2 = 0;
9024   u8 dot1q = 0;
9025   u8 dot1ad = 0;
9026   int len = 14;
9027
9028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9029     {
9030       if (unformat (input, "src"))
9031         src = 1;
9032       else if (unformat (input, "dst"))
9033         dst = 1;
9034       else if (unformat (input, "proto"))
9035         proto = 1;
9036       else if (unformat (input, "tag1"))
9037         tag1 = 1;
9038       else if (unformat (input, "tag2"))
9039         tag2 = 1;
9040       else if (unformat (input, "ignore-tag1"))
9041         ignore_tag1 = 1;
9042       else if (unformat (input, "ignore-tag2"))
9043         ignore_tag2 = 1;
9044       else if (unformat (input, "cos1"))
9045         cos1 = 1;
9046       else if (unformat (input, "cos2"))
9047         cos2 = 1;
9048       else if (unformat (input, "dot1q"))
9049         dot1q = 1;
9050       else if (unformat (input, "dot1ad"))
9051         dot1ad = 1;
9052       else
9053         break;
9054     }
9055   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9056        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9057     return 0;
9058
9059   if (tag1 || ignore_tag1 || cos1 || dot1q)
9060     len = 18;
9061   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9062     len = 22;
9063
9064   vec_validate (mask, len - 1);
9065
9066   if (dst)
9067     memset (mask, 0xff, 6);
9068
9069   if (src)
9070     memset (mask + 6, 0xff, 6);
9071
9072   if (tag2 || dot1ad)
9073     {
9074       /* inner vlan tag */
9075       if (tag2)
9076         {
9077           mask[19] = 0xff;
9078           mask[18] = 0x0f;
9079         }
9080       if (cos2)
9081         mask[18] |= 0xe0;
9082       if (proto)
9083         mask[21] = mask[20] = 0xff;
9084       if (tag1)
9085         {
9086           mask[15] = 0xff;
9087           mask[14] = 0x0f;
9088         }
9089       if (cos1)
9090         mask[14] |= 0xe0;
9091       *maskp = mask;
9092       return 1;
9093     }
9094   if (tag1 | dot1q)
9095     {
9096       if (tag1)
9097         {
9098           mask[15] = 0xff;
9099           mask[14] = 0x0f;
9100         }
9101       if (cos1)
9102         mask[14] |= 0xe0;
9103       if (proto)
9104         mask[16] = mask[17] = 0xff;
9105
9106       *maskp = mask;
9107       return 1;
9108     }
9109   if (cos2)
9110     mask[18] |= 0xe0;
9111   if (cos1)
9112     mask[14] |= 0xe0;
9113   if (proto)
9114     mask[12] = mask[13] = 0xff;
9115
9116   *maskp = mask;
9117   return 1;
9118 }
9119
9120 uword
9121 unformat_classify_mask (unformat_input_t * input, va_list * args)
9122 {
9123   u8 **maskp = va_arg (*args, u8 **);
9124   u32 *skipp = va_arg (*args, u32 *);
9125   u32 *matchp = va_arg (*args, u32 *);
9126   u32 match;
9127   u8 *mask = 0;
9128   u8 *l2 = 0;
9129   u8 *l3 = 0;
9130   u8 *l4 = 0;
9131   int i;
9132
9133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9134     {
9135       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9136         ;
9137       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9138         ;
9139       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9140         ;
9141       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9142         ;
9143       else
9144         break;
9145     }
9146
9147   if (l4 && !l3)
9148     {
9149       vec_free (mask);
9150       vec_free (l2);
9151       vec_free (l4);
9152       return 0;
9153     }
9154
9155   if (mask || l2 || l3 || l4)
9156     {
9157       if (l2 || l3 || l4)
9158         {
9159           /* "With a free Ethernet header in every package" */
9160           if (l2 == 0)
9161             vec_validate (l2, 13);
9162           mask = l2;
9163           if (vec_len (l3))
9164             {
9165               vec_append (mask, l3);
9166               vec_free (l3);
9167             }
9168           if (vec_len (l4))
9169             {
9170               vec_append (mask, l4);
9171               vec_free (l4);
9172             }
9173         }
9174
9175       /* Scan forward looking for the first significant mask octet */
9176       for (i = 0; i < vec_len (mask); i++)
9177         if (mask[i])
9178           break;
9179
9180       /* compute (skip, match) params */
9181       *skipp = i / sizeof (u32x4);
9182       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9183
9184       /* Pad mask to an even multiple of the vector size */
9185       while (vec_len (mask) % sizeof (u32x4))
9186         vec_add1 (mask, 0);
9187
9188       match = vec_len (mask) / sizeof (u32x4);
9189
9190       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9191         {
9192           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9193           if (*tmp || *(tmp + 1))
9194             break;
9195           match--;
9196         }
9197       if (match == 0)
9198         clib_warning ("BUG: match 0");
9199
9200       _vec_len (mask) = match * sizeof (u32x4);
9201
9202       *matchp = match;
9203       *maskp = mask;
9204
9205       return 1;
9206     }
9207
9208   return 0;
9209 }
9210 #endif /* VPP_API_TEST_BUILTIN */
9211
9212 #define foreach_l2_next                         \
9213 _(drop, DROP)                                   \
9214 _(ethernet, ETHERNET_INPUT)                     \
9215 _(ip4, IP4_INPUT)                               \
9216 _(ip6, IP6_INPUT)
9217
9218 uword
9219 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9220 {
9221   u32 *miss_next_indexp = va_arg (*args, u32 *);
9222   u32 next_index = 0;
9223   u32 tmp;
9224
9225 #define _(n,N) \
9226   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9227   foreach_l2_next;
9228 #undef _
9229
9230   if (unformat (input, "%d", &tmp))
9231     {
9232       next_index = tmp;
9233       goto out;
9234     }
9235
9236   return 0;
9237
9238 out:
9239   *miss_next_indexp = next_index;
9240   return 1;
9241 }
9242
9243 #define foreach_ip_next                         \
9244 _(drop, DROP)                                   \
9245 _(local, LOCAL)                                 \
9246 _(rewrite, REWRITE)
9247
9248 uword
9249 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9250 {
9251   u32 *miss_next_indexp = va_arg (*args, u32 *);
9252   u32 next_index = 0;
9253   u32 tmp;
9254
9255 #define _(n,N) \
9256   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9257   foreach_ip_next;
9258 #undef _
9259
9260   if (unformat (input, "%d", &tmp))
9261     {
9262       next_index = tmp;
9263       goto out;
9264     }
9265
9266   return 0;
9267
9268 out:
9269   *miss_next_indexp = next_index;
9270   return 1;
9271 }
9272
9273 #define foreach_acl_next                        \
9274 _(deny, DENY)
9275
9276 uword
9277 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9278 {
9279   u32 *miss_next_indexp = va_arg (*args, u32 *);
9280   u32 next_index = 0;
9281   u32 tmp;
9282
9283 #define _(n,N) \
9284   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9285   foreach_acl_next;
9286 #undef _
9287
9288   if (unformat (input, "permit"))
9289     {
9290       next_index = ~0;
9291       goto out;
9292     }
9293   else if (unformat (input, "%d", &tmp))
9294     {
9295       next_index = tmp;
9296       goto out;
9297     }
9298
9299   return 0;
9300
9301 out:
9302   *miss_next_indexp = next_index;
9303   return 1;
9304 }
9305
9306 uword
9307 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9308 {
9309   u32 *r = va_arg (*args, u32 *);
9310
9311   if (unformat (input, "conform-color"))
9312     *r = POLICE_CONFORM;
9313   else if (unformat (input, "exceed-color"))
9314     *r = POLICE_EXCEED;
9315   else
9316     return 0;
9317
9318   return 1;
9319 }
9320
9321 static int
9322 api_classify_add_del_table (vat_main_t * vam)
9323 {
9324   unformat_input_t *i = vam->input;
9325   vl_api_classify_add_del_table_t *mp;
9326
9327   u32 nbuckets = 2;
9328   u32 skip = ~0;
9329   u32 match = ~0;
9330   int is_add = 1;
9331   int del_chain = 0;
9332   u32 table_index = ~0;
9333   u32 next_table_index = ~0;
9334   u32 miss_next_index = ~0;
9335   u32 memory_size = 32 << 20;
9336   u8 *mask = 0;
9337   u32 current_data_flag = 0;
9338   int current_data_offset = 0;
9339   int ret;
9340
9341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9342     {
9343       if (unformat (i, "del"))
9344         is_add = 0;
9345       else if (unformat (i, "del-chain"))
9346         {
9347           is_add = 0;
9348           del_chain = 1;
9349         }
9350       else if (unformat (i, "buckets %d", &nbuckets))
9351         ;
9352       else if (unformat (i, "memory_size %d", &memory_size))
9353         ;
9354       else if (unformat (i, "skip %d", &skip))
9355         ;
9356       else if (unformat (i, "match %d", &match))
9357         ;
9358       else if (unformat (i, "table %d", &table_index))
9359         ;
9360       else if (unformat (i, "mask %U", unformat_classify_mask,
9361                          &mask, &skip, &match))
9362         ;
9363       else if (unformat (i, "next-table %d", &next_table_index))
9364         ;
9365       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9366                          &miss_next_index))
9367         ;
9368       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9369                          &miss_next_index))
9370         ;
9371       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9372                          &miss_next_index))
9373         ;
9374       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9375         ;
9376       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9377         ;
9378       else
9379         break;
9380     }
9381
9382   if (is_add && mask == 0)
9383     {
9384       errmsg ("Mask required");
9385       return -99;
9386     }
9387
9388   if (is_add && skip == ~0)
9389     {
9390       errmsg ("skip count required");
9391       return -99;
9392     }
9393
9394   if (is_add && match == ~0)
9395     {
9396       errmsg ("match count required");
9397       return -99;
9398     }
9399
9400   if (!is_add && table_index == ~0)
9401     {
9402       errmsg ("table index required for delete");
9403       return -99;
9404     }
9405
9406   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9407
9408   mp->is_add = is_add;
9409   mp->del_chain = del_chain;
9410   mp->table_index = ntohl (table_index);
9411   mp->nbuckets = ntohl (nbuckets);
9412   mp->memory_size = ntohl (memory_size);
9413   mp->skip_n_vectors = ntohl (skip);
9414   mp->match_n_vectors = ntohl (match);
9415   mp->next_table_index = ntohl (next_table_index);
9416   mp->miss_next_index = ntohl (miss_next_index);
9417   mp->current_data_flag = ntohl (current_data_flag);
9418   mp->current_data_offset = ntohl (current_data_offset);
9419   clib_memcpy (mp->mask, mask, vec_len (mask));
9420
9421   vec_free (mask);
9422
9423   S (mp);
9424   W (ret);
9425   return ret;
9426 }
9427
9428 #if VPP_API_TEST_BUILTIN == 0
9429 uword
9430 unformat_l4_match (unformat_input_t * input, va_list * args)
9431 {
9432   u8 **matchp = va_arg (*args, u8 **);
9433
9434   u8 *proto_header = 0;
9435   int src_port = 0;
9436   int dst_port = 0;
9437
9438   tcpudp_header_t h;
9439
9440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9441     {
9442       if (unformat (input, "src_port %d", &src_port))
9443         ;
9444       else if (unformat (input, "dst_port %d", &dst_port))
9445         ;
9446       else
9447         return 0;
9448     }
9449
9450   h.src_port = clib_host_to_net_u16 (src_port);
9451   h.dst_port = clib_host_to_net_u16 (dst_port);
9452   vec_validate (proto_header, sizeof (h) - 1);
9453   memcpy (proto_header, &h, sizeof (h));
9454
9455   *matchp = proto_header;
9456
9457   return 1;
9458 }
9459
9460 uword
9461 unformat_ip4_match (unformat_input_t * input, va_list * args)
9462 {
9463   u8 **matchp = va_arg (*args, u8 **);
9464   u8 *match = 0;
9465   ip4_header_t *ip;
9466   int version = 0;
9467   u32 version_val;
9468   int hdr_length = 0;
9469   u32 hdr_length_val;
9470   int src = 0, dst = 0;
9471   ip4_address_t src_val, dst_val;
9472   int proto = 0;
9473   u32 proto_val;
9474   int tos = 0;
9475   u32 tos_val;
9476   int length = 0;
9477   u32 length_val;
9478   int fragment_id = 0;
9479   u32 fragment_id_val;
9480   int ttl = 0;
9481   int ttl_val;
9482   int checksum = 0;
9483   u32 checksum_val;
9484
9485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9486     {
9487       if (unformat (input, "version %d", &version_val))
9488         version = 1;
9489       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9490         hdr_length = 1;
9491       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9492         src = 1;
9493       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9494         dst = 1;
9495       else if (unformat (input, "proto %d", &proto_val))
9496         proto = 1;
9497       else if (unformat (input, "tos %d", &tos_val))
9498         tos = 1;
9499       else if (unformat (input, "length %d", &length_val))
9500         length = 1;
9501       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9502         fragment_id = 1;
9503       else if (unformat (input, "ttl %d", &ttl_val))
9504         ttl = 1;
9505       else if (unformat (input, "checksum %d", &checksum_val))
9506         checksum = 1;
9507       else
9508         break;
9509     }
9510
9511   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9512       + ttl + checksum == 0)
9513     return 0;
9514
9515   /*
9516    * Aligned because we use the real comparison functions
9517    */
9518   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9519
9520   ip = (ip4_header_t *) match;
9521
9522   /* These are realistically matched in practice */
9523   if (src)
9524     ip->src_address.as_u32 = src_val.as_u32;
9525
9526   if (dst)
9527     ip->dst_address.as_u32 = dst_val.as_u32;
9528
9529   if (proto)
9530     ip->protocol = proto_val;
9531
9532
9533   /* These are not, but they're included for completeness */
9534   if (version)
9535     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9536
9537   if (hdr_length)
9538     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9539
9540   if (tos)
9541     ip->tos = tos_val;
9542
9543   if (length)
9544     ip->length = clib_host_to_net_u16 (length_val);
9545
9546   if (ttl)
9547     ip->ttl = ttl_val;
9548
9549   if (checksum)
9550     ip->checksum = clib_host_to_net_u16 (checksum_val);
9551
9552   *matchp = match;
9553   return 1;
9554 }
9555
9556 uword
9557 unformat_ip6_match (unformat_input_t * input, va_list * args)
9558 {
9559   u8 **matchp = va_arg (*args, u8 **);
9560   u8 *match = 0;
9561   ip6_header_t *ip;
9562   int version = 0;
9563   u32 version_val;
9564   u8 traffic_class = 0;
9565   u32 traffic_class_val = 0;
9566   u8 flow_label = 0;
9567   u8 flow_label_val;
9568   int src = 0, dst = 0;
9569   ip6_address_t src_val, dst_val;
9570   int proto = 0;
9571   u32 proto_val;
9572   int payload_length = 0;
9573   u32 payload_length_val;
9574   int hop_limit = 0;
9575   int hop_limit_val;
9576   u32 ip_version_traffic_class_and_flow_label;
9577
9578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9579     {
9580       if (unformat (input, "version %d", &version_val))
9581         version = 1;
9582       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9583         traffic_class = 1;
9584       else if (unformat (input, "flow_label %d", &flow_label_val))
9585         flow_label = 1;
9586       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9587         src = 1;
9588       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9589         dst = 1;
9590       else if (unformat (input, "proto %d", &proto_val))
9591         proto = 1;
9592       else if (unformat (input, "payload_length %d", &payload_length_val))
9593         payload_length = 1;
9594       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9595         hop_limit = 1;
9596       else
9597         break;
9598     }
9599
9600   if (version + traffic_class + flow_label + src + dst + proto +
9601       payload_length + hop_limit == 0)
9602     return 0;
9603
9604   /*
9605    * Aligned because we use the real comparison functions
9606    */
9607   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9608
9609   ip = (ip6_header_t *) match;
9610
9611   if (src)
9612     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9613
9614   if (dst)
9615     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9616
9617   if (proto)
9618     ip->protocol = proto_val;
9619
9620   ip_version_traffic_class_and_flow_label = 0;
9621
9622   if (version)
9623     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9624
9625   if (traffic_class)
9626     ip_version_traffic_class_and_flow_label |=
9627       (traffic_class_val & 0xFF) << 20;
9628
9629   if (flow_label)
9630     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9631
9632   ip->ip_version_traffic_class_and_flow_label =
9633     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9634
9635   if (payload_length)
9636     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9637
9638   if (hop_limit)
9639     ip->hop_limit = hop_limit_val;
9640
9641   *matchp = match;
9642   return 1;
9643 }
9644
9645 uword
9646 unformat_l3_match (unformat_input_t * input, va_list * args)
9647 {
9648   u8 **matchp = va_arg (*args, u8 **);
9649
9650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9651     {
9652       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9653         return 1;
9654       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9655         return 1;
9656       else
9657         break;
9658     }
9659   return 0;
9660 }
9661
9662 uword
9663 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9664 {
9665   u8 *tagp = va_arg (*args, u8 *);
9666   u32 tag;
9667
9668   if (unformat (input, "%d", &tag))
9669     {
9670       tagp[0] = (tag >> 8) & 0x0F;
9671       tagp[1] = tag & 0xFF;
9672       return 1;
9673     }
9674
9675   return 0;
9676 }
9677
9678 uword
9679 unformat_l2_match (unformat_input_t * input, va_list * args)
9680 {
9681   u8 **matchp = va_arg (*args, u8 **);
9682   u8 *match = 0;
9683   u8 src = 0;
9684   u8 src_val[6];
9685   u8 dst = 0;
9686   u8 dst_val[6];
9687   u8 proto = 0;
9688   u16 proto_val;
9689   u8 tag1 = 0;
9690   u8 tag1_val[2];
9691   u8 tag2 = 0;
9692   u8 tag2_val[2];
9693   int len = 14;
9694   u8 ignore_tag1 = 0;
9695   u8 ignore_tag2 = 0;
9696   u8 cos1 = 0;
9697   u8 cos2 = 0;
9698   u32 cos1_val = 0;
9699   u32 cos2_val = 0;
9700
9701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9702     {
9703       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9704         src = 1;
9705       else
9706         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9707         dst = 1;
9708       else if (unformat (input, "proto %U",
9709                          unformat_ethernet_type_host_byte_order, &proto_val))
9710         proto = 1;
9711       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9712         tag1 = 1;
9713       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9714         tag2 = 1;
9715       else if (unformat (input, "ignore-tag1"))
9716         ignore_tag1 = 1;
9717       else if (unformat (input, "ignore-tag2"))
9718         ignore_tag2 = 1;
9719       else if (unformat (input, "cos1 %d", &cos1_val))
9720         cos1 = 1;
9721       else if (unformat (input, "cos2 %d", &cos2_val))
9722         cos2 = 1;
9723       else
9724         break;
9725     }
9726   if ((src + dst + proto + tag1 + tag2 +
9727        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9728     return 0;
9729
9730   if (tag1 || ignore_tag1 || cos1)
9731     len = 18;
9732   if (tag2 || ignore_tag2 || cos2)
9733     len = 22;
9734
9735   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9736
9737   if (dst)
9738     clib_memcpy (match, dst_val, 6);
9739
9740   if (src)
9741     clib_memcpy (match + 6, src_val, 6);
9742
9743   if (tag2)
9744     {
9745       /* inner vlan tag */
9746       match[19] = tag2_val[1];
9747       match[18] = tag2_val[0];
9748       if (cos2)
9749         match[18] |= (cos2_val & 0x7) << 5;
9750       if (proto)
9751         {
9752           match[21] = proto_val & 0xff;
9753           match[20] = proto_val >> 8;
9754         }
9755       if (tag1)
9756         {
9757           match[15] = tag1_val[1];
9758           match[14] = tag1_val[0];
9759         }
9760       if (cos1)
9761         match[14] |= (cos1_val & 0x7) << 5;
9762       *matchp = match;
9763       return 1;
9764     }
9765   if (tag1)
9766     {
9767       match[15] = tag1_val[1];
9768       match[14] = tag1_val[0];
9769       if (proto)
9770         {
9771           match[17] = proto_val & 0xff;
9772           match[16] = proto_val >> 8;
9773         }
9774       if (cos1)
9775         match[14] |= (cos1_val & 0x7) << 5;
9776
9777       *matchp = match;
9778       return 1;
9779     }
9780   if (cos2)
9781     match[18] |= (cos2_val & 0x7) << 5;
9782   if (cos1)
9783     match[14] |= (cos1_val & 0x7) << 5;
9784   if (proto)
9785     {
9786       match[13] = proto_val & 0xff;
9787       match[12] = proto_val >> 8;
9788     }
9789
9790   *matchp = match;
9791   return 1;
9792 }
9793 #endif
9794
9795 uword
9796 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9797 {
9798   u8 **matchp = va_arg (*args, u8 **);
9799   u32 skip_n_vectors = va_arg (*args, u32);
9800   u32 match_n_vectors = va_arg (*args, u32);
9801
9802   u8 *match = 0;
9803   u8 *l2 = 0;
9804   u8 *l3 = 0;
9805   u8 *l4 = 0;
9806
9807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9808     {
9809       if (unformat (input, "hex %U", unformat_hex_string, &match))
9810         ;
9811       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9812         ;
9813       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9814         ;
9815       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9816         ;
9817       else
9818         break;
9819     }
9820
9821   if (l4 && !l3)
9822     {
9823       vec_free (match);
9824       vec_free (l2);
9825       vec_free (l4);
9826       return 0;
9827     }
9828
9829   if (match || l2 || l3 || l4)
9830     {
9831       if (l2 || l3 || l4)
9832         {
9833           /* "Win a free Ethernet header in every packet" */
9834           if (l2 == 0)
9835             vec_validate_aligned (l2, 13, sizeof (u32x4));
9836           match = l2;
9837           if (vec_len (l3))
9838             {
9839               vec_append_aligned (match, l3, sizeof (u32x4));
9840               vec_free (l3);
9841             }
9842           if (vec_len (l4))
9843             {
9844               vec_append_aligned (match, l4, sizeof (u32x4));
9845               vec_free (l4);
9846             }
9847         }
9848
9849       /* Make sure the vector is big enough even if key is all 0's */
9850       vec_validate_aligned
9851         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9852          sizeof (u32x4));
9853
9854       /* Set size, include skipped vectors */
9855       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9856
9857       *matchp = match;
9858
9859       return 1;
9860     }
9861
9862   return 0;
9863 }
9864
9865 static int
9866 api_classify_add_del_session (vat_main_t * vam)
9867 {
9868   unformat_input_t *i = vam->input;
9869   vl_api_classify_add_del_session_t *mp;
9870   int is_add = 1;
9871   u32 table_index = ~0;
9872   u32 hit_next_index = ~0;
9873   u32 opaque_index = ~0;
9874   u8 *match = 0;
9875   i32 advance = 0;
9876   u32 skip_n_vectors = 0;
9877   u32 match_n_vectors = 0;
9878   u32 action = 0;
9879   u32 metadata = 0;
9880   int ret;
9881
9882   /*
9883    * Warning: you have to supply skip_n and match_n
9884    * because the API client cant simply look at the classify
9885    * table object.
9886    */
9887
9888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9889     {
9890       if (unformat (i, "del"))
9891         is_add = 0;
9892       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9893                          &hit_next_index))
9894         ;
9895       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9896                          &hit_next_index))
9897         ;
9898       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9899                          &hit_next_index))
9900         ;
9901       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9902         ;
9903       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9904         ;
9905       else if (unformat (i, "opaque-index %d", &opaque_index))
9906         ;
9907       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9908         ;
9909       else if (unformat (i, "match_n %d", &match_n_vectors))
9910         ;
9911       else if (unformat (i, "match %U", api_unformat_classify_match,
9912                          &match, skip_n_vectors, match_n_vectors))
9913         ;
9914       else if (unformat (i, "advance %d", &advance))
9915         ;
9916       else if (unformat (i, "table-index %d", &table_index))
9917         ;
9918       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9919         action = 1;
9920       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9921         action = 2;
9922       else if (unformat (i, "action %d", &action))
9923         ;
9924       else if (unformat (i, "metadata %d", &metadata))
9925         ;
9926       else
9927         break;
9928     }
9929
9930   if (table_index == ~0)
9931     {
9932       errmsg ("Table index required");
9933       return -99;
9934     }
9935
9936   if (is_add && match == 0)
9937     {
9938       errmsg ("Match value required");
9939       return -99;
9940     }
9941
9942   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9943
9944   mp->is_add = is_add;
9945   mp->table_index = ntohl (table_index);
9946   mp->hit_next_index = ntohl (hit_next_index);
9947   mp->opaque_index = ntohl (opaque_index);
9948   mp->advance = ntohl (advance);
9949   mp->action = action;
9950   mp->metadata = ntohl (metadata);
9951   clib_memcpy (mp->match, match, vec_len (match));
9952   vec_free (match);
9953
9954   S (mp);
9955   W (ret);
9956   return ret;
9957 }
9958
9959 static int
9960 api_classify_set_interface_ip_table (vat_main_t * vam)
9961 {
9962   unformat_input_t *i = vam->input;
9963   vl_api_classify_set_interface_ip_table_t *mp;
9964   u32 sw_if_index;
9965   int sw_if_index_set;
9966   u32 table_index = ~0;
9967   u8 is_ipv6 = 0;
9968   int ret;
9969
9970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9971     {
9972       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9973         sw_if_index_set = 1;
9974       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9975         sw_if_index_set = 1;
9976       else if (unformat (i, "table %d", &table_index))
9977         ;
9978       else
9979         {
9980           clib_warning ("parse error '%U'", format_unformat_error, i);
9981           return -99;
9982         }
9983     }
9984
9985   if (sw_if_index_set == 0)
9986     {
9987       errmsg ("missing interface name or sw_if_index");
9988       return -99;
9989     }
9990
9991
9992   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9993
9994   mp->sw_if_index = ntohl (sw_if_index);
9995   mp->table_index = ntohl (table_index);
9996   mp->is_ipv6 = is_ipv6;
9997
9998   S (mp);
9999   W (ret);
10000   return ret;
10001 }
10002
10003 static int
10004 api_classify_set_interface_l2_tables (vat_main_t * vam)
10005 {
10006   unformat_input_t *i = vam->input;
10007   vl_api_classify_set_interface_l2_tables_t *mp;
10008   u32 sw_if_index;
10009   int sw_if_index_set;
10010   u32 ip4_table_index = ~0;
10011   u32 ip6_table_index = ~0;
10012   u32 other_table_index = ~0;
10013   u32 is_input = 1;
10014   int ret;
10015
10016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10017     {
10018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10019         sw_if_index_set = 1;
10020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10021         sw_if_index_set = 1;
10022       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10023         ;
10024       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10025         ;
10026       else if (unformat (i, "other-table %d", &other_table_index))
10027         ;
10028       else if (unformat (i, "is-input %d", &is_input))
10029         ;
10030       else
10031         {
10032           clib_warning ("parse error '%U'", format_unformat_error, i);
10033           return -99;
10034         }
10035     }
10036
10037   if (sw_if_index_set == 0)
10038     {
10039       errmsg ("missing interface name or sw_if_index");
10040       return -99;
10041     }
10042
10043
10044   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10045
10046   mp->sw_if_index = ntohl (sw_if_index);
10047   mp->ip4_table_index = ntohl (ip4_table_index);
10048   mp->ip6_table_index = ntohl (ip6_table_index);
10049   mp->other_table_index = ntohl (other_table_index);
10050   mp->is_input = (u8) is_input;
10051
10052   S (mp);
10053   W (ret);
10054   return ret;
10055 }
10056
10057 static int
10058 api_set_ipfix_exporter (vat_main_t * vam)
10059 {
10060   unformat_input_t *i = vam->input;
10061   vl_api_set_ipfix_exporter_t *mp;
10062   ip4_address_t collector_address;
10063   u8 collector_address_set = 0;
10064   u32 collector_port = ~0;
10065   ip4_address_t src_address;
10066   u8 src_address_set = 0;
10067   u32 vrf_id = ~0;
10068   u32 path_mtu = ~0;
10069   u32 template_interval = ~0;
10070   u8 udp_checksum = 0;
10071   int ret;
10072
10073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10074     {
10075       if (unformat (i, "collector_address %U", unformat_ip4_address,
10076                     &collector_address))
10077         collector_address_set = 1;
10078       else if (unformat (i, "collector_port %d", &collector_port))
10079         ;
10080       else if (unformat (i, "src_address %U", unformat_ip4_address,
10081                          &src_address))
10082         src_address_set = 1;
10083       else if (unformat (i, "vrf_id %d", &vrf_id))
10084         ;
10085       else if (unformat (i, "path_mtu %d", &path_mtu))
10086         ;
10087       else if (unformat (i, "template_interval %d", &template_interval))
10088         ;
10089       else if (unformat (i, "udp_checksum"))
10090         udp_checksum = 1;
10091       else
10092         break;
10093     }
10094
10095   if (collector_address_set == 0)
10096     {
10097       errmsg ("collector_address required");
10098       return -99;
10099     }
10100
10101   if (src_address_set == 0)
10102     {
10103       errmsg ("src_address required");
10104       return -99;
10105     }
10106
10107   M (SET_IPFIX_EXPORTER, mp);
10108
10109   memcpy (mp->collector_address, collector_address.data,
10110           sizeof (collector_address.data));
10111   mp->collector_port = htons ((u16) collector_port);
10112   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10113   mp->vrf_id = htonl (vrf_id);
10114   mp->path_mtu = htonl (path_mtu);
10115   mp->template_interval = htonl (template_interval);
10116   mp->udp_checksum = udp_checksum;
10117
10118   S (mp);
10119   W (ret);
10120   return ret;
10121 }
10122
10123 static int
10124 api_set_ipfix_classify_stream (vat_main_t * vam)
10125 {
10126   unformat_input_t *i = vam->input;
10127   vl_api_set_ipfix_classify_stream_t *mp;
10128   u32 domain_id = 0;
10129   u32 src_port = UDP_DST_PORT_ipfix;
10130   int ret;
10131
10132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10133     {
10134       if (unformat (i, "domain %d", &domain_id))
10135         ;
10136       else if (unformat (i, "src_port %d", &src_port))
10137         ;
10138       else
10139         {
10140           errmsg ("unknown input `%U'", format_unformat_error, i);
10141           return -99;
10142         }
10143     }
10144
10145   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10146
10147   mp->domain_id = htonl (domain_id);
10148   mp->src_port = htons ((u16) src_port);
10149
10150   S (mp);
10151   W (ret);
10152   return ret;
10153 }
10154
10155 static int
10156 api_ipfix_classify_table_add_del (vat_main_t * vam)
10157 {
10158   unformat_input_t *i = vam->input;
10159   vl_api_ipfix_classify_table_add_del_t *mp;
10160   int is_add = -1;
10161   u32 classify_table_index = ~0;
10162   u8 ip_version = 0;
10163   u8 transport_protocol = 255;
10164   int ret;
10165
10166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10167     {
10168       if (unformat (i, "add"))
10169         is_add = 1;
10170       else if (unformat (i, "del"))
10171         is_add = 0;
10172       else if (unformat (i, "table %d", &classify_table_index))
10173         ;
10174       else if (unformat (i, "ip4"))
10175         ip_version = 4;
10176       else if (unformat (i, "ip6"))
10177         ip_version = 6;
10178       else if (unformat (i, "tcp"))
10179         transport_protocol = 6;
10180       else if (unformat (i, "udp"))
10181         transport_protocol = 17;
10182       else
10183         {
10184           errmsg ("unknown input `%U'", format_unformat_error, i);
10185           return -99;
10186         }
10187     }
10188
10189   if (is_add == -1)
10190     {
10191       errmsg ("expecting: add|del");
10192       return -99;
10193     }
10194   if (classify_table_index == ~0)
10195     {
10196       errmsg ("classifier table not specified");
10197       return -99;
10198     }
10199   if (ip_version == 0)
10200     {
10201       errmsg ("IP version not specified");
10202       return -99;
10203     }
10204
10205   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10206
10207   mp->is_add = is_add;
10208   mp->table_id = htonl (classify_table_index);
10209   mp->ip_version = ip_version;
10210   mp->transport_protocol = transport_protocol;
10211
10212   S (mp);
10213   W (ret);
10214   return ret;
10215 }
10216
10217 static int
10218 api_get_node_index (vat_main_t * vam)
10219 {
10220   unformat_input_t *i = vam->input;
10221   vl_api_get_node_index_t *mp;
10222   u8 *name = 0;
10223   int ret;
10224
10225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10226     {
10227       if (unformat (i, "node %s", &name))
10228         ;
10229       else
10230         break;
10231     }
10232   if (name == 0)
10233     {
10234       errmsg ("node name required");
10235       return -99;
10236     }
10237   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10238     {
10239       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10240       return -99;
10241     }
10242
10243   M (GET_NODE_INDEX, mp);
10244   clib_memcpy (mp->node_name, name, vec_len (name));
10245   vec_free (name);
10246
10247   S (mp);
10248   W (ret);
10249   return ret;
10250 }
10251
10252 static int
10253 api_get_next_index (vat_main_t * vam)
10254 {
10255   unformat_input_t *i = vam->input;
10256   vl_api_get_next_index_t *mp;
10257   u8 *node_name = 0, *next_node_name = 0;
10258   int ret;
10259
10260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10261     {
10262       if (unformat (i, "node-name %s", &node_name))
10263         ;
10264       else if (unformat (i, "next-node-name %s", &next_node_name))
10265         break;
10266     }
10267
10268   if (node_name == 0)
10269     {
10270       errmsg ("node name required");
10271       return -99;
10272     }
10273   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10274     {
10275       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10276       return -99;
10277     }
10278
10279   if (next_node_name == 0)
10280     {
10281       errmsg ("next node name required");
10282       return -99;
10283     }
10284   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10285     {
10286       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10287       return -99;
10288     }
10289
10290   M (GET_NEXT_INDEX, mp);
10291   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10292   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10293   vec_free (node_name);
10294   vec_free (next_node_name);
10295
10296   S (mp);
10297   W (ret);
10298   return ret;
10299 }
10300
10301 static int
10302 api_add_node_next (vat_main_t * vam)
10303 {
10304   unformat_input_t *i = vam->input;
10305   vl_api_add_node_next_t *mp;
10306   u8 *name = 0;
10307   u8 *next = 0;
10308   int ret;
10309
10310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10311     {
10312       if (unformat (i, "node %s", &name))
10313         ;
10314       else if (unformat (i, "next %s", &next))
10315         ;
10316       else
10317         break;
10318     }
10319   if (name == 0)
10320     {
10321       errmsg ("node name required");
10322       return -99;
10323     }
10324   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10325     {
10326       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10327       return -99;
10328     }
10329   if (next == 0)
10330     {
10331       errmsg ("next node required");
10332       return -99;
10333     }
10334   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10335     {
10336       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10337       return -99;
10338     }
10339
10340   M (ADD_NODE_NEXT, mp);
10341   clib_memcpy (mp->node_name, name, vec_len (name));
10342   clib_memcpy (mp->next_name, next, vec_len (next));
10343   vec_free (name);
10344   vec_free (next);
10345
10346   S (mp);
10347   W (ret);
10348   return ret;
10349 }
10350
10351 static int
10352 api_l2tpv3_create_tunnel (vat_main_t * vam)
10353 {
10354   unformat_input_t *i = vam->input;
10355   ip6_address_t client_address, our_address;
10356   int client_address_set = 0;
10357   int our_address_set = 0;
10358   u32 local_session_id = 0;
10359   u32 remote_session_id = 0;
10360   u64 local_cookie = 0;
10361   u64 remote_cookie = 0;
10362   u8 l2_sublayer_present = 0;
10363   vl_api_l2tpv3_create_tunnel_t *mp;
10364   int ret;
10365
10366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10367     {
10368       if (unformat (i, "client_address %U", unformat_ip6_address,
10369                     &client_address))
10370         client_address_set = 1;
10371       else if (unformat (i, "our_address %U", unformat_ip6_address,
10372                          &our_address))
10373         our_address_set = 1;
10374       else if (unformat (i, "local_session_id %d", &local_session_id))
10375         ;
10376       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10377         ;
10378       else if (unformat (i, "local_cookie %lld", &local_cookie))
10379         ;
10380       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10381         ;
10382       else if (unformat (i, "l2-sublayer-present"))
10383         l2_sublayer_present = 1;
10384       else
10385         break;
10386     }
10387
10388   if (client_address_set == 0)
10389     {
10390       errmsg ("client_address required");
10391       return -99;
10392     }
10393
10394   if (our_address_set == 0)
10395     {
10396       errmsg ("our_address required");
10397       return -99;
10398     }
10399
10400   M (L2TPV3_CREATE_TUNNEL, mp);
10401
10402   clib_memcpy (mp->client_address, client_address.as_u8,
10403                sizeof (mp->client_address));
10404
10405   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10406
10407   mp->local_session_id = ntohl (local_session_id);
10408   mp->remote_session_id = ntohl (remote_session_id);
10409   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10410   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10411   mp->l2_sublayer_present = l2_sublayer_present;
10412   mp->is_ipv6 = 1;
10413
10414   S (mp);
10415   W (ret);
10416   return ret;
10417 }
10418
10419 static int
10420 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10421 {
10422   unformat_input_t *i = vam->input;
10423   u32 sw_if_index;
10424   u8 sw_if_index_set = 0;
10425   u64 new_local_cookie = 0;
10426   u64 new_remote_cookie = 0;
10427   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10428   int ret;
10429
10430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10431     {
10432       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10433         sw_if_index_set = 1;
10434       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10435         sw_if_index_set = 1;
10436       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10437         ;
10438       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10439         ;
10440       else
10441         break;
10442     }
10443
10444   if (sw_if_index_set == 0)
10445     {
10446       errmsg ("missing interface name or sw_if_index");
10447       return -99;
10448     }
10449
10450   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10451
10452   mp->sw_if_index = ntohl (sw_if_index);
10453   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10454   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10455
10456   S (mp);
10457   W (ret);
10458   return ret;
10459 }
10460
10461 static int
10462 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10463 {
10464   unformat_input_t *i = vam->input;
10465   vl_api_l2tpv3_interface_enable_disable_t *mp;
10466   u32 sw_if_index;
10467   u8 sw_if_index_set = 0;
10468   u8 enable_disable = 1;
10469   int ret;
10470
10471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10472     {
10473       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10474         sw_if_index_set = 1;
10475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10476         sw_if_index_set = 1;
10477       else if (unformat (i, "enable"))
10478         enable_disable = 1;
10479       else if (unformat (i, "disable"))
10480         enable_disable = 0;
10481       else
10482         break;
10483     }
10484
10485   if (sw_if_index_set == 0)
10486     {
10487       errmsg ("missing interface name or sw_if_index");
10488       return -99;
10489     }
10490
10491   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10492
10493   mp->sw_if_index = ntohl (sw_if_index);
10494   mp->enable_disable = enable_disable;
10495
10496   S (mp);
10497   W (ret);
10498   return ret;
10499 }
10500
10501 static int
10502 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10503 {
10504   unformat_input_t *i = vam->input;
10505   vl_api_l2tpv3_set_lookup_key_t *mp;
10506   u8 key = ~0;
10507   int ret;
10508
10509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10510     {
10511       if (unformat (i, "lookup_v6_src"))
10512         key = L2T_LOOKUP_SRC_ADDRESS;
10513       else if (unformat (i, "lookup_v6_dst"))
10514         key = L2T_LOOKUP_DST_ADDRESS;
10515       else if (unformat (i, "lookup_session_id"))
10516         key = L2T_LOOKUP_SESSION_ID;
10517       else
10518         break;
10519     }
10520
10521   if (key == (u8) ~ 0)
10522     {
10523       errmsg ("l2tp session lookup key unset");
10524       return -99;
10525     }
10526
10527   M (L2TPV3_SET_LOOKUP_KEY, mp);
10528
10529   mp->key = key;
10530
10531   S (mp);
10532   W (ret);
10533   return ret;
10534 }
10535
10536 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10537   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10538 {
10539   vat_main_t *vam = &vat_main;
10540
10541   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10542          format_ip6_address, mp->our_address,
10543          format_ip6_address, mp->client_address,
10544          clib_net_to_host_u32 (mp->sw_if_index));
10545
10546   print (vam->ofp,
10547          "   local cookies %016llx %016llx remote cookie %016llx",
10548          clib_net_to_host_u64 (mp->local_cookie[0]),
10549          clib_net_to_host_u64 (mp->local_cookie[1]),
10550          clib_net_to_host_u64 (mp->remote_cookie));
10551
10552   print (vam->ofp, "   local session-id %d remote session-id %d",
10553          clib_net_to_host_u32 (mp->local_session_id),
10554          clib_net_to_host_u32 (mp->remote_session_id));
10555
10556   print (vam->ofp, "   l2 specific sublayer %s\n",
10557          mp->l2_sublayer_present ? "preset" : "absent");
10558
10559 }
10560
10561 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10562   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10563 {
10564   vat_main_t *vam = &vat_main;
10565   vat_json_node_t *node = NULL;
10566   struct in6_addr addr;
10567
10568   if (VAT_JSON_ARRAY != vam->json_tree.type)
10569     {
10570       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10571       vat_json_init_array (&vam->json_tree);
10572     }
10573   node = vat_json_array_add (&vam->json_tree);
10574
10575   vat_json_init_object (node);
10576
10577   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10578   vat_json_object_add_ip6 (node, "our_address", addr);
10579   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10580   vat_json_object_add_ip6 (node, "client_address", addr);
10581
10582   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10583   vat_json_init_array (lc);
10584   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10585   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10586   vat_json_object_add_uint (node, "remote_cookie",
10587                             clib_net_to_host_u64 (mp->remote_cookie));
10588
10589   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10590   vat_json_object_add_uint (node, "local_session_id",
10591                             clib_net_to_host_u32 (mp->local_session_id));
10592   vat_json_object_add_uint (node, "remote_session_id",
10593                             clib_net_to_host_u32 (mp->remote_session_id));
10594   vat_json_object_add_string_copy (node, "l2_sublayer",
10595                                    mp->l2_sublayer_present ? (u8 *) "present"
10596                                    : (u8 *) "absent");
10597 }
10598
10599 static int
10600 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10601 {
10602   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10603   vl_api_control_ping_t *mp_ping;
10604   int ret;
10605
10606   /* Get list of l2tpv3-tunnel interfaces */
10607   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10608   S (mp);
10609
10610   /* Use a control ping for synchronization */
10611   M (CONTROL_PING, mp_ping);
10612   S (mp_ping);
10613
10614   W (ret);
10615   return ret;
10616 }
10617
10618
10619 static void vl_api_sw_interface_tap_details_t_handler
10620   (vl_api_sw_interface_tap_details_t * mp)
10621 {
10622   vat_main_t *vam = &vat_main;
10623
10624   print (vam->ofp, "%-16s %d",
10625          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10626 }
10627
10628 static void vl_api_sw_interface_tap_details_t_handler_json
10629   (vl_api_sw_interface_tap_details_t * mp)
10630 {
10631   vat_main_t *vam = &vat_main;
10632   vat_json_node_t *node = NULL;
10633
10634   if (VAT_JSON_ARRAY != vam->json_tree.type)
10635     {
10636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10637       vat_json_init_array (&vam->json_tree);
10638     }
10639   node = vat_json_array_add (&vam->json_tree);
10640
10641   vat_json_init_object (node);
10642   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10643   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10644 }
10645
10646 static int
10647 api_sw_interface_tap_dump (vat_main_t * vam)
10648 {
10649   vl_api_sw_interface_tap_dump_t *mp;
10650   vl_api_control_ping_t *mp_ping;
10651   int ret;
10652
10653   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10654   /* Get list of tap interfaces */
10655   M (SW_INTERFACE_TAP_DUMP, mp);
10656   S (mp);
10657
10658   /* Use a control ping for synchronization */
10659   M (CONTROL_PING, mp_ping);
10660   S (mp_ping);
10661
10662   W (ret);
10663   return ret;
10664 }
10665
10666 static uword unformat_vxlan_decap_next
10667   (unformat_input_t * input, va_list * args)
10668 {
10669   u32 *result = va_arg (*args, u32 *);
10670   u32 tmp;
10671
10672   if (unformat (input, "l2"))
10673     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10674   else if (unformat (input, "%d", &tmp))
10675     *result = tmp;
10676   else
10677     return 0;
10678   return 1;
10679 }
10680
10681 static int
10682 api_vxlan_add_del_tunnel (vat_main_t * vam)
10683 {
10684   unformat_input_t *line_input = vam->input;
10685   vl_api_vxlan_add_del_tunnel_t *mp;
10686   ip46_address_t src, dst;
10687   u8 is_add = 1;
10688   u8 ipv4_set = 0, ipv6_set = 0;
10689   u8 src_set = 0;
10690   u8 dst_set = 0;
10691   u8 grp_set = 0;
10692   u32 mcast_sw_if_index = ~0;
10693   u32 encap_vrf_id = 0;
10694   u32 decap_next_index = ~0;
10695   u32 vni = 0;
10696   int ret;
10697
10698   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10699   memset (&src, 0, sizeof src);
10700   memset (&dst, 0, sizeof dst);
10701
10702   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10703     {
10704       if (unformat (line_input, "del"))
10705         is_add = 0;
10706       else
10707         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10708         {
10709           ipv4_set = 1;
10710           src_set = 1;
10711         }
10712       else
10713         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10714         {
10715           ipv4_set = 1;
10716           dst_set = 1;
10717         }
10718       else
10719         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10720         {
10721           ipv6_set = 1;
10722           src_set = 1;
10723         }
10724       else
10725         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10726         {
10727           ipv6_set = 1;
10728           dst_set = 1;
10729         }
10730       else if (unformat (line_input, "group %U %U",
10731                          unformat_ip4_address, &dst.ip4,
10732                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10733         {
10734           grp_set = dst_set = 1;
10735           ipv4_set = 1;
10736         }
10737       else if (unformat (line_input, "group %U",
10738                          unformat_ip4_address, &dst.ip4))
10739         {
10740           grp_set = dst_set = 1;
10741           ipv4_set = 1;
10742         }
10743       else if (unformat (line_input, "group %U %U",
10744                          unformat_ip6_address, &dst.ip6,
10745                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10746         {
10747           grp_set = dst_set = 1;
10748           ipv6_set = 1;
10749         }
10750       else if (unformat (line_input, "group %U",
10751                          unformat_ip6_address, &dst.ip6))
10752         {
10753           grp_set = dst_set = 1;
10754           ipv6_set = 1;
10755         }
10756       else
10757         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10758         ;
10759       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10760         ;
10761       else if (unformat (line_input, "decap-next %U",
10762                          unformat_vxlan_decap_next, &decap_next_index))
10763         ;
10764       else if (unformat (line_input, "vni %d", &vni))
10765         ;
10766       else
10767         {
10768           errmsg ("parse error '%U'", format_unformat_error, line_input);
10769           return -99;
10770         }
10771     }
10772
10773   if (src_set == 0)
10774     {
10775       errmsg ("tunnel src address not specified");
10776       return -99;
10777     }
10778   if (dst_set == 0)
10779     {
10780       errmsg ("tunnel dst address not specified");
10781       return -99;
10782     }
10783
10784   if (grp_set && !ip46_address_is_multicast (&dst))
10785     {
10786       errmsg ("tunnel group address not multicast");
10787       return -99;
10788     }
10789   if (grp_set && mcast_sw_if_index == ~0)
10790     {
10791       errmsg ("tunnel nonexistent multicast device");
10792       return -99;
10793     }
10794   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10795     {
10796       errmsg ("tunnel dst address must be unicast");
10797       return -99;
10798     }
10799
10800
10801   if (ipv4_set && ipv6_set)
10802     {
10803       errmsg ("both IPv4 and IPv6 addresses specified");
10804       return -99;
10805     }
10806
10807   if ((vni == 0) || (vni >> 24))
10808     {
10809       errmsg ("vni not specified or out of range");
10810       return -99;
10811     }
10812
10813   M (VXLAN_ADD_DEL_TUNNEL, mp);
10814
10815   if (ipv6_set)
10816     {
10817       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10818       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10819     }
10820   else
10821     {
10822       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10823       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10824     }
10825   mp->encap_vrf_id = ntohl (encap_vrf_id);
10826   mp->decap_next_index = ntohl (decap_next_index);
10827   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10828   mp->vni = ntohl (vni);
10829   mp->is_add = is_add;
10830   mp->is_ipv6 = ipv6_set;
10831
10832   S (mp);
10833   W (ret);
10834   return ret;
10835 }
10836
10837 static void vl_api_vxlan_tunnel_details_t_handler
10838   (vl_api_vxlan_tunnel_details_t * mp)
10839 {
10840   vat_main_t *vam = &vat_main;
10841   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
10842   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
10843
10844   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10845          ntohl (mp->sw_if_index),
10846          format_ip46_address, &src, IP46_TYPE_ANY,
10847          format_ip46_address, &dst, IP46_TYPE_ANY,
10848          ntohl (mp->encap_vrf_id),
10849          ntohl (mp->decap_next_index), ntohl (mp->vni),
10850          ntohl (mp->mcast_sw_if_index));
10851 }
10852
10853 static void vl_api_vxlan_tunnel_details_t_handler_json
10854   (vl_api_vxlan_tunnel_details_t * mp)
10855 {
10856   vat_main_t *vam = &vat_main;
10857   vat_json_node_t *node = NULL;
10858
10859   if (VAT_JSON_ARRAY != vam->json_tree.type)
10860     {
10861       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10862       vat_json_init_array (&vam->json_tree);
10863     }
10864   node = vat_json_array_add (&vam->json_tree);
10865
10866   vat_json_init_object (node);
10867   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10868   if (mp->is_ipv6)
10869     {
10870       struct in6_addr ip6;
10871
10872       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10873       vat_json_object_add_ip6 (node, "src_address", ip6);
10874       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10875       vat_json_object_add_ip6 (node, "dst_address", ip6);
10876     }
10877   else
10878     {
10879       struct in_addr ip4;
10880
10881       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10882       vat_json_object_add_ip4 (node, "src_address", ip4);
10883       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10884       vat_json_object_add_ip4 (node, "dst_address", ip4);
10885     }
10886   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10887   vat_json_object_add_uint (node, "decap_next_index",
10888                             ntohl (mp->decap_next_index));
10889   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10890   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10891   vat_json_object_add_uint (node, "mcast_sw_if_index",
10892                             ntohl (mp->mcast_sw_if_index));
10893 }
10894
10895 static int
10896 api_vxlan_tunnel_dump (vat_main_t * vam)
10897 {
10898   unformat_input_t *i = vam->input;
10899   vl_api_vxlan_tunnel_dump_t *mp;
10900   vl_api_control_ping_t *mp_ping;
10901   u32 sw_if_index;
10902   u8 sw_if_index_set = 0;
10903   int ret;
10904
10905   /* Parse args required to build the message */
10906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10907     {
10908       if (unformat (i, "sw_if_index %d", &sw_if_index))
10909         sw_if_index_set = 1;
10910       else
10911         break;
10912     }
10913
10914   if (sw_if_index_set == 0)
10915     {
10916       sw_if_index = ~0;
10917     }
10918
10919   if (!vam->json_output)
10920     {
10921       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10922              "sw_if_index", "src_address", "dst_address",
10923              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10924     }
10925
10926   /* Get list of vxlan-tunnel interfaces */
10927   M (VXLAN_TUNNEL_DUMP, mp);
10928
10929   mp->sw_if_index = htonl (sw_if_index);
10930
10931   S (mp);
10932
10933   /* Use a control ping for synchronization */
10934   M (CONTROL_PING, mp_ping);
10935   S (mp_ping);
10936
10937   W (ret);
10938   return ret;
10939 }
10940
10941 static int
10942 api_gre_add_del_tunnel (vat_main_t * vam)
10943 {
10944   unformat_input_t *line_input = vam->input;
10945   vl_api_gre_add_del_tunnel_t *mp;
10946   ip4_address_t src4, dst4;
10947   u8 is_add = 1;
10948   u8 teb = 0;
10949   u8 src_set = 0;
10950   u8 dst_set = 0;
10951   u32 outer_fib_id = 0;
10952   int ret;
10953
10954   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10955     {
10956       if (unformat (line_input, "del"))
10957         is_add = 0;
10958       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10959         src_set = 1;
10960       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10961         dst_set = 1;
10962       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10963         ;
10964       else if (unformat (line_input, "teb"))
10965         teb = 1;
10966       else
10967         {
10968           errmsg ("parse error '%U'", format_unformat_error, line_input);
10969           return -99;
10970         }
10971     }
10972
10973   if (src_set == 0)
10974     {
10975       errmsg ("tunnel src address not specified");
10976       return -99;
10977     }
10978   if (dst_set == 0)
10979     {
10980       errmsg ("tunnel dst address not specified");
10981       return -99;
10982     }
10983
10984
10985   M (GRE_ADD_DEL_TUNNEL, mp);
10986
10987   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10988   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10989   mp->outer_fib_id = ntohl (outer_fib_id);
10990   mp->is_add = is_add;
10991   mp->teb = teb;
10992
10993   S (mp);
10994   W (ret);
10995   return ret;
10996 }
10997
10998 static void vl_api_gre_tunnel_details_t_handler
10999   (vl_api_gre_tunnel_details_t * mp)
11000 {
11001   vat_main_t *vam = &vat_main;
11002
11003   print (vam->ofp, "%11d%15U%15U%6d%14d",
11004          ntohl (mp->sw_if_index),
11005          format_ip4_address, &mp->src_address,
11006          format_ip4_address, &mp->dst_address,
11007          mp->teb, ntohl (mp->outer_fib_id));
11008 }
11009
11010 static void vl_api_gre_tunnel_details_t_handler_json
11011   (vl_api_gre_tunnel_details_t * mp)
11012 {
11013   vat_main_t *vam = &vat_main;
11014   vat_json_node_t *node = NULL;
11015   struct in_addr ip4;
11016
11017   if (VAT_JSON_ARRAY != vam->json_tree.type)
11018     {
11019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11020       vat_json_init_array (&vam->json_tree);
11021     }
11022   node = vat_json_array_add (&vam->json_tree);
11023
11024   vat_json_init_object (node);
11025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11026   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11027   vat_json_object_add_ip4 (node, "src_address", ip4);
11028   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11029   vat_json_object_add_ip4 (node, "dst_address", ip4);
11030   vat_json_object_add_uint (node, "teb", mp->teb);
11031   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11032 }
11033
11034 static int
11035 api_gre_tunnel_dump (vat_main_t * vam)
11036 {
11037   unformat_input_t *i = vam->input;
11038   vl_api_gre_tunnel_dump_t *mp;
11039   vl_api_control_ping_t *mp_ping;
11040   u32 sw_if_index;
11041   u8 sw_if_index_set = 0;
11042   int ret;
11043
11044   /* Parse args required to build the message */
11045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11046     {
11047       if (unformat (i, "sw_if_index %d", &sw_if_index))
11048         sw_if_index_set = 1;
11049       else
11050         break;
11051     }
11052
11053   if (sw_if_index_set == 0)
11054     {
11055       sw_if_index = ~0;
11056     }
11057
11058   if (!vam->json_output)
11059     {
11060       print (vam->ofp, "%11s%15s%15s%6s%14s",
11061              "sw_if_index", "src_address", "dst_address", "teb",
11062              "outer_fib_id");
11063     }
11064
11065   /* Get list of gre-tunnel interfaces */
11066   M (GRE_TUNNEL_DUMP, mp);
11067
11068   mp->sw_if_index = htonl (sw_if_index);
11069
11070   S (mp);
11071
11072   /* Use a control ping for synchronization */
11073   M (CONTROL_PING, mp_ping);
11074   S (mp_ping);
11075
11076   W (ret);
11077   return ret;
11078 }
11079
11080 static int
11081 api_l2_fib_clear_table (vat_main_t * vam)
11082 {
11083 //  unformat_input_t * i = vam->input;
11084   vl_api_l2_fib_clear_table_t *mp;
11085   int ret;
11086
11087   M (L2_FIB_CLEAR_TABLE, mp);
11088
11089   S (mp);
11090   W (ret);
11091   return ret;
11092 }
11093
11094 static int
11095 api_l2_interface_efp_filter (vat_main_t * vam)
11096 {
11097   unformat_input_t *i = vam->input;
11098   vl_api_l2_interface_efp_filter_t *mp;
11099   u32 sw_if_index;
11100   u8 enable = 1;
11101   u8 sw_if_index_set = 0;
11102   int ret;
11103
11104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11105     {
11106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11107         sw_if_index_set = 1;
11108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11109         sw_if_index_set = 1;
11110       else if (unformat (i, "enable"))
11111         enable = 1;
11112       else if (unformat (i, "disable"))
11113         enable = 0;
11114       else
11115         {
11116           clib_warning ("parse error '%U'", format_unformat_error, i);
11117           return -99;
11118         }
11119     }
11120
11121   if (sw_if_index_set == 0)
11122     {
11123       errmsg ("missing sw_if_index");
11124       return -99;
11125     }
11126
11127   M (L2_INTERFACE_EFP_FILTER, mp);
11128
11129   mp->sw_if_index = ntohl (sw_if_index);
11130   mp->enable_disable = enable;
11131
11132   S (mp);
11133   W (ret);
11134   return ret;
11135 }
11136
11137 #define foreach_vtr_op                          \
11138 _("disable",  L2_VTR_DISABLED)                  \
11139 _("push-1",  L2_VTR_PUSH_1)                     \
11140 _("push-2",  L2_VTR_PUSH_2)                     \
11141 _("pop-1",  L2_VTR_POP_1)                       \
11142 _("pop-2",  L2_VTR_POP_2)                       \
11143 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11144 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11145 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11146 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11147
11148 static int
11149 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11150 {
11151   unformat_input_t *i = vam->input;
11152   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11153   u32 sw_if_index;
11154   u8 sw_if_index_set = 0;
11155   u8 vtr_op_set = 0;
11156   u32 vtr_op = 0;
11157   u32 push_dot1q = 1;
11158   u32 tag1 = ~0;
11159   u32 tag2 = ~0;
11160   int ret;
11161
11162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11163     {
11164       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11165         sw_if_index_set = 1;
11166       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11167         sw_if_index_set = 1;
11168       else if (unformat (i, "vtr_op %d", &vtr_op))
11169         vtr_op_set = 1;
11170 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11171       foreach_vtr_op
11172 #undef _
11173         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11174         ;
11175       else if (unformat (i, "tag1 %d", &tag1))
11176         ;
11177       else if (unformat (i, "tag2 %d", &tag2))
11178         ;
11179       else
11180         {
11181           clib_warning ("parse error '%U'", format_unformat_error, i);
11182           return -99;
11183         }
11184     }
11185
11186   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11187     {
11188       errmsg ("missing vtr operation or sw_if_index");
11189       return -99;
11190     }
11191
11192   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11193   mp->sw_if_index = ntohl (sw_if_index);
11194   mp->vtr_op = ntohl (vtr_op);
11195   mp->push_dot1q = ntohl (push_dot1q);
11196   mp->tag1 = ntohl (tag1);
11197   mp->tag2 = ntohl (tag2);
11198
11199   S (mp);
11200   W (ret);
11201   return ret;
11202 }
11203
11204 static int
11205 api_create_vhost_user_if (vat_main_t * vam)
11206 {
11207   unformat_input_t *i = vam->input;
11208   vl_api_create_vhost_user_if_t *mp;
11209   u8 *file_name;
11210   u8 is_server = 0;
11211   u8 file_name_set = 0;
11212   u32 custom_dev_instance = ~0;
11213   u8 hwaddr[6];
11214   u8 use_custom_mac = 0;
11215   u8 *tag = 0;
11216   int ret;
11217   u8 operation_mode = VHOST_USER_POLLING_MODE;
11218
11219   /* Shut up coverity */
11220   memset (hwaddr, 0, sizeof (hwaddr));
11221
11222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11223     {
11224       if (unformat (i, "socket %s", &file_name))
11225         {
11226           file_name_set = 1;
11227         }
11228       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11229         ;
11230       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11231         use_custom_mac = 1;
11232       else if (unformat (i, "server"))
11233         is_server = 1;
11234       else if (unformat (i, "tag %s", &tag))
11235         ;
11236       else if (unformat (i, "mode %U",
11237                          api_unformat_vhost_user_operation_mode,
11238                          &operation_mode))
11239         ;
11240       else
11241         break;
11242     }
11243
11244   if (file_name_set == 0)
11245     {
11246       errmsg ("missing socket file name");
11247       return -99;
11248     }
11249
11250   if (vec_len (file_name) > 255)
11251     {
11252       errmsg ("socket file name too long");
11253       return -99;
11254     }
11255   vec_add1 (file_name, 0);
11256
11257   M (CREATE_VHOST_USER_IF, mp);
11258
11259   mp->operation_mode = operation_mode;
11260   mp->is_server = is_server;
11261   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11262   vec_free (file_name);
11263   if (custom_dev_instance != ~0)
11264     {
11265       mp->renumber = 1;
11266       mp->custom_dev_instance = ntohl (custom_dev_instance);
11267     }
11268   mp->use_custom_mac = use_custom_mac;
11269   clib_memcpy (mp->mac_address, hwaddr, 6);
11270   if (tag)
11271     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11272   vec_free (tag);
11273
11274   S (mp);
11275   W (ret);
11276   return ret;
11277 }
11278
11279 static int
11280 api_modify_vhost_user_if (vat_main_t * vam)
11281 {
11282   unformat_input_t *i = vam->input;
11283   vl_api_modify_vhost_user_if_t *mp;
11284   u8 *file_name;
11285   u8 is_server = 0;
11286   u8 file_name_set = 0;
11287   u32 custom_dev_instance = ~0;
11288   u8 sw_if_index_set = 0;
11289   u32 sw_if_index = (u32) ~ 0;
11290   int ret;
11291   u8 operation_mode = VHOST_USER_POLLING_MODE;
11292
11293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11294     {
11295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11296         sw_if_index_set = 1;
11297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11298         sw_if_index_set = 1;
11299       else if (unformat (i, "socket %s", &file_name))
11300         {
11301           file_name_set = 1;
11302         }
11303       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11304         ;
11305       else if (unformat (i, "server"))
11306         is_server = 1;
11307       else if (unformat (i, "mode %U",
11308                          api_unformat_vhost_user_operation_mode,
11309                          &operation_mode))
11310         ;
11311       else
11312         break;
11313     }
11314
11315   if (sw_if_index_set == 0)
11316     {
11317       errmsg ("missing sw_if_index or interface name");
11318       return -99;
11319     }
11320
11321   if (file_name_set == 0)
11322     {
11323       errmsg ("missing socket file name");
11324       return -99;
11325     }
11326
11327   if (vec_len (file_name) > 255)
11328     {
11329       errmsg ("socket file name too long");
11330       return -99;
11331     }
11332   vec_add1 (file_name, 0);
11333
11334   M (MODIFY_VHOST_USER_IF, mp);
11335
11336   mp->operation_mode = operation_mode;
11337   mp->sw_if_index = ntohl (sw_if_index);
11338   mp->is_server = is_server;
11339   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11340   vec_free (file_name);
11341   if (custom_dev_instance != ~0)
11342     {
11343       mp->renumber = 1;
11344       mp->custom_dev_instance = ntohl (custom_dev_instance);
11345     }
11346
11347   S (mp);
11348   W (ret);
11349   return ret;
11350 }
11351
11352 static int
11353 api_delete_vhost_user_if (vat_main_t * vam)
11354 {
11355   unformat_input_t *i = vam->input;
11356   vl_api_delete_vhost_user_if_t *mp;
11357   u32 sw_if_index = ~0;
11358   u8 sw_if_index_set = 0;
11359   int ret;
11360
11361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11362     {
11363       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11364         sw_if_index_set = 1;
11365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11366         sw_if_index_set = 1;
11367       else
11368         break;
11369     }
11370
11371   if (sw_if_index_set == 0)
11372     {
11373       errmsg ("missing sw_if_index or interface name");
11374       return -99;
11375     }
11376
11377
11378   M (DELETE_VHOST_USER_IF, mp);
11379
11380   mp->sw_if_index = ntohl (sw_if_index);
11381
11382   S (mp);
11383   W (ret);
11384   return ret;
11385 }
11386
11387 static void vl_api_sw_interface_vhost_user_details_t_handler
11388   (vl_api_sw_interface_vhost_user_details_t * mp)
11389 {
11390   vat_main_t *vam = &vat_main;
11391
11392   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
11393          (char *) mp->interface_name,
11394          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11395          clib_net_to_host_u64 (mp->features), mp->is_server,
11396          ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11397          mp->operation_mode, (char *) mp->sock_filename);
11398   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11399 }
11400
11401 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11402   (vl_api_sw_interface_vhost_user_details_t * mp)
11403 {
11404   vat_main_t *vam = &vat_main;
11405   vat_json_node_t *node = NULL;
11406
11407   if (VAT_JSON_ARRAY != vam->json_tree.type)
11408     {
11409       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11410       vat_json_init_array (&vam->json_tree);
11411     }
11412   node = vat_json_array_add (&vam->json_tree);
11413
11414   vat_json_init_object (node);
11415   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11416   vat_json_object_add_string_copy (node, "interface_name",
11417                                    mp->interface_name);
11418   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11419                             ntohl (mp->virtio_net_hdr_sz));
11420   vat_json_object_add_uint (node, "features",
11421                             clib_net_to_host_u64 (mp->features));
11422   vat_json_object_add_uint (node, "is_server", mp->is_server);
11423   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11424   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11425   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11426   vat_json_object_add_uint (node, "mode", mp->operation_mode);
11427 }
11428
11429 static int
11430 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11431 {
11432   vl_api_sw_interface_vhost_user_dump_t *mp;
11433   vl_api_control_ping_t *mp_ping;
11434   int ret;
11435   print (vam->ofp,
11436          "Interface name            idx hdr_sz features server regions mode"
11437          "      filename");
11438
11439   /* Get list of vhost-user interfaces */
11440   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11441   S (mp);
11442
11443   /* Use a control ping for synchronization */
11444   M (CONTROL_PING, mp_ping);
11445   S (mp_ping);
11446
11447   W (ret);
11448   return ret;
11449 }
11450
11451 static int
11452 api_show_version (vat_main_t * vam)
11453 {
11454   vl_api_show_version_t *mp;
11455   int ret;
11456
11457   M (SHOW_VERSION, mp);
11458
11459   S (mp);
11460   W (ret);
11461   return ret;
11462 }
11463
11464
11465 static int
11466 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11467 {
11468   unformat_input_t *line_input = vam->input;
11469   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11470   ip4_address_t local4, remote4;
11471   ip6_address_t local6, remote6;
11472   u8 is_add = 1;
11473   u8 ipv4_set = 0, ipv6_set = 0;
11474   u8 local_set = 0;
11475   u8 remote_set = 0;
11476   u32 encap_vrf_id = 0;
11477   u32 decap_vrf_id = 0;
11478   u8 protocol = ~0;
11479   u32 vni;
11480   u8 vni_set = 0;
11481   int ret;
11482
11483   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (line_input, "del"))
11486         is_add = 0;
11487       else if (unformat (line_input, "local %U",
11488                          unformat_ip4_address, &local4))
11489         {
11490           local_set = 1;
11491           ipv4_set = 1;
11492         }
11493       else if (unformat (line_input, "remote %U",
11494                          unformat_ip4_address, &remote4))
11495         {
11496           remote_set = 1;
11497           ipv4_set = 1;
11498         }
11499       else if (unformat (line_input, "local %U",
11500                          unformat_ip6_address, &local6))
11501         {
11502           local_set = 1;
11503           ipv6_set = 1;
11504         }
11505       else if (unformat (line_input, "remote %U",
11506                          unformat_ip6_address, &remote6))
11507         {
11508           remote_set = 1;
11509           ipv6_set = 1;
11510         }
11511       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11512         ;
11513       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11514         ;
11515       else if (unformat (line_input, "vni %d", &vni))
11516         vni_set = 1;
11517       else if (unformat (line_input, "next-ip4"))
11518         protocol = 1;
11519       else if (unformat (line_input, "next-ip6"))
11520         protocol = 2;
11521       else if (unformat (line_input, "next-ethernet"))
11522         protocol = 3;
11523       else if (unformat (line_input, "next-nsh"))
11524         protocol = 4;
11525       else
11526         {
11527           errmsg ("parse error '%U'", format_unformat_error, line_input);
11528           return -99;
11529         }
11530     }
11531
11532   if (local_set == 0)
11533     {
11534       errmsg ("tunnel local address not specified");
11535       return -99;
11536     }
11537   if (remote_set == 0)
11538     {
11539       errmsg ("tunnel remote address not specified");
11540       return -99;
11541     }
11542   if (ipv4_set && ipv6_set)
11543     {
11544       errmsg ("both IPv4 and IPv6 addresses specified");
11545       return -99;
11546     }
11547
11548   if (vni_set == 0)
11549     {
11550       errmsg ("vni not specified");
11551       return -99;
11552     }
11553
11554   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11555
11556
11557   if (ipv6_set)
11558     {
11559       clib_memcpy (&mp->local, &local6, sizeof (local6));
11560       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11561     }
11562   else
11563     {
11564       clib_memcpy (&mp->local, &local4, sizeof (local4));
11565       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11566     }
11567
11568   mp->encap_vrf_id = ntohl (encap_vrf_id);
11569   mp->decap_vrf_id = ntohl (decap_vrf_id);
11570   mp->protocol = protocol;
11571   mp->vni = ntohl (vni);
11572   mp->is_add = is_add;
11573   mp->is_ipv6 = ipv6_set;
11574
11575   S (mp);
11576   W (ret);
11577   return ret;
11578 }
11579
11580 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11581   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11582 {
11583   vat_main_t *vam = &vat_main;
11584
11585   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11586          ntohl (mp->sw_if_index),
11587          format_ip46_address, &(mp->local[0]),
11588          format_ip46_address, &(mp->remote[0]),
11589          ntohl (mp->vni),
11590          ntohl (mp->protocol),
11591          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11592 }
11593
11594 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11595   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11596 {
11597   vat_main_t *vam = &vat_main;
11598   vat_json_node_t *node = NULL;
11599   struct in_addr ip4;
11600   struct in6_addr ip6;
11601
11602   if (VAT_JSON_ARRAY != vam->json_tree.type)
11603     {
11604       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11605       vat_json_init_array (&vam->json_tree);
11606     }
11607   node = vat_json_array_add (&vam->json_tree);
11608
11609   vat_json_init_object (node);
11610   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11611   if (mp->is_ipv6)
11612     {
11613       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11614       vat_json_object_add_ip6 (node, "local", ip6);
11615       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11616       vat_json_object_add_ip6 (node, "remote", ip6);
11617     }
11618   else
11619     {
11620       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11621       vat_json_object_add_ip4 (node, "local", ip4);
11622       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11623       vat_json_object_add_ip4 (node, "remote", ip4);
11624     }
11625   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11626   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11627   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11628   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11629   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11630 }
11631
11632 static int
11633 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11634 {
11635   unformat_input_t *i = vam->input;
11636   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11637   vl_api_control_ping_t *mp_ping;
11638   u32 sw_if_index;
11639   u8 sw_if_index_set = 0;
11640   int ret;
11641
11642   /* Parse args required to build the message */
11643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11644     {
11645       if (unformat (i, "sw_if_index %d", &sw_if_index))
11646         sw_if_index_set = 1;
11647       else
11648         break;
11649     }
11650
11651   if (sw_if_index_set == 0)
11652     {
11653       sw_if_index = ~0;
11654     }
11655
11656   if (!vam->json_output)
11657     {
11658       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11659              "sw_if_index", "local", "remote", "vni",
11660              "protocol", "encap_vrf_id", "decap_vrf_id");
11661     }
11662
11663   /* Get list of vxlan-tunnel interfaces */
11664   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11665
11666   mp->sw_if_index = htonl (sw_if_index);
11667
11668   S (mp);
11669
11670   /* Use a control ping for synchronization */
11671   M (CONTROL_PING, mp_ping);
11672   S (mp_ping);
11673
11674   W (ret);
11675   return ret;
11676 }
11677
11678 u8 *
11679 format_l2_fib_mac_address (u8 * s, va_list * args)
11680 {
11681   u8 *a = va_arg (*args, u8 *);
11682
11683   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11684                  a[2], a[3], a[4], a[5], a[6], a[7]);
11685 }
11686
11687 static void vl_api_l2_fib_table_entry_t_handler
11688   (vl_api_l2_fib_table_entry_t * mp)
11689 {
11690   vat_main_t *vam = &vat_main;
11691
11692   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11693          "       %d       %d     %d",
11694          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11695          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11696          mp->bvi_mac);
11697 }
11698
11699 static void vl_api_l2_fib_table_entry_t_handler_json
11700   (vl_api_l2_fib_table_entry_t * mp)
11701 {
11702   vat_main_t *vam = &vat_main;
11703   vat_json_node_t *node = NULL;
11704
11705   if (VAT_JSON_ARRAY != vam->json_tree.type)
11706     {
11707       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11708       vat_json_init_array (&vam->json_tree);
11709     }
11710   node = vat_json_array_add (&vam->json_tree);
11711
11712   vat_json_init_object (node);
11713   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11714   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11715   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11716   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11717   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11718   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11719 }
11720
11721 static int
11722 api_l2_fib_table_dump (vat_main_t * vam)
11723 {
11724   unformat_input_t *i = vam->input;
11725   vl_api_l2_fib_table_dump_t *mp;
11726   vl_api_control_ping_t *mp_ping;
11727   u32 bd_id;
11728   u8 bd_id_set = 0;
11729   int ret;
11730
11731   /* Parse args required to build the message */
11732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11733     {
11734       if (unformat (i, "bd_id %d", &bd_id))
11735         bd_id_set = 1;
11736       else
11737         break;
11738     }
11739
11740   if (bd_id_set == 0)
11741     {
11742       errmsg ("missing bridge domain");
11743       return -99;
11744     }
11745
11746   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11747
11748   /* Get list of l2 fib entries */
11749   M (L2_FIB_TABLE_DUMP, mp);
11750
11751   mp->bd_id = ntohl (bd_id);
11752   S (mp);
11753
11754   /* Use a control ping for synchronization */
11755   M (CONTROL_PING, mp_ping);
11756   S (mp_ping);
11757
11758   W (ret);
11759   return ret;
11760 }
11761
11762
11763 static int
11764 api_interface_name_renumber (vat_main_t * vam)
11765 {
11766   unformat_input_t *line_input = vam->input;
11767   vl_api_interface_name_renumber_t *mp;
11768   u32 sw_if_index = ~0;
11769   u32 new_show_dev_instance = ~0;
11770   int ret;
11771
11772   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11773     {
11774       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11775                     &sw_if_index))
11776         ;
11777       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11778         ;
11779       else if (unformat (line_input, "new_show_dev_instance %d",
11780                          &new_show_dev_instance))
11781         ;
11782       else
11783         break;
11784     }
11785
11786   if (sw_if_index == ~0)
11787     {
11788       errmsg ("missing interface name or sw_if_index");
11789       return -99;
11790     }
11791
11792   if (new_show_dev_instance == ~0)
11793     {
11794       errmsg ("missing new_show_dev_instance");
11795       return -99;
11796     }
11797
11798   M (INTERFACE_NAME_RENUMBER, mp);
11799
11800   mp->sw_if_index = ntohl (sw_if_index);
11801   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11802
11803   S (mp);
11804   W (ret);
11805   return ret;
11806 }
11807
11808 static int
11809 api_want_ip4_arp_events (vat_main_t * vam)
11810 {
11811   unformat_input_t *line_input = vam->input;
11812   vl_api_want_ip4_arp_events_t *mp;
11813   ip4_address_t address;
11814   int address_set = 0;
11815   u32 enable_disable = 1;
11816   int ret;
11817
11818   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11819     {
11820       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11821         address_set = 1;
11822       else if (unformat (line_input, "del"))
11823         enable_disable = 0;
11824       else
11825         break;
11826     }
11827
11828   if (address_set == 0)
11829     {
11830       errmsg ("missing addresses");
11831       return -99;
11832     }
11833
11834   M (WANT_IP4_ARP_EVENTS, mp);
11835   mp->enable_disable = enable_disable;
11836   mp->pid = htonl (getpid ());
11837   mp->address = address.as_u32;
11838
11839   S (mp);
11840   W (ret);
11841   return ret;
11842 }
11843
11844 static int
11845 api_want_ip6_nd_events (vat_main_t * vam)
11846 {
11847   unformat_input_t *line_input = vam->input;
11848   vl_api_want_ip6_nd_events_t *mp;
11849   ip6_address_t address;
11850   int address_set = 0;
11851   u32 enable_disable = 1;
11852   int ret;
11853
11854   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11855     {
11856       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11857         address_set = 1;
11858       else if (unformat (line_input, "del"))
11859         enable_disable = 0;
11860       else
11861         break;
11862     }
11863
11864   if (address_set == 0)
11865     {
11866       errmsg ("missing addresses");
11867       return -99;
11868     }
11869
11870   M (WANT_IP6_ND_EVENTS, mp);
11871   mp->enable_disable = enable_disable;
11872   mp->pid = htonl (getpid ());
11873   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11874
11875   S (mp);
11876   W (ret);
11877   return ret;
11878 }
11879
11880 static int
11881 api_input_acl_set_interface (vat_main_t * vam)
11882 {
11883   unformat_input_t *i = vam->input;
11884   vl_api_input_acl_set_interface_t *mp;
11885   u32 sw_if_index;
11886   int sw_if_index_set;
11887   u32 ip4_table_index = ~0;
11888   u32 ip6_table_index = ~0;
11889   u32 l2_table_index = ~0;
11890   u8 is_add = 1;
11891   int ret;
11892
11893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11894     {
11895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11896         sw_if_index_set = 1;
11897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11898         sw_if_index_set = 1;
11899       else if (unformat (i, "del"))
11900         is_add = 0;
11901       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11902         ;
11903       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11904         ;
11905       else if (unformat (i, "l2-table %d", &l2_table_index))
11906         ;
11907       else
11908         {
11909           clib_warning ("parse error '%U'", format_unformat_error, i);
11910           return -99;
11911         }
11912     }
11913
11914   if (sw_if_index_set == 0)
11915     {
11916       errmsg ("missing interface name or sw_if_index");
11917       return -99;
11918     }
11919
11920   M (INPUT_ACL_SET_INTERFACE, mp);
11921
11922   mp->sw_if_index = ntohl (sw_if_index);
11923   mp->ip4_table_index = ntohl (ip4_table_index);
11924   mp->ip6_table_index = ntohl (ip6_table_index);
11925   mp->l2_table_index = ntohl (l2_table_index);
11926   mp->is_add = is_add;
11927
11928   S (mp);
11929   W (ret);
11930   return ret;
11931 }
11932
11933 static int
11934 api_ip_address_dump (vat_main_t * vam)
11935 {
11936   unformat_input_t *i = vam->input;
11937   vl_api_ip_address_dump_t *mp;
11938   vl_api_control_ping_t *mp_ping;
11939   u32 sw_if_index = ~0;
11940   u8 sw_if_index_set = 0;
11941   u8 ipv4_set = 0;
11942   u8 ipv6_set = 0;
11943   int ret;
11944
11945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11946     {
11947       if (unformat (i, "sw_if_index %d", &sw_if_index))
11948         sw_if_index_set = 1;
11949       else
11950         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11951         sw_if_index_set = 1;
11952       else if (unformat (i, "ipv4"))
11953         ipv4_set = 1;
11954       else if (unformat (i, "ipv6"))
11955         ipv6_set = 1;
11956       else
11957         break;
11958     }
11959
11960   if (ipv4_set && ipv6_set)
11961     {
11962       errmsg ("ipv4 and ipv6 flags cannot be both set");
11963       return -99;
11964     }
11965
11966   if ((!ipv4_set) && (!ipv6_set))
11967     {
11968       errmsg ("no ipv4 nor ipv6 flag set");
11969       return -99;
11970     }
11971
11972   if (sw_if_index_set == 0)
11973     {
11974       errmsg ("missing interface name or sw_if_index");
11975       return -99;
11976     }
11977
11978   vam->current_sw_if_index = sw_if_index;
11979   vam->is_ipv6 = ipv6_set;
11980
11981   M (IP_ADDRESS_DUMP, mp);
11982   mp->sw_if_index = ntohl (sw_if_index);
11983   mp->is_ipv6 = ipv6_set;
11984   S (mp);
11985
11986   /* Use a control ping for synchronization */
11987   M (CONTROL_PING, mp_ping);
11988   S (mp_ping);
11989
11990   W (ret);
11991   return ret;
11992 }
11993
11994 static int
11995 api_ip_dump (vat_main_t * vam)
11996 {
11997   vl_api_ip_dump_t *mp;
11998   vl_api_control_ping_t *mp_ping;
11999   unformat_input_t *in = vam->input;
12000   int ipv4_set = 0;
12001   int ipv6_set = 0;
12002   int is_ipv6;
12003   int i;
12004   int ret;
12005
12006   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12007     {
12008       if (unformat (in, "ipv4"))
12009         ipv4_set = 1;
12010       else if (unformat (in, "ipv6"))
12011         ipv6_set = 1;
12012       else
12013         break;
12014     }
12015
12016   if (ipv4_set && ipv6_set)
12017     {
12018       errmsg ("ipv4 and ipv6 flags cannot be both set");
12019       return -99;
12020     }
12021
12022   if ((!ipv4_set) && (!ipv6_set))
12023     {
12024       errmsg ("no ipv4 nor ipv6 flag set");
12025       return -99;
12026     }
12027
12028   is_ipv6 = ipv6_set;
12029   vam->is_ipv6 = is_ipv6;
12030
12031   /* free old data */
12032   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12033     {
12034       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12035     }
12036   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12037
12038   M (IP_DUMP, mp);
12039   mp->is_ipv6 = ipv6_set;
12040   S (mp);
12041
12042   /* Use a control ping for synchronization */
12043   M (CONTROL_PING, mp_ping);
12044   S (mp_ping);
12045
12046   W (ret);
12047   return ret;
12048 }
12049
12050 static int
12051 api_ipsec_spd_add_del (vat_main_t * vam)
12052 {
12053   unformat_input_t *i = vam->input;
12054   vl_api_ipsec_spd_add_del_t *mp;
12055   u32 spd_id = ~0;
12056   u8 is_add = 1;
12057   int ret;
12058
12059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12060     {
12061       if (unformat (i, "spd_id %d", &spd_id))
12062         ;
12063       else if (unformat (i, "del"))
12064         is_add = 0;
12065       else
12066         {
12067           clib_warning ("parse error '%U'", format_unformat_error, i);
12068           return -99;
12069         }
12070     }
12071   if (spd_id == ~0)
12072     {
12073       errmsg ("spd_id must be set");
12074       return -99;
12075     }
12076
12077   M (IPSEC_SPD_ADD_DEL, mp);
12078
12079   mp->spd_id = ntohl (spd_id);
12080   mp->is_add = is_add;
12081
12082   S (mp);
12083   W (ret);
12084   return ret;
12085 }
12086
12087 static int
12088 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12089 {
12090   unformat_input_t *i = vam->input;
12091   vl_api_ipsec_interface_add_del_spd_t *mp;
12092   u32 sw_if_index;
12093   u8 sw_if_index_set = 0;
12094   u32 spd_id = (u32) ~ 0;
12095   u8 is_add = 1;
12096   int ret;
12097
12098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12099     {
12100       if (unformat (i, "del"))
12101         is_add = 0;
12102       else if (unformat (i, "spd_id %d", &spd_id))
12103         ;
12104       else
12105         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12106         sw_if_index_set = 1;
12107       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12108         sw_if_index_set = 1;
12109       else
12110         {
12111           clib_warning ("parse error '%U'", format_unformat_error, i);
12112           return -99;
12113         }
12114
12115     }
12116
12117   if (spd_id == (u32) ~ 0)
12118     {
12119       errmsg ("spd_id must be set");
12120       return -99;
12121     }
12122
12123   if (sw_if_index_set == 0)
12124     {
12125       errmsg ("missing interface name or sw_if_index");
12126       return -99;
12127     }
12128
12129   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12130
12131   mp->spd_id = ntohl (spd_id);
12132   mp->sw_if_index = ntohl (sw_if_index);
12133   mp->is_add = is_add;
12134
12135   S (mp);
12136   W (ret);
12137   return ret;
12138 }
12139
12140 static int
12141 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12142 {
12143   unformat_input_t *i = vam->input;
12144   vl_api_ipsec_spd_add_del_entry_t *mp;
12145   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12146   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12147   i32 priority = 0;
12148   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12149   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12150   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12151   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12152   int ret;
12153
12154   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12155   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12156   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12157   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12158   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12159   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12160
12161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12162     {
12163       if (unformat (i, "del"))
12164         is_add = 0;
12165       if (unformat (i, "outbound"))
12166         is_outbound = 1;
12167       if (unformat (i, "inbound"))
12168         is_outbound = 0;
12169       else if (unformat (i, "spd_id %d", &spd_id))
12170         ;
12171       else if (unformat (i, "sa_id %d", &sa_id))
12172         ;
12173       else if (unformat (i, "priority %d", &priority))
12174         ;
12175       else if (unformat (i, "protocol %d", &protocol))
12176         ;
12177       else if (unformat (i, "lport_start %d", &lport_start))
12178         ;
12179       else if (unformat (i, "lport_stop %d", &lport_stop))
12180         ;
12181       else if (unformat (i, "rport_start %d", &rport_start))
12182         ;
12183       else if (unformat (i, "rport_stop %d", &rport_stop))
12184         ;
12185       else
12186         if (unformat
12187             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12188         {
12189           is_ipv6 = 0;
12190           is_ip_any = 0;
12191         }
12192       else
12193         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12194         {
12195           is_ipv6 = 0;
12196           is_ip_any = 0;
12197         }
12198       else
12199         if (unformat
12200             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12201         {
12202           is_ipv6 = 0;
12203           is_ip_any = 0;
12204         }
12205       else
12206         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12207         {
12208           is_ipv6 = 0;
12209           is_ip_any = 0;
12210         }
12211       else
12212         if (unformat
12213             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12214         {
12215           is_ipv6 = 1;
12216           is_ip_any = 0;
12217         }
12218       else
12219         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12220         {
12221           is_ipv6 = 1;
12222           is_ip_any = 0;
12223         }
12224       else
12225         if (unformat
12226             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12227         {
12228           is_ipv6 = 1;
12229           is_ip_any = 0;
12230         }
12231       else
12232         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12233         {
12234           is_ipv6 = 1;
12235           is_ip_any = 0;
12236         }
12237       else
12238         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12239         {
12240           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12241             {
12242               clib_warning ("unsupported action: 'resolve'");
12243               return -99;
12244             }
12245         }
12246       else
12247         {
12248           clib_warning ("parse error '%U'", format_unformat_error, i);
12249           return -99;
12250         }
12251
12252     }
12253
12254   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12255
12256   mp->spd_id = ntohl (spd_id);
12257   mp->priority = ntohl (priority);
12258   mp->is_outbound = is_outbound;
12259
12260   mp->is_ipv6 = is_ipv6;
12261   if (is_ipv6 || is_ip_any)
12262     {
12263       clib_memcpy (mp->remote_address_start, &raddr6_start,
12264                    sizeof (ip6_address_t));
12265       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12266                    sizeof (ip6_address_t));
12267       clib_memcpy (mp->local_address_start, &laddr6_start,
12268                    sizeof (ip6_address_t));
12269       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12270                    sizeof (ip6_address_t));
12271     }
12272   else
12273     {
12274       clib_memcpy (mp->remote_address_start, &raddr4_start,
12275                    sizeof (ip4_address_t));
12276       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12277                    sizeof (ip4_address_t));
12278       clib_memcpy (mp->local_address_start, &laddr4_start,
12279                    sizeof (ip4_address_t));
12280       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12281                    sizeof (ip4_address_t));
12282     }
12283   mp->protocol = (u8) protocol;
12284   mp->local_port_start = ntohs ((u16) lport_start);
12285   mp->local_port_stop = ntohs ((u16) lport_stop);
12286   mp->remote_port_start = ntohs ((u16) rport_start);
12287   mp->remote_port_stop = ntohs ((u16) rport_stop);
12288   mp->policy = (u8) policy;
12289   mp->sa_id = ntohl (sa_id);
12290   mp->is_add = is_add;
12291   mp->is_ip_any = is_ip_any;
12292   S (mp);
12293   W (ret);
12294   return ret;
12295 }
12296
12297 static int
12298 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12299 {
12300   unformat_input_t *i = vam->input;
12301   vl_api_ipsec_sad_add_del_entry_t *mp;
12302   u32 sad_id = 0, spi = 0;
12303   u8 *ck = 0, *ik = 0;
12304   u8 is_add = 1;
12305
12306   u8 protocol = IPSEC_PROTOCOL_AH;
12307   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12308   u32 crypto_alg = 0, integ_alg = 0;
12309   ip4_address_t tun_src4;
12310   ip4_address_t tun_dst4;
12311   ip6_address_t tun_src6;
12312   ip6_address_t tun_dst6;
12313   int ret;
12314
12315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12316     {
12317       if (unformat (i, "del"))
12318         is_add = 0;
12319       else if (unformat (i, "sad_id %d", &sad_id))
12320         ;
12321       else if (unformat (i, "spi %d", &spi))
12322         ;
12323       else if (unformat (i, "esp"))
12324         protocol = IPSEC_PROTOCOL_ESP;
12325       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12326         {
12327           is_tunnel = 1;
12328           is_tunnel_ipv6 = 0;
12329         }
12330       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12331         {
12332           is_tunnel = 1;
12333           is_tunnel_ipv6 = 0;
12334         }
12335       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12336         {
12337           is_tunnel = 1;
12338           is_tunnel_ipv6 = 1;
12339         }
12340       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12341         {
12342           is_tunnel = 1;
12343           is_tunnel_ipv6 = 1;
12344         }
12345       else
12346         if (unformat
12347             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12348         {
12349           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12350               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12351             {
12352               clib_warning ("unsupported crypto-alg: '%U'",
12353                             format_ipsec_crypto_alg, crypto_alg);
12354               return -99;
12355             }
12356         }
12357       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12358         ;
12359       else
12360         if (unformat
12361             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12362         {
12363           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12364               integ_alg >= IPSEC_INTEG_N_ALG)
12365             {
12366               clib_warning ("unsupported integ-alg: '%U'",
12367                             format_ipsec_integ_alg, integ_alg);
12368               return -99;
12369             }
12370         }
12371       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12372         ;
12373       else
12374         {
12375           clib_warning ("parse error '%U'", format_unformat_error, i);
12376           return -99;
12377         }
12378
12379     }
12380
12381   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12382
12383   mp->sad_id = ntohl (sad_id);
12384   mp->is_add = is_add;
12385   mp->protocol = protocol;
12386   mp->spi = ntohl (spi);
12387   mp->is_tunnel = is_tunnel;
12388   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12389   mp->crypto_algorithm = crypto_alg;
12390   mp->integrity_algorithm = integ_alg;
12391   mp->crypto_key_length = vec_len (ck);
12392   mp->integrity_key_length = vec_len (ik);
12393
12394   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12395     mp->crypto_key_length = sizeof (mp->crypto_key);
12396
12397   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12398     mp->integrity_key_length = sizeof (mp->integrity_key);
12399
12400   if (ck)
12401     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12402   if (ik)
12403     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12404
12405   if (is_tunnel)
12406     {
12407       if (is_tunnel_ipv6)
12408         {
12409           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12410                        sizeof (ip6_address_t));
12411           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12412                        sizeof (ip6_address_t));
12413         }
12414       else
12415         {
12416           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12417                        sizeof (ip4_address_t));
12418           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12419                        sizeof (ip4_address_t));
12420         }
12421     }
12422
12423   S (mp);
12424   W (ret);
12425   return ret;
12426 }
12427
12428 static int
12429 api_ipsec_sa_set_key (vat_main_t * vam)
12430 {
12431   unformat_input_t *i = vam->input;
12432   vl_api_ipsec_sa_set_key_t *mp;
12433   u32 sa_id;
12434   u8 *ck = 0, *ik = 0;
12435   int ret;
12436
12437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12438     {
12439       if (unformat (i, "sa_id %d", &sa_id))
12440         ;
12441       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12442         ;
12443       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12444         ;
12445       else
12446         {
12447           clib_warning ("parse error '%U'", format_unformat_error, i);
12448           return -99;
12449         }
12450     }
12451
12452   M (IPSEC_SA_SET_KEY, mp);
12453
12454   mp->sa_id = ntohl (sa_id);
12455   mp->crypto_key_length = vec_len (ck);
12456   mp->integrity_key_length = vec_len (ik);
12457
12458   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12459     mp->crypto_key_length = sizeof (mp->crypto_key);
12460
12461   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12462     mp->integrity_key_length = sizeof (mp->integrity_key);
12463
12464   if (ck)
12465     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12466   if (ik)
12467     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12468
12469   S (mp);
12470   W (ret);
12471   return ret;
12472 }
12473
12474 static int
12475 api_ikev2_profile_add_del (vat_main_t * vam)
12476 {
12477   unformat_input_t *i = vam->input;
12478   vl_api_ikev2_profile_add_del_t *mp;
12479   u8 is_add = 1;
12480   u8 *name = 0;
12481   int ret;
12482
12483   const char *valid_chars = "a-zA-Z0-9_";
12484
12485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12486     {
12487       if (unformat (i, "del"))
12488         is_add = 0;
12489       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12490         vec_add1 (name, 0);
12491       else
12492         {
12493           errmsg ("parse error '%U'", format_unformat_error, i);
12494           return -99;
12495         }
12496     }
12497
12498   if (!vec_len (name))
12499     {
12500       errmsg ("profile name must be specified");
12501       return -99;
12502     }
12503
12504   if (vec_len (name) > 64)
12505     {
12506       errmsg ("profile name too long");
12507       return -99;
12508     }
12509
12510   M (IKEV2_PROFILE_ADD_DEL, mp);
12511
12512   clib_memcpy (mp->name, name, vec_len (name));
12513   mp->is_add = is_add;
12514   vec_free (name);
12515
12516   S (mp);
12517   W (ret);
12518   return ret;
12519 }
12520
12521 static int
12522 api_ikev2_profile_set_auth (vat_main_t * vam)
12523 {
12524   unformat_input_t *i = vam->input;
12525   vl_api_ikev2_profile_set_auth_t *mp;
12526   u8 *name = 0;
12527   u8 *data = 0;
12528   u32 auth_method = 0;
12529   u8 is_hex = 0;
12530   int ret;
12531
12532   const char *valid_chars = "a-zA-Z0-9_";
12533
12534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12535     {
12536       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12537         vec_add1 (name, 0);
12538       else if (unformat (i, "auth_method %U",
12539                          unformat_ikev2_auth_method, &auth_method))
12540         ;
12541       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12542         is_hex = 1;
12543       else if (unformat (i, "auth_data %v", &data))
12544         ;
12545       else
12546         {
12547           errmsg ("parse error '%U'", format_unformat_error, i);
12548           return -99;
12549         }
12550     }
12551
12552   if (!vec_len (name))
12553     {
12554       errmsg ("profile name must be specified");
12555       return -99;
12556     }
12557
12558   if (vec_len (name) > 64)
12559     {
12560       errmsg ("profile name too long");
12561       return -99;
12562     }
12563
12564   if (!vec_len (data))
12565     {
12566       errmsg ("auth_data must be specified");
12567       return -99;
12568     }
12569
12570   if (!auth_method)
12571     {
12572       errmsg ("auth_method must be specified");
12573       return -99;
12574     }
12575
12576   M (IKEV2_PROFILE_SET_AUTH, mp);
12577
12578   mp->is_hex = is_hex;
12579   mp->auth_method = (u8) auth_method;
12580   mp->data_len = vec_len (data);
12581   clib_memcpy (mp->name, name, vec_len (name));
12582   clib_memcpy (mp->data, data, vec_len (data));
12583   vec_free (name);
12584   vec_free (data);
12585
12586   S (mp);
12587   W (ret);
12588   return ret;
12589 }
12590
12591 static int
12592 api_ikev2_profile_set_id (vat_main_t * vam)
12593 {
12594   unformat_input_t *i = vam->input;
12595   vl_api_ikev2_profile_set_id_t *mp;
12596   u8 *name = 0;
12597   u8 *data = 0;
12598   u8 is_local = 0;
12599   u32 id_type = 0;
12600   ip4_address_t ip4;
12601   int ret;
12602
12603   const char *valid_chars = "a-zA-Z0-9_";
12604
12605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12606     {
12607       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12608         vec_add1 (name, 0);
12609       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12610         ;
12611       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12612         {
12613           data = vec_new (u8, 4);
12614           clib_memcpy (data, ip4.as_u8, 4);
12615         }
12616       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12617         ;
12618       else if (unformat (i, "id_data %v", &data))
12619         ;
12620       else if (unformat (i, "local"))
12621         is_local = 1;
12622       else if (unformat (i, "remote"))
12623         is_local = 0;
12624       else
12625         {
12626           errmsg ("parse error '%U'", format_unformat_error, i);
12627           return -99;
12628         }
12629     }
12630
12631   if (!vec_len (name))
12632     {
12633       errmsg ("profile name must be specified");
12634       return -99;
12635     }
12636
12637   if (vec_len (name) > 64)
12638     {
12639       errmsg ("profile name too long");
12640       return -99;
12641     }
12642
12643   if (!vec_len (data))
12644     {
12645       errmsg ("id_data must be specified");
12646       return -99;
12647     }
12648
12649   if (!id_type)
12650     {
12651       errmsg ("id_type must be specified");
12652       return -99;
12653     }
12654
12655   M (IKEV2_PROFILE_SET_ID, mp);
12656
12657   mp->is_local = is_local;
12658   mp->id_type = (u8) id_type;
12659   mp->data_len = vec_len (data);
12660   clib_memcpy (mp->name, name, vec_len (name));
12661   clib_memcpy (mp->data, data, vec_len (data));
12662   vec_free (name);
12663   vec_free (data);
12664
12665   S (mp);
12666   W (ret);
12667   return ret;
12668 }
12669
12670 static int
12671 api_ikev2_profile_set_ts (vat_main_t * vam)
12672 {
12673   unformat_input_t *i = vam->input;
12674   vl_api_ikev2_profile_set_ts_t *mp;
12675   u8 *name = 0;
12676   u8 is_local = 0;
12677   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12678   ip4_address_t start_addr, end_addr;
12679
12680   const char *valid_chars = "a-zA-Z0-9_";
12681   int ret;
12682
12683   start_addr.as_u32 = 0;
12684   end_addr.as_u32 = (u32) ~ 0;
12685
12686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12687     {
12688       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12689         vec_add1 (name, 0);
12690       else if (unformat (i, "protocol %d", &proto))
12691         ;
12692       else if (unformat (i, "start_port %d", &start_port))
12693         ;
12694       else if (unformat (i, "end_port %d", &end_port))
12695         ;
12696       else
12697         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12698         ;
12699       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12700         ;
12701       else if (unformat (i, "local"))
12702         is_local = 1;
12703       else if (unformat (i, "remote"))
12704         is_local = 0;
12705       else
12706         {
12707           errmsg ("parse error '%U'", format_unformat_error, i);
12708           return -99;
12709         }
12710     }
12711
12712   if (!vec_len (name))
12713     {
12714       errmsg ("profile name must be specified");
12715       return -99;
12716     }
12717
12718   if (vec_len (name) > 64)
12719     {
12720       errmsg ("profile name too long");
12721       return -99;
12722     }
12723
12724   M (IKEV2_PROFILE_SET_TS, mp);
12725
12726   mp->is_local = is_local;
12727   mp->proto = (u8) proto;
12728   mp->start_port = (u16) start_port;
12729   mp->end_port = (u16) end_port;
12730   mp->start_addr = start_addr.as_u32;
12731   mp->end_addr = end_addr.as_u32;
12732   clib_memcpy (mp->name, name, vec_len (name));
12733   vec_free (name);
12734
12735   S (mp);
12736   W (ret);
12737   return ret;
12738 }
12739
12740 static int
12741 api_ikev2_set_local_key (vat_main_t * vam)
12742 {
12743   unformat_input_t *i = vam->input;
12744   vl_api_ikev2_set_local_key_t *mp;
12745   u8 *file = 0;
12746   int ret;
12747
12748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12749     {
12750       if (unformat (i, "file %v", &file))
12751         vec_add1 (file, 0);
12752       else
12753         {
12754           errmsg ("parse error '%U'", format_unformat_error, i);
12755           return -99;
12756         }
12757     }
12758
12759   if (!vec_len (file))
12760     {
12761       errmsg ("RSA key file must be specified");
12762       return -99;
12763     }
12764
12765   if (vec_len (file) > 256)
12766     {
12767       errmsg ("file name too long");
12768       return -99;
12769     }
12770
12771   M (IKEV2_SET_LOCAL_KEY, mp);
12772
12773   clib_memcpy (mp->key_file, file, vec_len (file));
12774   vec_free (file);
12775
12776   S (mp);
12777   W (ret);
12778   return ret;
12779 }
12780
12781 static int
12782 api_ikev2_set_responder (vat_main_t * vam)
12783 {
12784   unformat_input_t *i = vam->input;
12785   vl_api_ikev2_set_responder_t *mp;
12786   int ret;
12787   u8 *name = 0;
12788   u32 sw_if_index = ~0;
12789   ip4_address_t address;
12790
12791   const char *valid_chars = "a-zA-Z0-9_";
12792
12793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12794     {
12795       if (unformat
12796           (i, "%U interface %d address %U", unformat_token, valid_chars,
12797            &name, &sw_if_index, unformat_ip4_address, &address))
12798         vec_add1 (name, 0);
12799       else
12800         {
12801           errmsg ("parse error '%U'", format_unformat_error, i);
12802           return -99;
12803         }
12804     }
12805
12806   if (!vec_len (name))
12807     {
12808       errmsg ("profile name must be specified");
12809       return -99;
12810     }
12811
12812   if (vec_len (name) > 64)
12813     {
12814       errmsg ("profile name too long");
12815       return -99;
12816     }
12817
12818   M (IKEV2_SET_RESPONDER, mp);
12819
12820   clib_memcpy (mp->name, name, vec_len (name));
12821   vec_free (name);
12822
12823   mp->sw_if_index = sw_if_index;
12824   clib_memcpy (mp->address, &address, sizeof (address));
12825
12826   S (mp);
12827   W (ret);
12828   return ret;
12829 }
12830
12831 static int
12832 api_ikev2_set_ike_transforms (vat_main_t * vam)
12833 {
12834   unformat_input_t *i = vam->input;
12835   vl_api_ikev2_set_ike_transforms_t *mp;
12836   int ret;
12837   u8 *name = 0;
12838   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12839
12840   const char *valid_chars = "a-zA-Z0-9_";
12841
12842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12843     {
12844       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12845                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12846         vec_add1 (name, 0);
12847       else
12848         {
12849           errmsg ("parse error '%U'", format_unformat_error, i);
12850           return -99;
12851         }
12852     }
12853
12854   if (!vec_len (name))
12855     {
12856       errmsg ("profile name must be specified");
12857       return -99;
12858     }
12859
12860   if (vec_len (name) > 64)
12861     {
12862       errmsg ("profile name too long");
12863       return -99;
12864     }
12865
12866   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12867
12868   clib_memcpy (mp->name, name, vec_len (name));
12869   vec_free (name);
12870   mp->crypto_alg = crypto_alg;
12871   mp->crypto_key_size = crypto_key_size;
12872   mp->integ_alg = integ_alg;
12873   mp->dh_group = dh_group;
12874
12875   S (mp);
12876   W (ret);
12877   return ret;
12878 }
12879
12880
12881 static int
12882 api_ikev2_set_esp_transforms (vat_main_t * vam)
12883 {
12884   unformat_input_t *i = vam->input;
12885   vl_api_ikev2_set_esp_transforms_t *mp;
12886   int ret;
12887   u8 *name = 0;
12888   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12889
12890   const char *valid_chars = "a-zA-Z0-9_";
12891
12892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12893     {
12894       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12895                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12896         vec_add1 (name, 0);
12897       else
12898         {
12899           errmsg ("parse error '%U'", format_unformat_error, i);
12900           return -99;
12901         }
12902     }
12903
12904   if (!vec_len (name))
12905     {
12906       errmsg ("profile name must be specified");
12907       return -99;
12908     }
12909
12910   if (vec_len (name) > 64)
12911     {
12912       errmsg ("profile name too long");
12913       return -99;
12914     }
12915
12916   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12917
12918   clib_memcpy (mp->name, name, vec_len (name));
12919   vec_free (name);
12920   mp->crypto_alg = crypto_alg;
12921   mp->crypto_key_size = crypto_key_size;
12922   mp->integ_alg = integ_alg;
12923   mp->dh_group = dh_group;
12924
12925   S (mp);
12926   W (ret);
12927   return ret;
12928 }
12929
12930 static int
12931 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12932 {
12933   unformat_input_t *i = vam->input;
12934   vl_api_ikev2_set_sa_lifetime_t *mp;
12935   int ret;
12936   u8 *name = 0;
12937   u64 lifetime, lifetime_maxdata;
12938   u32 lifetime_jitter, handover;
12939
12940   const char *valid_chars = "a-zA-Z0-9_";
12941
12942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12943     {
12944       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12945                     &lifetime, &lifetime_jitter, &handover,
12946                     &lifetime_maxdata))
12947         vec_add1 (name, 0);
12948       else
12949         {
12950           errmsg ("parse error '%U'", format_unformat_error, i);
12951           return -99;
12952         }
12953     }
12954
12955   if (!vec_len (name))
12956     {
12957       errmsg ("profile name must be specified");
12958       return -99;
12959     }
12960
12961   if (vec_len (name) > 64)
12962     {
12963       errmsg ("profile name too long");
12964       return -99;
12965     }
12966
12967   M (IKEV2_SET_SA_LIFETIME, mp);
12968
12969   clib_memcpy (mp->name, name, vec_len (name));
12970   vec_free (name);
12971   mp->lifetime = lifetime;
12972   mp->lifetime_jitter = lifetime_jitter;
12973   mp->handover = handover;
12974   mp->lifetime_maxdata = lifetime_maxdata;
12975
12976   S (mp);
12977   W (ret);
12978   return ret;
12979 }
12980
12981 static int
12982 api_ikev2_initiate_sa_init (vat_main_t * vam)
12983 {
12984   unformat_input_t *i = vam->input;
12985   vl_api_ikev2_initiate_sa_init_t *mp;
12986   int ret;
12987   u8 *name = 0;
12988
12989   const char *valid_chars = "a-zA-Z0-9_";
12990
12991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12992     {
12993       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12994         vec_add1 (name, 0);
12995       else
12996         {
12997           errmsg ("parse error '%U'", format_unformat_error, i);
12998           return -99;
12999         }
13000     }
13001
13002   if (!vec_len (name))
13003     {
13004       errmsg ("profile name must be specified");
13005       return -99;
13006     }
13007
13008   if (vec_len (name) > 64)
13009     {
13010       errmsg ("profile name too long");
13011       return -99;
13012     }
13013
13014   M (IKEV2_INITIATE_SA_INIT, mp);
13015
13016   clib_memcpy (mp->name, name, vec_len (name));
13017   vec_free (name);
13018
13019   S (mp);
13020   W (ret);
13021   return ret;
13022 }
13023
13024 static int
13025 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13026 {
13027   unformat_input_t *i = vam->input;
13028   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13029   int ret;
13030   u64 ispi;
13031
13032
13033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13034     {
13035       if (unformat (i, "%lx", &ispi))
13036         ;
13037       else
13038         {
13039           errmsg ("parse error '%U'", format_unformat_error, i);
13040           return -99;
13041         }
13042     }
13043
13044   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13045
13046   mp->ispi = ispi;
13047
13048   S (mp);
13049   W (ret);
13050   return ret;
13051 }
13052
13053 static int
13054 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13055 {
13056   unformat_input_t *i = vam->input;
13057   vl_api_ikev2_initiate_del_child_sa_t *mp;
13058   int ret;
13059   u32 ispi;
13060
13061
13062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13063     {
13064       if (unformat (i, "%x", &ispi))
13065         ;
13066       else
13067         {
13068           errmsg ("parse error '%U'", format_unformat_error, i);
13069           return -99;
13070         }
13071     }
13072
13073   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13074
13075   mp->ispi = ispi;
13076
13077   S (mp);
13078   W (ret);
13079   return ret;
13080 }
13081
13082 static int
13083 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13084 {
13085   unformat_input_t *i = vam->input;
13086   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13087   int ret;
13088   u32 ispi;
13089
13090
13091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13092     {
13093       if (unformat (i, "%x", &ispi))
13094         ;
13095       else
13096         {
13097           errmsg ("parse error '%U'", format_unformat_error, i);
13098           return -99;
13099         }
13100     }
13101
13102   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13103
13104   mp->ispi = ispi;
13105
13106   S (mp);
13107   W (ret);
13108   return ret;
13109 }
13110
13111 /*
13112  * MAP
13113  */
13114 static int
13115 api_map_add_domain (vat_main_t * vam)
13116 {
13117   unformat_input_t *i = vam->input;
13118   vl_api_map_add_domain_t *mp;
13119
13120   ip4_address_t ip4_prefix;
13121   ip6_address_t ip6_prefix;
13122   ip6_address_t ip6_src;
13123   u32 num_m_args = 0;
13124   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13125     0, psid_length = 0;
13126   u8 is_translation = 0;
13127   u32 mtu = 0;
13128   u32 ip6_src_len = 128;
13129   int ret;
13130
13131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13132     {
13133       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13134                     &ip4_prefix, &ip4_prefix_len))
13135         num_m_args++;
13136       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13137                          &ip6_prefix, &ip6_prefix_len))
13138         num_m_args++;
13139       else
13140         if (unformat
13141             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13142              &ip6_src_len))
13143         num_m_args++;
13144       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13145         num_m_args++;
13146       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13147         num_m_args++;
13148       else if (unformat (i, "psid-offset %d", &psid_offset))
13149         num_m_args++;
13150       else if (unformat (i, "psid-len %d", &psid_length))
13151         num_m_args++;
13152       else if (unformat (i, "mtu %d", &mtu))
13153         num_m_args++;
13154       else if (unformat (i, "map-t"))
13155         is_translation = 1;
13156       else
13157         {
13158           clib_warning ("parse error '%U'", format_unformat_error, i);
13159           return -99;
13160         }
13161     }
13162
13163   if (num_m_args < 3)
13164     {
13165       errmsg ("mandatory argument(s) missing");
13166       return -99;
13167     }
13168
13169   /* Construct the API message */
13170   M (MAP_ADD_DOMAIN, mp);
13171
13172   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13173   mp->ip4_prefix_len = ip4_prefix_len;
13174
13175   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13176   mp->ip6_prefix_len = ip6_prefix_len;
13177
13178   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13179   mp->ip6_src_prefix_len = ip6_src_len;
13180
13181   mp->ea_bits_len = ea_bits_len;
13182   mp->psid_offset = psid_offset;
13183   mp->psid_length = psid_length;
13184   mp->is_translation = is_translation;
13185   mp->mtu = htons (mtu);
13186
13187   /* send it... */
13188   S (mp);
13189
13190   /* Wait for a reply, return good/bad news  */
13191   W (ret);
13192   return ret;
13193 }
13194
13195 static int
13196 api_map_del_domain (vat_main_t * vam)
13197 {
13198   unformat_input_t *i = vam->input;
13199   vl_api_map_del_domain_t *mp;
13200
13201   u32 num_m_args = 0;
13202   u32 index;
13203   int ret;
13204
13205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13206     {
13207       if (unformat (i, "index %d", &index))
13208         num_m_args++;
13209       else
13210         {
13211           clib_warning ("parse error '%U'", format_unformat_error, i);
13212           return -99;
13213         }
13214     }
13215
13216   if (num_m_args != 1)
13217     {
13218       errmsg ("mandatory argument(s) missing");
13219       return -99;
13220     }
13221
13222   /* Construct the API message */
13223   M (MAP_DEL_DOMAIN, mp);
13224
13225   mp->index = ntohl (index);
13226
13227   /* send it... */
13228   S (mp);
13229
13230   /* Wait for a reply, return good/bad news  */
13231   W (ret);
13232   return ret;
13233 }
13234
13235 static int
13236 api_map_add_del_rule (vat_main_t * vam)
13237 {
13238   unformat_input_t *i = vam->input;
13239   vl_api_map_add_del_rule_t *mp;
13240   u8 is_add = 1;
13241   ip6_address_t ip6_dst;
13242   u32 num_m_args = 0, index, psid = 0;
13243   int ret;
13244
13245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13246     {
13247       if (unformat (i, "index %d", &index))
13248         num_m_args++;
13249       else if (unformat (i, "psid %d", &psid))
13250         num_m_args++;
13251       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13252         num_m_args++;
13253       else if (unformat (i, "del"))
13254         {
13255           is_add = 0;
13256         }
13257       else
13258         {
13259           clib_warning ("parse error '%U'", format_unformat_error, i);
13260           return -99;
13261         }
13262     }
13263
13264   /* Construct the API message */
13265   M (MAP_ADD_DEL_RULE, mp);
13266
13267   mp->index = ntohl (index);
13268   mp->is_add = is_add;
13269   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13270   mp->psid = ntohs (psid);
13271
13272   /* send it... */
13273   S (mp);
13274
13275   /* Wait for a reply, return good/bad news  */
13276   W (ret);
13277   return ret;
13278 }
13279
13280 static int
13281 api_map_domain_dump (vat_main_t * vam)
13282 {
13283   vl_api_map_domain_dump_t *mp;
13284   vl_api_control_ping_t *mp_ping;
13285   int ret;
13286
13287   /* Construct the API message */
13288   M (MAP_DOMAIN_DUMP, mp);
13289
13290   /* send it... */
13291   S (mp);
13292
13293   /* Use a control ping for synchronization */
13294   M (CONTROL_PING, mp_ping);
13295   S (mp_ping);
13296
13297   W (ret);
13298   return ret;
13299 }
13300
13301 static int
13302 api_map_rule_dump (vat_main_t * vam)
13303 {
13304   unformat_input_t *i = vam->input;
13305   vl_api_map_rule_dump_t *mp;
13306   vl_api_control_ping_t *mp_ping;
13307   u32 domain_index = ~0;
13308   int ret;
13309
13310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13311     {
13312       if (unformat (i, "index %u", &domain_index))
13313         ;
13314       else
13315         break;
13316     }
13317
13318   if (domain_index == ~0)
13319     {
13320       clib_warning ("parse error: domain index expected");
13321       return -99;
13322     }
13323
13324   /* Construct the API message */
13325   M (MAP_RULE_DUMP, mp);
13326
13327   mp->domain_index = htonl (domain_index);
13328
13329   /* send it... */
13330   S (mp);
13331
13332   /* Use a control ping for synchronization */
13333   M (CONTROL_PING, mp_ping);
13334   S (mp_ping);
13335
13336   W (ret);
13337   return ret;
13338 }
13339
13340 static void vl_api_map_add_domain_reply_t_handler
13341   (vl_api_map_add_domain_reply_t * mp)
13342 {
13343   vat_main_t *vam = &vat_main;
13344   i32 retval = ntohl (mp->retval);
13345
13346   if (vam->async_mode)
13347     {
13348       vam->async_errors += (retval < 0);
13349     }
13350   else
13351     {
13352       vam->retval = retval;
13353       vam->result_ready = 1;
13354     }
13355 }
13356
13357 static void vl_api_map_add_domain_reply_t_handler_json
13358   (vl_api_map_add_domain_reply_t * mp)
13359 {
13360   vat_main_t *vam = &vat_main;
13361   vat_json_node_t node;
13362
13363   vat_json_init_object (&node);
13364   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13365   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13366
13367   vat_json_print (vam->ofp, &node);
13368   vat_json_free (&node);
13369
13370   vam->retval = ntohl (mp->retval);
13371   vam->result_ready = 1;
13372 }
13373
13374 static int
13375 api_get_first_msg_id (vat_main_t * vam)
13376 {
13377   vl_api_get_first_msg_id_t *mp;
13378   unformat_input_t *i = vam->input;
13379   u8 *name;
13380   u8 name_set = 0;
13381   int ret;
13382
13383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13384     {
13385       if (unformat (i, "client %s", &name))
13386         name_set = 1;
13387       else
13388         break;
13389     }
13390
13391   if (name_set == 0)
13392     {
13393       errmsg ("missing client name");
13394       return -99;
13395     }
13396   vec_add1 (name, 0);
13397
13398   if (vec_len (name) > 63)
13399     {
13400       errmsg ("client name too long");
13401       return -99;
13402     }
13403
13404   M (GET_FIRST_MSG_ID, mp);
13405   clib_memcpy (mp->name, name, vec_len (name));
13406   S (mp);
13407   W (ret);
13408   return ret;
13409 }
13410
13411 static int
13412 api_cop_interface_enable_disable (vat_main_t * vam)
13413 {
13414   unformat_input_t *line_input = vam->input;
13415   vl_api_cop_interface_enable_disable_t *mp;
13416   u32 sw_if_index = ~0;
13417   u8 enable_disable = 1;
13418   int ret;
13419
13420   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13421     {
13422       if (unformat (line_input, "disable"))
13423         enable_disable = 0;
13424       if (unformat (line_input, "enable"))
13425         enable_disable = 1;
13426       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13427                          vam, &sw_if_index))
13428         ;
13429       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13430         ;
13431       else
13432         break;
13433     }
13434
13435   if (sw_if_index == ~0)
13436     {
13437       errmsg ("missing interface name or sw_if_index");
13438       return -99;
13439     }
13440
13441   /* Construct the API message */
13442   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13443   mp->sw_if_index = ntohl (sw_if_index);
13444   mp->enable_disable = enable_disable;
13445
13446   /* send it... */
13447   S (mp);
13448   /* Wait for the reply */
13449   W (ret);
13450   return ret;
13451 }
13452
13453 static int
13454 api_cop_whitelist_enable_disable (vat_main_t * vam)
13455 {
13456   unformat_input_t *line_input = vam->input;
13457   vl_api_cop_whitelist_enable_disable_t *mp;
13458   u32 sw_if_index = ~0;
13459   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13460   u32 fib_id = 0;
13461   int ret;
13462
13463   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13464     {
13465       if (unformat (line_input, "ip4"))
13466         ip4 = 1;
13467       else if (unformat (line_input, "ip6"))
13468         ip6 = 1;
13469       else if (unformat (line_input, "default"))
13470         default_cop = 1;
13471       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13472                          vam, &sw_if_index))
13473         ;
13474       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13475         ;
13476       else if (unformat (line_input, "fib-id %d", &fib_id))
13477         ;
13478       else
13479         break;
13480     }
13481
13482   if (sw_if_index == ~0)
13483     {
13484       errmsg ("missing interface name or sw_if_index");
13485       return -99;
13486     }
13487
13488   /* Construct the API message */
13489   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13490   mp->sw_if_index = ntohl (sw_if_index);
13491   mp->fib_id = ntohl (fib_id);
13492   mp->ip4 = ip4;
13493   mp->ip6 = ip6;
13494   mp->default_cop = default_cop;
13495
13496   /* send it... */
13497   S (mp);
13498   /* Wait for the reply */
13499   W (ret);
13500   return ret;
13501 }
13502
13503 static int
13504 api_get_node_graph (vat_main_t * vam)
13505 {
13506   vl_api_get_node_graph_t *mp;
13507   int ret;
13508
13509   M (GET_NODE_GRAPH, mp);
13510
13511   /* send it... */
13512   S (mp);
13513   /* Wait for the reply */
13514   W (ret);
13515   return ret;
13516 }
13517
13518 /* *INDENT-OFF* */
13519 /** Used for parsing LISP eids */
13520 typedef CLIB_PACKED(struct{
13521   u8 addr[16];   /**< eid address */
13522   u32 len;       /**< prefix length if IP */
13523   u8 type;      /**< type of eid */
13524 }) lisp_eid_vat_t;
13525 /* *INDENT-ON* */
13526
13527 static uword
13528 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13529 {
13530   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13531
13532   memset (a, 0, sizeof (a[0]));
13533
13534   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13535     {
13536       a->type = 0;              /* ipv4 type */
13537     }
13538   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13539     {
13540       a->type = 1;              /* ipv6 type */
13541     }
13542   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13543     {
13544       a->type = 2;              /* mac type */
13545     }
13546   else
13547     {
13548       return 0;
13549     }
13550
13551   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13552     {
13553       return 0;
13554     }
13555
13556   return 1;
13557 }
13558
13559 static int
13560 lisp_eid_size_vat (u8 type)
13561 {
13562   switch (type)
13563     {
13564     case 0:
13565       return 4;
13566     case 1:
13567       return 16;
13568     case 2:
13569       return 6;
13570     }
13571   return 0;
13572 }
13573
13574 static void
13575 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13576 {
13577   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13578 }
13579
13580 static int
13581 api_one_add_del_locator_set (vat_main_t * vam)
13582 {
13583   unformat_input_t *input = vam->input;
13584   vl_api_one_add_del_locator_set_t *mp;
13585   u8 is_add = 1;
13586   u8 *locator_set_name = NULL;
13587   u8 locator_set_name_set = 0;
13588   vl_api_local_locator_t locator, *locators = 0;
13589   u32 sw_if_index, priority, weight;
13590   u32 data_len = 0;
13591
13592   int ret;
13593   /* Parse args required to build the message */
13594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13595     {
13596       if (unformat (input, "del"))
13597         {
13598           is_add = 0;
13599         }
13600       else if (unformat (input, "locator-set %s", &locator_set_name))
13601         {
13602           locator_set_name_set = 1;
13603         }
13604       else if (unformat (input, "sw_if_index %u p %u w %u",
13605                          &sw_if_index, &priority, &weight))
13606         {
13607           locator.sw_if_index = htonl (sw_if_index);
13608           locator.priority = priority;
13609           locator.weight = weight;
13610           vec_add1 (locators, locator);
13611         }
13612       else
13613         if (unformat
13614             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13615              &sw_if_index, &priority, &weight))
13616         {
13617           locator.sw_if_index = htonl (sw_if_index);
13618           locator.priority = priority;
13619           locator.weight = weight;
13620           vec_add1 (locators, locator);
13621         }
13622       else
13623         break;
13624     }
13625
13626   if (locator_set_name_set == 0)
13627     {
13628       errmsg ("missing locator-set name");
13629       vec_free (locators);
13630       return -99;
13631     }
13632
13633   if (vec_len (locator_set_name) > 64)
13634     {
13635       errmsg ("locator-set name too long");
13636       vec_free (locator_set_name);
13637       vec_free (locators);
13638       return -99;
13639     }
13640   vec_add1 (locator_set_name, 0);
13641
13642   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13643
13644   /* Construct the API message */
13645   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13646
13647   mp->is_add = is_add;
13648   clib_memcpy (mp->locator_set_name, locator_set_name,
13649                vec_len (locator_set_name));
13650   vec_free (locator_set_name);
13651
13652   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13653   if (locators)
13654     clib_memcpy (mp->locators, locators, data_len);
13655   vec_free (locators);
13656
13657   /* send it... */
13658   S (mp);
13659
13660   /* Wait for a reply... */
13661   W (ret);
13662   return ret;
13663 }
13664
13665 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13666
13667 static int
13668 api_one_add_del_locator (vat_main_t * vam)
13669 {
13670   unformat_input_t *input = vam->input;
13671   vl_api_one_add_del_locator_t *mp;
13672   u32 tmp_if_index = ~0;
13673   u32 sw_if_index = ~0;
13674   u8 sw_if_index_set = 0;
13675   u8 sw_if_index_if_name_set = 0;
13676   u32 priority = ~0;
13677   u8 priority_set = 0;
13678   u32 weight = ~0;
13679   u8 weight_set = 0;
13680   u8 is_add = 1;
13681   u8 *locator_set_name = NULL;
13682   u8 locator_set_name_set = 0;
13683   int ret;
13684
13685   /* Parse args required to build the message */
13686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13687     {
13688       if (unformat (input, "del"))
13689         {
13690           is_add = 0;
13691         }
13692       else if (unformat (input, "locator-set %s", &locator_set_name))
13693         {
13694           locator_set_name_set = 1;
13695         }
13696       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13697                          &tmp_if_index))
13698         {
13699           sw_if_index_if_name_set = 1;
13700           sw_if_index = tmp_if_index;
13701         }
13702       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13703         {
13704           sw_if_index_set = 1;
13705           sw_if_index = tmp_if_index;
13706         }
13707       else if (unformat (input, "p %d", &priority))
13708         {
13709           priority_set = 1;
13710         }
13711       else if (unformat (input, "w %d", &weight))
13712         {
13713           weight_set = 1;
13714         }
13715       else
13716         break;
13717     }
13718
13719   if (locator_set_name_set == 0)
13720     {
13721       errmsg ("missing locator-set name");
13722       return -99;
13723     }
13724
13725   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13726     {
13727       errmsg ("missing sw_if_index");
13728       vec_free (locator_set_name);
13729       return -99;
13730     }
13731
13732   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13733     {
13734       errmsg ("cannot use both params interface name and sw_if_index");
13735       vec_free (locator_set_name);
13736       return -99;
13737     }
13738
13739   if (priority_set == 0)
13740     {
13741       errmsg ("missing locator-set priority");
13742       vec_free (locator_set_name);
13743       return -99;
13744     }
13745
13746   if (weight_set == 0)
13747     {
13748       errmsg ("missing locator-set weight");
13749       vec_free (locator_set_name);
13750       return -99;
13751     }
13752
13753   if (vec_len (locator_set_name) > 64)
13754     {
13755       errmsg ("locator-set name too long");
13756       vec_free (locator_set_name);
13757       return -99;
13758     }
13759   vec_add1 (locator_set_name, 0);
13760
13761   /* Construct the API message */
13762   M (ONE_ADD_DEL_LOCATOR, mp);
13763
13764   mp->is_add = is_add;
13765   mp->sw_if_index = ntohl (sw_if_index);
13766   mp->priority = priority;
13767   mp->weight = weight;
13768   clib_memcpy (mp->locator_set_name, locator_set_name,
13769                vec_len (locator_set_name));
13770   vec_free (locator_set_name);
13771
13772   /* send it... */
13773   S (mp);
13774
13775   /* Wait for a reply... */
13776   W (ret);
13777   return ret;
13778 }
13779
13780 #define api_lisp_add_del_locator api_one_add_del_locator
13781
13782 uword
13783 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13784 {
13785   u32 *key_id = va_arg (*args, u32 *);
13786   u8 *s = 0;
13787
13788   if (unformat (input, "%s", &s))
13789     {
13790       if (!strcmp ((char *) s, "sha1"))
13791         key_id[0] = HMAC_SHA_1_96;
13792       else if (!strcmp ((char *) s, "sha256"))
13793         key_id[0] = HMAC_SHA_256_128;
13794       else
13795         {
13796           clib_warning ("invalid key_id: '%s'", s);
13797           key_id[0] = HMAC_NO_KEY;
13798         }
13799     }
13800   else
13801     return 0;
13802
13803   vec_free (s);
13804   return 1;
13805 }
13806
13807 static int
13808 api_one_add_del_local_eid (vat_main_t * vam)
13809 {
13810   unformat_input_t *input = vam->input;
13811   vl_api_one_add_del_local_eid_t *mp;
13812   u8 is_add = 1;
13813   u8 eid_set = 0;
13814   lisp_eid_vat_t _eid, *eid = &_eid;
13815   u8 *locator_set_name = 0;
13816   u8 locator_set_name_set = 0;
13817   u32 vni = 0;
13818   u16 key_id = 0;
13819   u8 *key = 0;
13820   int ret;
13821
13822   /* Parse args required to build the message */
13823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13824     {
13825       if (unformat (input, "del"))
13826         {
13827           is_add = 0;
13828         }
13829       else if (unformat (input, "vni %d", &vni))
13830         {
13831           ;
13832         }
13833       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13834         {
13835           eid_set = 1;
13836         }
13837       else if (unformat (input, "locator-set %s", &locator_set_name))
13838         {
13839           locator_set_name_set = 1;
13840         }
13841       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13842         ;
13843       else if (unformat (input, "secret-key %_%v%_", &key))
13844         ;
13845       else
13846         break;
13847     }
13848
13849   if (locator_set_name_set == 0)
13850     {
13851       errmsg ("missing locator-set name");
13852       return -99;
13853     }
13854
13855   if (0 == eid_set)
13856     {
13857       errmsg ("EID address not set!");
13858       vec_free (locator_set_name);
13859       return -99;
13860     }
13861
13862   if (key && (0 == key_id))
13863     {
13864       errmsg ("invalid key_id!");
13865       return -99;
13866     }
13867
13868   if (vec_len (key) > 64)
13869     {
13870       errmsg ("key too long");
13871       vec_free (key);
13872       return -99;
13873     }
13874
13875   if (vec_len (locator_set_name) > 64)
13876     {
13877       errmsg ("locator-set name too long");
13878       vec_free (locator_set_name);
13879       return -99;
13880     }
13881   vec_add1 (locator_set_name, 0);
13882
13883   /* Construct the API message */
13884   M (ONE_ADD_DEL_LOCAL_EID, mp);
13885
13886   mp->is_add = is_add;
13887   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13888   mp->eid_type = eid->type;
13889   mp->prefix_len = eid->len;
13890   mp->vni = clib_host_to_net_u32 (vni);
13891   mp->key_id = clib_host_to_net_u16 (key_id);
13892   clib_memcpy (mp->locator_set_name, locator_set_name,
13893                vec_len (locator_set_name));
13894   clib_memcpy (mp->key, key, vec_len (key));
13895
13896   vec_free (locator_set_name);
13897   vec_free (key);
13898
13899   /* send it... */
13900   S (mp);
13901
13902   /* Wait for a reply... */
13903   W (ret);
13904   return ret;
13905 }
13906
13907 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13908
13909 static int
13910 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13911 {
13912   u32 dp_table = 0, vni = 0;;
13913   unformat_input_t *input = vam->input;
13914   vl_api_gpe_add_del_fwd_entry_t *mp;
13915   u8 is_add = 1;
13916   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13917   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13918   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13919   u32 action = ~0, w;
13920   ip4_address_t rmt_rloc4, lcl_rloc4;
13921   ip6_address_t rmt_rloc6, lcl_rloc6;
13922   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13923   int ret;
13924
13925   memset (&rloc, 0, sizeof (rloc));
13926
13927   /* Parse args required to build the message */
13928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13929     {
13930       if (unformat (input, "del"))
13931         is_add = 0;
13932       else if (unformat (input, "add"))
13933         is_add = 1;
13934       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13935         {
13936           rmt_eid_set = 1;
13937         }
13938       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13939         {
13940           lcl_eid_set = 1;
13941         }
13942       else if (unformat (input, "vrf %d", &dp_table))
13943         ;
13944       else if (unformat (input, "bd %d", &dp_table))
13945         ;
13946       else if (unformat (input, "vni %d", &vni))
13947         ;
13948       else if (unformat (input, "w %d", &w))
13949         {
13950           if (!curr_rloc)
13951             {
13952               errmsg ("No RLOC configured for setting priority/weight!");
13953               return -99;
13954             }
13955           curr_rloc->weight = w;
13956         }
13957       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13958                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13959         {
13960           rloc.is_ip4 = 1;
13961
13962           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13963           rloc.weight = 0;
13964           vec_add1 (lcl_locs, rloc);
13965
13966           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13967           vec_add1 (rmt_locs, rloc);
13968           /* weight saved in rmt loc */
13969           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13970         }
13971       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13972                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13973         {
13974           rloc.is_ip4 = 0;
13975           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13976           rloc.weight = 0;
13977           vec_add1 (lcl_locs, rloc);
13978
13979           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13980           vec_add1 (rmt_locs, rloc);
13981           /* weight saved in rmt loc */
13982           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13983         }
13984       else if (unformat (input, "action %d", &action))
13985         {
13986           ;
13987         }
13988       else
13989         {
13990           clib_warning ("parse error '%U'", format_unformat_error, input);
13991           return -99;
13992         }
13993     }
13994
13995   if (!rmt_eid_set)
13996     {
13997       errmsg ("remote eid addresses not set");
13998       return -99;
13999     }
14000
14001   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14002     {
14003       errmsg ("eid types don't match");
14004       return -99;
14005     }
14006
14007   if (0 == rmt_locs && (u32) ~ 0 == action)
14008     {
14009       errmsg ("action not set for negative mapping");
14010       return -99;
14011     }
14012
14013   /* Construct the API message */
14014   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14015       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14016
14017   mp->is_add = is_add;
14018   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14019   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14020   mp->eid_type = rmt_eid->type;
14021   mp->dp_table = clib_host_to_net_u32 (dp_table);
14022   mp->vni = clib_host_to_net_u32 (vni);
14023   mp->rmt_len = rmt_eid->len;
14024   mp->lcl_len = lcl_eid->len;
14025   mp->action = action;
14026
14027   if (0 != rmt_locs && 0 != lcl_locs)
14028     {
14029       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14030       clib_memcpy (mp->locs, lcl_locs,
14031                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14032
14033       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14034       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14035                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14036     }
14037   vec_free (lcl_locs);
14038   vec_free (rmt_locs);
14039
14040   /* send it... */
14041   S (mp);
14042
14043   /* Wait for a reply... */
14044   W (ret);
14045   return ret;
14046 }
14047
14048 static int
14049 api_one_add_del_map_server (vat_main_t * vam)
14050 {
14051   unformat_input_t *input = vam->input;
14052   vl_api_one_add_del_map_server_t *mp;
14053   u8 is_add = 1;
14054   u8 ipv4_set = 0;
14055   u8 ipv6_set = 0;
14056   ip4_address_t ipv4;
14057   ip6_address_t ipv6;
14058   int ret;
14059
14060   /* Parse args required to build the message */
14061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14062     {
14063       if (unformat (input, "del"))
14064         {
14065           is_add = 0;
14066         }
14067       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14068         {
14069           ipv4_set = 1;
14070         }
14071       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14072         {
14073           ipv6_set = 1;
14074         }
14075       else
14076         break;
14077     }
14078
14079   if (ipv4_set && ipv6_set)
14080     {
14081       errmsg ("both eid v4 and v6 addresses set");
14082       return -99;
14083     }
14084
14085   if (!ipv4_set && !ipv6_set)
14086     {
14087       errmsg ("eid addresses not set");
14088       return -99;
14089     }
14090
14091   /* Construct the API message */
14092   M (ONE_ADD_DEL_MAP_SERVER, mp);
14093
14094   mp->is_add = is_add;
14095   if (ipv6_set)
14096     {
14097       mp->is_ipv6 = 1;
14098       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14099     }
14100   else
14101     {
14102       mp->is_ipv6 = 0;
14103       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14104     }
14105
14106   /* send it... */
14107   S (mp);
14108
14109   /* Wait for a reply... */
14110   W (ret);
14111   return ret;
14112 }
14113
14114 #define api_lisp_add_del_map_server api_one_add_del_map_server
14115
14116 static int
14117 api_one_add_del_map_resolver (vat_main_t * vam)
14118 {
14119   unformat_input_t *input = vam->input;
14120   vl_api_one_add_del_map_resolver_t *mp;
14121   u8 is_add = 1;
14122   u8 ipv4_set = 0;
14123   u8 ipv6_set = 0;
14124   ip4_address_t ipv4;
14125   ip6_address_t ipv6;
14126   int ret;
14127
14128   /* Parse args required to build the message */
14129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14130     {
14131       if (unformat (input, "del"))
14132         {
14133           is_add = 0;
14134         }
14135       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14136         {
14137           ipv4_set = 1;
14138         }
14139       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14140         {
14141           ipv6_set = 1;
14142         }
14143       else
14144         break;
14145     }
14146
14147   if (ipv4_set && ipv6_set)
14148     {
14149       errmsg ("both eid v4 and v6 addresses set");
14150       return -99;
14151     }
14152
14153   if (!ipv4_set && !ipv6_set)
14154     {
14155       errmsg ("eid addresses not set");
14156       return -99;
14157     }
14158
14159   /* Construct the API message */
14160   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14161
14162   mp->is_add = is_add;
14163   if (ipv6_set)
14164     {
14165       mp->is_ipv6 = 1;
14166       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14167     }
14168   else
14169     {
14170       mp->is_ipv6 = 0;
14171       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14172     }
14173
14174   /* send it... */
14175   S (mp);
14176
14177   /* Wait for a reply... */
14178   W (ret);
14179   return ret;
14180 }
14181
14182 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14183
14184 static int
14185 api_lisp_gpe_enable_disable (vat_main_t * vam)
14186 {
14187   unformat_input_t *input = vam->input;
14188   vl_api_gpe_enable_disable_t *mp;
14189   u8 is_set = 0;
14190   u8 is_en = 1;
14191   int ret;
14192
14193   /* Parse args required to build the message */
14194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14195     {
14196       if (unformat (input, "enable"))
14197         {
14198           is_set = 1;
14199           is_en = 1;
14200         }
14201       else if (unformat (input, "disable"))
14202         {
14203           is_set = 1;
14204           is_en = 0;
14205         }
14206       else
14207         break;
14208     }
14209
14210   if (is_set == 0)
14211     {
14212       errmsg ("Value not set");
14213       return -99;
14214     }
14215
14216   /* Construct the API message */
14217   M (GPE_ENABLE_DISABLE, mp);
14218
14219   mp->is_en = is_en;
14220
14221   /* send it... */
14222   S (mp);
14223
14224   /* Wait for a reply... */
14225   W (ret);
14226   return ret;
14227 }
14228
14229 static int
14230 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14231 {
14232   unformat_input_t *input = vam->input;
14233   vl_api_one_rloc_probe_enable_disable_t *mp;
14234   u8 is_set = 0;
14235   u8 is_en = 0;
14236   int ret;
14237
14238   /* Parse args required to build the message */
14239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14240     {
14241       if (unformat (input, "enable"))
14242         {
14243           is_set = 1;
14244           is_en = 1;
14245         }
14246       else if (unformat (input, "disable"))
14247         is_set = 1;
14248       else
14249         break;
14250     }
14251
14252   if (!is_set)
14253     {
14254       errmsg ("Value not set");
14255       return -99;
14256     }
14257
14258   /* Construct the API message */
14259   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14260
14261   mp->is_enabled = is_en;
14262
14263   /* send it... */
14264   S (mp);
14265
14266   /* Wait for a reply... */
14267   W (ret);
14268   return ret;
14269 }
14270
14271 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14272
14273 static int
14274 api_one_map_register_enable_disable (vat_main_t * vam)
14275 {
14276   unformat_input_t *input = vam->input;
14277   vl_api_one_map_register_enable_disable_t *mp;
14278   u8 is_set = 0;
14279   u8 is_en = 0;
14280   int ret;
14281
14282   /* Parse args required to build the message */
14283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14284     {
14285       if (unformat (input, "enable"))
14286         {
14287           is_set = 1;
14288           is_en = 1;
14289         }
14290       else if (unformat (input, "disable"))
14291         is_set = 1;
14292       else
14293         break;
14294     }
14295
14296   if (!is_set)
14297     {
14298       errmsg ("Value not set");
14299       return -99;
14300     }
14301
14302   /* Construct the API message */
14303   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14304
14305   mp->is_enabled = is_en;
14306
14307   /* send it... */
14308   S (mp);
14309
14310   /* Wait for a reply... */
14311   W (ret);
14312   return ret;
14313 }
14314
14315 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14316
14317 static int
14318 api_one_enable_disable (vat_main_t * vam)
14319 {
14320   unformat_input_t *input = vam->input;
14321   vl_api_one_enable_disable_t *mp;
14322   u8 is_set = 0;
14323   u8 is_en = 0;
14324   int ret;
14325
14326   /* Parse args required to build the message */
14327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14328     {
14329       if (unformat (input, "enable"))
14330         {
14331           is_set = 1;
14332           is_en = 1;
14333         }
14334       else if (unformat (input, "disable"))
14335         {
14336           is_set = 1;
14337         }
14338       else
14339         break;
14340     }
14341
14342   if (!is_set)
14343     {
14344       errmsg ("Value not set");
14345       return -99;
14346     }
14347
14348   /* Construct the API message */
14349   M (ONE_ENABLE_DISABLE, mp);
14350
14351   mp->is_en = is_en;
14352
14353   /* send it... */
14354   S (mp);
14355
14356   /* Wait for a reply... */
14357   W (ret);
14358   return ret;
14359 }
14360
14361 #define api_lisp_enable_disable api_one_enable_disable
14362
14363 static int
14364 api_show_one_map_register_state (vat_main_t * vam)
14365 {
14366   vl_api_show_one_map_register_state_t *mp;
14367   int ret;
14368
14369   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14370
14371   /* send */
14372   S (mp);
14373
14374   /* wait for reply */
14375   W (ret);
14376   return ret;
14377 }
14378
14379 #define api_show_lisp_map_register_state api_show_one_map_register_state
14380
14381 static int
14382 api_show_one_rloc_probe_state (vat_main_t * vam)
14383 {
14384   vl_api_show_one_rloc_probe_state_t *mp;
14385   int ret;
14386
14387   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14388
14389   /* send */
14390   S (mp);
14391
14392   /* wait for reply */
14393   W (ret);
14394   return ret;
14395 }
14396
14397 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14398
14399 static int
14400 api_one_stats_enable_disable (vat_main_t * vam)
14401 {
14402   vl_api_one_stats_enable_disable_t *mp;
14403   unformat_input_t *input = vam->input;
14404   u8 is_set = 0;
14405   u8 is_en = 0;
14406   int ret;
14407
14408   /* Parse args required to build the message */
14409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14410     {
14411       if (unformat (input, "enable"))
14412         {
14413           is_set = 1;
14414           is_en = 1;
14415         }
14416       else if (unformat (input, "disable"))
14417         {
14418           is_set = 1;
14419         }
14420       else
14421         break;
14422     }
14423
14424   if (!is_set)
14425     {
14426       errmsg ("Value not set");
14427       return -99;
14428     }
14429
14430   M (ONE_STATS_ENABLE_DISABLE, mp);
14431   mp->is_en = is_en;
14432
14433   /* send */
14434   S (mp);
14435
14436   /* wait for reply */
14437   W (ret);
14438   return ret;
14439 }
14440
14441 static int
14442 api_show_one_stats_enable_disable (vat_main_t * vam)
14443 {
14444   vl_api_show_one_stats_enable_disable_t *mp;
14445   int ret;
14446
14447   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14448
14449   /* send */
14450   S (mp);
14451
14452   /* wait for reply */
14453   W (ret);
14454   return ret;
14455 }
14456
14457 static int
14458 api_show_one_map_request_mode (vat_main_t * vam)
14459 {
14460   vl_api_show_one_map_request_mode_t *mp;
14461   int ret;
14462
14463   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14464
14465   /* send */
14466   S (mp);
14467
14468   /* wait for reply */
14469   W (ret);
14470   return ret;
14471 }
14472
14473 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14474
14475 static int
14476 api_one_map_request_mode (vat_main_t * vam)
14477 {
14478   unformat_input_t *input = vam->input;
14479   vl_api_one_map_request_mode_t *mp;
14480   u8 mode = 0;
14481   int ret;
14482
14483   /* Parse args required to build the message */
14484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14485     {
14486       if (unformat (input, "dst-only"))
14487         mode = 0;
14488       else if (unformat (input, "src-dst"))
14489         mode = 1;
14490       else
14491         {
14492           errmsg ("parse error '%U'", format_unformat_error, input);
14493           return -99;
14494         }
14495     }
14496
14497   M (ONE_MAP_REQUEST_MODE, mp);
14498
14499   mp->mode = mode;
14500
14501   /* send */
14502   S (mp);
14503
14504   /* wait for reply */
14505   W (ret);
14506   return ret;
14507 }
14508
14509 #define api_lisp_map_request_mode api_one_map_request_mode
14510
14511 /**
14512  * Enable/disable ONE proxy ITR.
14513  *
14514  * @param vam vpp API test context
14515  * @return return code
14516  */
14517 static int
14518 api_one_pitr_set_locator_set (vat_main_t * vam)
14519 {
14520   u8 ls_name_set = 0;
14521   unformat_input_t *input = vam->input;
14522   vl_api_one_pitr_set_locator_set_t *mp;
14523   u8 is_add = 1;
14524   u8 *ls_name = 0;
14525   int ret;
14526
14527   /* Parse args required to build the message */
14528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14529     {
14530       if (unformat (input, "del"))
14531         is_add = 0;
14532       else if (unformat (input, "locator-set %s", &ls_name))
14533         ls_name_set = 1;
14534       else
14535         {
14536           errmsg ("parse error '%U'", format_unformat_error, input);
14537           return -99;
14538         }
14539     }
14540
14541   if (!ls_name_set)
14542     {
14543       errmsg ("locator-set name not set!");
14544       return -99;
14545     }
14546
14547   M (ONE_PITR_SET_LOCATOR_SET, mp);
14548
14549   mp->is_add = is_add;
14550   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14551   vec_free (ls_name);
14552
14553   /* send */
14554   S (mp);
14555
14556   /* wait for reply */
14557   W (ret);
14558   return ret;
14559 }
14560
14561 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14562
14563 static int
14564 api_show_one_pitr (vat_main_t * vam)
14565 {
14566   vl_api_show_one_pitr_t *mp;
14567   int ret;
14568
14569   if (!vam->json_output)
14570     {
14571       print (vam->ofp, "%=20s", "lisp status:");
14572     }
14573
14574   M (SHOW_ONE_PITR, mp);
14575   /* send it... */
14576   S (mp);
14577
14578   /* Wait for a reply... */
14579   W (ret);
14580   return ret;
14581 }
14582
14583 #define api_show_lisp_pitr api_show_one_pitr
14584
14585 static int
14586 api_one_use_petr (vat_main_t * vam)
14587 {
14588   unformat_input_t *input = vam->input;
14589   vl_api_one_use_petr_t *mp;
14590   u8 is_add = 0;
14591   ip_address_t ip;
14592   int ret;
14593
14594   memset (&ip, 0, sizeof (ip));
14595
14596   /* Parse args required to build the message */
14597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14598     {
14599       if (unformat (input, "disable"))
14600         is_add = 0;
14601       else
14602         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14603         {
14604           is_add = 1;
14605           ip_addr_version (&ip) = IP4;
14606         }
14607       else
14608         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14609         {
14610           is_add = 1;
14611           ip_addr_version (&ip) = IP6;
14612         }
14613       else
14614         {
14615           errmsg ("parse error '%U'", format_unformat_error, input);
14616           return -99;
14617         }
14618     }
14619
14620   M (ONE_USE_PETR, mp);
14621
14622   mp->is_add = is_add;
14623   if (is_add)
14624     {
14625       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14626       if (mp->is_ip4)
14627         clib_memcpy (mp->address, &ip, 4);
14628       else
14629         clib_memcpy (mp->address, &ip, 16);
14630     }
14631
14632   /* send */
14633   S (mp);
14634
14635   /* wait for reply */
14636   W (ret);
14637   return ret;
14638 }
14639
14640 #define api_lisp_use_petr api_one_use_petr
14641
14642 static int
14643 api_show_one_use_petr (vat_main_t * vam)
14644 {
14645   vl_api_show_one_use_petr_t *mp;
14646   int ret;
14647
14648   if (!vam->json_output)
14649     {
14650       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14651     }
14652
14653   M (SHOW_ONE_USE_PETR, mp);
14654   /* send it... */
14655   S (mp);
14656
14657   /* Wait for a reply... */
14658   W (ret);
14659   return ret;
14660 }
14661
14662 #define api_show_lisp_use_petr api_show_one_use_petr
14663
14664 /**
14665  * Add/delete mapping between vni and vrf
14666  */
14667 static int
14668 api_one_eid_table_add_del_map (vat_main_t * vam)
14669 {
14670   unformat_input_t *input = vam->input;
14671   vl_api_one_eid_table_add_del_map_t *mp;
14672   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14673   u32 vni, vrf, bd_index;
14674   int ret;
14675
14676   /* Parse args required to build the message */
14677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14678     {
14679       if (unformat (input, "del"))
14680         is_add = 0;
14681       else if (unformat (input, "vrf %d", &vrf))
14682         vrf_set = 1;
14683       else if (unformat (input, "bd_index %d", &bd_index))
14684         bd_index_set = 1;
14685       else if (unformat (input, "vni %d", &vni))
14686         vni_set = 1;
14687       else
14688         break;
14689     }
14690
14691   if (!vni_set || (!vrf_set && !bd_index_set))
14692     {
14693       errmsg ("missing arguments!");
14694       return -99;
14695     }
14696
14697   if (vrf_set && bd_index_set)
14698     {
14699       errmsg ("error: both vrf and bd entered!");
14700       return -99;
14701     }
14702
14703   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14704
14705   mp->is_add = is_add;
14706   mp->vni = htonl (vni);
14707   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14708   mp->is_l2 = bd_index_set;
14709
14710   /* send */
14711   S (mp);
14712
14713   /* wait for reply */
14714   W (ret);
14715   return ret;
14716 }
14717
14718 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14719
14720 uword
14721 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14722 {
14723   u32 *action = va_arg (*args, u32 *);
14724   u8 *s = 0;
14725
14726   if (unformat (input, "%s", &s))
14727     {
14728       if (!strcmp ((char *) s, "no-action"))
14729         action[0] = 0;
14730       else if (!strcmp ((char *) s, "natively-forward"))
14731         action[0] = 1;
14732       else if (!strcmp ((char *) s, "send-map-request"))
14733         action[0] = 2;
14734       else if (!strcmp ((char *) s, "drop"))
14735         action[0] = 3;
14736       else
14737         {
14738           clib_warning ("invalid action: '%s'", s);
14739           action[0] = 3;
14740         }
14741     }
14742   else
14743     return 0;
14744
14745   vec_free (s);
14746   return 1;
14747 }
14748
14749 /**
14750  * Add/del remote mapping to/from ONE control plane
14751  *
14752  * @param vam vpp API test context
14753  * @return return code
14754  */
14755 static int
14756 api_one_add_del_remote_mapping (vat_main_t * vam)
14757 {
14758   unformat_input_t *input = vam->input;
14759   vl_api_one_add_del_remote_mapping_t *mp;
14760   u32 vni = 0;
14761   lisp_eid_vat_t _eid, *eid = &_eid;
14762   lisp_eid_vat_t _seid, *seid = &_seid;
14763   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14764   u32 action = ~0, p, w, data_len;
14765   ip4_address_t rloc4;
14766   ip6_address_t rloc6;
14767   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14768   int ret;
14769
14770   memset (&rloc, 0, sizeof (rloc));
14771
14772   /* Parse args required to build the message */
14773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14774     {
14775       if (unformat (input, "del-all"))
14776         {
14777           del_all = 1;
14778         }
14779       else if (unformat (input, "del"))
14780         {
14781           is_add = 0;
14782         }
14783       else if (unformat (input, "add"))
14784         {
14785           is_add = 1;
14786         }
14787       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14788         {
14789           eid_set = 1;
14790         }
14791       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14792         {
14793           seid_set = 1;
14794         }
14795       else if (unformat (input, "vni %d", &vni))
14796         {
14797           ;
14798         }
14799       else if (unformat (input, "p %d w %d", &p, &w))
14800         {
14801           if (!curr_rloc)
14802             {
14803               errmsg ("No RLOC configured for setting priority/weight!");
14804               return -99;
14805             }
14806           curr_rloc->priority = p;
14807           curr_rloc->weight = w;
14808         }
14809       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14810         {
14811           rloc.is_ip4 = 1;
14812           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14813           vec_add1 (rlocs, rloc);
14814           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14815         }
14816       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14817         {
14818           rloc.is_ip4 = 0;
14819           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14820           vec_add1 (rlocs, rloc);
14821           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14822         }
14823       else if (unformat (input, "action %U",
14824                          unformat_negative_mapping_action, &action))
14825         {
14826           ;
14827         }
14828       else
14829         {
14830           clib_warning ("parse error '%U'", format_unformat_error, input);
14831           return -99;
14832         }
14833     }
14834
14835   if (0 == eid_set)
14836     {
14837       errmsg ("missing params!");
14838       return -99;
14839     }
14840
14841   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14842     {
14843       errmsg ("no action set for negative map-reply!");
14844       return -99;
14845     }
14846
14847   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14848
14849   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14850   mp->is_add = is_add;
14851   mp->vni = htonl (vni);
14852   mp->action = (u8) action;
14853   mp->is_src_dst = seid_set;
14854   mp->eid_len = eid->len;
14855   mp->seid_len = seid->len;
14856   mp->del_all = del_all;
14857   mp->eid_type = eid->type;
14858   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14859   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14860
14861   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14862   clib_memcpy (mp->rlocs, rlocs, data_len);
14863   vec_free (rlocs);
14864
14865   /* send it... */
14866   S (mp);
14867
14868   /* Wait for a reply... */
14869   W (ret);
14870   return ret;
14871 }
14872
14873 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14874
14875 /**
14876  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14877  * forwarding entries in data-plane accordingly.
14878  *
14879  * @param vam vpp API test context
14880  * @return return code
14881  */
14882 static int
14883 api_one_add_del_adjacency (vat_main_t * vam)
14884 {
14885   unformat_input_t *input = vam->input;
14886   vl_api_one_add_del_adjacency_t *mp;
14887   u32 vni = 0;
14888   ip4_address_t leid4, reid4;
14889   ip6_address_t leid6, reid6;
14890   u8 reid_mac[6] = { 0 };
14891   u8 leid_mac[6] = { 0 };
14892   u8 reid_type, leid_type;
14893   u32 leid_len = 0, reid_len = 0, len;
14894   u8 is_add = 1;
14895   int ret;
14896
14897   leid_type = reid_type = (u8) ~ 0;
14898
14899   /* Parse args required to build the message */
14900   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14901     {
14902       if (unformat (input, "del"))
14903         {
14904           is_add = 0;
14905         }
14906       else if (unformat (input, "add"))
14907         {
14908           is_add = 1;
14909         }
14910       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14911                          &reid4, &len))
14912         {
14913           reid_type = 0;        /* ipv4 */
14914           reid_len = len;
14915         }
14916       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14917                          &reid6, &len))
14918         {
14919           reid_type = 1;        /* ipv6 */
14920           reid_len = len;
14921         }
14922       else if (unformat (input, "reid %U", unformat_ethernet_address,
14923                          reid_mac))
14924         {
14925           reid_type = 2;        /* mac */
14926         }
14927       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14928                          &leid4, &len))
14929         {
14930           leid_type = 0;        /* ipv4 */
14931           leid_len = len;
14932         }
14933       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14934                          &leid6, &len))
14935         {
14936           leid_type = 1;        /* ipv6 */
14937           leid_len = len;
14938         }
14939       else if (unformat (input, "leid %U", unformat_ethernet_address,
14940                          leid_mac))
14941         {
14942           leid_type = 2;        /* mac */
14943         }
14944       else if (unformat (input, "vni %d", &vni))
14945         {
14946           ;
14947         }
14948       else
14949         {
14950           errmsg ("parse error '%U'", format_unformat_error, input);
14951           return -99;
14952         }
14953     }
14954
14955   if ((u8) ~ 0 == reid_type)
14956     {
14957       errmsg ("missing params!");
14958       return -99;
14959     }
14960
14961   if (leid_type != reid_type)
14962     {
14963       errmsg ("remote and local EIDs are of different types!");
14964       return -99;
14965     }
14966
14967   M (ONE_ADD_DEL_ADJACENCY, mp);
14968   mp->is_add = is_add;
14969   mp->vni = htonl (vni);
14970   mp->leid_len = leid_len;
14971   mp->reid_len = reid_len;
14972   mp->eid_type = reid_type;
14973
14974   switch (mp->eid_type)
14975     {
14976     case 0:
14977       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14978       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14979       break;
14980     case 1:
14981       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14982       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14983       break;
14984     case 2:
14985       clib_memcpy (mp->leid, leid_mac, 6);
14986       clib_memcpy (mp->reid, reid_mac, 6);
14987       break;
14988     default:
14989       errmsg ("unknown EID type %d!", mp->eid_type);
14990       return 0;
14991     }
14992
14993   /* send it... */
14994   S (mp);
14995
14996   /* Wait for a reply... */
14997   W (ret);
14998   return ret;
14999 }
15000
15001 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15002
15003 uword
15004 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15005 {
15006   u32 *mode = va_arg (*args, u32 *);
15007
15008   if (unformat (input, "lisp"))
15009     *mode = 0;
15010   else if (unformat (input, "vxlan"))
15011     *mode = 1;
15012   else
15013     return 0;
15014
15015   return 1;
15016 }
15017
15018 static int
15019 api_gpe_get_encap_mode (vat_main_t * vam)
15020 {
15021   vl_api_gpe_get_encap_mode_t *mp;
15022   int ret;
15023
15024   /* Construct the API message */
15025   M (GPE_GET_ENCAP_MODE, mp);
15026
15027   /* send it... */
15028   S (mp);
15029
15030   /* Wait for a reply... */
15031   W (ret);
15032   return ret;
15033 }
15034
15035 static int
15036 api_gpe_set_encap_mode (vat_main_t * vam)
15037 {
15038   unformat_input_t *input = vam->input;
15039   vl_api_gpe_set_encap_mode_t *mp;
15040   int ret;
15041   u32 mode = 0;
15042
15043   /* Parse args required to build the message */
15044   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15045     {
15046       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15047         ;
15048       else
15049         break;
15050     }
15051
15052   /* Construct the API message */
15053   M (GPE_SET_ENCAP_MODE, mp);
15054
15055   mp->mode = mode;
15056
15057   /* send it... */
15058   S (mp);
15059
15060   /* Wait for a reply... */
15061   W (ret);
15062   return ret;
15063 }
15064
15065 static int
15066 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15067 {
15068   unformat_input_t *input = vam->input;
15069   vl_api_gpe_add_del_iface_t *mp;
15070   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15071   u32 dp_table = 0, vni = 0;
15072   int ret;
15073
15074   /* Parse args required to build the message */
15075   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15076     {
15077       if (unformat (input, "up"))
15078         {
15079           action_set = 1;
15080           is_add = 1;
15081         }
15082       else if (unformat (input, "down"))
15083         {
15084           action_set = 1;
15085           is_add = 0;
15086         }
15087       else if (unformat (input, "table_id %d", &dp_table))
15088         {
15089           dp_table_set = 1;
15090         }
15091       else if (unformat (input, "bd_id %d", &dp_table))
15092         {
15093           dp_table_set = 1;
15094           is_l2 = 1;
15095         }
15096       else if (unformat (input, "vni %d", &vni))
15097         {
15098           vni_set = 1;
15099         }
15100       else
15101         break;
15102     }
15103
15104   if (action_set == 0)
15105     {
15106       errmsg ("Action not set");
15107       return -99;
15108     }
15109   if (dp_table_set == 0 || vni_set == 0)
15110     {
15111       errmsg ("vni and dp_table must be set");
15112       return -99;
15113     }
15114
15115   /* Construct the API message */
15116   M (GPE_ADD_DEL_IFACE, mp);
15117
15118   mp->is_add = is_add;
15119   mp->dp_table = dp_table;
15120   mp->is_l2 = is_l2;
15121   mp->vni = vni;
15122
15123   /* send it... */
15124   S (mp);
15125
15126   /* Wait for a reply... */
15127   W (ret);
15128   return ret;
15129 }
15130
15131 /**
15132  * Add/del map request itr rlocs from ONE control plane and updates
15133  *
15134  * @param vam vpp API test context
15135  * @return return code
15136  */
15137 static int
15138 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15139 {
15140   unformat_input_t *input = vam->input;
15141   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15142   u8 *locator_set_name = 0;
15143   u8 locator_set_name_set = 0;
15144   u8 is_add = 1;
15145   int ret;
15146
15147   /* Parse args required to build the message */
15148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15149     {
15150       if (unformat (input, "del"))
15151         {
15152           is_add = 0;
15153         }
15154       else if (unformat (input, "%_%v%_", &locator_set_name))
15155         {
15156           locator_set_name_set = 1;
15157         }
15158       else
15159         {
15160           clib_warning ("parse error '%U'", format_unformat_error, input);
15161           return -99;
15162         }
15163     }
15164
15165   if (is_add && !locator_set_name_set)
15166     {
15167       errmsg ("itr-rloc is not set!");
15168       return -99;
15169     }
15170
15171   if (is_add && vec_len (locator_set_name) > 64)
15172     {
15173       errmsg ("itr-rloc locator-set name too long");
15174       vec_free (locator_set_name);
15175       return -99;
15176     }
15177
15178   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15179   mp->is_add = is_add;
15180   if (is_add)
15181     {
15182       clib_memcpy (mp->locator_set_name, locator_set_name,
15183                    vec_len (locator_set_name));
15184     }
15185   else
15186     {
15187       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15188     }
15189   vec_free (locator_set_name);
15190
15191   /* send it... */
15192   S (mp);
15193
15194   /* Wait for a reply... */
15195   W (ret);
15196   return ret;
15197 }
15198
15199 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15200
15201 static int
15202 api_one_locator_dump (vat_main_t * vam)
15203 {
15204   unformat_input_t *input = vam->input;
15205   vl_api_one_locator_dump_t *mp;
15206   vl_api_control_ping_t *mp_ping;
15207   u8 is_index_set = 0, is_name_set = 0;
15208   u8 *ls_name = 0;
15209   u32 ls_index = ~0;
15210   int ret;
15211
15212   /* Parse args required to build the message */
15213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15214     {
15215       if (unformat (input, "ls_name %_%v%_", &ls_name))
15216         {
15217           is_name_set = 1;
15218         }
15219       else if (unformat (input, "ls_index %d", &ls_index))
15220         {
15221           is_index_set = 1;
15222         }
15223       else
15224         {
15225           errmsg ("parse error '%U'", format_unformat_error, input);
15226           return -99;
15227         }
15228     }
15229
15230   if (!is_index_set && !is_name_set)
15231     {
15232       errmsg ("error: expected one of index or name!");
15233       return -99;
15234     }
15235
15236   if (is_index_set && is_name_set)
15237     {
15238       errmsg ("error: only one param expected!");
15239       return -99;
15240     }
15241
15242   if (vec_len (ls_name) > 62)
15243     {
15244       errmsg ("error: locator set name too long!");
15245       return -99;
15246     }
15247
15248   if (!vam->json_output)
15249     {
15250       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15251     }
15252
15253   M (ONE_LOCATOR_DUMP, mp);
15254   mp->is_index_set = is_index_set;
15255
15256   if (is_index_set)
15257     mp->ls_index = clib_host_to_net_u32 (ls_index);
15258   else
15259     {
15260       vec_add1 (ls_name, 0);
15261       strncpy ((char *) mp->ls_name, (char *) ls_name,
15262                sizeof (mp->ls_name) - 1);
15263     }
15264
15265   /* send it... */
15266   S (mp);
15267
15268   /* Use a control ping for synchronization */
15269   M (CONTROL_PING, mp_ping);
15270   S (mp_ping);
15271
15272   /* Wait for a reply... */
15273   W (ret);
15274   return ret;
15275 }
15276
15277 #define api_lisp_locator_dump api_one_locator_dump
15278
15279 static int
15280 api_one_locator_set_dump (vat_main_t * vam)
15281 {
15282   vl_api_one_locator_set_dump_t *mp;
15283   vl_api_control_ping_t *mp_ping;
15284   unformat_input_t *input = vam->input;
15285   u8 filter = 0;
15286   int ret;
15287
15288   /* Parse args required to build the message */
15289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15290     {
15291       if (unformat (input, "local"))
15292         {
15293           filter = 1;
15294         }
15295       else if (unformat (input, "remote"))
15296         {
15297           filter = 2;
15298         }
15299       else
15300         {
15301           errmsg ("parse error '%U'", format_unformat_error, input);
15302           return -99;
15303         }
15304     }
15305
15306   if (!vam->json_output)
15307     {
15308       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15309     }
15310
15311   M (ONE_LOCATOR_SET_DUMP, mp);
15312
15313   mp->filter = filter;
15314
15315   /* send it... */
15316   S (mp);
15317
15318   /* Use a control ping for synchronization */
15319   M (CONTROL_PING, mp_ping);
15320   S (mp_ping);
15321
15322   /* Wait for a reply... */
15323   W (ret);
15324   return ret;
15325 }
15326
15327 #define api_lisp_locator_set_dump api_one_locator_set_dump
15328
15329 static int
15330 api_one_eid_table_map_dump (vat_main_t * vam)
15331 {
15332   u8 is_l2 = 0;
15333   u8 mode_set = 0;
15334   unformat_input_t *input = vam->input;
15335   vl_api_one_eid_table_map_dump_t *mp;
15336   vl_api_control_ping_t *mp_ping;
15337   int ret;
15338
15339   /* Parse args required to build the message */
15340   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15341     {
15342       if (unformat (input, "l2"))
15343         {
15344           is_l2 = 1;
15345           mode_set = 1;
15346         }
15347       else if (unformat (input, "l3"))
15348         {
15349           is_l2 = 0;
15350           mode_set = 1;
15351         }
15352       else
15353         {
15354           errmsg ("parse error '%U'", format_unformat_error, input);
15355           return -99;
15356         }
15357     }
15358
15359   if (!mode_set)
15360     {
15361       errmsg ("expected one of 'l2' or 'l3' parameter!");
15362       return -99;
15363     }
15364
15365   if (!vam->json_output)
15366     {
15367       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15368     }
15369
15370   M (ONE_EID_TABLE_MAP_DUMP, mp);
15371   mp->is_l2 = is_l2;
15372
15373   /* send it... */
15374   S (mp);
15375
15376   /* Use a control ping for synchronization */
15377   M (CONTROL_PING, mp_ping);
15378   S (mp_ping);
15379
15380   /* Wait for a reply... */
15381   W (ret);
15382   return ret;
15383 }
15384
15385 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15386
15387 static int
15388 api_one_eid_table_vni_dump (vat_main_t * vam)
15389 {
15390   vl_api_one_eid_table_vni_dump_t *mp;
15391   vl_api_control_ping_t *mp_ping;
15392   int ret;
15393
15394   if (!vam->json_output)
15395     {
15396       print (vam->ofp, "VNI");
15397     }
15398
15399   M (ONE_EID_TABLE_VNI_DUMP, mp);
15400
15401   /* send it... */
15402   S (mp);
15403
15404   /* Use a control ping for synchronization */
15405   M (CONTROL_PING, mp_ping);
15406   S (mp_ping);
15407
15408   /* Wait for a reply... */
15409   W (ret);
15410   return ret;
15411 }
15412
15413 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15414
15415 static int
15416 api_one_eid_table_dump (vat_main_t * vam)
15417 {
15418   unformat_input_t *i = vam->input;
15419   vl_api_one_eid_table_dump_t *mp;
15420   vl_api_control_ping_t *mp_ping;
15421   struct in_addr ip4;
15422   struct in6_addr ip6;
15423   u8 mac[6];
15424   u8 eid_type = ~0, eid_set = 0;
15425   u32 prefix_length = ~0, t, vni = 0;
15426   u8 filter = 0;
15427   int ret;
15428
15429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15430     {
15431       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15432         {
15433           eid_set = 1;
15434           eid_type = 0;
15435           prefix_length = t;
15436         }
15437       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15438         {
15439           eid_set = 1;
15440           eid_type = 1;
15441           prefix_length = t;
15442         }
15443       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15444         {
15445           eid_set = 1;
15446           eid_type = 2;
15447         }
15448       else if (unformat (i, "vni %d", &t))
15449         {
15450           vni = t;
15451         }
15452       else if (unformat (i, "local"))
15453         {
15454           filter = 1;
15455         }
15456       else if (unformat (i, "remote"))
15457         {
15458           filter = 2;
15459         }
15460       else
15461         {
15462           errmsg ("parse error '%U'", format_unformat_error, i);
15463           return -99;
15464         }
15465     }
15466
15467   if (!vam->json_output)
15468     {
15469       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15470              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15471     }
15472
15473   M (ONE_EID_TABLE_DUMP, mp);
15474
15475   mp->filter = filter;
15476   if (eid_set)
15477     {
15478       mp->eid_set = 1;
15479       mp->vni = htonl (vni);
15480       mp->eid_type = eid_type;
15481       switch (eid_type)
15482         {
15483         case 0:
15484           mp->prefix_length = prefix_length;
15485           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15486           break;
15487         case 1:
15488           mp->prefix_length = prefix_length;
15489           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15490           break;
15491         case 2:
15492           clib_memcpy (mp->eid, mac, sizeof (mac));
15493           break;
15494         default:
15495           errmsg ("unknown EID type %d!", eid_type);
15496           return -99;
15497         }
15498     }
15499
15500   /* send it... */
15501   S (mp);
15502
15503   /* Use a control ping for synchronization */
15504   M (CONTROL_PING, mp_ping);
15505   S (mp_ping);
15506
15507   /* Wait for a reply... */
15508   W (ret);
15509   return ret;
15510 }
15511
15512 #define api_lisp_eid_table_dump api_one_eid_table_dump
15513
15514 static int
15515 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15516 {
15517   unformat_input_t *i = vam->input;
15518   vl_api_gpe_fwd_entries_get_t *mp;
15519   u8 vni_set = 0;
15520   u32 vni = ~0;
15521   int ret;
15522
15523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15524     {
15525       if (unformat (i, "vni %d", &vni))
15526         {
15527           vni_set = 1;
15528         }
15529       else
15530         {
15531           errmsg ("parse error '%U'", format_unformat_error, i);
15532           return -99;
15533         }
15534     }
15535
15536   if (!vni_set)
15537     {
15538       errmsg ("vni not set!");
15539       return -99;
15540     }
15541
15542   if (!vam->json_output)
15543     {
15544       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15545              "leid", "reid");
15546     }
15547
15548   M (GPE_FWD_ENTRIES_GET, mp);
15549   mp->vni = clib_host_to_net_u32 (vni);
15550
15551   /* send it... */
15552   S (mp);
15553
15554   /* Wait for a reply... */
15555   W (ret);
15556   return ret;
15557 }
15558
15559 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15560 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15561 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15562 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15563
15564 static int
15565 api_one_adjacencies_get (vat_main_t * vam)
15566 {
15567   unformat_input_t *i = vam->input;
15568   vl_api_one_adjacencies_get_t *mp;
15569   u8 vni_set = 0;
15570   u32 vni = ~0;
15571   int ret;
15572
15573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15574     {
15575       if (unformat (i, "vni %d", &vni))
15576         {
15577           vni_set = 1;
15578         }
15579       else
15580         {
15581           errmsg ("parse error '%U'", format_unformat_error, i);
15582           return -99;
15583         }
15584     }
15585
15586   if (!vni_set)
15587     {
15588       errmsg ("vni not set!");
15589       return -99;
15590     }
15591
15592   if (!vam->json_output)
15593     {
15594       print (vam->ofp, "%s %40s", "leid", "reid");
15595     }
15596
15597   M (ONE_ADJACENCIES_GET, mp);
15598   mp->vni = clib_host_to_net_u32 (vni);
15599
15600   /* send it... */
15601   S (mp);
15602
15603   /* Wait for a reply... */
15604   W (ret);
15605   return ret;
15606 }
15607
15608 #define api_lisp_adjacencies_get api_one_adjacencies_get
15609
15610 static int
15611 api_one_map_server_dump (vat_main_t * vam)
15612 {
15613   vl_api_one_map_server_dump_t *mp;
15614   vl_api_control_ping_t *mp_ping;
15615   int ret;
15616
15617   if (!vam->json_output)
15618     {
15619       print (vam->ofp, "%=20s", "Map server");
15620     }
15621
15622   M (ONE_MAP_SERVER_DUMP, mp);
15623   /* send it... */
15624   S (mp);
15625
15626   /* Use a control ping for synchronization */
15627   M (CONTROL_PING, mp_ping);
15628   S (mp_ping);
15629
15630   /* Wait for a reply... */
15631   W (ret);
15632   return ret;
15633 }
15634
15635 #define api_lisp_map_server_dump api_one_map_server_dump
15636
15637 static int
15638 api_one_map_resolver_dump (vat_main_t * vam)
15639 {
15640   vl_api_one_map_resolver_dump_t *mp;
15641   vl_api_control_ping_t *mp_ping;
15642   int ret;
15643
15644   if (!vam->json_output)
15645     {
15646       print (vam->ofp, "%=20s", "Map resolver");
15647     }
15648
15649   M (ONE_MAP_RESOLVER_DUMP, mp);
15650   /* send it... */
15651   S (mp);
15652
15653   /* Use a control ping for synchronization */
15654   M (CONTROL_PING, mp_ping);
15655   S (mp_ping);
15656
15657   /* Wait for a reply... */
15658   W (ret);
15659   return ret;
15660 }
15661
15662 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15663
15664 static int
15665 api_one_stats_dump (vat_main_t * vam)
15666 {
15667   vl_api_one_stats_dump_t *mp;
15668   vl_api_control_ping_t *mp_ping;
15669   int ret;
15670
15671   M (ONE_STATS_DUMP, mp);
15672   /* send it... */
15673   S (mp);
15674
15675   /* Use a control ping for synchronization */
15676   M (CONTROL_PING, mp_ping);
15677   S (mp_ping);
15678
15679   /* Wait for a reply... */
15680   W (ret);
15681   return ret;
15682 }
15683
15684 static int
15685 api_show_one_status (vat_main_t * vam)
15686 {
15687   vl_api_show_one_status_t *mp;
15688   int ret;
15689
15690   if (!vam->json_output)
15691     {
15692       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15693     }
15694
15695   M (SHOW_ONE_STATUS, mp);
15696   /* send it... */
15697   S (mp);
15698   /* Wait for a reply... */
15699   W (ret);
15700   return ret;
15701 }
15702
15703 #define api_show_lisp_status api_show_one_status
15704
15705 static int
15706 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15707 {
15708   vl_api_gpe_fwd_entry_path_dump_t *mp;
15709   vl_api_control_ping_t *mp_ping;
15710   unformat_input_t *i = vam->input;
15711   u32 fwd_entry_index = ~0;
15712   int ret;
15713
15714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15715     {
15716       if (unformat (i, "index %d", &fwd_entry_index))
15717         ;
15718       else
15719         break;
15720     }
15721
15722   if (~0 == fwd_entry_index)
15723     {
15724       errmsg ("no index specified!");
15725       return -99;
15726     }
15727
15728   if (!vam->json_output)
15729     {
15730       print (vam->ofp, "first line");
15731     }
15732
15733   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15734
15735   /* send it... */
15736   S (mp);
15737   /* Use a control ping for synchronization */
15738   M (CONTROL_PING, mp_ping);
15739   S (mp_ping);
15740
15741   /* Wait for a reply... */
15742   W (ret);
15743   return ret;
15744 }
15745
15746 static int
15747 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15748 {
15749   vl_api_one_get_map_request_itr_rlocs_t *mp;
15750   int ret;
15751
15752   if (!vam->json_output)
15753     {
15754       print (vam->ofp, "%=20s", "itr-rlocs:");
15755     }
15756
15757   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15758   /* send it... */
15759   S (mp);
15760   /* Wait for a reply... */
15761   W (ret);
15762   return ret;
15763 }
15764
15765 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15766
15767 static int
15768 api_af_packet_create (vat_main_t * vam)
15769 {
15770   unformat_input_t *i = vam->input;
15771   vl_api_af_packet_create_t *mp;
15772   u8 *host_if_name = 0;
15773   u8 hw_addr[6];
15774   u8 random_hw_addr = 1;
15775   int ret;
15776
15777   memset (hw_addr, 0, sizeof (hw_addr));
15778
15779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15780     {
15781       if (unformat (i, "name %s", &host_if_name))
15782         vec_add1 (host_if_name, 0);
15783       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15784         random_hw_addr = 0;
15785       else
15786         break;
15787     }
15788
15789   if (!vec_len (host_if_name))
15790     {
15791       errmsg ("host-interface name must be specified");
15792       return -99;
15793     }
15794
15795   if (vec_len (host_if_name) > 64)
15796     {
15797       errmsg ("host-interface name too long");
15798       return -99;
15799     }
15800
15801   M (AF_PACKET_CREATE, mp);
15802
15803   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15804   clib_memcpy (mp->hw_addr, hw_addr, 6);
15805   mp->use_random_hw_addr = random_hw_addr;
15806   vec_free (host_if_name);
15807
15808   S (mp);
15809
15810   /* *INDENT-OFF* */
15811   W2 (ret,
15812       ({
15813         if (ret == 0)
15814           fprintf (vam->ofp ? vam->ofp : stderr,
15815                    " new sw_if_index = %d\n", vam->sw_if_index);
15816       }));
15817   /* *INDENT-ON* */
15818   return ret;
15819 }
15820
15821 static int
15822 api_af_packet_delete (vat_main_t * vam)
15823 {
15824   unformat_input_t *i = vam->input;
15825   vl_api_af_packet_delete_t *mp;
15826   u8 *host_if_name = 0;
15827   int ret;
15828
15829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15830     {
15831       if (unformat (i, "name %s", &host_if_name))
15832         vec_add1 (host_if_name, 0);
15833       else
15834         break;
15835     }
15836
15837   if (!vec_len (host_if_name))
15838     {
15839       errmsg ("host-interface name must be specified");
15840       return -99;
15841     }
15842
15843   if (vec_len (host_if_name) > 64)
15844     {
15845       errmsg ("host-interface name too long");
15846       return -99;
15847     }
15848
15849   M (AF_PACKET_DELETE, mp);
15850
15851   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15852   vec_free (host_if_name);
15853
15854   S (mp);
15855   W (ret);
15856   return ret;
15857 }
15858
15859 static int
15860 api_policer_add_del (vat_main_t * vam)
15861 {
15862   unformat_input_t *i = vam->input;
15863   vl_api_policer_add_del_t *mp;
15864   u8 is_add = 1;
15865   u8 *name = 0;
15866   u32 cir = 0;
15867   u32 eir = 0;
15868   u64 cb = 0;
15869   u64 eb = 0;
15870   u8 rate_type = 0;
15871   u8 round_type = 0;
15872   u8 type = 0;
15873   u8 color_aware = 0;
15874   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15875   int ret;
15876
15877   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15878   conform_action.dscp = 0;
15879   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15880   exceed_action.dscp = 0;
15881   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15882   violate_action.dscp = 0;
15883
15884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15885     {
15886       if (unformat (i, "del"))
15887         is_add = 0;
15888       else if (unformat (i, "name %s", &name))
15889         vec_add1 (name, 0);
15890       else if (unformat (i, "cir %u", &cir))
15891         ;
15892       else if (unformat (i, "eir %u", &eir))
15893         ;
15894       else if (unformat (i, "cb %u", &cb))
15895         ;
15896       else if (unformat (i, "eb %u", &eb))
15897         ;
15898       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15899                          &rate_type))
15900         ;
15901       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15902                          &round_type))
15903         ;
15904       else if (unformat (i, "type %U", unformat_policer_type, &type))
15905         ;
15906       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15907                          &conform_action))
15908         ;
15909       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15910                          &exceed_action))
15911         ;
15912       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15913                          &violate_action))
15914         ;
15915       else if (unformat (i, "color-aware"))
15916         color_aware = 1;
15917       else
15918         break;
15919     }
15920
15921   if (!vec_len (name))
15922     {
15923       errmsg ("policer name must be specified");
15924       return -99;
15925     }
15926
15927   if (vec_len (name) > 64)
15928     {
15929       errmsg ("policer name too long");
15930       return -99;
15931     }
15932
15933   M (POLICER_ADD_DEL, mp);
15934
15935   clib_memcpy (mp->name, name, vec_len (name));
15936   vec_free (name);
15937   mp->is_add = is_add;
15938   mp->cir = cir;
15939   mp->eir = eir;
15940   mp->cb = cb;
15941   mp->eb = eb;
15942   mp->rate_type = rate_type;
15943   mp->round_type = round_type;
15944   mp->type = type;
15945   mp->conform_action_type = conform_action.action_type;
15946   mp->conform_dscp = conform_action.dscp;
15947   mp->exceed_action_type = exceed_action.action_type;
15948   mp->exceed_dscp = exceed_action.dscp;
15949   mp->violate_action_type = violate_action.action_type;
15950   mp->violate_dscp = violate_action.dscp;
15951   mp->color_aware = color_aware;
15952
15953   S (mp);
15954   W (ret);
15955   return ret;
15956 }
15957
15958 static int
15959 api_policer_dump (vat_main_t * vam)
15960 {
15961   unformat_input_t *i = vam->input;
15962   vl_api_policer_dump_t *mp;
15963   vl_api_control_ping_t *mp_ping;
15964   u8 *match_name = 0;
15965   u8 match_name_valid = 0;
15966   int ret;
15967
15968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15969     {
15970       if (unformat (i, "name %s", &match_name))
15971         {
15972           vec_add1 (match_name, 0);
15973           match_name_valid = 1;
15974         }
15975       else
15976         break;
15977     }
15978
15979   M (POLICER_DUMP, mp);
15980   mp->match_name_valid = match_name_valid;
15981   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15982   vec_free (match_name);
15983   /* send it... */
15984   S (mp);
15985
15986   /* Use a control ping for synchronization */
15987   M (CONTROL_PING, mp_ping);
15988   S (mp_ping);
15989
15990   /* Wait for a reply... */
15991   W (ret);
15992   return ret;
15993 }
15994
15995 static int
15996 api_policer_classify_set_interface (vat_main_t * vam)
15997 {
15998   unformat_input_t *i = vam->input;
15999   vl_api_policer_classify_set_interface_t *mp;
16000   u32 sw_if_index;
16001   int sw_if_index_set;
16002   u32 ip4_table_index = ~0;
16003   u32 ip6_table_index = ~0;
16004   u32 l2_table_index = ~0;
16005   u8 is_add = 1;
16006   int ret;
16007
16008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16009     {
16010       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16011         sw_if_index_set = 1;
16012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16013         sw_if_index_set = 1;
16014       else if (unformat (i, "del"))
16015         is_add = 0;
16016       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16017         ;
16018       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16019         ;
16020       else if (unformat (i, "l2-table %d", &l2_table_index))
16021         ;
16022       else
16023         {
16024           clib_warning ("parse error '%U'", format_unformat_error, i);
16025           return -99;
16026         }
16027     }
16028
16029   if (sw_if_index_set == 0)
16030     {
16031       errmsg ("missing interface name or sw_if_index");
16032       return -99;
16033     }
16034
16035   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16036
16037   mp->sw_if_index = ntohl (sw_if_index);
16038   mp->ip4_table_index = ntohl (ip4_table_index);
16039   mp->ip6_table_index = ntohl (ip6_table_index);
16040   mp->l2_table_index = ntohl (l2_table_index);
16041   mp->is_add = is_add;
16042
16043   S (mp);
16044   W (ret);
16045   return ret;
16046 }
16047
16048 static int
16049 api_policer_classify_dump (vat_main_t * vam)
16050 {
16051   unformat_input_t *i = vam->input;
16052   vl_api_policer_classify_dump_t *mp;
16053   vl_api_control_ping_t *mp_ping;
16054   u8 type = POLICER_CLASSIFY_N_TABLES;
16055   int ret;
16056
16057   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16058     ;
16059   else
16060     {
16061       errmsg ("classify table type must be specified");
16062       return -99;
16063     }
16064
16065   if (!vam->json_output)
16066     {
16067       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16068     }
16069
16070   M (POLICER_CLASSIFY_DUMP, mp);
16071   mp->type = type;
16072   /* send it... */
16073   S (mp);
16074
16075   /* Use a control ping for synchronization */
16076   M (CONTROL_PING, mp_ping);
16077   S (mp_ping);
16078
16079   /* Wait for a reply... */
16080   W (ret);
16081   return ret;
16082 }
16083
16084 static int
16085 api_netmap_create (vat_main_t * vam)
16086 {
16087   unformat_input_t *i = vam->input;
16088   vl_api_netmap_create_t *mp;
16089   u8 *if_name = 0;
16090   u8 hw_addr[6];
16091   u8 random_hw_addr = 1;
16092   u8 is_pipe = 0;
16093   u8 is_master = 0;
16094   int ret;
16095
16096   memset (hw_addr, 0, sizeof (hw_addr));
16097
16098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16099     {
16100       if (unformat (i, "name %s", &if_name))
16101         vec_add1 (if_name, 0);
16102       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16103         random_hw_addr = 0;
16104       else if (unformat (i, "pipe"))
16105         is_pipe = 1;
16106       else if (unformat (i, "master"))
16107         is_master = 1;
16108       else if (unformat (i, "slave"))
16109         is_master = 0;
16110       else
16111         break;
16112     }
16113
16114   if (!vec_len (if_name))
16115     {
16116       errmsg ("interface name must be specified");
16117       return -99;
16118     }
16119
16120   if (vec_len (if_name) > 64)
16121     {
16122       errmsg ("interface name too long");
16123       return -99;
16124     }
16125
16126   M (NETMAP_CREATE, mp);
16127
16128   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16129   clib_memcpy (mp->hw_addr, hw_addr, 6);
16130   mp->use_random_hw_addr = random_hw_addr;
16131   mp->is_pipe = is_pipe;
16132   mp->is_master = is_master;
16133   vec_free (if_name);
16134
16135   S (mp);
16136   W (ret);
16137   return ret;
16138 }
16139
16140 static int
16141 api_netmap_delete (vat_main_t * vam)
16142 {
16143   unformat_input_t *i = vam->input;
16144   vl_api_netmap_delete_t *mp;
16145   u8 *if_name = 0;
16146   int ret;
16147
16148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16149     {
16150       if (unformat (i, "name %s", &if_name))
16151         vec_add1 (if_name, 0);
16152       else
16153         break;
16154     }
16155
16156   if (!vec_len (if_name))
16157     {
16158       errmsg ("interface name must be specified");
16159       return -99;
16160     }
16161
16162   if (vec_len (if_name) > 64)
16163     {
16164       errmsg ("interface name too long");
16165       return -99;
16166     }
16167
16168   M (NETMAP_DELETE, mp);
16169
16170   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16171   vec_free (if_name);
16172
16173   S (mp);
16174   W (ret);
16175   return ret;
16176 }
16177
16178 static void vl_api_mpls_tunnel_details_t_handler
16179   (vl_api_mpls_tunnel_details_t * mp)
16180 {
16181   vat_main_t *vam = &vat_main;
16182   i32 len = mp->mt_next_hop_n_labels;
16183   i32 i;
16184
16185   print (vam->ofp, "[%d]: via %U %d labels ",
16186          mp->tunnel_index,
16187          format_ip4_address, mp->mt_next_hop,
16188          ntohl (mp->mt_next_hop_sw_if_index));
16189   for (i = 0; i < len; i++)
16190     {
16191       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
16192     }
16193   print (vam->ofp, "");
16194 }
16195
16196 static void vl_api_mpls_tunnel_details_t_handler_json
16197   (vl_api_mpls_tunnel_details_t * mp)
16198 {
16199   vat_main_t *vam = &vat_main;
16200   vat_json_node_t *node = NULL;
16201   struct in_addr ip4;
16202   i32 i;
16203   i32 len = mp->mt_next_hop_n_labels;
16204
16205   if (VAT_JSON_ARRAY != vam->json_tree.type)
16206     {
16207       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16208       vat_json_init_array (&vam->json_tree);
16209     }
16210   node = vat_json_array_add (&vam->json_tree);
16211
16212   vat_json_init_object (node);
16213   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
16214   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
16215   vat_json_object_add_ip4 (node, "next_hop", ip4);
16216   vat_json_object_add_uint (node, "next_hop_sw_if_index",
16217                             ntohl (mp->mt_next_hop_sw_if_index));
16218   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
16219   vat_json_object_add_uint (node, "label_count", len);
16220   for (i = 0; i < len; i++)
16221     {
16222       vat_json_object_add_uint (node, "label",
16223                                 ntohl (mp->mt_next_hop_out_labels[i]));
16224     }
16225 }
16226
16227 static int
16228 api_mpls_tunnel_dump (vat_main_t * vam)
16229 {
16230   vl_api_mpls_tunnel_dump_t *mp;
16231   vl_api_control_ping_t *mp_ping;
16232   i32 index = -1;
16233   int ret;
16234
16235   /* Parse args required to build the message */
16236   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16237     {
16238       if (!unformat (vam->input, "tunnel_index %d", &index))
16239         {
16240           index = -1;
16241           break;
16242         }
16243     }
16244
16245   print (vam->ofp, "  tunnel_index %d", index);
16246
16247   M (MPLS_TUNNEL_DUMP, mp);
16248   mp->tunnel_index = htonl (index);
16249   S (mp);
16250
16251   /* Use a control ping for synchronization */
16252   M (CONTROL_PING, mp_ping);
16253   S (mp_ping);
16254
16255   W (ret);
16256   return ret;
16257 }
16258
16259 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16260 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16261
16262 static void
16263 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16264 {
16265   vat_main_t *vam = &vat_main;
16266   int count = ntohl (mp->count);
16267   vl_api_fib_path2_t *fp;
16268   int i;
16269
16270   print (vam->ofp,
16271          "table-id %d, label %u, ess_bit %u",
16272          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16273   fp = mp->path;
16274   for (i = 0; i < count; i++)
16275     {
16276       if (fp->afi == IP46_TYPE_IP6)
16277         print (vam->ofp,
16278                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16279                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16280                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16281                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16282                format_ip6_address, fp->next_hop);
16283       else if (fp->afi == IP46_TYPE_IP4)
16284         print (vam->ofp,
16285                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16286                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16287                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16288                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16289                format_ip4_address, fp->next_hop);
16290       fp++;
16291     }
16292 }
16293
16294 static void vl_api_mpls_fib_details_t_handler_json
16295   (vl_api_mpls_fib_details_t * mp)
16296 {
16297   vat_main_t *vam = &vat_main;
16298   int count = ntohl (mp->count);
16299   vat_json_node_t *node = NULL;
16300   struct in_addr ip4;
16301   struct in6_addr ip6;
16302   vl_api_fib_path2_t *fp;
16303   int i;
16304
16305   if (VAT_JSON_ARRAY != vam->json_tree.type)
16306     {
16307       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16308       vat_json_init_array (&vam->json_tree);
16309     }
16310   node = vat_json_array_add (&vam->json_tree);
16311
16312   vat_json_init_object (node);
16313   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16314   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16315   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16316   vat_json_object_add_uint (node, "path_count", count);
16317   fp = mp->path;
16318   for (i = 0; i < count; i++)
16319     {
16320       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16321       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16322       vat_json_object_add_uint (node, "is_local", fp->is_local);
16323       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16324       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16325       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16326       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16327       if (fp->afi == IP46_TYPE_IP4)
16328         {
16329           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16330           vat_json_object_add_ip4 (node, "next_hop", ip4);
16331         }
16332       else if (fp->afi == IP46_TYPE_IP6)
16333         {
16334           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16335           vat_json_object_add_ip6 (node, "next_hop", ip6);
16336         }
16337     }
16338 }
16339
16340 static int
16341 api_mpls_fib_dump (vat_main_t * vam)
16342 {
16343   vl_api_mpls_fib_dump_t *mp;
16344   vl_api_control_ping_t *mp_ping;
16345   int ret;
16346
16347   M (MPLS_FIB_DUMP, mp);
16348   S (mp);
16349
16350   /* Use a control ping for synchronization */
16351   M (CONTROL_PING, mp_ping);
16352   S (mp_ping);
16353
16354   W (ret);
16355   return ret;
16356 }
16357
16358 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16359 #define vl_api_ip_fib_details_t_print vl_noop_handler
16360
16361 static void
16362 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16363 {
16364   vat_main_t *vam = &vat_main;
16365   int count = ntohl (mp->count);
16366   vl_api_fib_path_t *fp;
16367   int i;
16368
16369   print (vam->ofp,
16370          "table-id %d, prefix %U/%d",
16371          ntohl (mp->table_id), format_ip4_address, mp->address,
16372          mp->address_length);
16373   fp = mp->path;
16374   for (i = 0; i < count; i++)
16375     {
16376       if (fp->afi == IP46_TYPE_IP6)
16377         print (vam->ofp,
16378                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16379                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16380                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16381                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16382                format_ip6_address, fp->next_hop);
16383       else if (fp->afi == IP46_TYPE_IP4)
16384         print (vam->ofp,
16385                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16386                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16387                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16388                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16389                format_ip4_address, fp->next_hop);
16390       fp++;
16391     }
16392 }
16393
16394 static void vl_api_ip_fib_details_t_handler_json
16395   (vl_api_ip_fib_details_t * mp)
16396 {
16397   vat_main_t *vam = &vat_main;
16398   int count = ntohl (mp->count);
16399   vat_json_node_t *node = NULL;
16400   struct in_addr ip4;
16401   struct in6_addr ip6;
16402   vl_api_fib_path_t *fp;
16403   int i;
16404
16405   if (VAT_JSON_ARRAY != vam->json_tree.type)
16406     {
16407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16408       vat_json_init_array (&vam->json_tree);
16409     }
16410   node = vat_json_array_add (&vam->json_tree);
16411
16412   vat_json_init_object (node);
16413   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16414   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16415   vat_json_object_add_ip4 (node, "prefix", ip4);
16416   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16417   vat_json_object_add_uint (node, "path_count", count);
16418   fp = mp->path;
16419   for (i = 0; i < count; i++)
16420     {
16421       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16422       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16423       vat_json_object_add_uint (node, "is_local", fp->is_local);
16424       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16425       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16426       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16427       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16428       if (fp->afi == IP46_TYPE_IP4)
16429         {
16430           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16431           vat_json_object_add_ip4 (node, "next_hop", ip4);
16432         }
16433       else if (fp->afi == IP46_TYPE_IP6)
16434         {
16435           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16436           vat_json_object_add_ip6 (node, "next_hop", ip6);
16437         }
16438     }
16439 }
16440
16441 static int
16442 api_ip_fib_dump (vat_main_t * vam)
16443 {
16444   vl_api_ip_fib_dump_t *mp;
16445   vl_api_control_ping_t *mp_ping;
16446   int ret;
16447
16448   M (IP_FIB_DUMP, mp);
16449   S (mp);
16450
16451   /* Use a control ping for synchronization */
16452   M (CONTROL_PING, mp_ping);
16453   S (mp_ping);
16454
16455   W (ret);
16456   return ret;
16457 }
16458
16459 static int
16460 api_ip_mfib_dump (vat_main_t * vam)
16461 {
16462   vl_api_ip_mfib_dump_t *mp;
16463   vl_api_control_ping_t *mp_ping;
16464   int ret;
16465
16466   M (IP_MFIB_DUMP, mp);
16467   S (mp);
16468
16469   /* Use a control ping for synchronization */
16470   M (CONTROL_PING, mp_ping);
16471   S (mp_ping);
16472
16473   W (ret);
16474   return ret;
16475 }
16476
16477 static void vl_api_ip_neighbor_details_t_handler
16478   (vl_api_ip_neighbor_details_t * mp)
16479 {
16480   vat_main_t *vam = &vat_main;
16481
16482   print (vam->ofp, "%c %U %U",
16483          (mp->is_static) ? 'S' : 'D',
16484          format_ethernet_address, &mp->mac_address,
16485          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16486          &mp->ip_address);
16487 }
16488
16489 static void vl_api_ip_neighbor_details_t_handler_json
16490   (vl_api_ip_neighbor_details_t * mp)
16491 {
16492
16493   vat_main_t *vam = &vat_main;
16494   vat_json_node_t *node;
16495   struct in_addr ip4;
16496   struct in6_addr ip6;
16497
16498   if (VAT_JSON_ARRAY != vam->json_tree.type)
16499     {
16500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16501       vat_json_init_array (&vam->json_tree);
16502     }
16503   node = vat_json_array_add (&vam->json_tree);
16504
16505   vat_json_init_object (node);
16506   vat_json_object_add_string_copy (node, "flag",
16507                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16508                                    "dynamic");
16509
16510   vat_json_object_add_string_copy (node, "link_layer",
16511                                    format (0, "%U", format_ethernet_address,
16512                                            &mp->mac_address));
16513
16514   if (mp->is_ipv6)
16515     {
16516       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16517       vat_json_object_add_ip6 (node, "ip_address", ip6);
16518     }
16519   else
16520     {
16521       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16522       vat_json_object_add_ip4 (node, "ip_address", ip4);
16523     }
16524 }
16525
16526 static int
16527 api_ip_neighbor_dump (vat_main_t * vam)
16528 {
16529   unformat_input_t *i = vam->input;
16530   vl_api_ip_neighbor_dump_t *mp;
16531   vl_api_control_ping_t *mp_ping;
16532   u8 is_ipv6 = 0;
16533   u32 sw_if_index = ~0;
16534   int ret;
16535
16536   /* Parse args required to build the message */
16537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16538     {
16539       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16540         ;
16541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16542         ;
16543       else if (unformat (i, "ip6"))
16544         is_ipv6 = 1;
16545       else
16546         break;
16547     }
16548
16549   if (sw_if_index == ~0)
16550     {
16551       errmsg ("missing interface name or sw_if_index");
16552       return -99;
16553     }
16554
16555   M (IP_NEIGHBOR_DUMP, mp);
16556   mp->is_ipv6 = (u8) is_ipv6;
16557   mp->sw_if_index = ntohl (sw_if_index);
16558   S (mp);
16559
16560   /* Use a control ping for synchronization */
16561   M (CONTROL_PING, mp_ping);
16562   S (mp_ping);
16563
16564   W (ret);
16565   return ret;
16566 }
16567
16568 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16569 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16570
16571 static void
16572 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16573 {
16574   vat_main_t *vam = &vat_main;
16575   int count = ntohl (mp->count);
16576   vl_api_fib_path_t *fp;
16577   int i;
16578
16579   print (vam->ofp,
16580          "table-id %d, prefix %U/%d",
16581          ntohl (mp->table_id), format_ip6_address, mp->address,
16582          mp->address_length);
16583   fp = mp->path;
16584   for (i = 0; i < count; i++)
16585     {
16586       if (fp->afi == IP46_TYPE_IP6)
16587         print (vam->ofp,
16588                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16589                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16590                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16591                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16592                format_ip6_address, fp->next_hop);
16593       else if (fp->afi == IP46_TYPE_IP4)
16594         print (vam->ofp,
16595                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16596                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16597                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16598                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16599                format_ip4_address, fp->next_hop);
16600       fp++;
16601     }
16602 }
16603
16604 static void vl_api_ip6_fib_details_t_handler_json
16605   (vl_api_ip6_fib_details_t * mp)
16606 {
16607   vat_main_t *vam = &vat_main;
16608   int count = ntohl (mp->count);
16609   vat_json_node_t *node = NULL;
16610   struct in_addr ip4;
16611   struct in6_addr ip6;
16612   vl_api_fib_path_t *fp;
16613   int i;
16614
16615   if (VAT_JSON_ARRAY != vam->json_tree.type)
16616     {
16617       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16618       vat_json_init_array (&vam->json_tree);
16619     }
16620   node = vat_json_array_add (&vam->json_tree);
16621
16622   vat_json_init_object (node);
16623   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16624   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16625   vat_json_object_add_ip6 (node, "prefix", ip6);
16626   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16627   vat_json_object_add_uint (node, "path_count", count);
16628   fp = mp->path;
16629   for (i = 0; i < count; i++)
16630     {
16631       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16632       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16633       vat_json_object_add_uint (node, "is_local", fp->is_local);
16634       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16635       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16636       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16637       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16638       if (fp->afi == IP46_TYPE_IP4)
16639         {
16640           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16641           vat_json_object_add_ip4 (node, "next_hop", ip4);
16642         }
16643       else if (fp->afi == IP46_TYPE_IP6)
16644         {
16645           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16646           vat_json_object_add_ip6 (node, "next_hop", ip6);
16647         }
16648     }
16649 }
16650
16651 static int
16652 api_ip6_fib_dump (vat_main_t * vam)
16653 {
16654   vl_api_ip6_fib_dump_t *mp;
16655   vl_api_control_ping_t *mp_ping;
16656   int ret;
16657
16658   M (IP6_FIB_DUMP, mp);
16659   S (mp);
16660
16661   /* Use a control ping for synchronization */
16662   M (CONTROL_PING, mp_ping);
16663   S (mp_ping);
16664
16665   W (ret);
16666   return ret;
16667 }
16668
16669 static int
16670 api_ip6_mfib_dump (vat_main_t * vam)
16671 {
16672   vl_api_ip6_mfib_dump_t *mp;
16673   vl_api_control_ping_t *mp_ping;
16674   int ret;
16675
16676   M (IP6_MFIB_DUMP, mp);
16677   S (mp);
16678
16679   /* Use a control ping for synchronization */
16680   M (CONTROL_PING, mp_ping);
16681   S (mp_ping);
16682
16683   W (ret);
16684   return ret;
16685 }
16686
16687 int
16688 api_classify_table_ids (vat_main_t * vam)
16689 {
16690   vl_api_classify_table_ids_t *mp;
16691   int ret;
16692
16693   /* Construct the API message */
16694   M (CLASSIFY_TABLE_IDS, mp);
16695   mp->context = 0;
16696
16697   S (mp);
16698   W (ret);
16699   return ret;
16700 }
16701
16702 int
16703 api_classify_table_by_interface (vat_main_t * vam)
16704 {
16705   unformat_input_t *input = vam->input;
16706   vl_api_classify_table_by_interface_t *mp;
16707
16708   u32 sw_if_index = ~0;
16709   int ret;
16710   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16711     {
16712       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16713         ;
16714       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16715         ;
16716       else
16717         break;
16718     }
16719   if (sw_if_index == ~0)
16720     {
16721       errmsg ("missing interface name or sw_if_index");
16722       return -99;
16723     }
16724
16725   /* Construct the API message */
16726   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16727   mp->context = 0;
16728   mp->sw_if_index = ntohl (sw_if_index);
16729
16730   S (mp);
16731   W (ret);
16732   return ret;
16733 }
16734
16735 int
16736 api_classify_table_info (vat_main_t * vam)
16737 {
16738   unformat_input_t *input = vam->input;
16739   vl_api_classify_table_info_t *mp;
16740
16741   u32 table_id = ~0;
16742   int ret;
16743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16744     {
16745       if (unformat (input, "table_id %d", &table_id))
16746         ;
16747       else
16748         break;
16749     }
16750   if (table_id == ~0)
16751     {
16752       errmsg ("missing table id");
16753       return -99;
16754     }
16755
16756   /* Construct the API message */
16757   M (CLASSIFY_TABLE_INFO, mp);
16758   mp->context = 0;
16759   mp->table_id = ntohl (table_id);
16760
16761   S (mp);
16762   W (ret);
16763   return ret;
16764 }
16765
16766 int
16767 api_classify_session_dump (vat_main_t * vam)
16768 {
16769   unformat_input_t *input = vam->input;
16770   vl_api_classify_session_dump_t *mp;
16771   vl_api_control_ping_t *mp_ping;
16772
16773   u32 table_id = ~0;
16774   int ret;
16775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16776     {
16777       if (unformat (input, "table_id %d", &table_id))
16778         ;
16779       else
16780         break;
16781     }
16782   if (table_id == ~0)
16783     {
16784       errmsg ("missing table id");
16785       return -99;
16786     }
16787
16788   /* Construct the API message */
16789   M (CLASSIFY_SESSION_DUMP, mp);
16790   mp->context = 0;
16791   mp->table_id = ntohl (table_id);
16792   S (mp);
16793
16794   /* Use a control ping for synchronization */
16795   M (CONTROL_PING, mp_ping);
16796   S (mp_ping);
16797
16798   W (ret);
16799   return ret;
16800 }
16801
16802 static void
16803 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16804 {
16805   vat_main_t *vam = &vat_main;
16806
16807   print (vam->ofp, "collector_address %U, collector_port %d, "
16808          "src_address %U, vrf_id %d, path_mtu %u, "
16809          "template_interval %u, udp_checksum %d",
16810          format_ip4_address, mp->collector_address,
16811          ntohs (mp->collector_port),
16812          format_ip4_address, mp->src_address,
16813          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16814          ntohl (mp->template_interval), mp->udp_checksum);
16815
16816   vam->retval = 0;
16817   vam->result_ready = 1;
16818 }
16819
16820 static void
16821   vl_api_ipfix_exporter_details_t_handler_json
16822   (vl_api_ipfix_exporter_details_t * mp)
16823 {
16824   vat_main_t *vam = &vat_main;
16825   vat_json_node_t node;
16826   struct in_addr collector_address;
16827   struct in_addr src_address;
16828
16829   vat_json_init_object (&node);
16830   clib_memcpy (&collector_address, &mp->collector_address,
16831                sizeof (collector_address));
16832   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16833   vat_json_object_add_uint (&node, "collector_port",
16834                             ntohs (mp->collector_port));
16835   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16836   vat_json_object_add_ip4 (&node, "src_address", src_address);
16837   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16838   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16839   vat_json_object_add_uint (&node, "template_interval",
16840                             ntohl (mp->template_interval));
16841   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16842
16843   vat_json_print (vam->ofp, &node);
16844   vat_json_free (&node);
16845   vam->retval = 0;
16846   vam->result_ready = 1;
16847 }
16848
16849 int
16850 api_ipfix_exporter_dump (vat_main_t * vam)
16851 {
16852   vl_api_ipfix_exporter_dump_t *mp;
16853   int ret;
16854
16855   /* Construct the API message */
16856   M (IPFIX_EXPORTER_DUMP, mp);
16857   mp->context = 0;
16858
16859   S (mp);
16860   W (ret);
16861   return ret;
16862 }
16863
16864 static int
16865 api_ipfix_classify_stream_dump (vat_main_t * vam)
16866 {
16867   vl_api_ipfix_classify_stream_dump_t *mp;
16868   int ret;
16869
16870   /* Construct the API message */
16871   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16872   mp->context = 0;
16873
16874   S (mp);
16875   W (ret);
16876   return ret;
16877   /* NOTREACHED */
16878   return 0;
16879 }
16880
16881 static void
16882   vl_api_ipfix_classify_stream_details_t_handler
16883   (vl_api_ipfix_classify_stream_details_t * mp)
16884 {
16885   vat_main_t *vam = &vat_main;
16886   print (vam->ofp, "domain_id %d, src_port %d",
16887          ntohl (mp->domain_id), ntohs (mp->src_port));
16888   vam->retval = 0;
16889   vam->result_ready = 1;
16890 }
16891
16892 static void
16893   vl_api_ipfix_classify_stream_details_t_handler_json
16894   (vl_api_ipfix_classify_stream_details_t * mp)
16895 {
16896   vat_main_t *vam = &vat_main;
16897   vat_json_node_t node;
16898
16899   vat_json_init_object (&node);
16900   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16901   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16902
16903   vat_json_print (vam->ofp, &node);
16904   vat_json_free (&node);
16905   vam->retval = 0;
16906   vam->result_ready = 1;
16907 }
16908
16909 static int
16910 api_ipfix_classify_table_dump (vat_main_t * vam)
16911 {
16912   vl_api_ipfix_classify_table_dump_t *mp;
16913   vl_api_control_ping_t *mp_ping;
16914   int ret;
16915
16916   if (!vam->json_output)
16917     {
16918       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16919              "transport_protocol");
16920     }
16921
16922   /* Construct the API message */
16923   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16924
16925   /* send it... */
16926   S (mp);
16927
16928   /* Use a control ping for synchronization */
16929   M (CONTROL_PING, mp_ping);
16930   S (mp_ping);
16931
16932   W (ret);
16933   return ret;
16934 }
16935
16936 static void
16937   vl_api_ipfix_classify_table_details_t_handler
16938   (vl_api_ipfix_classify_table_details_t * mp)
16939 {
16940   vat_main_t *vam = &vat_main;
16941   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16942          mp->transport_protocol);
16943 }
16944
16945 static void
16946   vl_api_ipfix_classify_table_details_t_handler_json
16947   (vl_api_ipfix_classify_table_details_t * mp)
16948 {
16949   vat_json_node_t *node = NULL;
16950   vat_main_t *vam = &vat_main;
16951
16952   if (VAT_JSON_ARRAY != vam->json_tree.type)
16953     {
16954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16955       vat_json_init_array (&vam->json_tree);
16956     }
16957
16958   node = vat_json_array_add (&vam->json_tree);
16959   vat_json_init_object (node);
16960
16961   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16962   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16963   vat_json_object_add_uint (node, "transport_protocol",
16964                             mp->transport_protocol);
16965 }
16966
16967 static int
16968 api_sw_interface_span_enable_disable (vat_main_t * vam)
16969 {
16970   unformat_input_t *i = vam->input;
16971   vl_api_sw_interface_span_enable_disable_t *mp;
16972   u32 src_sw_if_index = ~0;
16973   u32 dst_sw_if_index = ~0;
16974   u8 state = 3;
16975   int ret;
16976
16977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16978     {
16979       if (unformat
16980           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16981         ;
16982       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16983         ;
16984       else
16985         if (unformat
16986             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16987         ;
16988       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16989         ;
16990       else if (unformat (i, "disable"))
16991         state = 0;
16992       else if (unformat (i, "rx"))
16993         state = 1;
16994       else if (unformat (i, "tx"))
16995         state = 2;
16996       else if (unformat (i, "both"))
16997         state = 3;
16998       else
16999         break;
17000     }
17001
17002   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17003
17004   mp->sw_if_index_from = htonl (src_sw_if_index);
17005   mp->sw_if_index_to = htonl (dst_sw_if_index);
17006   mp->state = state;
17007
17008   S (mp);
17009   W (ret);
17010   return ret;
17011 }
17012
17013 static void
17014 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17015                                             * mp)
17016 {
17017   vat_main_t *vam = &vat_main;
17018   u8 *sw_if_from_name = 0;
17019   u8 *sw_if_to_name = 0;
17020   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17021   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17022   char *states[] = { "none", "rx", "tx", "both" };
17023   hash_pair_t *p;
17024
17025   /* *INDENT-OFF* */
17026   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17027   ({
17028     if ((u32) p->value[0] == sw_if_index_from)
17029       {
17030         sw_if_from_name = (u8 *)(p->key);
17031         if (sw_if_to_name)
17032           break;
17033       }
17034     if ((u32) p->value[0] == sw_if_index_to)
17035       {
17036         sw_if_to_name = (u8 *)(p->key);
17037         if (sw_if_from_name)
17038           break;
17039       }
17040   }));
17041   /* *INDENT-ON* */
17042   print (vam->ofp, "%20s => %20s (%s)",
17043          sw_if_from_name, sw_if_to_name, states[mp->state]);
17044 }
17045
17046 static void
17047   vl_api_sw_interface_span_details_t_handler_json
17048   (vl_api_sw_interface_span_details_t * mp)
17049 {
17050   vat_main_t *vam = &vat_main;
17051   vat_json_node_t *node = NULL;
17052   u8 *sw_if_from_name = 0;
17053   u8 *sw_if_to_name = 0;
17054   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17055   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17056   hash_pair_t *p;
17057
17058   /* *INDENT-OFF* */
17059   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17060   ({
17061     if ((u32) p->value[0] == sw_if_index_from)
17062       {
17063         sw_if_from_name = (u8 *)(p->key);
17064         if (sw_if_to_name)
17065           break;
17066       }
17067     if ((u32) p->value[0] == sw_if_index_to)
17068       {
17069         sw_if_to_name = (u8 *)(p->key);
17070         if (sw_if_from_name)
17071           break;
17072       }
17073   }));
17074   /* *INDENT-ON* */
17075
17076   if (VAT_JSON_ARRAY != vam->json_tree.type)
17077     {
17078       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17079       vat_json_init_array (&vam->json_tree);
17080     }
17081   node = vat_json_array_add (&vam->json_tree);
17082
17083   vat_json_init_object (node);
17084   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17085   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17086   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17087   if (0 != sw_if_to_name)
17088     {
17089       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17090     }
17091   vat_json_object_add_uint (node, "state", mp->state);
17092 }
17093
17094 static int
17095 api_sw_interface_span_dump (vat_main_t * vam)
17096 {
17097   vl_api_sw_interface_span_dump_t *mp;
17098   vl_api_control_ping_t *mp_ping;
17099   int ret;
17100
17101   M (SW_INTERFACE_SPAN_DUMP, mp);
17102   S (mp);
17103
17104   /* Use a control ping for synchronization */
17105   M (CONTROL_PING, mp_ping);
17106   S (mp_ping);
17107
17108   W (ret);
17109   return ret;
17110 }
17111
17112 int
17113 api_pg_create_interface (vat_main_t * vam)
17114 {
17115   unformat_input_t *input = vam->input;
17116   vl_api_pg_create_interface_t *mp;
17117
17118   u32 if_id = ~0;
17119   int ret;
17120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17121     {
17122       if (unformat (input, "if_id %d", &if_id))
17123         ;
17124       else
17125         break;
17126     }
17127   if (if_id == ~0)
17128     {
17129       errmsg ("missing pg interface index");
17130       return -99;
17131     }
17132
17133   /* Construct the API message */
17134   M (PG_CREATE_INTERFACE, mp);
17135   mp->context = 0;
17136   mp->interface_id = ntohl (if_id);
17137
17138   S (mp);
17139   W (ret);
17140   return ret;
17141 }
17142
17143 int
17144 api_pg_capture (vat_main_t * vam)
17145 {
17146   unformat_input_t *input = vam->input;
17147   vl_api_pg_capture_t *mp;
17148
17149   u32 if_id = ~0;
17150   u8 enable = 1;
17151   u32 count = 1;
17152   u8 pcap_file_set = 0;
17153   u8 *pcap_file = 0;
17154   int ret;
17155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17156     {
17157       if (unformat (input, "if_id %d", &if_id))
17158         ;
17159       else if (unformat (input, "pcap %s", &pcap_file))
17160         pcap_file_set = 1;
17161       else if (unformat (input, "count %d", &count))
17162         ;
17163       else if (unformat (input, "disable"))
17164         enable = 0;
17165       else
17166         break;
17167     }
17168   if (if_id == ~0)
17169     {
17170       errmsg ("missing pg interface index");
17171       return -99;
17172     }
17173   if (pcap_file_set > 0)
17174     {
17175       if (vec_len (pcap_file) > 255)
17176         {
17177           errmsg ("pcap file name is too long");
17178           return -99;
17179         }
17180     }
17181
17182   u32 name_len = vec_len (pcap_file);
17183   /* Construct the API message */
17184   M (PG_CAPTURE, mp);
17185   mp->context = 0;
17186   mp->interface_id = ntohl (if_id);
17187   mp->is_enabled = enable;
17188   mp->count = ntohl (count);
17189   mp->pcap_name_length = ntohl (name_len);
17190   if (pcap_file_set != 0)
17191     {
17192       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17193     }
17194   vec_free (pcap_file);
17195
17196   S (mp);
17197   W (ret);
17198   return ret;
17199 }
17200
17201 int
17202 api_pg_enable_disable (vat_main_t * vam)
17203 {
17204   unformat_input_t *input = vam->input;
17205   vl_api_pg_enable_disable_t *mp;
17206
17207   u8 enable = 1;
17208   u8 stream_name_set = 0;
17209   u8 *stream_name = 0;
17210   int ret;
17211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17212     {
17213       if (unformat (input, "stream %s", &stream_name))
17214         stream_name_set = 1;
17215       else if (unformat (input, "disable"))
17216         enable = 0;
17217       else
17218         break;
17219     }
17220
17221   if (stream_name_set > 0)
17222     {
17223       if (vec_len (stream_name) > 255)
17224         {
17225           errmsg ("stream name too long");
17226           return -99;
17227         }
17228     }
17229
17230   u32 name_len = vec_len (stream_name);
17231   /* Construct the API message */
17232   M (PG_ENABLE_DISABLE, mp);
17233   mp->context = 0;
17234   mp->is_enabled = enable;
17235   if (stream_name_set != 0)
17236     {
17237       mp->stream_name_length = ntohl (name_len);
17238       clib_memcpy (mp->stream_name, stream_name, name_len);
17239     }
17240   vec_free (stream_name);
17241
17242   S (mp);
17243   W (ret);
17244   return ret;
17245 }
17246
17247 int
17248 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17249 {
17250   unformat_input_t *input = vam->input;
17251   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17252
17253   u16 *low_ports = 0;
17254   u16 *high_ports = 0;
17255   u16 this_low;
17256   u16 this_hi;
17257   ip4_address_t ip4_addr;
17258   ip6_address_t ip6_addr;
17259   u32 length;
17260   u32 tmp, tmp2;
17261   u8 prefix_set = 0;
17262   u32 vrf_id = ~0;
17263   u8 is_add = 1;
17264   u8 is_ipv6 = 0;
17265   int ret;
17266
17267   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17268     {
17269       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17270         {
17271           prefix_set = 1;
17272         }
17273       else
17274         if (unformat
17275             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17276         {
17277           prefix_set = 1;
17278           is_ipv6 = 1;
17279         }
17280       else if (unformat (input, "vrf %d", &vrf_id))
17281         ;
17282       else if (unformat (input, "del"))
17283         is_add = 0;
17284       else if (unformat (input, "port %d", &tmp))
17285         {
17286           if (tmp == 0 || tmp > 65535)
17287             {
17288               errmsg ("port %d out of range", tmp);
17289               return -99;
17290             }
17291           this_low = tmp;
17292           this_hi = this_low + 1;
17293           vec_add1 (low_ports, this_low);
17294           vec_add1 (high_ports, this_hi);
17295         }
17296       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17297         {
17298           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17299             {
17300               errmsg ("incorrect range parameters");
17301               return -99;
17302             }
17303           this_low = tmp;
17304           /* Note: in debug CLI +1 is added to high before
17305              passing to real fn that does "the work"
17306              (ip_source_and_port_range_check_add_del).
17307              This fn is a wrapper around the binary API fn a
17308              control plane will call, which expects this increment
17309              to have occurred. Hence letting the binary API control
17310              plane fn do the increment for consistency between VAT
17311              and other control planes.
17312            */
17313           this_hi = tmp2;
17314           vec_add1 (low_ports, this_low);
17315           vec_add1 (high_ports, this_hi);
17316         }
17317       else
17318         break;
17319     }
17320
17321   if (prefix_set == 0)
17322     {
17323       errmsg ("<address>/<mask> not specified");
17324       return -99;
17325     }
17326
17327   if (vrf_id == ~0)
17328     {
17329       errmsg ("VRF ID required, not specified");
17330       return -99;
17331     }
17332
17333   if (vrf_id == 0)
17334     {
17335       errmsg
17336         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17337       return -99;
17338     }
17339
17340   if (vec_len (low_ports) == 0)
17341     {
17342       errmsg ("At least one port or port range required");
17343       return -99;
17344     }
17345
17346   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17347
17348   mp->is_add = is_add;
17349
17350   if (is_ipv6)
17351     {
17352       mp->is_ipv6 = 1;
17353       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17354     }
17355   else
17356     {
17357       mp->is_ipv6 = 0;
17358       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17359     }
17360
17361   mp->mask_length = length;
17362   mp->number_of_ranges = vec_len (low_ports);
17363
17364   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17365   vec_free (low_ports);
17366
17367   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17368   vec_free (high_ports);
17369
17370   mp->vrf_id = ntohl (vrf_id);
17371
17372   S (mp);
17373   W (ret);
17374   return ret;
17375 }
17376
17377 int
17378 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17379 {
17380   unformat_input_t *input = vam->input;
17381   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17382   u32 sw_if_index = ~0;
17383   int vrf_set = 0;
17384   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17385   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17386   u8 is_add = 1;
17387   int ret;
17388
17389   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17390     {
17391       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17392         ;
17393       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17394         ;
17395       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17396         vrf_set = 1;
17397       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17398         vrf_set = 1;
17399       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17400         vrf_set = 1;
17401       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17402         vrf_set = 1;
17403       else if (unformat (input, "del"))
17404         is_add = 0;
17405       else
17406         break;
17407     }
17408
17409   if (sw_if_index == ~0)
17410     {
17411       errmsg ("Interface required but not specified");
17412       return -99;
17413     }
17414
17415   if (vrf_set == 0)
17416     {
17417       errmsg ("VRF ID required but not specified");
17418       return -99;
17419     }
17420
17421   if (tcp_out_vrf_id == 0
17422       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17423     {
17424       errmsg
17425         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17426       return -99;
17427     }
17428
17429   /* Construct the API message */
17430   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17431
17432   mp->sw_if_index = ntohl (sw_if_index);
17433   mp->is_add = is_add;
17434   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17435   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17436   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17437   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17438
17439   /* send it... */
17440   S (mp);
17441
17442   /* Wait for a reply... */
17443   W (ret);
17444   return ret;
17445 }
17446
17447 static int
17448 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17449 {
17450   unformat_input_t *i = vam->input;
17451   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17452   u32 local_sa_id = 0;
17453   u32 remote_sa_id = 0;
17454   ip4_address_t src_address;
17455   ip4_address_t dst_address;
17456   u8 is_add = 1;
17457   int ret;
17458
17459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17460     {
17461       if (unformat (i, "local_sa %d", &local_sa_id))
17462         ;
17463       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17464         ;
17465       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17466         ;
17467       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17468         ;
17469       else if (unformat (i, "del"))
17470         is_add = 0;
17471       else
17472         {
17473           clib_warning ("parse error '%U'", format_unformat_error, i);
17474           return -99;
17475         }
17476     }
17477
17478   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17479
17480   mp->local_sa_id = ntohl (local_sa_id);
17481   mp->remote_sa_id = ntohl (remote_sa_id);
17482   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17483   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17484   mp->is_add = is_add;
17485
17486   S (mp);
17487   W (ret);
17488   return ret;
17489 }
17490
17491 static int
17492 api_punt (vat_main_t * vam)
17493 {
17494   unformat_input_t *i = vam->input;
17495   vl_api_punt_t *mp;
17496   u32 ipv = ~0;
17497   u32 protocol = ~0;
17498   u32 port = ~0;
17499   int is_add = 1;
17500   int ret;
17501
17502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17503     {
17504       if (unformat (i, "ip %d", &ipv))
17505         ;
17506       else if (unformat (i, "protocol %d", &protocol))
17507         ;
17508       else if (unformat (i, "port %d", &port))
17509         ;
17510       else if (unformat (i, "del"))
17511         is_add = 0;
17512       else
17513         {
17514           clib_warning ("parse error '%U'", format_unformat_error, i);
17515           return -99;
17516         }
17517     }
17518
17519   M (PUNT, mp);
17520
17521   mp->is_add = (u8) is_add;
17522   mp->ipv = (u8) ipv;
17523   mp->l4_protocol = (u8) protocol;
17524   mp->l4_port = htons ((u16) port);
17525
17526   S (mp);
17527   W (ret);
17528   return ret;
17529 }
17530
17531 static void vl_api_ipsec_gre_tunnel_details_t_handler
17532   (vl_api_ipsec_gre_tunnel_details_t * mp)
17533 {
17534   vat_main_t *vam = &vat_main;
17535
17536   print (vam->ofp, "%11d%15U%15U%14d%14d",
17537          ntohl (mp->sw_if_index),
17538          format_ip4_address, &mp->src_address,
17539          format_ip4_address, &mp->dst_address,
17540          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17541 }
17542
17543 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17544   (vl_api_ipsec_gre_tunnel_details_t * mp)
17545 {
17546   vat_main_t *vam = &vat_main;
17547   vat_json_node_t *node = NULL;
17548   struct in_addr ip4;
17549
17550   if (VAT_JSON_ARRAY != vam->json_tree.type)
17551     {
17552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17553       vat_json_init_array (&vam->json_tree);
17554     }
17555   node = vat_json_array_add (&vam->json_tree);
17556
17557   vat_json_init_object (node);
17558   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17559   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17560   vat_json_object_add_ip4 (node, "src_address", ip4);
17561   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17562   vat_json_object_add_ip4 (node, "dst_address", ip4);
17563   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17564   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17565 }
17566
17567 static int
17568 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17569 {
17570   unformat_input_t *i = vam->input;
17571   vl_api_ipsec_gre_tunnel_dump_t *mp;
17572   vl_api_control_ping_t *mp_ping;
17573   u32 sw_if_index;
17574   u8 sw_if_index_set = 0;
17575   int ret;
17576
17577   /* Parse args required to build the message */
17578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17579     {
17580       if (unformat (i, "sw_if_index %d", &sw_if_index))
17581         sw_if_index_set = 1;
17582       else
17583         break;
17584     }
17585
17586   if (sw_if_index_set == 0)
17587     {
17588       sw_if_index = ~0;
17589     }
17590
17591   if (!vam->json_output)
17592     {
17593       print (vam->ofp, "%11s%15s%15s%14s%14s",
17594              "sw_if_index", "src_address", "dst_address",
17595              "local_sa_id", "remote_sa_id");
17596     }
17597
17598   /* Get list of gre-tunnel interfaces */
17599   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17600
17601   mp->sw_if_index = htonl (sw_if_index);
17602
17603   S (mp);
17604
17605   /* Use a control ping for synchronization */
17606   M (CONTROL_PING, mp_ping);
17607   S (mp_ping);
17608
17609   W (ret);
17610   return ret;
17611 }
17612
17613 static int
17614 api_delete_subif (vat_main_t * vam)
17615 {
17616   unformat_input_t *i = vam->input;
17617   vl_api_delete_subif_t *mp;
17618   u32 sw_if_index = ~0;
17619   int ret;
17620
17621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17622     {
17623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17624         ;
17625       if (unformat (i, "sw_if_index %d", &sw_if_index))
17626         ;
17627       else
17628         break;
17629     }
17630
17631   if (sw_if_index == ~0)
17632     {
17633       errmsg ("missing sw_if_index");
17634       return -99;
17635     }
17636
17637   /* Construct the API message */
17638   M (DELETE_SUBIF, mp);
17639   mp->sw_if_index = ntohl (sw_if_index);
17640
17641   S (mp);
17642   W (ret);
17643   return ret;
17644 }
17645
17646 #define foreach_pbb_vtr_op      \
17647 _("disable",  L2_VTR_DISABLED)  \
17648 _("pop",  L2_VTR_POP_2)         \
17649 _("push",  L2_VTR_PUSH_2)
17650
17651 static int
17652 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17653 {
17654   unformat_input_t *i = vam->input;
17655   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17656   u32 sw_if_index = ~0, vtr_op = ~0;
17657   u16 outer_tag = ~0;
17658   u8 dmac[6], smac[6];
17659   u8 dmac_set = 0, smac_set = 0;
17660   u16 vlanid = 0;
17661   u32 sid = ~0;
17662   u32 tmp;
17663   int ret;
17664
17665   /* Shut up coverity */
17666   memset (dmac, 0, sizeof (dmac));
17667   memset (smac, 0, sizeof (smac));
17668
17669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17670     {
17671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17672         ;
17673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17674         ;
17675       else if (unformat (i, "vtr_op %d", &vtr_op))
17676         ;
17677 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17678       foreach_pbb_vtr_op
17679 #undef _
17680         else if (unformat (i, "translate_pbb_stag"))
17681         {
17682           if (unformat (i, "%d", &tmp))
17683             {
17684               vtr_op = L2_VTR_TRANSLATE_2_1;
17685               outer_tag = tmp;
17686             }
17687           else
17688             {
17689               errmsg
17690                 ("translate_pbb_stag operation requires outer tag definition");
17691               return -99;
17692             }
17693         }
17694       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17695         dmac_set++;
17696       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17697         smac_set++;
17698       else if (unformat (i, "sid %d", &sid))
17699         ;
17700       else if (unformat (i, "vlanid %d", &tmp))
17701         vlanid = tmp;
17702       else
17703         {
17704           clib_warning ("parse error '%U'", format_unformat_error, i);
17705           return -99;
17706         }
17707     }
17708
17709   if ((sw_if_index == ~0) || (vtr_op == ~0))
17710     {
17711       errmsg ("missing sw_if_index or vtr operation");
17712       return -99;
17713     }
17714   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17715       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17716     {
17717       errmsg
17718         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17719       return -99;
17720     }
17721
17722   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17723   mp->sw_if_index = ntohl (sw_if_index);
17724   mp->vtr_op = ntohl (vtr_op);
17725   mp->outer_tag = ntohs (outer_tag);
17726   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17727   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17728   mp->b_vlanid = ntohs (vlanid);
17729   mp->i_sid = ntohl (sid);
17730
17731   S (mp);
17732   W (ret);
17733   return ret;
17734 }
17735
17736 static int
17737 api_flow_classify_set_interface (vat_main_t * vam)
17738 {
17739   unformat_input_t *i = vam->input;
17740   vl_api_flow_classify_set_interface_t *mp;
17741   u32 sw_if_index;
17742   int sw_if_index_set;
17743   u32 ip4_table_index = ~0;
17744   u32 ip6_table_index = ~0;
17745   u8 is_add = 1;
17746   int ret;
17747
17748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17749     {
17750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17751         sw_if_index_set = 1;
17752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17753         sw_if_index_set = 1;
17754       else if (unformat (i, "del"))
17755         is_add = 0;
17756       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17757         ;
17758       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17759         ;
17760       else
17761         {
17762           clib_warning ("parse error '%U'", format_unformat_error, i);
17763           return -99;
17764         }
17765     }
17766
17767   if (sw_if_index_set == 0)
17768     {
17769       errmsg ("missing interface name or sw_if_index");
17770       return -99;
17771     }
17772
17773   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17774
17775   mp->sw_if_index = ntohl (sw_if_index);
17776   mp->ip4_table_index = ntohl (ip4_table_index);
17777   mp->ip6_table_index = ntohl (ip6_table_index);
17778   mp->is_add = is_add;
17779
17780   S (mp);
17781   W (ret);
17782   return ret;
17783 }
17784
17785 static int
17786 api_flow_classify_dump (vat_main_t * vam)
17787 {
17788   unformat_input_t *i = vam->input;
17789   vl_api_flow_classify_dump_t *mp;
17790   vl_api_control_ping_t *mp_ping;
17791   u8 type = FLOW_CLASSIFY_N_TABLES;
17792   int ret;
17793
17794   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17795     ;
17796   else
17797     {
17798       errmsg ("classify table type must be specified");
17799       return -99;
17800     }
17801
17802   if (!vam->json_output)
17803     {
17804       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17805     }
17806
17807   M (FLOW_CLASSIFY_DUMP, mp);
17808   mp->type = type;
17809   /* send it... */
17810   S (mp);
17811
17812   /* Use a control ping for synchronization */
17813   M (CONTROL_PING, mp_ping);
17814   S (mp_ping);
17815
17816   /* Wait for a reply... */
17817   W (ret);
17818   return ret;
17819 }
17820
17821 static int
17822 api_feature_enable_disable (vat_main_t * vam)
17823 {
17824   unformat_input_t *i = vam->input;
17825   vl_api_feature_enable_disable_t *mp;
17826   u8 *arc_name = 0;
17827   u8 *feature_name = 0;
17828   u32 sw_if_index = ~0;
17829   u8 enable = 1;
17830   int ret;
17831
17832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17833     {
17834       if (unformat (i, "arc_name %s", &arc_name))
17835         ;
17836       else if (unformat (i, "feature_name %s", &feature_name))
17837         ;
17838       else
17839         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17840         ;
17841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17842         ;
17843       else if (unformat (i, "disable"))
17844         enable = 0;
17845       else
17846         break;
17847     }
17848
17849   if (arc_name == 0)
17850     {
17851       errmsg ("missing arc name");
17852       return -99;
17853     }
17854   if (vec_len (arc_name) > 63)
17855     {
17856       errmsg ("arc name too long");
17857     }
17858
17859   if (feature_name == 0)
17860     {
17861       errmsg ("missing feature name");
17862       return -99;
17863     }
17864   if (vec_len (feature_name) > 63)
17865     {
17866       errmsg ("feature name too long");
17867     }
17868
17869   if (sw_if_index == ~0)
17870     {
17871       errmsg ("missing interface name or sw_if_index");
17872       return -99;
17873     }
17874
17875   /* Construct the API message */
17876   M (FEATURE_ENABLE_DISABLE, mp);
17877   mp->sw_if_index = ntohl (sw_if_index);
17878   mp->enable = enable;
17879   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17880   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17881   vec_free (arc_name);
17882   vec_free (feature_name);
17883
17884   S (mp);
17885   W (ret);
17886   return ret;
17887 }
17888
17889 static int
17890 api_sw_interface_tag_add_del (vat_main_t * vam)
17891 {
17892   unformat_input_t *i = vam->input;
17893   vl_api_sw_interface_tag_add_del_t *mp;
17894   u32 sw_if_index = ~0;
17895   u8 *tag = 0;
17896   u8 enable = 1;
17897   int ret;
17898
17899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17900     {
17901       if (unformat (i, "tag %s", &tag))
17902         ;
17903       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17904         ;
17905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17906         ;
17907       else if (unformat (i, "del"))
17908         enable = 0;
17909       else
17910         break;
17911     }
17912
17913   if (sw_if_index == ~0)
17914     {
17915       errmsg ("missing interface name or sw_if_index");
17916       return -99;
17917     }
17918
17919   if (enable && (tag == 0))
17920     {
17921       errmsg ("no tag specified");
17922       return -99;
17923     }
17924
17925   /* Construct the API message */
17926   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17927   mp->sw_if_index = ntohl (sw_if_index);
17928   mp->is_add = enable;
17929   if (enable)
17930     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17931   vec_free (tag);
17932
17933   S (mp);
17934   W (ret);
17935   return ret;
17936 }
17937
17938 static void vl_api_l2_xconnect_details_t_handler
17939   (vl_api_l2_xconnect_details_t * mp)
17940 {
17941   vat_main_t *vam = &vat_main;
17942
17943   print (vam->ofp, "%15d%15d",
17944          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17945 }
17946
17947 static void vl_api_l2_xconnect_details_t_handler_json
17948   (vl_api_l2_xconnect_details_t * mp)
17949 {
17950   vat_main_t *vam = &vat_main;
17951   vat_json_node_t *node = NULL;
17952
17953   if (VAT_JSON_ARRAY != vam->json_tree.type)
17954     {
17955       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17956       vat_json_init_array (&vam->json_tree);
17957     }
17958   node = vat_json_array_add (&vam->json_tree);
17959
17960   vat_json_init_object (node);
17961   vat_json_object_add_uint (node, "rx_sw_if_index",
17962                             ntohl (mp->rx_sw_if_index));
17963   vat_json_object_add_uint (node, "tx_sw_if_index",
17964                             ntohl (mp->tx_sw_if_index));
17965 }
17966
17967 static int
17968 api_l2_xconnect_dump (vat_main_t * vam)
17969 {
17970   vl_api_l2_xconnect_dump_t *mp;
17971   vl_api_control_ping_t *mp_ping;
17972   int ret;
17973
17974   if (!vam->json_output)
17975     {
17976       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17977     }
17978
17979   M (L2_XCONNECT_DUMP, mp);
17980
17981   S (mp);
17982
17983   /* Use a control ping for synchronization */
17984   M (CONTROL_PING, mp_ping);
17985   S (mp_ping);
17986
17987   W (ret);
17988   return ret;
17989 }
17990
17991 static int
17992 api_sw_interface_set_mtu (vat_main_t * vam)
17993 {
17994   unformat_input_t *i = vam->input;
17995   vl_api_sw_interface_set_mtu_t *mp;
17996   u32 sw_if_index = ~0;
17997   u32 mtu = 0;
17998   int ret;
17999
18000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18001     {
18002       if (unformat (i, "mtu %d", &mtu))
18003         ;
18004       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18005         ;
18006       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18007         ;
18008       else
18009         break;
18010     }
18011
18012   if (sw_if_index == ~0)
18013     {
18014       errmsg ("missing interface name or sw_if_index");
18015       return -99;
18016     }
18017
18018   if (mtu == 0)
18019     {
18020       errmsg ("no mtu specified");
18021       return -99;
18022     }
18023
18024   /* Construct the API message */
18025   M (SW_INTERFACE_SET_MTU, mp);
18026   mp->sw_if_index = ntohl (sw_if_index);
18027   mp->mtu = ntohs ((u16) mtu);
18028
18029   S (mp);
18030   W (ret);
18031   return ret;
18032 }
18033
18034
18035 static int
18036 q_or_quit (vat_main_t * vam)
18037 {
18038 #if VPP_API_TEST_BUILTIN == 0
18039   longjmp (vam->jump_buf, 1);
18040 #endif
18041   return 0;                     /* not so much */
18042 }
18043
18044 static int
18045 q (vat_main_t * vam)
18046 {
18047   return q_or_quit (vam);
18048 }
18049
18050 static int
18051 quit (vat_main_t * vam)
18052 {
18053   return q_or_quit (vam);
18054 }
18055
18056 static int
18057 comment (vat_main_t * vam)
18058 {
18059   return 0;
18060 }
18061
18062 static int
18063 cmd_cmp (void *a1, void *a2)
18064 {
18065   u8 **c1 = a1;
18066   u8 **c2 = a2;
18067
18068   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18069 }
18070
18071 static int
18072 help (vat_main_t * vam)
18073 {
18074   u8 **cmds = 0;
18075   u8 *name = 0;
18076   hash_pair_t *p;
18077   unformat_input_t *i = vam->input;
18078   int j;
18079
18080   if (unformat (i, "%s", &name))
18081     {
18082       uword *hs;
18083
18084       vec_add1 (name, 0);
18085
18086       hs = hash_get_mem (vam->help_by_name, name);
18087       if (hs)
18088         print (vam->ofp, "usage: %s %s", name, hs[0]);
18089       else
18090         print (vam->ofp, "No such msg / command '%s'", name);
18091       vec_free (name);
18092       return 0;
18093     }
18094
18095   print (vam->ofp, "Help is available for the following:");
18096
18097     /* *INDENT-OFF* */
18098     hash_foreach_pair (p, vam->function_by_name,
18099     ({
18100       vec_add1 (cmds, (u8 *)(p->key));
18101     }));
18102     /* *INDENT-ON* */
18103
18104   vec_sort_with_function (cmds, cmd_cmp);
18105
18106   for (j = 0; j < vec_len (cmds); j++)
18107     print (vam->ofp, "%s", cmds[j]);
18108
18109   vec_free (cmds);
18110   return 0;
18111 }
18112
18113 static int
18114 set (vat_main_t * vam)
18115 {
18116   u8 *name = 0, *value = 0;
18117   unformat_input_t *i = vam->input;
18118
18119   if (unformat (i, "%s", &name))
18120     {
18121       /* The input buffer is a vector, not a string. */
18122       value = vec_dup (i->buffer);
18123       vec_delete (value, i->index, 0);
18124       /* Almost certainly has a trailing newline */
18125       if (value[vec_len (value) - 1] == '\n')
18126         value[vec_len (value) - 1] = 0;
18127       /* Make sure it's a proper string, one way or the other */
18128       vec_add1 (value, 0);
18129       (void) clib_macro_set_value (&vam->macro_main,
18130                                    (char *) name, (char *) value);
18131     }
18132   else
18133     errmsg ("usage: set <name> <value>");
18134
18135   vec_free (name);
18136   vec_free (value);
18137   return 0;
18138 }
18139
18140 static int
18141 unset (vat_main_t * vam)
18142 {
18143   u8 *name = 0;
18144
18145   if (unformat (vam->input, "%s", &name))
18146     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18147       errmsg ("unset: %s wasn't set", name);
18148   vec_free (name);
18149   return 0;
18150 }
18151
18152 typedef struct
18153 {
18154   u8 *name;
18155   u8 *value;
18156 } macro_sort_t;
18157
18158
18159 static int
18160 macro_sort_cmp (void *a1, void *a2)
18161 {
18162   macro_sort_t *s1 = a1;
18163   macro_sort_t *s2 = a2;
18164
18165   return strcmp ((char *) (s1->name), (char *) (s2->name));
18166 }
18167
18168 static int
18169 dump_macro_table (vat_main_t * vam)
18170 {
18171   macro_sort_t *sort_me = 0, *sm;
18172   int i;
18173   hash_pair_t *p;
18174
18175     /* *INDENT-OFF* */
18176     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18177     ({
18178       vec_add2 (sort_me, sm, 1);
18179       sm->name = (u8 *)(p->key);
18180       sm->value = (u8 *) (p->value[0]);
18181     }));
18182     /* *INDENT-ON* */
18183
18184   vec_sort_with_function (sort_me, macro_sort_cmp);
18185
18186   if (vec_len (sort_me))
18187     print (vam->ofp, "%-15s%s", "Name", "Value");
18188   else
18189     print (vam->ofp, "The macro table is empty...");
18190
18191   for (i = 0; i < vec_len (sort_me); i++)
18192     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18193   return 0;
18194 }
18195
18196 static int
18197 dump_node_table (vat_main_t * vam)
18198 {
18199   int i, j;
18200   vlib_node_t *node, *next_node;
18201
18202   if (vec_len (vam->graph_nodes) == 0)
18203     {
18204       print (vam->ofp, "Node table empty, issue get_node_graph...");
18205       return 0;
18206     }
18207
18208   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18209     {
18210       node = vam->graph_nodes[i];
18211       print (vam->ofp, "[%d] %s", i, node->name);
18212       for (j = 0; j < vec_len (node->next_nodes); j++)
18213         {
18214           if (node->next_nodes[j] != ~0)
18215             {
18216               next_node = vam->graph_nodes[node->next_nodes[j]];
18217               print (vam->ofp, "  [%d] %s", j, next_node->name);
18218             }
18219         }
18220     }
18221   return 0;
18222 }
18223
18224 static int
18225 value_sort_cmp (void *a1, void *a2)
18226 {
18227   name_sort_t *n1 = a1;
18228   name_sort_t *n2 = a2;
18229
18230   if (n1->value < n2->value)
18231     return -1;
18232   if (n1->value > n2->value)
18233     return 1;
18234   return 0;
18235 }
18236
18237
18238 static int
18239 dump_msg_api_table (vat_main_t * vam)
18240 {
18241   api_main_t *am = &api_main;
18242   name_sort_t *nses = 0, *ns;
18243   hash_pair_t *hp;
18244   int i;
18245
18246   /* *INDENT-OFF* */
18247   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18248   ({
18249     vec_add2 (nses, ns, 1);
18250     ns->name = (u8 *)(hp->key);
18251     ns->value = (u32) hp->value[0];
18252   }));
18253   /* *INDENT-ON* */
18254
18255   vec_sort_with_function (nses, value_sort_cmp);
18256
18257   for (i = 0; i < vec_len (nses); i++)
18258     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18259   vec_free (nses);
18260   return 0;
18261 }
18262
18263 static int
18264 get_msg_id (vat_main_t * vam)
18265 {
18266   u8 *name_and_crc;
18267   u32 message_index;
18268
18269   if (unformat (vam->input, "%s", &name_and_crc))
18270     {
18271       message_index = vl_api_get_msg_index (name_and_crc);
18272       if (message_index == ~0)
18273         {
18274           print (vam->ofp, " '%s' not found", name_and_crc);
18275           return 0;
18276         }
18277       print (vam->ofp, " '%s' has message index %d",
18278              name_and_crc, message_index);
18279       return 0;
18280     }
18281   errmsg ("name_and_crc required...");
18282   return 0;
18283 }
18284
18285 static int
18286 search_node_table (vat_main_t * vam)
18287 {
18288   unformat_input_t *line_input = vam->input;
18289   u8 *node_to_find;
18290   int j;
18291   vlib_node_t *node, *next_node;
18292   uword *p;
18293
18294   if (vam->graph_node_index_by_name == 0)
18295     {
18296       print (vam->ofp, "Node table empty, issue get_node_graph...");
18297       return 0;
18298     }
18299
18300   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18301     {
18302       if (unformat (line_input, "%s", &node_to_find))
18303         {
18304           vec_add1 (node_to_find, 0);
18305           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18306           if (p == 0)
18307             {
18308               print (vam->ofp, "%s not found...", node_to_find);
18309               goto out;
18310             }
18311           node = vam->graph_nodes[p[0]];
18312           print (vam->ofp, "[%d] %s", p[0], node->name);
18313           for (j = 0; j < vec_len (node->next_nodes); j++)
18314             {
18315               if (node->next_nodes[j] != ~0)
18316                 {
18317                   next_node = vam->graph_nodes[node->next_nodes[j]];
18318                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18319                 }
18320             }
18321         }
18322
18323       else
18324         {
18325           clib_warning ("parse error '%U'", format_unformat_error,
18326                         line_input);
18327           return -99;
18328         }
18329
18330     out:
18331       vec_free (node_to_find);
18332
18333     }
18334
18335   return 0;
18336 }
18337
18338
18339 static int
18340 script (vat_main_t * vam)
18341 {
18342 #if (VPP_API_TEST_BUILTIN==0)
18343   u8 *s = 0;
18344   char *save_current_file;
18345   unformat_input_t save_input;
18346   jmp_buf save_jump_buf;
18347   u32 save_line_number;
18348
18349   FILE *new_fp, *save_ifp;
18350
18351   if (unformat (vam->input, "%s", &s))
18352     {
18353       new_fp = fopen ((char *) s, "r");
18354       if (new_fp == 0)
18355         {
18356           errmsg ("Couldn't open script file %s", s);
18357           vec_free (s);
18358           return -99;
18359         }
18360     }
18361   else
18362     {
18363       errmsg ("Missing script name");
18364       return -99;
18365     }
18366
18367   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18368   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18369   save_ifp = vam->ifp;
18370   save_line_number = vam->input_line_number;
18371   save_current_file = (char *) vam->current_file;
18372
18373   vam->input_line_number = 0;
18374   vam->ifp = new_fp;
18375   vam->current_file = s;
18376   do_one_file (vam);
18377
18378   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18379   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18380   vam->ifp = save_ifp;
18381   vam->input_line_number = save_line_number;
18382   vam->current_file = (u8 *) save_current_file;
18383   vec_free (s);
18384
18385   return 0;
18386 #else
18387   clib_warning ("use the exec command...");
18388   return -99;
18389 #endif
18390 }
18391
18392 static int
18393 echo (vat_main_t * vam)
18394 {
18395   print (vam->ofp, "%v", vam->input->buffer);
18396   return 0;
18397 }
18398
18399 /* List of API message constructors, CLI names map to api_xxx */
18400 #define foreach_vpe_api_msg                                             \
18401 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18402 _(sw_interface_dump,"")                                                 \
18403 _(sw_interface_set_flags,                                               \
18404   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18405 _(sw_interface_add_del_address,                                         \
18406   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18407 _(sw_interface_set_table,                                               \
18408   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18409 _(sw_interface_set_mpls_enable,                                         \
18410   "<intfc> | sw_if_index [disable | dis]")                              \
18411 _(sw_interface_set_vpath,                                               \
18412   "<intfc> | sw_if_index <id> enable | disable")                        \
18413 _(sw_interface_set_vxlan_bypass,                                        \
18414   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18415 _(sw_interface_set_l2_xconnect,                                         \
18416   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18417   "enable | disable")                                                   \
18418 _(sw_interface_set_l2_bridge,                                           \
18419   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18420   "[shg <split-horizon-group>] [bvi]\n"                                 \
18421   "enable | disable")                                                   \
18422 _(bridge_domain_add_del,                                                \
18423   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18424 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18425 _(l2fib_add_del,                                                        \
18426   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18427 _(l2_flags,                                                             \
18428   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18429 _(bridge_flags,                                                         \
18430   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18431 _(tap_connect,                                                          \
18432   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18433 _(tap_modify,                                                           \
18434   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18435 _(tap_delete,                                                           \
18436   "<vpp-if-name> | sw_if_index <id>")                                   \
18437 _(sw_interface_tap_dump, "")                                            \
18438 _(ip_add_del_route,                                                     \
18439   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18440   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18441   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18442   "[multipath] [count <n>]")                                            \
18443 _(ip_mroute_add_del,                                                    \
18444   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18445   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18446 _(mpls_route_add_del,                                                   \
18447   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18448   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18449   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18450   "[multipath] [count <n>]")                                            \
18451 _(mpls_ip_bind_unbind,                                                  \
18452   "<label> <addr/len>")                                                 \
18453 _(mpls_tunnel_add_del,                                                  \
18454   " via <addr> [table-id <n>]\n"                                        \
18455   "sw_if_index <id>] [l2]  [del]")                                      \
18456 _(proxy_arp_add_del,                                                    \
18457   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18458 _(proxy_arp_intfc_enable_disable,                                       \
18459   "<intfc> | sw_if_index <id> enable | disable")                        \
18460 _(sw_interface_set_unnumbered,                                          \
18461   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18462 _(ip_neighbor_add_del,                                                  \
18463   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18464   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18465 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18466 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18467 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18468   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18469   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18470   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18471 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18472 _(reset_fib, "vrf <n> [ipv6]")                                          \
18473 _(dhcp_proxy_config,                                                    \
18474   "svr <v46-address> src <v46-address>\n"                               \
18475    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18476 _(dhcp_proxy_set_vss,                                                   \
18477   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18478 _(dhcp_proxy_dump, "ip6")                                               \
18479 _(dhcp_client_config,                                                   \
18480   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18481 _(set_ip_flow_hash,                                                     \
18482   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18483 _(sw_interface_ip6_enable_disable,                                      \
18484   "<intfc> | sw_if_index <id> enable | disable")                        \
18485 _(sw_interface_ip6_set_link_local_address,                              \
18486   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18487 _(ip6nd_proxy_add_del,                                                  \
18488   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18489 _(ip6nd_proxy_dump, "")                                                 \
18490 _(sw_interface_ip6nd_ra_prefix,                                         \
18491   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18492   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18493   "[nolink] [isno]")                                                    \
18494 _(sw_interface_ip6nd_ra_config,                                         \
18495   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18496   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18497   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18498 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18499 _(l2_patch_add_del,                                                     \
18500   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18501   "enable | disable")                                                   \
18502 _(sr_localsid_add_del,                                                  \
18503   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18504   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18505 _(classify_add_del_table,                                               \
18506   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18507   " [del] [del-chain] mask <mask-value>\n"                              \
18508   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18509   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18510 _(classify_add_del_session,                                             \
18511   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18512   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18513   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18514   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18515 _(classify_set_interface_ip_table,                                      \
18516   "<intfc> | sw_if_index <nn> table <nn>")                              \
18517 _(classify_set_interface_l2_tables,                                     \
18518   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18519   "  [other-table <nn>]")                                               \
18520 _(get_node_index, "node <node-name")                                    \
18521 _(add_node_next, "node <node-name> next <next-node-name>")              \
18522 _(l2tpv3_create_tunnel,                                                 \
18523   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18524   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18525   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18526 _(l2tpv3_set_tunnel_cookies,                                            \
18527   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18528   "[new_remote_cookie <nn>]\n")                                         \
18529 _(l2tpv3_interface_enable_disable,                                      \
18530   "<intfc> | sw_if_index <nn> enable | disable")                        \
18531 _(l2tpv3_set_lookup_key,                                                \
18532   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18533 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18534 _(vxlan_add_del_tunnel,                                                 \
18535   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18536   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18537   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18538 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18539 _(gre_add_del_tunnel,                                                   \
18540   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18541 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18542 _(l2_fib_clear_table, "")                                               \
18543 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18544 _(l2_interface_vlan_tag_rewrite,                                        \
18545   "<intfc> | sw_if_index <nn> \n"                                       \
18546   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18547   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18548 _(create_vhost_user_if,                                                 \
18549         "socket <filename> [server] [renumber <dev_instance>] "         \
18550         "[mac <mac_address>] "                                          \
18551         "[mode <interrupt | polling>]")                                 \
18552 _(modify_vhost_user_if,                                                 \
18553         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18554         "[server] [renumber <dev_instance>] "                           \
18555         "[mode <interrupt | polling>]")                                 \
18556 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18557 _(sw_interface_vhost_user_dump, "")                                     \
18558 _(show_version, "")                                                     \
18559 _(vxlan_gpe_add_del_tunnel,                                             \
18560   "local <addr> remote <addr> vni <nn>\n"                               \
18561     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18562   "[next-ethernet] [next-nsh]\n")                                       \
18563 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18564 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18565 _(interface_name_renumber,                                              \
18566   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18567 _(input_acl_set_interface,                                              \
18568   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18569   "  [l2-table <nn>] [del]")                                            \
18570 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18571 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18572 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18573 _(ip_dump, "ipv4 | ipv6")                                               \
18574 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18575 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18576   "  spid_id <n> ")                                                     \
18577 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18578   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18579   "  integ_alg <alg> integ_key <hex>")                                  \
18580 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18581   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18582   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18583   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18584 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18585 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18586 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18587   "(auth_data 0x<data> | auth_data <data>)")                            \
18588 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18589   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18590 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18591   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18592   "(local|remote)")                                                     \
18593 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18594 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18595 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18596 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18597 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18598 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18599 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18600 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18601 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18602 _(delete_loopback,"sw_if_index <nn>")                                   \
18603 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18604 _(map_add_domain,                                                       \
18605   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18606   "ip6-src <ip6addr> "                                                  \
18607   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18608 _(map_del_domain, "index <n>")                                          \
18609 _(map_add_del_rule,                                                     \
18610   "index <n> psid <n> dst <ip6addr> [del]")                             \
18611 _(map_domain_dump, "")                                                  \
18612 _(map_rule_dump, "index <map-domain>")                                  \
18613 _(want_interface_events,  "enable|disable")                             \
18614 _(want_stats,"enable|disable")                                          \
18615 _(get_first_msg_id, "client <name>")                                    \
18616 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18617 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18618   "fib-id <nn> [ip4][ip6][default]")                                    \
18619 _(get_node_graph, " ")                                                  \
18620 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18621 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18622 _(ioam_disable, "")                                                     \
18623 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18624                             " sw_if_index <sw_if_index> p <priority> "  \
18625                             "w <weight>] [del]")                        \
18626 _(one_add_del_locator, "locator-set <locator_name> "                    \
18627                         "iface <intf> | sw_if_index <sw_if_index> "     \
18628                         "p <priority> w <weight> [del]")                \
18629 _(one_add_del_local_eid,"vni <vni> eid "                                \
18630                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18631                          "locator-set <locator_name> [del]"             \
18632                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18633 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18634 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18635 _(one_enable_disable, "enable|disable")                                 \
18636 _(one_map_register_enable_disable, "enable|disable")                    \
18637 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18638 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18639                                "[seid <seid>] "                         \
18640                                "rloc <locator> p <prio> "               \
18641                                "w <weight> [rloc <loc> ... ] "          \
18642                                "action <action> [del-all]")             \
18643 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18644                           "<local-eid>")                                \
18645 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18646 _(one_use_petr, "ip-address> | disable")                                \
18647 _(one_map_request_mode, "src-dst|dst-only")                             \
18648 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18649 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18650 _(one_locator_set_dump, "[local | remote]")                             \
18651 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18652 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18653                        "[local] | [remote]")                            \
18654 _(one_stats_enable_disable, "enable|disalbe")                           \
18655 _(show_one_stats_enable_disable, "")                                    \
18656 _(one_eid_table_vni_dump, "")                                           \
18657 _(one_eid_table_map_dump, "l2|l3")                                      \
18658 _(one_map_resolver_dump, "")                                            \
18659 _(one_map_server_dump, "")                                              \
18660 _(one_adjacencies_get, "vni <vni>")                                     \
18661 _(show_one_rloc_probe_state, "")                                        \
18662 _(show_one_map_register_state, "")                                      \
18663 _(show_one_status, "")                                                  \
18664 _(one_stats_dump, "")                                                   \
18665 _(one_get_map_request_itr_rlocs, "")                                    \
18666 _(show_one_pitr, "")                                                    \
18667 _(show_one_use_petr, "")                                                \
18668 _(show_one_map_request_mode, "")                                        \
18669 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18670                             " sw_if_index <sw_if_index> p <priority> "  \
18671                             "w <weight>] [del]")                        \
18672 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18673                         "iface <intf> | sw_if_index <sw_if_index> "     \
18674                         "p <priority> w <weight> [del]")                \
18675 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18676                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18677                          "locator-set <locator_name> [del]"             \
18678                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18679 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18680 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18681 _(lisp_enable_disable, "enable|disable")                                \
18682 _(lisp_map_register_enable_disable, "enable|disable")                   \
18683 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18684 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18685                                "[seid <seid>] "                         \
18686                                "rloc <locator> p <prio> "               \
18687                                "w <weight> [rloc <loc> ... ] "          \
18688                                "action <action> [del-all]")             \
18689 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18690                           "<local-eid>")                                \
18691 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18692 _(lisp_use_petr, "<ip-address> | disable")                              \
18693 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18694 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18695 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18696 _(lisp_locator_set_dump, "[local | remote]")                            \
18697 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18698 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18699                        "[local] | [remote]")                            \
18700 _(lisp_eid_table_vni_dump, "")                                          \
18701 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18702 _(lisp_map_resolver_dump, "")                                           \
18703 _(lisp_map_server_dump, "")                                             \
18704 _(lisp_adjacencies_get, "vni <vni>")                                    \
18705 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18706 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18707 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18708 _(gpe_get_encap_mode, "")                                               \
18709 _(lisp_gpe_add_del_iface, "up|down")                                    \
18710 _(lisp_gpe_enable_disable, "enable|disable")                            \
18711 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18712   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18713 _(show_lisp_rloc_probe_state, "")                                       \
18714 _(show_lisp_map_register_state, "")                                     \
18715 _(show_lisp_status, "")                                                 \
18716 _(lisp_get_map_request_itr_rlocs, "")                                   \
18717 _(show_lisp_pitr, "")                                                   \
18718 _(show_lisp_use_petr, "")                                               \
18719 _(show_lisp_map_request_mode, "")                                       \
18720 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18721 _(af_packet_delete, "name <host interface name>")                       \
18722 _(policer_add_del, "name <policer name> <params> [del]")                \
18723 _(policer_dump, "[name <policer name>]")                                \
18724 _(policer_classify_set_interface,                                       \
18725   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18726   "  [l2-table <nn>] [del]")                                            \
18727 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18728 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18729     "[master|slave]")                                                   \
18730 _(netmap_delete, "name <interface name>")                               \
18731 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18732 _(mpls_fib_dump, "")                                                    \
18733 _(classify_table_ids, "")                                               \
18734 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18735 _(classify_table_info, "table_id <nn>")                                 \
18736 _(classify_session_dump, "table_id <nn>")                               \
18737 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18738     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18739     "[template_interval <nn>] [udp_checksum]")                          \
18740 _(ipfix_exporter_dump, "")                                              \
18741 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18742 _(ipfix_classify_stream_dump, "")                                       \
18743 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18744 _(ipfix_classify_table_dump, "")                                        \
18745 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18746 _(sw_interface_span_dump, "")                                           \
18747 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18748 _(pg_create_interface, "if_id <nn>")                                    \
18749 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18750 _(pg_enable_disable, "[stream <id>] disable")                           \
18751 _(ip_source_and_port_range_check_add_del,                               \
18752   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18753 _(ip_source_and_port_range_check_interface_add_del,                     \
18754   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18755   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18756 _(ipsec_gre_add_del_tunnel,                                             \
18757   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18758 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18759 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18760 _(l2_interface_pbb_tag_rewrite,                                         \
18761   "<intfc> | sw_if_index <nn> \n"                                       \
18762   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18763   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18764 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18765 _(flow_classify_set_interface,                                          \
18766   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18767 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18768 _(ip_fib_dump, "")                                                      \
18769 _(ip_mfib_dump, "")                                                     \
18770 _(ip6_fib_dump, "")                                                     \
18771 _(ip6_mfib_dump, "")                                                    \
18772 _(feature_enable_disable, "arc_name <arc_name> "                        \
18773   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18774 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18775 "[disable]")                                                            \
18776 _(l2_xconnect_dump, "")                                                 \
18777 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18778 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18779 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18780
18781 /* List of command functions, CLI names map directly to functions */
18782 #define foreach_cli_function                                    \
18783 _(comment, "usage: comment <ignore-rest-of-line>")              \
18784 _(dump_interface_table, "usage: dump_interface_table")          \
18785 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18786 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18787 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18788 _(dump_stats_table, "usage: dump_stats_table")                  \
18789 _(dump_macro_table, "usage: dump_macro_table ")                 \
18790 _(dump_node_table, "usage: dump_node_table")                    \
18791 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18792 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18793 _(echo, "usage: echo <message>")                                \
18794 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18795 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18796 _(help, "usage: help")                                          \
18797 _(q, "usage: quit")                                             \
18798 _(quit, "usage: quit")                                          \
18799 _(search_node_table, "usage: search_node_table <name>...")      \
18800 _(set, "usage: set <variable-name> <value>")                    \
18801 _(script, "usage: script <file-name>")                          \
18802 _(unset, "usage: unset <variable-name>")
18803
18804 #define _(N,n)                                  \
18805     static void vl_api_##n##_t_handler_uni      \
18806     (vl_api_##n##_t * mp)                       \
18807     {                                           \
18808         vat_main_t * vam = &vat_main;           \
18809         if (vam->json_output) {                 \
18810             vl_api_##n##_t_handler_json(mp);    \
18811         } else {                                \
18812             vl_api_##n##_t_handler(mp);         \
18813         }                                       \
18814     }
18815 foreach_vpe_api_reply_msg;
18816 #if VPP_API_TEST_BUILTIN == 0
18817 foreach_standalone_reply_msg;
18818 #endif
18819 #undef _
18820
18821 void
18822 vat_api_hookup (vat_main_t * vam)
18823 {
18824 #define _(N,n)                                                  \
18825     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18826                            vl_api_##n##_t_handler_uni,          \
18827                            vl_noop_handler,                     \
18828                            vl_api_##n##_t_endian,               \
18829                            vl_api_##n##_t_print,                \
18830                            sizeof(vl_api_##n##_t), 1);
18831   foreach_vpe_api_reply_msg;
18832 #if VPP_API_TEST_BUILTIN == 0
18833   foreach_standalone_reply_msg;
18834 #endif
18835 #undef _
18836
18837 #if (VPP_API_TEST_BUILTIN==0)
18838   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18839
18840   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18841
18842   vam->function_by_name = hash_create_string (0, sizeof (uword));
18843
18844   vam->help_by_name = hash_create_string (0, sizeof (uword));
18845 #endif
18846
18847   /* API messages we can send */
18848 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18849   foreach_vpe_api_msg;
18850 #undef _
18851
18852   /* Help strings */
18853 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18854   foreach_vpe_api_msg;
18855 #undef _
18856
18857   /* CLI functions */
18858 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18859   foreach_cli_function;
18860 #undef _
18861
18862   /* Help strings */
18863 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18864   foreach_cli_function;
18865 #undef _
18866 }
18867
18868 #if VPP_API_TEST_BUILTIN
18869 static clib_error_t *
18870 vat_api_hookup_shim (vlib_main_t * vm)
18871 {
18872   vat_api_hookup (&vat_main);
18873   return 0;
18874 }
18875
18876 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18877 #endif
18878
18879 /*
18880  * fd.io coding-style-patch-verification: ON
18881  *
18882  * Local Variables:
18883  * eval: (c-set-style "gnu")
18884  * End:
18885  */