BD/API:add bridge_domain_set_mac_age api
[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_bridge_domain_set_mac_age_reply_t_handler
1463   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1464 {
1465   vat_main_t *vam = &vat_main;
1466   i32 retval = ntohl (mp->retval);
1467   if (vam->async_mode)
1468     {
1469       vam->async_errors += (retval < 0);
1470     }
1471   else
1472     {
1473       vam->retval = retval;
1474       vam->result_ready = 1;
1475     }
1476 }
1477
1478 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1479   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   vat_json_node_t node;
1483
1484   vat_json_init_object (&node);
1485   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1486
1487   vat_json_print (vam->ofp, &node);
1488   vat_json_free (&node);
1489
1490   vam->retval = ntohl (mp->retval);
1491   vam->result_ready = 1;
1492 }
1493
1494 static void
1495 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->result_ready = 1;
1507     }
1508 }
1509
1510 static void vl_api_l2_flags_reply_t_handler_json
1511   (vl_api_l2_flags_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   vat_json_node_t node;
1515
1516   vat_json_init_object (&node);
1517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1518   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1519                             ntohl (mp->resulting_feature_bitmap));
1520
1521   vat_json_print (vam->ofp, &node);
1522   vat_json_free (&node);
1523
1524   vam->retval = ntohl (mp->retval);
1525   vam->result_ready = 1;
1526 }
1527
1528 static void vl_api_bridge_flags_reply_t_handler
1529   (vl_api_bridge_flags_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   i32 retval = ntohl (mp->retval);
1533   if (vam->async_mode)
1534     {
1535       vam->async_errors += (retval < 0);
1536     }
1537   else
1538     {
1539       vam->retval = retval;
1540       vam->result_ready = 1;
1541     }
1542 }
1543
1544 static void vl_api_bridge_flags_reply_t_handler_json
1545   (vl_api_bridge_flags_reply_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t node;
1549
1550   vat_json_init_object (&node);
1551   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1552   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1553                             ntohl (mp->resulting_feature_bitmap));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560 }
1561
1562 static void vl_api_tap_connect_reply_t_handler
1563   (vl_api_tap_connect_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   i32 retval = ntohl (mp->retval);
1567   if (vam->async_mode)
1568     {
1569       vam->async_errors += (retval < 0);
1570     }
1571   else
1572     {
1573       vam->retval = retval;
1574       vam->sw_if_index = ntohl (mp->sw_if_index);
1575       vam->result_ready = 1;
1576     }
1577
1578 }
1579
1580 static void vl_api_tap_connect_reply_t_handler_json
1581   (vl_api_tap_connect_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595
1596 }
1597
1598 static void
1599 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1600 {
1601   vat_main_t *vam = &vat_main;
1602   i32 retval = ntohl (mp->retval);
1603   if (vam->async_mode)
1604     {
1605       vam->async_errors += (retval < 0);
1606     }
1607   else
1608     {
1609       vam->retval = retval;
1610       vam->sw_if_index = ntohl (mp->sw_if_index);
1611       vam->result_ready = 1;
1612     }
1613 }
1614
1615 static void vl_api_tap_modify_reply_t_handler_json
1616   (vl_api_tap_modify_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1624
1625   vat_json_print (vam->ofp, &node);
1626   vat_json_free (&node);
1627
1628   vam->retval = ntohl (mp->retval);
1629   vam->result_ready = 1;
1630 }
1631
1632 static void
1633 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   i32 retval = ntohl (mp->retval);
1637   if (vam->async_mode)
1638     {
1639       vam->async_errors += (retval < 0);
1640     }
1641   else
1642     {
1643       vam->retval = retval;
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_tap_delete_reply_t_handler_json
1649   (vl_api_tap_delete_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1665   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1681   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1689                             ntohl (mp->sw_if_index));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1699   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->sw_if_index = ntohl (mp->sw_if_index);
1711       vam->result_ready = 1;
1712     }
1713 }
1714
1715 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1716   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732
1733 static void vl_api_one_add_del_locator_set_reply_t_handler
1734   (vl_api_one_add_del_locator_set_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->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1750   (vl_api_one_add_del_locator_set_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1758
1759   vat_json_print (vam->ofp, &node);
1760   vat_json_free (&node);
1761
1762   vam->retval = ntohl (mp->retval);
1763   vam->result_ready = 1;
1764 }
1765
1766 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1767   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1768 {
1769   vat_main_t *vam = &vat_main;
1770   i32 retval = ntohl (mp->retval);
1771   if (vam->async_mode)
1772     {
1773       vam->async_errors += (retval < 0);
1774     }
1775   else
1776     {
1777       vam->retval = retval;
1778       vam->sw_if_index = ntohl (mp->sw_if_index);
1779       vam->result_ready = 1;
1780     }
1781 }
1782
1783 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1784   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1785 {
1786   vat_main_t *vam = &vat_main;
1787   vat_json_node_t node;
1788
1789   vat_json_init_object (&node);
1790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1791   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1792
1793   vat_json_print (vam->ofp, &node);
1794   vat_json_free (&node);
1795
1796   vam->retval = ntohl (mp->retval);
1797   vam->result_ready = 1;
1798 }
1799
1800 static void vl_api_gre_add_del_tunnel_reply_t_handler
1801   (vl_api_gre_add_del_tunnel_reply_t * mp)
1802 {
1803   vat_main_t *vam = &vat_main;
1804   i32 retval = ntohl (mp->retval);
1805   if (vam->async_mode)
1806     {
1807       vam->async_errors += (retval < 0);
1808     }
1809   else
1810     {
1811       vam->retval = retval;
1812       vam->sw_if_index = ntohl (mp->sw_if_index);
1813       vam->result_ready = 1;
1814     }
1815 }
1816
1817 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1818   (vl_api_gre_add_del_tunnel_reply_t * mp)
1819 {
1820   vat_main_t *vam = &vat_main;
1821   vat_json_node_t node;
1822
1823   vat_json_init_object (&node);
1824   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1825   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1826
1827   vat_json_print (vam->ofp, &node);
1828   vat_json_free (&node);
1829
1830   vam->retval = ntohl (mp->retval);
1831   vam->result_ready = 1;
1832 }
1833
1834 static void vl_api_create_vhost_user_if_reply_t_handler
1835   (vl_api_create_vhost_user_if_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   i32 retval = ntohl (mp->retval);
1839   if (vam->async_mode)
1840     {
1841       vam->async_errors += (retval < 0);
1842     }
1843   else
1844     {
1845       vam->retval = retval;
1846       vam->sw_if_index = ntohl (mp->sw_if_index);
1847       vam->result_ready = 1;
1848     }
1849 }
1850
1851 static void vl_api_create_vhost_user_if_reply_t_handler_json
1852   (vl_api_create_vhost_user_if_reply_t * mp)
1853 {
1854   vat_main_t *vam = &vat_main;
1855   vat_json_node_t node;
1856
1857   vat_json_init_object (&node);
1858   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1859   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1860
1861   vat_json_print (vam->ofp, &node);
1862   vat_json_free (&node);
1863
1864   vam->retval = ntohl (mp->retval);
1865   vam->result_ready = 1;
1866 }
1867
1868 static void vl_api_ip_address_details_t_handler
1869   (vl_api_ip_address_details_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static ip_address_details_t empty_ip_address_details = { {0} };
1873   ip_address_details_t *address = NULL;
1874   ip_details_t *current_ip_details = NULL;
1875   ip_details_t *details = NULL;
1876
1877   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1878
1879   if (!details || vam->current_sw_if_index >= vec_len (details)
1880       || !details[vam->current_sw_if_index].present)
1881     {
1882       errmsg ("ip address details arrived but not stored");
1883       errmsg ("ip_dump should be called first");
1884       return;
1885     }
1886
1887   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1888
1889 #define addresses (current_ip_details->addr)
1890
1891   vec_validate_init_empty (addresses, vec_len (addresses),
1892                            empty_ip_address_details);
1893
1894   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1895
1896   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1897   address->prefix_length = mp->prefix_length;
1898 #undef addresses
1899 }
1900
1901 static void vl_api_ip_address_details_t_handler_json
1902   (vl_api_ip_address_details_t * mp)
1903 {
1904   vat_main_t *vam = &vat_main;
1905   vat_json_node_t *node = NULL;
1906   struct in6_addr ip6;
1907   struct in_addr ip4;
1908
1909   if (VAT_JSON_ARRAY != vam->json_tree.type)
1910     {
1911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1912       vat_json_init_array (&vam->json_tree);
1913     }
1914   node = vat_json_array_add (&vam->json_tree);
1915
1916   vat_json_init_object (node);
1917   if (vam->is_ipv6)
1918     {
1919       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1920       vat_json_object_add_ip6 (node, "ip", ip6);
1921     }
1922   else
1923     {
1924       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1925       vat_json_object_add_ip4 (node, "ip", ip4);
1926     }
1927   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1928 }
1929
1930 static void
1931 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   static ip_details_t empty_ip_details = { 0 };
1935   ip_details_t *ip = NULL;
1936   u32 sw_if_index = ~0;
1937
1938   sw_if_index = ntohl (mp->sw_if_index);
1939
1940   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1941                            sw_if_index, empty_ip_details);
1942
1943   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1944                          sw_if_index);
1945
1946   ip->present = 1;
1947 }
1948
1949 static void
1950 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1951 {
1952   vat_main_t *vam = &vat_main;
1953
1954   if (VAT_JSON_ARRAY != vam->json_tree.type)
1955     {
1956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1957       vat_json_init_array (&vam->json_tree);
1958     }
1959   vat_json_array_add_uint (&vam->json_tree,
1960                            clib_net_to_host_u32 (mp->sw_if_index));
1961 }
1962
1963 static void vl_api_map_domain_details_t_handler_json
1964   (vl_api_map_domain_details_t * mp)
1965 {
1966   vat_json_node_t *node = NULL;
1967   vat_main_t *vam = &vat_main;
1968   struct in6_addr ip6;
1969   struct in_addr ip4;
1970
1971   if (VAT_JSON_ARRAY != vam->json_tree.type)
1972     {
1973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1974       vat_json_init_array (&vam->json_tree);
1975     }
1976
1977   node = vat_json_array_add (&vam->json_tree);
1978   vat_json_init_object (node);
1979
1980   vat_json_object_add_uint (node, "domain_index",
1981                             clib_net_to_host_u32 (mp->domain_index));
1982   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1983   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1984   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1985   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1986   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1987   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1988   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1989   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1990   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1991   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1992   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1993   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1994   vat_json_object_add_uint (node, "flags", mp->flags);
1995   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1996   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1997 }
1998
1999 static void vl_api_map_domain_details_t_handler
2000   (vl_api_map_domain_details_t * mp)
2001 {
2002   vat_main_t *vam = &vat_main;
2003
2004   if (mp->is_translation)
2005     {
2006       print (vam->ofp,
2007              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2008              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2009              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2010              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2011              clib_net_to_host_u32 (mp->domain_index));
2012     }
2013   else
2014     {
2015       print (vam->ofp,
2016              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2017              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2018              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2019              format_ip6_address, mp->ip6_src,
2020              clib_net_to_host_u32 (mp->domain_index));
2021     }
2022   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2023          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2024          mp->is_translation ? "map-t" : "");
2025 }
2026
2027 static void vl_api_map_rule_details_t_handler_json
2028   (vl_api_map_rule_details_t * mp)
2029 {
2030   struct in6_addr ip6;
2031   vat_json_node_t *node = NULL;
2032   vat_main_t *vam = &vat_main;
2033
2034   if (VAT_JSON_ARRAY != vam->json_tree.type)
2035     {
2036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2037       vat_json_init_array (&vam->json_tree);
2038     }
2039
2040   node = vat_json_array_add (&vam->json_tree);
2041   vat_json_init_object (node);
2042
2043   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2044   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2045   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2046 }
2047
2048 static void
2049 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2050 {
2051   vat_main_t *vam = &vat_main;
2052   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2053          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2054 }
2055
2056 static void
2057 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2058 {
2059   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2060           "router_addr %U host_mac %U",
2061           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2062           format_ip4_address, &mp->host_address,
2063           format_ip4_address, &mp->router_address,
2064           format_ethernet_address, mp->host_mac);
2065 }
2066
2067 static void vl_api_dhcp_compl_event_t_handler_json
2068   (vl_api_dhcp_compl_event_t * mp)
2069 {
2070   /* JSON output not supported */
2071 }
2072
2073 static void
2074 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2075                               u32 counter)
2076 {
2077   vat_main_t *vam = &vat_main;
2078   static u64 default_counter = 0;
2079
2080   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2081                            NULL);
2082   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2083                            sw_if_index, default_counter);
2084   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2085 }
2086
2087 static void
2088 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2089                                 interface_counter_t counter)
2090 {
2091   vat_main_t *vam = &vat_main;
2092   static interface_counter_t default_counter = { 0, };
2093
2094   vec_validate_init_empty (vam->combined_interface_counters,
2095                            vnet_counter_type, NULL);
2096   vec_validate_init_empty (vam->combined_interface_counters
2097                            [vnet_counter_type], sw_if_index, default_counter);
2098   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2099 }
2100
2101 static void vl_api_vnet_interface_counters_t_handler
2102   (vl_api_vnet_interface_counters_t * mp)
2103 {
2104   /* not supported */
2105 }
2106
2107 static void vl_api_vnet_interface_counters_t_handler_json
2108   (vl_api_vnet_interface_counters_t * mp)
2109 {
2110   interface_counter_t counter;
2111   vlib_counter_t *v;
2112   u64 *v_packets;
2113   u64 packets;
2114   u32 count;
2115   u32 first_sw_if_index;
2116   int i;
2117
2118   count = ntohl (mp->count);
2119   first_sw_if_index = ntohl (mp->first_sw_if_index);
2120
2121   if (!mp->is_combined)
2122     {
2123       v_packets = (u64 *) & mp->data;
2124       for (i = 0; i < count; i++)
2125         {
2126           packets =
2127             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2128           set_simple_interface_counter (mp->vnet_counter_type,
2129                                         first_sw_if_index + i, packets);
2130           v_packets++;
2131         }
2132     }
2133   else
2134     {
2135       v = (vlib_counter_t *) & mp->data;
2136       for (i = 0; i < count; i++)
2137         {
2138           counter.packets =
2139             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2140           counter.bytes =
2141             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2142           set_combined_interface_counter (mp->vnet_counter_type,
2143                                           first_sw_if_index + i, counter);
2144           v++;
2145         }
2146     }
2147 }
2148
2149 static u32
2150 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2151 {
2152   vat_main_t *vam = &vat_main;
2153   u32 i;
2154
2155   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2156     {
2157       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2158         {
2159           return i;
2160         }
2161     }
2162   return ~0;
2163 }
2164
2165 static u32
2166 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2167 {
2168   vat_main_t *vam = &vat_main;
2169   u32 i;
2170
2171   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2172     {
2173       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2174         {
2175           return i;
2176         }
2177     }
2178   return ~0;
2179 }
2180
2181 static void vl_api_vnet_ip4_fib_counters_t_handler
2182   (vl_api_vnet_ip4_fib_counters_t * mp)
2183 {
2184   /* not supported */
2185 }
2186
2187 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2188   (vl_api_vnet_ip4_fib_counters_t * mp)
2189 {
2190   vat_main_t *vam = &vat_main;
2191   vl_api_ip4_fib_counter_t *v;
2192   ip4_fib_counter_t *counter;
2193   struct in_addr ip4;
2194   u32 vrf_id;
2195   u32 vrf_index;
2196   u32 count;
2197   int i;
2198
2199   vrf_id = ntohl (mp->vrf_id);
2200   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2201   if (~0 == vrf_index)
2202     {
2203       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2204       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2205       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2206       vec_validate (vam->ip4_fib_counters, vrf_index);
2207       vam->ip4_fib_counters[vrf_index] = NULL;
2208     }
2209
2210   vec_free (vam->ip4_fib_counters[vrf_index]);
2211   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2212   count = ntohl (mp->count);
2213   for (i = 0; i < count; i++)
2214     {
2215       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2216       counter = &vam->ip4_fib_counters[vrf_index][i];
2217       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2218       counter->address = ip4;
2219       counter->address_length = v->address_length;
2220       counter->packets = clib_net_to_host_u64 (v->packets);
2221       counter->bytes = clib_net_to_host_u64 (v->bytes);
2222       v++;
2223     }
2224 }
2225
2226 static void vl_api_vnet_ip4_nbr_counters_t_handler
2227   (vl_api_vnet_ip4_nbr_counters_t * mp)
2228 {
2229   /* not supported */
2230 }
2231
2232 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2233   (vl_api_vnet_ip4_nbr_counters_t * mp)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   vl_api_ip4_nbr_counter_t *v;
2237   ip4_nbr_counter_t *counter;
2238   u32 sw_if_index;
2239   u32 count;
2240   int i;
2241
2242   sw_if_index = ntohl (mp->sw_if_index);
2243   count = ntohl (mp->count);
2244   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2245
2246   if (mp->begin)
2247     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2248
2249   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2250   for (i = 0; i < count; i++)
2251     {
2252       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2253       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2254       counter->address.s_addr = v->address;
2255       counter->packets = clib_net_to_host_u64 (v->packets);
2256       counter->bytes = clib_net_to_host_u64 (v->bytes);
2257       counter->linkt = v->link_type;
2258       v++;
2259     }
2260 }
2261
2262 static void vl_api_vnet_ip6_fib_counters_t_handler
2263   (vl_api_vnet_ip6_fib_counters_t * mp)
2264 {
2265   /* not supported */
2266 }
2267
2268 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2269   (vl_api_vnet_ip6_fib_counters_t * mp)
2270 {
2271   vat_main_t *vam = &vat_main;
2272   vl_api_ip6_fib_counter_t *v;
2273   ip6_fib_counter_t *counter;
2274   struct in6_addr ip6;
2275   u32 vrf_id;
2276   u32 vrf_index;
2277   u32 count;
2278   int i;
2279
2280   vrf_id = ntohl (mp->vrf_id);
2281   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2282   if (~0 == vrf_index)
2283     {
2284       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2285       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2286       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2287       vec_validate (vam->ip6_fib_counters, vrf_index);
2288       vam->ip6_fib_counters[vrf_index] = NULL;
2289     }
2290
2291   vec_free (vam->ip6_fib_counters[vrf_index]);
2292   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2293   count = ntohl (mp->count);
2294   for (i = 0; i < count; i++)
2295     {
2296       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2297       counter = &vam->ip6_fib_counters[vrf_index][i];
2298       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2299       counter->address = ip6;
2300       counter->address_length = v->address_length;
2301       counter->packets = clib_net_to_host_u64 (v->packets);
2302       counter->bytes = clib_net_to_host_u64 (v->bytes);
2303       v++;
2304     }
2305 }
2306
2307 static void vl_api_vnet_ip6_nbr_counters_t_handler
2308   (vl_api_vnet_ip6_nbr_counters_t * mp)
2309 {
2310   /* not supported */
2311 }
2312
2313 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2314   (vl_api_vnet_ip6_nbr_counters_t * mp)
2315 {
2316   vat_main_t *vam = &vat_main;
2317   vl_api_ip6_nbr_counter_t *v;
2318   ip6_nbr_counter_t *counter;
2319   struct in6_addr ip6;
2320   u32 sw_if_index;
2321   u32 count;
2322   int i;
2323
2324   sw_if_index = ntohl (mp->sw_if_index);
2325   count = ntohl (mp->count);
2326   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2327
2328   if (mp->begin)
2329     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2330
2331   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2332   for (i = 0; i < count; i++)
2333     {
2334       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2335       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2336       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2337       counter->address = ip6;
2338       counter->packets = clib_net_to_host_u64 (v->packets);
2339       counter->bytes = clib_net_to_host_u64 (v->bytes);
2340       v++;
2341     }
2342 }
2343
2344 static void vl_api_get_first_msg_id_reply_t_handler
2345   (vl_api_get_first_msg_id_reply_t * mp)
2346 {
2347   vat_main_t *vam = &vat_main;
2348   i32 retval = ntohl (mp->retval);
2349
2350   if (vam->async_mode)
2351     {
2352       vam->async_errors += (retval < 0);
2353     }
2354   else
2355     {
2356       vam->retval = retval;
2357       vam->result_ready = 1;
2358     }
2359   if (retval >= 0)
2360     {
2361       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2362     }
2363 }
2364
2365 static void vl_api_get_first_msg_id_reply_t_handler_json
2366   (vl_api_get_first_msg_id_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   vat_json_node_t node;
2370
2371   vat_json_init_object (&node);
2372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2373   vat_json_object_add_uint (&node, "first_msg_id",
2374                             (uint) ntohs (mp->first_msg_id));
2375
2376   vat_json_print (vam->ofp, &node);
2377   vat_json_free (&node);
2378
2379   vam->retval = ntohl (mp->retval);
2380   vam->result_ready = 1;
2381 }
2382
2383 static void vl_api_get_node_graph_reply_t_handler
2384   (vl_api_get_node_graph_reply_t * mp)
2385 {
2386   vat_main_t *vam = &vat_main;
2387   api_main_t *am = &api_main;
2388   i32 retval = ntohl (mp->retval);
2389   u8 *pvt_copy, *reply;
2390   void *oldheap;
2391   vlib_node_t *node;
2392   int i;
2393
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->result_ready = 1;
2402     }
2403
2404   /* "Should never happen..." */
2405   if (retval != 0)
2406     return;
2407
2408   reply = (u8 *) (mp->reply_in_shmem);
2409   pvt_copy = vec_dup (reply);
2410
2411   /* Toss the shared-memory original... */
2412   pthread_mutex_lock (&am->vlib_rp->mutex);
2413   oldheap = svm_push_data_heap (am->vlib_rp);
2414
2415   vec_free (reply);
2416
2417   svm_pop_heap (oldheap);
2418   pthread_mutex_unlock (&am->vlib_rp->mutex);
2419
2420   if (vam->graph_nodes)
2421     {
2422       hash_free (vam->graph_node_index_by_name);
2423
2424       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2425         {
2426           node = vam->graph_nodes[i];
2427           vec_free (node->name);
2428           vec_free (node->next_nodes);
2429           vec_free (node);
2430         }
2431       vec_free (vam->graph_nodes);
2432     }
2433
2434   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2435   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2436   vec_free (pvt_copy);
2437
2438   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2439     {
2440       node = vam->graph_nodes[i];
2441       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2442     }
2443 }
2444
2445 static void vl_api_get_node_graph_reply_t_handler_json
2446   (vl_api_get_node_graph_reply_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449   api_main_t *am = &api_main;
2450   void *oldheap;
2451   vat_json_node_t node;
2452   u8 *reply;
2453
2454   /* $$$$ make this real? */
2455   vat_json_init_object (&node);
2456   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2457   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2458
2459   reply = (u8 *) (mp->reply_in_shmem);
2460
2461   /* Toss the shared-memory original... */
2462   pthread_mutex_lock (&am->vlib_rp->mutex);
2463   oldheap = svm_push_data_heap (am->vlib_rp);
2464
2465   vec_free (reply);
2466
2467   svm_pop_heap (oldheap);
2468   pthread_mutex_unlock (&am->vlib_rp->mutex);
2469
2470   vat_json_print (vam->ofp, &node);
2471   vat_json_free (&node);
2472
2473   vam->retval = ntohl (mp->retval);
2474   vam->result_ready = 1;
2475 }
2476
2477 static void
2478 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   u8 *s = 0;
2482
2483   if (mp->local)
2484     {
2485       s = format (s, "%=16d%=16d%=16d",
2486                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2487     }
2488   else
2489     {
2490       s = format (s, "%=16U%=16d%=16d",
2491                   mp->is_ipv6 ? format_ip6_address :
2492                   format_ip4_address,
2493                   mp->ip_address, mp->priority, mp->weight);
2494     }
2495
2496   print (vam->ofp, "%v", s);
2497   vec_free (s);
2498 }
2499
2500 static void
2501 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   vat_json_node_t *node = NULL;
2505   struct in6_addr ip6;
2506   struct in_addr ip4;
2507
2508   if (VAT_JSON_ARRAY != vam->json_tree.type)
2509     {
2510       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2511       vat_json_init_array (&vam->json_tree);
2512     }
2513   node = vat_json_array_add (&vam->json_tree);
2514   vat_json_init_object (node);
2515
2516   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2517   vat_json_object_add_uint (node, "priority", mp->priority);
2518   vat_json_object_add_uint (node, "weight", mp->weight);
2519
2520   if (mp->local)
2521     vat_json_object_add_uint (node, "sw_if_index",
2522                               clib_net_to_host_u32 (mp->sw_if_index));
2523   else
2524     {
2525       if (mp->is_ipv6)
2526         {
2527           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2528           vat_json_object_add_ip6 (node, "address", ip6);
2529         }
2530       else
2531         {
2532           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2533           vat_json_object_add_ip4 (node, "address", ip4);
2534         }
2535     }
2536 }
2537
2538 static void
2539 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2540                                           mp)
2541 {
2542   vat_main_t *vam = &vat_main;
2543   u8 *ls_name = 0;
2544
2545   ls_name = format (0, "%s", mp->ls_name);
2546
2547   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2548          ls_name);
2549   vec_free (ls_name);
2550 }
2551
2552 static void
2553   vl_api_one_locator_set_details_t_handler_json
2554   (vl_api_one_locator_set_details_t * mp)
2555 {
2556   vat_main_t *vam = &vat_main;
2557   vat_json_node_t *node = 0;
2558   u8 *ls_name = 0;
2559
2560   ls_name = format (0, "%s", mp->ls_name);
2561   vec_add1 (ls_name, 0);
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2572   vat_json_object_add_uint (node, "ls_index",
2573                             clib_net_to_host_u32 (mp->ls_index));
2574   vec_free (ls_name);
2575 }
2576
2577 static u8 *
2578 format_lisp_flat_eid (u8 * s, va_list * args)
2579 {
2580   u32 type = va_arg (*args, u32);
2581   u8 *eid = va_arg (*args, u8 *);
2582   u32 eid_len = va_arg (*args, u32);
2583
2584   switch (type)
2585     {
2586     case 0:
2587       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2588     case 1:
2589       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2590     case 2:
2591       return format (s, "%U", format_ethernet_address, eid);
2592     }
2593   return 0;
2594 }
2595
2596 static u8 *
2597 format_lisp_eid_vat (u8 * s, va_list * args)
2598 {
2599   u32 type = va_arg (*args, u32);
2600   u8 *eid = va_arg (*args, u8 *);
2601   u32 eid_len = va_arg (*args, u32);
2602   u8 *seid = va_arg (*args, u8 *);
2603   u32 seid_len = va_arg (*args, u32);
2604   u32 is_src_dst = va_arg (*args, u32);
2605
2606   if (is_src_dst)
2607     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2608
2609   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2610
2611   return s;
2612 }
2613
2614 static void
2615 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618   u8 *s = 0, *eid = 0;
2619
2620   if (~0 == mp->locator_set_index)
2621     s = format (0, "action: %d", mp->action);
2622   else
2623     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2624
2625   eid = format (0, "%U", format_lisp_eid_vat,
2626                 mp->eid_type,
2627                 mp->eid,
2628                 mp->eid_prefix_len,
2629                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2630   vec_add1 (eid, 0);
2631
2632   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2633          clib_net_to_host_u32 (mp->vni),
2634          eid,
2635          mp->is_local ? "local" : "remote",
2636          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2637          clib_net_to_host_u16 (mp->key_id), mp->key);
2638
2639   vec_free (s);
2640   vec_free (eid);
2641 }
2642
2643 static void
2644 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2645                                              * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   vat_json_node_t *node = 0;
2649   u8 *eid = 0;
2650
2651   if (VAT_JSON_ARRAY != vam->json_tree.type)
2652     {
2653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2654       vat_json_init_array (&vam->json_tree);
2655     }
2656   node = vat_json_array_add (&vam->json_tree);
2657
2658   vat_json_init_object (node);
2659   if (~0 == mp->locator_set_index)
2660     vat_json_object_add_uint (node, "action", mp->action);
2661   else
2662     vat_json_object_add_uint (node, "locator_set_index",
2663                               clib_net_to_host_u32 (mp->locator_set_index));
2664
2665   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2666   eid = format (0, "%U", format_lisp_eid_vat,
2667                 mp->eid_type,
2668                 mp->eid,
2669                 mp->eid_prefix_len,
2670                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2671   vec_add1 (eid, 0);
2672   vat_json_object_add_string_copy (node, "eid", eid);
2673   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2674   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2675   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2676
2677   if (mp->key_id)
2678     {
2679       vat_json_object_add_uint (node, "key_id",
2680                                 clib_net_to_host_u16 (mp->key_id));
2681       vat_json_object_add_string_copy (node, "key", mp->key);
2682     }
2683   vec_free (eid);
2684 }
2685
2686 static void
2687 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   u8 *seid = 0, *deid = 0;
2691   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2692
2693   deid = format (0, "%U", format_lisp_eid_vat,
2694                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2695
2696   seid = format (0, "%U", format_lisp_eid_vat,
2697                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2698
2699   vec_add1 (deid, 0);
2700   vec_add1 (seid, 0);
2701
2702   if (mp->is_ip4)
2703     format_ip_address_fcn = format_ip4_address;
2704   else
2705     format_ip_address_fcn = format_ip6_address;
2706
2707
2708   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2709          clib_net_to_host_u32 (mp->vni),
2710          seid, deid,
2711          format_ip_address_fcn, mp->lloc,
2712          format_ip_address_fcn, mp->rloc,
2713          clib_net_to_host_u32 (mp->pkt_count),
2714          clib_net_to_host_u32 (mp->bytes));
2715
2716   vec_free (deid);
2717   vec_free (seid);
2718 }
2719
2720 static void
2721 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2722 {
2723   struct in6_addr ip6;
2724   struct in_addr ip4;
2725   vat_main_t *vam = &vat_main;
2726   vat_json_node_t *node = 0;
2727   u8 *deid = 0, *seid = 0;
2728
2729   if (VAT_JSON_ARRAY != vam->json_tree.type)
2730     {
2731       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2732       vat_json_init_array (&vam->json_tree);
2733     }
2734   node = vat_json_array_add (&vam->json_tree);
2735
2736   vat_json_init_object (node);
2737   deid = format (0, "%U", format_lisp_eid_vat,
2738                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2739
2740   seid = format (0, "%U", format_lisp_eid_vat,
2741                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2742
2743   vec_add1 (deid, 0);
2744   vec_add1 (seid, 0);
2745
2746   vat_json_object_add_string_copy (node, "seid", seid);
2747   vat_json_object_add_string_copy (node, "deid", deid);
2748   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2749
2750   if (mp->is_ip4)
2751     {
2752       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2753       vat_json_object_add_ip4 (node, "lloc", ip4);
2754       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2755       vat_json_object_add_ip4 (node, "rloc", ip4);
2756     }
2757   else
2758     {
2759       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2760       vat_json_object_add_ip6 (node, "lloc", ip6);
2761       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2762       vat_json_object_add_ip6 (node, "rloc", ip6);
2763     }
2764   vat_json_object_add_uint (node, "pkt_count",
2765                             clib_net_to_host_u32 (mp->pkt_count));
2766   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2767
2768   vec_free (deid);
2769   vec_free (seid);
2770 }
2771
2772 static void
2773   vl_api_one_eid_table_map_details_t_handler
2774   (vl_api_one_eid_table_map_details_t * mp)
2775 {
2776   vat_main_t *vam = &vat_main;
2777
2778   u8 *line = format (0, "%=10d%=10d",
2779                      clib_net_to_host_u32 (mp->vni),
2780                      clib_net_to_host_u32 (mp->dp_table));
2781   print (vam->ofp, "%v", line);
2782   vec_free (line);
2783 }
2784
2785 static void
2786   vl_api_one_eid_table_map_details_t_handler_json
2787   (vl_api_one_eid_table_map_details_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   vat_json_node_t *node = NULL;
2791
2792   if (VAT_JSON_ARRAY != vam->json_tree.type)
2793     {
2794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2795       vat_json_init_array (&vam->json_tree);
2796     }
2797   node = vat_json_array_add (&vam->json_tree);
2798   vat_json_init_object (node);
2799   vat_json_object_add_uint (node, "dp_table",
2800                             clib_net_to_host_u32 (mp->dp_table));
2801   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2802 }
2803
2804 static void
2805   vl_api_one_eid_table_vni_details_t_handler
2806   (vl_api_one_eid_table_vni_details_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809
2810   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2811   print (vam->ofp, "%v", line);
2812   vec_free (line);
2813 }
2814
2815 static void
2816   vl_api_one_eid_table_vni_details_t_handler_json
2817   (vl_api_one_eid_table_vni_details_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   vat_json_node_t *node = NULL;
2821
2822   if (VAT_JSON_ARRAY != vam->json_tree.type)
2823     {
2824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2825       vat_json_init_array (&vam->json_tree);
2826     }
2827   node = vat_json_array_add (&vam->json_tree);
2828   vat_json_init_object (node);
2829   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2830 }
2831
2832 static void
2833   vl_api_show_one_map_register_state_reply_t_handler
2834   (vl_api_show_one_map_register_state_reply_t * mp)
2835 {
2836   vat_main_t *vam = &vat_main;
2837   int retval = clib_net_to_host_u32 (mp->retval);
2838
2839   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2840
2841   vam->retval = retval;
2842   vam->result_ready = 1;
2843 }
2844
2845 static void
2846   vl_api_show_one_map_register_state_reply_t_handler_json
2847   (vl_api_show_one_map_register_state_reply_t * mp)
2848 {
2849   vat_main_t *vam = &vat_main;
2850   vat_json_node_t _node, *node = &_node;
2851   int retval = clib_net_to_host_u32 (mp->retval);
2852
2853   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2854
2855   vat_json_init_object (node);
2856   vat_json_object_add_string_copy (node, "state", s);
2857
2858   vat_json_print (vam->ofp, node);
2859   vat_json_free (node);
2860
2861   vam->retval = retval;
2862   vam->result_ready = 1;
2863   vec_free (s);
2864 }
2865
2866 static void
2867   vl_api_show_one_rloc_probe_state_reply_t_handler
2868   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2869 {
2870   vat_main_t *vam = &vat_main;
2871   int retval = clib_net_to_host_u32 (mp->retval);
2872
2873   if (retval)
2874     goto end;
2875
2876   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2877 end:
2878   vam->retval = retval;
2879   vam->result_ready = 1;
2880 }
2881
2882 static void
2883   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2884   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2885 {
2886   vat_main_t *vam = &vat_main;
2887   vat_json_node_t _node, *node = &_node;
2888   int retval = clib_net_to_host_u32 (mp->retval);
2889
2890   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2891   vat_json_init_object (node);
2892   vat_json_object_add_string_copy (node, "state", s);
2893
2894   vat_json_print (vam->ofp, node);
2895   vat_json_free (node);
2896
2897   vam->retval = retval;
2898   vam->result_ready = 1;
2899   vec_free (s);
2900 }
2901
2902 static void
2903   vl_api_show_one_stats_enable_disable_reply_t_handler
2904   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2905 {
2906   vat_main_t *vam = &vat_main;
2907   int retval = clib_net_to_host_u32 (mp->retval);
2908
2909   if (retval)
2910     goto end;
2911
2912   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2913 end:
2914   vam->retval = retval;
2915   vam->result_ready = 1;
2916 }
2917
2918 static void
2919   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2920   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2921 {
2922   vat_main_t *vam = &vat_main;
2923   vat_json_node_t _node, *node = &_node;
2924   int retval = clib_net_to_host_u32 (mp->retval);
2925
2926   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2927   vat_json_init_object (node);
2928   vat_json_object_add_string_copy (node, "state", s);
2929
2930   vat_json_print (vam->ofp, node);
2931   vat_json_free (node);
2932
2933   vam->retval = retval;
2934   vam->result_ready = 1;
2935   vec_free (s);
2936 }
2937
2938 static void
2939 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2940 {
2941   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2942   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2943 }
2944
2945 static void
2946   gpe_fwd_entries_get_reply_t_net_to_host
2947   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2948 {
2949   u32 i;
2950
2951   mp->count = clib_net_to_host_u32 (mp->count);
2952   for (i = 0; i < mp->count; i++)
2953     {
2954       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2955     }
2956 }
2957
2958 static u8 *
2959 format_gpe_encap_mode (u8 * s, va_list * args)
2960 {
2961   u32 mode = va_arg (*args, u32);
2962
2963   switch (mode)
2964     {
2965     case 0:
2966       return format (s, "lisp");
2967     case 1:
2968       return format (s, "vxlan");
2969     }
2970   return 0;
2971 }
2972
2973 static void
2974   vl_api_gpe_get_encap_mode_reply_t_handler
2975   (vl_api_gpe_get_encap_mode_reply_t * mp)
2976 {
2977   vat_main_t *vam = &vat_main;
2978
2979   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2980   vam->retval = ntohl (mp->retval);
2981   vam->result_ready = 1;
2982 }
2983
2984 static void
2985   vl_api_gpe_get_encap_mode_reply_t_handler_json
2986   (vl_api_gpe_get_encap_mode_reply_t * mp)
2987 {
2988   vat_main_t *vam = &vat_main;
2989   vat_json_node_t node;
2990
2991   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2992   vec_add1 (encap_mode, 0);
2993
2994   vat_json_init_object (&node);
2995   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2996
2997   vec_free (encap_mode);
2998   vat_json_print (vam->ofp, &node);
2999   vat_json_free (&node);
3000
3001   vam->retval = ntohl (mp->retval);
3002   vam->result_ready = 1;
3003 }
3004
3005 static void
3006   vl_api_gpe_fwd_entry_path_details_t_handler
3007   (vl_api_gpe_fwd_entry_path_details_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3011
3012   if (mp->lcl_loc.is_ip4)
3013     format_ip_address_fcn = format_ip4_address;
3014   else
3015     format_ip_address_fcn = format_ip6_address;
3016
3017   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3018          format_ip_address_fcn, &mp->lcl_loc,
3019          format_ip_address_fcn, &mp->rmt_loc);
3020 }
3021
3022 static void
3023 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3024 {
3025   struct in6_addr ip6;
3026   struct in_addr ip4;
3027
3028   if (loc->is_ip4)
3029     {
3030       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3031       vat_json_object_add_ip4 (n, "address", ip4);
3032     }
3033   else
3034     {
3035       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3036       vat_json_object_add_ip6 (n, "address", ip6);
3037     }
3038   vat_json_object_add_uint (n, "weight", loc->weight);
3039 }
3040
3041 static void
3042   vl_api_gpe_fwd_entry_path_details_t_handler_json
3043   (vl_api_gpe_fwd_entry_path_details_t * mp)
3044 {
3045   vat_main_t *vam = &vat_main;
3046   vat_json_node_t *node = NULL;
3047   vat_json_node_t *loc_node;
3048
3049   if (VAT_JSON_ARRAY != vam->json_tree.type)
3050     {
3051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3052       vat_json_init_array (&vam->json_tree);
3053     }
3054   node = vat_json_array_add (&vam->json_tree);
3055   vat_json_init_object (node);
3056
3057   loc_node = vat_json_object_add (node, "local_locator");
3058   vat_json_init_object (loc_node);
3059   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3060
3061   loc_node = vat_json_object_add (node, "remote_locator");
3062   vat_json_init_object (loc_node);
3063   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3064 }
3065
3066 static void
3067   vl_api_gpe_fwd_entries_get_reply_t_handler
3068   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3069 {
3070   vat_main_t *vam = &vat_main;
3071   u32 i;
3072   int retval = clib_net_to_host_u32 (mp->retval);
3073   vl_api_gpe_fwd_entry_t *e;
3074
3075   if (retval)
3076     goto end;
3077
3078   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3079
3080   for (i = 0; i < mp->count; i++)
3081     {
3082       e = &mp->entries[i];
3083       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3084              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3085              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3086     }
3087
3088 end:
3089   vam->retval = retval;
3090   vam->result_ready = 1;
3091 }
3092
3093 static void
3094   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3095   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3096 {
3097   u8 *s = 0;
3098   vat_main_t *vam = &vat_main;
3099   vat_json_node_t *e = 0, root;
3100   u32 i;
3101   int retval = clib_net_to_host_u32 (mp->retval);
3102   vl_api_gpe_fwd_entry_t *fwd;
3103
3104   if (retval)
3105     goto end;
3106
3107   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3108   vat_json_init_array (&root);
3109
3110   for (i = 0; i < mp->count; i++)
3111     {
3112       e = vat_json_array_add (&root);
3113       fwd = &mp->entries[i];
3114
3115       vat_json_init_object (e);
3116       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3117       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3118
3119       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3120                   fwd->leid_prefix_len);
3121       vec_add1 (s, 0);
3122       vat_json_object_add_string_copy (e, "leid", s);
3123       vec_free (s);
3124
3125       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3126                   fwd->reid_prefix_len);
3127       vec_add1 (s, 0);
3128       vat_json_object_add_string_copy (e, "reid", s);
3129       vec_free (s);
3130     }
3131
3132   vat_json_print (vam->ofp, &root);
3133   vat_json_free (&root);
3134
3135 end:
3136   vam->retval = retval;
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_one_adjacencies_get_reply_t_handler
3142   (vl_api_one_adjacencies_get_reply_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   u32 i, n;
3146   int retval = clib_net_to_host_u32 (mp->retval);
3147   vl_api_one_adjacency_t *a;
3148
3149   if (retval)
3150     goto end;
3151
3152   n = clib_net_to_host_u32 (mp->count);
3153
3154   for (i = 0; i < n; i++)
3155     {
3156       a = &mp->adjacencies[i];
3157       print (vam->ofp, "%U %40U",
3158              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3159              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3160     }
3161
3162 end:
3163   vam->retval = retval;
3164   vam->result_ready = 1;
3165 }
3166
3167 static void
3168   vl_api_one_adjacencies_get_reply_t_handler_json
3169   (vl_api_one_adjacencies_get_reply_t * mp)
3170 {
3171   u8 *s = 0;
3172   vat_main_t *vam = &vat_main;
3173   vat_json_node_t *e = 0, root;
3174   u32 i, n;
3175   int retval = clib_net_to_host_u32 (mp->retval);
3176   vl_api_one_adjacency_t *a;
3177
3178   if (retval)
3179     goto end;
3180
3181   n = clib_net_to_host_u32 (mp->count);
3182   vat_json_init_array (&root);
3183
3184   for (i = 0; i < n; i++)
3185     {
3186       e = vat_json_array_add (&root);
3187       a = &mp->adjacencies[i];
3188
3189       vat_json_init_object (e);
3190       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3191                   a->leid_prefix_len);
3192       vec_add1 (s, 0);
3193       vat_json_object_add_string_copy (e, "leid", s);
3194       vec_free (s);
3195
3196       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3197                   a->reid_prefix_len);
3198       vec_add1 (s, 0);
3199       vat_json_object_add_string_copy (e, "reid", s);
3200       vec_free (s);
3201     }
3202
3203   vat_json_print (vam->ofp, &root);
3204   vat_json_free (&root);
3205
3206 end:
3207   vam->retval = retval;
3208   vam->result_ready = 1;
3209 }
3210
3211 static void
3212 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3213 {
3214   vat_main_t *vam = &vat_main;
3215
3216   print (vam->ofp, "%=20U",
3217          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3218          mp->ip_address);
3219 }
3220
3221 static void
3222   vl_api_one_map_server_details_t_handler_json
3223   (vl_api_one_map_server_details_t * mp)
3224 {
3225   vat_main_t *vam = &vat_main;
3226   vat_json_node_t *node = NULL;
3227   struct in6_addr ip6;
3228   struct in_addr ip4;
3229
3230   if (VAT_JSON_ARRAY != vam->json_tree.type)
3231     {
3232       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3233       vat_json_init_array (&vam->json_tree);
3234     }
3235   node = vat_json_array_add (&vam->json_tree);
3236
3237   vat_json_init_object (node);
3238   if (mp->is_ipv6)
3239     {
3240       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3241       vat_json_object_add_ip6 (node, "map-server", ip6);
3242     }
3243   else
3244     {
3245       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3246       vat_json_object_add_ip4 (node, "map-server", ip4);
3247     }
3248 }
3249
3250 static void
3251 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3252                                            * mp)
3253 {
3254   vat_main_t *vam = &vat_main;
3255
3256   print (vam->ofp, "%=20U",
3257          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3258          mp->ip_address);
3259 }
3260
3261 static void
3262   vl_api_one_map_resolver_details_t_handler_json
3263   (vl_api_one_map_resolver_details_t * mp)
3264 {
3265   vat_main_t *vam = &vat_main;
3266   vat_json_node_t *node = NULL;
3267   struct in6_addr ip6;
3268   struct in_addr ip4;
3269
3270   if (VAT_JSON_ARRAY != vam->json_tree.type)
3271     {
3272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3273       vat_json_init_array (&vam->json_tree);
3274     }
3275   node = vat_json_array_add (&vam->json_tree);
3276
3277   vat_json_init_object (node);
3278   if (mp->is_ipv6)
3279     {
3280       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3281       vat_json_object_add_ip6 (node, "map resolver", ip6);
3282     }
3283   else
3284     {
3285       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3286       vat_json_object_add_ip4 (node, "map resolver", ip4);
3287     }
3288 }
3289
3290 static void
3291 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3292 {
3293   vat_main_t *vam = &vat_main;
3294   i32 retval = ntohl (mp->retval);
3295
3296   if (0 <= retval)
3297     {
3298       print (vam->ofp, "feature: %s\ngpe: %s",
3299              mp->feature_status ? "enabled" : "disabled",
3300              mp->gpe_status ? "enabled" : "disabled");
3301     }
3302
3303   vam->retval = retval;
3304   vam->result_ready = 1;
3305 }
3306
3307 static void
3308   vl_api_show_one_status_reply_t_handler_json
3309   (vl_api_show_one_status_reply_t * mp)
3310 {
3311   vat_main_t *vam = &vat_main;
3312   vat_json_node_t node;
3313   u8 *gpe_status = NULL;
3314   u8 *feature_status = NULL;
3315
3316   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3317   feature_status = format (0, "%s",
3318                            mp->feature_status ? "enabled" : "disabled");
3319   vec_add1 (gpe_status, 0);
3320   vec_add1 (feature_status, 0);
3321
3322   vat_json_init_object (&node);
3323   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3324   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3325
3326   vec_free (gpe_status);
3327   vec_free (feature_status);
3328
3329   vat_json_print (vam->ofp, &node);
3330   vat_json_free (&node);
3331
3332   vam->retval = ntohl (mp->retval);
3333   vam->result_ready = 1;
3334 }
3335
3336 static void
3337   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3338   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341   i32 retval = ntohl (mp->retval);
3342
3343   if (retval >= 0)
3344     {
3345       print (vam->ofp, "%=20s", mp->locator_set_name);
3346     }
3347
3348   vam->retval = retval;
3349   vam->result_ready = 1;
3350 }
3351
3352 static void
3353   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3354   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3355 {
3356   vat_main_t *vam = &vat_main;
3357   vat_json_node_t *node = NULL;
3358
3359   if (VAT_JSON_ARRAY != vam->json_tree.type)
3360     {
3361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3362       vat_json_init_array (&vam->json_tree);
3363     }
3364   node = vat_json_array_add (&vam->json_tree);
3365
3366   vat_json_init_object (node);
3367   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3368
3369   vat_json_print (vam->ofp, node);
3370   vat_json_free (node);
3371
3372   vam->retval = ntohl (mp->retval);
3373   vam->result_ready = 1;
3374 }
3375
3376 static u8 *
3377 format_lisp_map_request_mode (u8 * s, va_list * args)
3378 {
3379   u32 mode = va_arg (*args, u32);
3380
3381   switch (mode)
3382     {
3383     case 0:
3384       return format (0, "dst-only");
3385     case 1:
3386       return format (0, "src-dst");
3387     }
3388   return 0;
3389 }
3390
3391 static void
3392   vl_api_show_one_map_request_mode_reply_t_handler
3393   (vl_api_show_one_map_request_mode_reply_t * mp)
3394 {
3395   vat_main_t *vam = &vat_main;
3396   i32 retval = ntohl (mp->retval);
3397
3398   if (0 <= retval)
3399     {
3400       u32 mode = mp->mode;
3401       print (vam->ofp, "map_request_mode: %U",
3402              format_lisp_map_request_mode, mode);
3403     }
3404
3405   vam->retval = retval;
3406   vam->result_ready = 1;
3407 }
3408
3409 static void
3410   vl_api_show_one_map_request_mode_reply_t_handler_json
3411   (vl_api_show_one_map_request_mode_reply_t * mp)
3412 {
3413   vat_main_t *vam = &vat_main;
3414   vat_json_node_t node;
3415   u8 *s = 0;
3416   u32 mode;
3417
3418   mode = mp->mode;
3419   s = format (0, "%U", format_lisp_map_request_mode, mode);
3420   vec_add1 (s, 0);
3421
3422   vat_json_init_object (&node);
3423   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3424   vat_json_print (vam->ofp, &node);
3425   vat_json_free (&node);
3426
3427   vec_free (s);
3428   vam->retval = ntohl (mp->retval);
3429   vam->result_ready = 1;
3430 }
3431
3432 static void
3433   vl_api_show_one_use_petr_reply_t_handler
3434   (vl_api_show_one_use_petr_reply_t * mp)
3435 {
3436   vat_main_t *vam = &vat_main;
3437   i32 retval = ntohl (mp->retval);
3438
3439   if (0 <= retval)
3440     {
3441       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3442       if (mp->status)
3443         {
3444           print (vam->ofp, "Proxy-ETR address; %U",
3445                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3446                  mp->address);
3447         }
3448     }
3449
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_use_petr_reply_t_handler_json
3456   (vl_api_show_one_use_petr_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t node;
3460   u8 *status = 0;
3461   struct in_addr ip4;
3462   struct in6_addr ip6;
3463
3464   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3465   vec_add1 (status, 0);
3466
3467   vat_json_init_object (&node);
3468   vat_json_object_add_string_copy (&node, "status", status);
3469   if (mp->status)
3470     {
3471       if (mp->is_ip4)
3472         {
3473           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3474           vat_json_object_add_ip6 (&node, "address", ip6);
3475         }
3476       else
3477         {
3478           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3479           vat_json_object_add_ip4 (&node, "address", ip4);
3480         }
3481     }
3482
3483   vec_free (status);
3484
3485   vat_json_print (vam->ofp, &node);
3486   vat_json_free (&node);
3487
3488   vam->retval = ntohl (mp->retval);
3489   vam->result_ready = 1;
3490 }
3491
3492 static void
3493 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3494 {
3495   vat_main_t *vam = &vat_main;
3496   i32 retval = ntohl (mp->retval);
3497
3498   if (0 <= retval)
3499     {
3500       print (vam->ofp, "%-20s%-16s",
3501              mp->status ? "enabled" : "disabled",
3502              mp->status ? (char *) mp->locator_set_name : "");
3503     }
3504
3505   vam->retval = retval;
3506   vam->result_ready = 1;
3507 }
3508
3509 static void
3510 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3511 {
3512   vat_main_t *vam = &vat_main;
3513   vat_json_node_t node;
3514   u8 *status = 0;
3515
3516   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3517   vec_add1 (status, 0);
3518
3519   vat_json_init_object (&node);
3520   vat_json_object_add_string_copy (&node, "status", status);
3521   if (mp->status)
3522     {
3523       vat_json_object_add_string_copy (&node, "locator_set",
3524                                        mp->locator_set_name);
3525     }
3526
3527   vec_free (status);
3528
3529   vat_json_print (vam->ofp, &node);
3530   vat_json_free (&node);
3531
3532   vam->retval = ntohl (mp->retval);
3533   vam->result_ready = 1;
3534 }
3535
3536 static u8 *
3537 format_policer_type (u8 * s, va_list * va)
3538 {
3539   u32 i = va_arg (*va, u32);
3540
3541   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3542     s = format (s, "1r2c");
3543   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3544     s = format (s, "1r3c");
3545   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3546     s = format (s, "2r3c-2698");
3547   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3548     s = format (s, "2r3c-4115");
3549   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3550     s = format (s, "2r3c-mef5cf1");
3551   else
3552     s = format (s, "ILLEGAL");
3553   return s;
3554 }
3555
3556 static u8 *
3557 format_policer_rate_type (u8 * s, va_list * va)
3558 {
3559   u32 i = va_arg (*va, u32);
3560
3561   if (i == SSE2_QOS_RATE_KBPS)
3562     s = format (s, "kbps");
3563   else if (i == SSE2_QOS_RATE_PPS)
3564     s = format (s, "pps");
3565   else
3566     s = format (s, "ILLEGAL");
3567   return s;
3568 }
3569
3570 static u8 *
3571 format_policer_round_type (u8 * s, va_list * va)
3572 {
3573   u32 i = va_arg (*va, u32);
3574
3575   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3576     s = format (s, "closest");
3577   else if (i == SSE2_QOS_ROUND_TO_UP)
3578     s = format (s, "up");
3579   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3580     s = format (s, "down");
3581   else
3582     s = format (s, "ILLEGAL");
3583   return s;
3584 }
3585
3586 static u8 *
3587 format_policer_action_type (u8 * s, va_list * va)
3588 {
3589   u32 i = va_arg (*va, u32);
3590
3591   if (i == SSE2_QOS_ACTION_DROP)
3592     s = format (s, "drop");
3593   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3594     s = format (s, "transmit");
3595   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3596     s = format (s, "mark-and-transmit");
3597   else
3598     s = format (s, "ILLEGAL");
3599   return s;
3600 }
3601
3602 static u8 *
3603 format_dscp (u8 * s, va_list * va)
3604 {
3605   u32 i = va_arg (*va, u32);
3606   char *t = 0;
3607
3608   switch (i)
3609     {
3610 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3611       foreach_vnet_dscp
3612 #undef _
3613     default:
3614       return format (s, "ILLEGAL");
3615     }
3616   s = format (s, "%s", t);
3617   return s;
3618 }
3619
3620 static void
3621 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3625
3626   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3627     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3628   else
3629     conform_dscp_str = format (0, "");
3630
3631   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3632     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3633   else
3634     exceed_dscp_str = format (0, "");
3635
3636   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3637     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3638   else
3639     violate_dscp_str = format (0, "");
3640
3641   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3642          "rate type %U, round type %U, %s rate, %s color-aware, "
3643          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3644          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3645          "conform action %U%s, exceed action %U%s, violate action %U%s",
3646          mp->name,
3647          format_policer_type, mp->type,
3648          ntohl (mp->cir),
3649          ntohl (mp->eir),
3650          clib_net_to_host_u64 (mp->cb),
3651          clib_net_to_host_u64 (mp->eb),
3652          format_policer_rate_type, mp->rate_type,
3653          format_policer_round_type, mp->round_type,
3654          mp->single_rate ? "single" : "dual",
3655          mp->color_aware ? "is" : "not",
3656          ntohl (mp->cir_tokens_per_period),
3657          ntohl (mp->pir_tokens_per_period),
3658          ntohl (mp->scale),
3659          ntohl (mp->current_limit),
3660          ntohl (mp->current_bucket),
3661          ntohl (mp->extended_limit),
3662          ntohl (mp->extended_bucket),
3663          clib_net_to_host_u64 (mp->last_update_time),
3664          format_policer_action_type, mp->conform_action_type,
3665          conform_dscp_str,
3666          format_policer_action_type, mp->exceed_action_type,
3667          exceed_dscp_str,
3668          format_policer_action_type, mp->violate_action_type,
3669          violate_dscp_str);
3670
3671   vec_free (conform_dscp_str);
3672   vec_free (exceed_dscp_str);
3673   vec_free (violate_dscp_str);
3674 }
3675
3676 static void vl_api_policer_details_t_handler_json
3677   (vl_api_policer_details_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680   vat_json_node_t *node;
3681   u8 *rate_type_str, *round_type_str, *type_str;
3682   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3683
3684   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3685   round_type_str =
3686     format (0, "%U", format_policer_round_type, mp->round_type);
3687   type_str = format (0, "%U", format_policer_type, mp->type);
3688   conform_action_str = format (0, "%U", format_policer_action_type,
3689                                mp->conform_action_type);
3690   exceed_action_str = format (0, "%U", format_policer_action_type,
3691                               mp->exceed_action_type);
3692   violate_action_str = format (0, "%U", format_policer_action_type,
3693                                mp->violate_action_type);
3694
3695   if (VAT_JSON_ARRAY != vam->json_tree.type)
3696     {
3697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3698       vat_json_init_array (&vam->json_tree);
3699     }
3700   node = vat_json_array_add (&vam->json_tree);
3701
3702   vat_json_init_object (node);
3703   vat_json_object_add_string_copy (node, "name", mp->name);
3704   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3705   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3706   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3707   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3708   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3709   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3710   vat_json_object_add_string_copy (node, "type", type_str);
3711   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3712   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3713   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3714   vat_json_object_add_uint (node, "cir_tokens_per_period",
3715                             ntohl (mp->cir_tokens_per_period));
3716   vat_json_object_add_uint (node, "eir_tokens_per_period",
3717                             ntohl (mp->pir_tokens_per_period));
3718   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3719   vat_json_object_add_uint (node, "current_bucket",
3720                             ntohl (mp->current_bucket));
3721   vat_json_object_add_uint (node, "extended_limit",
3722                             ntohl (mp->extended_limit));
3723   vat_json_object_add_uint (node, "extended_bucket",
3724                             ntohl (mp->extended_bucket));
3725   vat_json_object_add_uint (node, "last_update_time",
3726                             ntohl (mp->last_update_time));
3727   vat_json_object_add_string_copy (node, "conform_action",
3728                                    conform_action_str);
3729   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3730     {
3731       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3732       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3733       vec_free (dscp_str);
3734     }
3735   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3736   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3737     {
3738       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3739       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3740       vec_free (dscp_str);
3741     }
3742   vat_json_object_add_string_copy (node, "violate_action",
3743                                    violate_action_str);
3744   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3745     {
3746       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3747       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3748       vec_free (dscp_str);
3749     }
3750
3751   vec_free (rate_type_str);
3752   vec_free (round_type_str);
3753   vec_free (type_str);
3754   vec_free (conform_action_str);
3755   vec_free (exceed_action_str);
3756   vec_free (violate_action_str);
3757 }
3758
3759 static void
3760 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3761                                            mp)
3762 {
3763   vat_main_t *vam = &vat_main;
3764   int i, count = ntohl (mp->count);
3765
3766   if (count > 0)
3767     print (vam->ofp, "classify table ids (%d) : ", count);
3768   for (i = 0; i < count; i++)
3769     {
3770       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3771       print (vam->ofp, (i < count - 1) ? "," : "");
3772     }
3773   vam->retval = ntohl (mp->retval);
3774   vam->result_ready = 1;
3775 }
3776
3777 static void
3778   vl_api_classify_table_ids_reply_t_handler_json
3779   (vl_api_classify_table_ids_reply_t * mp)
3780 {
3781   vat_main_t *vam = &vat_main;
3782   int i, count = ntohl (mp->count);
3783
3784   if (count > 0)
3785     {
3786       vat_json_node_t node;
3787
3788       vat_json_init_object (&node);
3789       for (i = 0; i < count; i++)
3790         {
3791           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3792         }
3793       vat_json_print (vam->ofp, &node);
3794       vat_json_free (&node);
3795     }
3796   vam->retval = ntohl (mp->retval);
3797   vam->result_ready = 1;
3798 }
3799
3800 static void
3801   vl_api_classify_table_by_interface_reply_t_handler
3802   (vl_api_classify_table_by_interface_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 table_id;
3806
3807   table_id = ntohl (mp->l2_table_id);
3808   if (table_id != ~0)
3809     print (vam->ofp, "l2 table id : %d", table_id);
3810   else
3811     print (vam->ofp, "l2 table id : No input ACL tables configured");
3812   table_id = ntohl (mp->ip4_table_id);
3813   if (table_id != ~0)
3814     print (vam->ofp, "ip4 table id : %d", table_id);
3815   else
3816     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3817   table_id = ntohl (mp->ip6_table_id);
3818   if (table_id != ~0)
3819     print (vam->ofp, "ip6 table id : %d", table_id);
3820   else
3821     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3822   vam->retval = ntohl (mp->retval);
3823   vam->result_ready = 1;
3824 }
3825
3826 static void
3827   vl_api_classify_table_by_interface_reply_t_handler_json
3828   (vl_api_classify_table_by_interface_reply_t * mp)
3829 {
3830   vat_main_t *vam = &vat_main;
3831   vat_json_node_t node;
3832
3833   vat_json_init_object (&node);
3834
3835   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3836   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3837   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3838
3839   vat_json_print (vam->ofp, &node);
3840   vat_json_free (&node);
3841
3842   vam->retval = ntohl (mp->retval);
3843   vam->result_ready = 1;
3844 }
3845
3846 static void vl_api_policer_add_del_reply_t_handler
3847   (vl_api_policer_add_del_reply_t * mp)
3848 {
3849   vat_main_t *vam = &vat_main;
3850   i32 retval = ntohl (mp->retval);
3851   if (vam->async_mode)
3852     {
3853       vam->async_errors += (retval < 0);
3854     }
3855   else
3856     {
3857       vam->retval = retval;
3858       vam->result_ready = 1;
3859       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3860         /*
3861          * Note: this is just barely thread-safe, depends on
3862          * the main thread spinning waiting for an answer...
3863          */
3864         errmsg ("policer index %d", ntohl (mp->policer_index));
3865     }
3866 }
3867
3868 static void vl_api_policer_add_del_reply_t_handler_json
3869   (vl_api_policer_add_del_reply_t * mp)
3870 {
3871   vat_main_t *vam = &vat_main;
3872   vat_json_node_t node;
3873
3874   vat_json_init_object (&node);
3875   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3876   vat_json_object_add_uint (&node, "policer_index",
3877                             ntohl (mp->policer_index));
3878
3879   vat_json_print (vam->ofp, &node);
3880   vat_json_free (&node);
3881
3882   vam->retval = ntohl (mp->retval);
3883   vam->result_ready = 1;
3884 }
3885
3886 /* Format hex dump. */
3887 u8 *
3888 format_hex_bytes (u8 * s, va_list * va)
3889 {
3890   u8 *bytes = va_arg (*va, u8 *);
3891   int n_bytes = va_arg (*va, int);
3892   uword i;
3893
3894   /* Print short or long form depending on byte count. */
3895   uword short_form = n_bytes <= 32;
3896   uword indent = format_get_indent (s);
3897
3898   if (n_bytes == 0)
3899     return s;
3900
3901   for (i = 0; i < n_bytes; i++)
3902     {
3903       if (!short_form && (i % 32) == 0)
3904         s = format (s, "%08x: ", i);
3905       s = format (s, "%02x", bytes[i]);
3906       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3907         s = format (s, "\n%U", format_white_space, indent);
3908     }
3909
3910   return s;
3911 }
3912
3913 static void
3914 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3915                                             * mp)
3916 {
3917   vat_main_t *vam = &vat_main;
3918   i32 retval = ntohl (mp->retval);
3919   if (retval == 0)
3920     {
3921       print (vam->ofp, "classify table info :");
3922       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3923              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3924              ntohl (mp->miss_next_index));
3925       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3926              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3927              ntohl (mp->match_n_vectors));
3928       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3929              ntohl (mp->mask_length));
3930     }
3931   vam->retval = retval;
3932   vam->result_ready = 1;
3933 }
3934
3935 static void
3936   vl_api_classify_table_info_reply_t_handler_json
3937   (vl_api_classify_table_info_reply_t * mp)
3938 {
3939   vat_main_t *vam = &vat_main;
3940   vat_json_node_t node;
3941
3942   i32 retval = ntohl (mp->retval);
3943   if (retval == 0)
3944     {
3945       vat_json_init_object (&node);
3946
3947       vat_json_object_add_int (&node, "sessions",
3948                                ntohl (mp->active_sessions));
3949       vat_json_object_add_int (&node, "nexttbl",
3950                                ntohl (mp->next_table_index));
3951       vat_json_object_add_int (&node, "nextnode",
3952                                ntohl (mp->miss_next_index));
3953       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3954       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3955       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3956       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3957                       ntohl (mp->mask_length), 0);
3958       vat_json_object_add_string_copy (&node, "mask", s);
3959
3960       vat_json_print (vam->ofp, &node);
3961       vat_json_free (&node);
3962     }
3963   vam->retval = ntohl (mp->retval);
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3969                                            mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972
3973   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3974          ntohl (mp->hit_next_index), ntohl (mp->advance),
3975          ntohl (mp->opaque_index));
3976   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3977          ntohl (mp->match_length));
3978 }
3979
3980 static void
3981   vl_api_classify_session_details_t_handler_json
3982   (vl_api_classify_session_details_t * mp)
3983 {
3984   vat_main_t *vam = &vat_main;
3985   vat_json_node_t *node = NULL;
3986
3987   if (VAT_JSON_ARRAY != vam->json_tree.type)
3988     {
3989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3990       vat_json_init_array (&vam->json_tree);
3991     }
3992   node = vat_json_array_add (&vam->json_tree);
3993
3994   vat_json_init_object (node);
3995   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3996   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3997   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3998   u8 *s =
3999     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4000             0);
4001   vat_json_object_add_string_copy (node, "match", s);
4002 }
4003
4004 static void vl_api_pg_create_interface_reply_t_handler
4005   (vl_api_pg_create_interface_reply_t * mp)
4006 {
4007   vat_main_t *vam = &vat_main;
4008
4009   vam->retval = ntohl (mp->retval);
4010   vam->result_ready = 1;
4011 }
4012
4013 static void vl_api_pg_create_interface_reply_t_handler_json
4014   (vl_api_pg_create_interface_reply_t * mp)
4015 {
4016   vat_main_t *vam = &vat_main;
4017   vat_json_node_t node;
4018
4019   i32 retval = ntohl (mp->retval);
4020   if (retval == 0)
4021     {
4022       vat_json_init_object (&node);
4023
4024       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4025
4026       vat_json_print (vam->ofp, &node);
4027       vat_json_free (&node);
4028     }
4029   vam->retval = ntohl (mp->retval);
4030   vam->result_ready = 1;
4031 }
4032
4033 static void vl_api_policer_classify_details_t_handler
4034   (vl_api_policer_classify_details_t * mp)
4035 {
4036   vat_main_t *vam = &vat_main;
4037
4038   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4039          ntohl (mp->table_index));
4040 }
4041
4042 static void vl_api_policer_classify_details_t_handler_json
4043   (vl_api_policer_classify_details_t * mp)
4044 {
4045   vat_main_t *vam = &vat_main;
4046   vat_json_node_t *node;
4047
4048   if (VAT_JSON_ARRAY != vam->json_tree.type)
4049     {
4050       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4051       vat_json_init_array (&vam->json_tree);
4052     }
4053   node = vat_json_array_add (&vam->json_tree);
4054
4055   vat_json_init_object (node);
4056   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4057   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4058 }
4059
4060 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4061   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064   i32 retval = ntohl (mp->retval);
4065   if (vam->async_mode)
4066     {
4067       vam->async_errors += (retval < 0);
4068     }
4069   else
4070     {
4071       vam->retval = retval;
4072       vam->sw_if_index = ntohl (mp->sw_if_index);
4073       vam->result_ready = 1;
4074     }
4075 }
4076
4077 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4078   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081   vat_json_node_t node;
4082
4083   vat_json_init_object (&node);
4084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4085   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4086
4087   vat_json_print (vam->ofp, &node);
4088   vat_json_free (&node);
4089
4090   vam->retval = ntohl (mp->retval);
4091   vam->result_ready = 1;
4092 }
4093
4094 static void vl_api_flow_classify_details_t_handler
4095   (vl_api_flow_classify_details_t * mp)
4096 {
4097   vat_main_t *vam = &vat_main;
4098
4099   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4100          ntohl (mp->table_index));
4101 }
4102
4103 static void vl_api_flow_classify_details_t_handler_json
4104   (vl_api_flow_classify_details_t * mp)
4105 {
4106   vat_main_t *vam = &vat_main;
4107   vat_json_node_t *node;
4108
4109   if (VAT_JSON_ARRAY != vam->json_tree.type)
4110     {
4111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4112       vat_json_init_array (&vam->json_tree);
4113     }
4114   node = vat_json_array_add (&vam->json_tree);
4115
4116   vat_json_init_object (node);
4117   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4118   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4119 }
4120
4121
4122
4123 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4124 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4125 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4126 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4127 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4128 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4129 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4130 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4131 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4132 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4133
4134 /*
4135  * Generate boilerplate reply handlers, which
4136  * dig the return value out of the xxx_reply_t API message,
4137  * stick it into vam->retval, and set vam->result_ready
4138  *
4139  * Could also do this by pointing N message decode slots at
4140  * a single function, but that could break in subtle ways.
4141  */
4142
4143 #define foreach_standard_reply_retval_handler           \
4144 _(sw_interface_set_flags_reply)                         \
4145 _(sw_interface_add_del_address_reply)                   \
4146 _(sw_interface_set_table_reply)                         \
4147 _(sw_interface_set_mpls_enable_reply)                   \
4148 _(sw_interface_set_vpath_reply)                         \
4149 _(sw_interface_set_vxlan_bypass_reply)                  \
4150 _(sw_interface_set_l2_bridge_reply)                     \
4151 _(bridge_domain_add_del_reply)                          \
4152 _(sw_interface_set_l2_xconnect_reply)                   \
4153 _(l2fib_add_del_reply)                                  \
4154 _(ip_add_del_route_reply)                               \
4155 _(ip_mroute_add_del_reply)                              \
4156 _(mpls_route_add_del_reply)                             \
4157 _(mpls_ip_bind_unbind_reply)                            \
4158 _(proxy_arp_add_del_reply)                              \
4159 _(proxy_arp_intfc_enable_disable_reply)                 \
4160 _(sw_interface_set_unnumbered_reply)                    \
4161 _(ip_neighbor_add_del_reply)                            \
4162 _(reset_vrf_reply)                                      \
4163 _(oam_add_del_reply)                                    \
4164 _(reset_fib_reply)                                      \
4165 _(dhcp_proxy_config_reply)                              \
4166 _(dhcp_proxy_set_vss_reply)                             \
4167 _(dhcp_client_config_reply)                             \
4168 _(set_ip_flow_hash_reply)                               \
4169 _(sw_interface_ip6_enable_disable_reply)                \
4170 _(sw_interface_ip6_set_link_local_address_reply)        \
4171 _(ip6nd_proxy_add_del_reply)                            \
4172 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4173 _(sw_interface_ip6nd_ra_config_reply)                   \
4174 _(set_arp_neighbor_limit_reply)                         \
4175 _(l2_patch_add_del_reply)                               \
4176 _(sr_policy_add_reply)                                  \
4177 _(sr_policy_mod_reply)                                  \
4178 _(sr_policy_del_reply)                                  \
4179 _(sr_localsid_add_del_reply)                            \
4180 _(sr_steering_add_del_reply)                            \
4181 _(classify_add_del_session_reply)                       \
4182 _(classify_set_interface_ip_table_reply)                \
4183 _(classify_set_interface_l2_tables_reply)               \
4184 _(l2tpv3_set_tunnel_cookies_reply)                      \
4185 _(l2tpv3_interface_enable_disable_reply)                \
4186 _(l2tpv3_set_lookup_key_reply)                          \
4187 _(l2_fib_clear_table_reply)                             \
4188 _(l2_interface_efp_filter_reply)                        \
4189 _(l2_interface_vlan_tag_rewrite_reply)                  \
4190 _(modify_vhost_user_if_reply)                           \
4191 _(delete_vhost_user_if_reply)                           \
4192 _(want_ip4_arp_events_reply)                            \
4193 _(want_ip6_nd_events_reply)                             \
4194 _(input_acl_set_interface_reply)                        \
4195 _(ipsec_spd_add_del_reply)                              \
4196 _(ipsec_interface_add_del_spd_reply)                    \
4197 _(ipsec_spd_add_del_entry_reply)                        \
4198 _(ipsec_sad_add_del_entry_reply)                        \
4199 _(ipsec_sa_set_key_reply)                               \
4200 _(ikev2_profile_add_del_reply)                          \
4201 _(ikev2_profile_set_auth_reply)                         \
4202 _(ikev2_profile_set_id_reply)                           \
4203 _(ikev2_profile_set_ts_reply)                           \
4204 _(ikev2_set_local_key_reply)                            \
4205 _(ikev2_set_responder_reply)                            \
4206 _(ikev2_set_ike_transforms_reply)                       \
4207 _(ikev2_set_esp_transforms_reply)                       \
4208 _(ikev2_set_sa_lifetime_reply)                          \
4209 _(ikev2_initiate_sa_init_reply)                         \
4210 _(ikev2_initiate_del_ike_sa_reply)                      \
4211 _(ikev2_initiate_del_child_sa_reply)                    \
4212 _(ikev2_initiate_rekey_child_sa_reply)                  \
4213 _(delete_loopback_reply)                                \
4214 _(bd_ip_mac_add_del_reply)                              \
4215 _(map_del_domain_reply)                                 \
4216 _(map_add_del_rule_reply)                               \
4217 _(want_interface_events_reply)                          \
4218 _(want_stats_reply)                                     \
4219 _(cop_interface_enable_disable_reply)                   \
4220 _(cop_whitelist_enable_disable_reply)                   \
4221 _(sw_interface_clear_stats_reply)                       \
4222 _(ioam_enable_reply)                              \
4223 _(ioam_disable_reply)                              \
4224 _(one_add_del_locator_reply)                            \
4225 _(one_add_del_local_eid_reply)                          \
4226 _(one_add_del_remote_mapping_reply)                     \
4227 _(one_add_del_adjacency_reply)                          \
4228 _(one_add_del_map_resolver_reply)                       \
4229 _(one_add_del_map_server_reply)                         \
4230 _(one_enable_disable_reply)                             \
4231 _(one_rloc_probe_enable_disable_reply)                  \
4232 _(one_map_register_enable_disable_reply)                \
4233 _(one_pitr_set_locator_set_reply)                       \
4234 _(one_map_request_mode_reply)                           \
4235 _(one_add_del_map_request_itr_rlocs_reply)              \
4236 _(one_eid_table_add_del_map_reply)                      \
4237 _(one_use_petr_reply)                                   \
4238 _(one_stats_enable_disable_reply)                       \
4239 _(gpe_add_del_fwd_entry_reply)                          \
4240 _(gpe_enable_disable_reply)                             \
4241 _(gpe_set_encap_mode_reply)                             \
4242 _(gpe_add_del_iface_reply)                              \
4243 _(vxlan_gpe_add_del_tunnel_reply)                       \
4244 _(af_packet_delete_reply)                               \
4245 _(policer_classify_set_interface_reply)                 \
4246 _(netmap_create_reply)                                  \
4247 _(netmap_delete_reply)                                  \
4248 _(set_ipfix_exporter_reply)                             \
4249 _(set_ipfix_classify_stream_reply)                      \
4250 _(ipfix_classify_table_add_del_reply)                   \
4251 _(flow_classify_set_interface_reply)                    \
4252 _(sw_interface_span_enable_disable_reply)               \
4253 _(pg_capture_reply)                                     \
4254 _(pg_enable_disable_reply)                              \
4255 _(ip_source_and_port_range_check_add_del_reply)         \
4256 _(ip_source_and_port_range_check_interface_add_del_reply)\
4257 _(delete_subif_reply)                                   \
4258 _(l2_interface_pbb_tag_rewrite_reply)                   \
4259 _(punt_reply)                                           \
4260 _(feature_enable_disable_reply)                         \
4261 _(sw_interface_tag_add_del_reply)                       \
4262 _(sw_interface_set_mtu_reply)
4263
4264 #define _(n)                                    \
4265     static void vl_api_##n##_t_handler          \
4266     (vl_api_##n##_t * mp)                       \
4267     {                                           \
4268         vat_main_t * vam = &vat_main;           \
4269         i32 retval = ntohl(mp->retval);         \
4270         if (vam->async_mode) {                  \
4271             vam->async_errors += (retval < 0);  \
4272         } else {                                \
4273             vam->retval = retval;               \
4274             vam->result_ready = 1;              \
4275         }                                       \
4276     }
4277 foreach_standard_reply_retval_handler;
4278 #undef _
4279
4280 #define _(n)                                    \
4281     static void vl_api_##n##_t_handler_json     \
4282     (vl_api_##n##_t * mp)                       \
4283     {                                           \
4284         vat_main_t * vam = &vat_main;           \
4285         vat_json_node_t node;                   \
4286         vat_json_init_object(&node);            \
4287         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4288         vat_json_print(vam->ofp, &node);        \
4289         vam->retval = ntohl(mp->retval);        \
4290         vam->result_ready = 1;                  \
4291     }
4292 foreach_standard_reply_retval_handler;
4293 #undef _
4294
4295 /*
4296  * Table of message reply handlers, must include boilerplate handlers
4297  * we just generated
4298  */
4299
4300 #define foreach_vpe_api_reply_msg                                       \
4301 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4302 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4303 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4304 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4305 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4306 _(CLI_REPLY, cli_reply)                                                 \
4307 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4308 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4309   sw_interface_add_del_address_reply)                                   \
4310 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4311 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4312 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4313 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4314 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4315   sw_interface_set_l2_xconnect_reply)                                   \
4316 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4317   sw_interface_set_l2_bridge_reply)                                     \
4318 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4319 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4320 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4321 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4322 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4323 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4324 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4325 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4326 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4327 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4328 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4329 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4330 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4331 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4332 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4333 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4334 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4335   proxy_arp_intfc_enable_disable_reply)                                 \
4336 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4337 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4338   sw_interface_set_unnumbered_reply)                                    \
4339 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4340 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4341 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4342 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4343 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4344 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4345 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4346 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4347 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4348 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4349 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4350 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4351   sw_interface_ip6_enable_disable_reply)                                \
4352 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4353   sw_interface_ip6_set_link_local_address_reply)                        \
4354 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4355 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4356 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4357   sw_interface_ip6nd_ra_prefix_reply)                                   \
4358 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4359   sw_interface_ip6nd_ra_config_reply)                                   \
4360 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4361 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4362 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4363 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4364 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4365 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4366 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4367 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4368 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4369 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4370 classify_set_interface_ip_table_reply)                                  \
4371 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4372   classify_set_interface_l2_tables_reply)                               \
4373 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4374 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4375 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4376 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4377 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4378   l2tpv3_interface_enable_disable_reply)                                \
4379 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4380 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4381 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4382 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4383 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4384 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4385 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4386 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4387 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4388 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4389 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4390 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4391 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4392 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4393 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4394 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4395 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4396 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4397 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4398 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4399 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4400 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4401 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4402 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4403 _(IP_DETAILS, ip_details)                                               \
4404 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4405 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4406 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4407 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4408 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4409 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4410 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4411 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4412 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4413 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4414 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4415 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4416 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4417 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4418 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4419 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4420 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4421 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4422 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4423 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4424 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4425 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4426 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4427 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4428 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4429 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4430 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4431 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4432 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4433 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4434 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4435 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4436 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4437 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4438 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4439 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4440 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4441 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4442 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4443 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4444 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4445 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4446 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4447 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4448   one_map_register_enable_disable_reply)                                \
4449 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4450   one_rloc_probe_enable_disable_reply)                                  \
4451 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4452 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4453 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4454 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4455 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4456 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4457 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4458 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4459 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4460 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4461 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4462 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4463 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4464 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4465 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4466   show_one_stats_enable_disable_reply)                                  \
4467 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4468 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4469 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4470 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4471 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4472 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4473 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4474   gpe_fwd_entry_path_details)                                           \
4475 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4476 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4477   one_add_del_map_request_itr_rlocs_reply)                              \
4478 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4479   one_get_map_request_itr_rlocs_reply)                                  \
4480 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4481 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4482 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4483 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4484 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4485   show_one_map_register_state_reply)                                    \
4486 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4487 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4488 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4489 _(POLICER_DETAILS, policer_details)                                     \
4490 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4491 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4492 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4493 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4494 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4495 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4496 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4497 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4498 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4499 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4500 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4501 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4502 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4503 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4504 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4505 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4506 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4507 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4508 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4509 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4510 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4511 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4512 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4513 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4514 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4515  ip_source_and_port_range_check_add_del_reply)                          \
4516 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4517  ip_source_and_port_range_check_interface_add_del_reply)                \
4518 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4519 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4520 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4521 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4522 _(PUNT_REPLY, punt_reply)                                               \
4523 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4524 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4525 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4526 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4527 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4528 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4529 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4530 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4531
4532 #define foreach_standalone_reply_msg                                    \
4533 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4534 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4535 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4536 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4537 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4538 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4539
4540 typedef struct
4541 {
4542   u8 *name;
4543   u32 value;
4544 } name_sort_t;
4545
4546
4547 #define STR_VTR_OP_CASE(op)     \
4548     case L2_VTR_ ## op:         \
4549         return "" # op;
4550
4551 static const char *
4552 str_vtr_op (u32 vtr_op)
4553 {
4554   switch (vtr_op)
4555     {
4556       STR_VTR_OP_CASE (DISABLED);
4557       STR_VTR_OP_CASE (PUSH_1);
4558       STR_VTR_OP_CASE (PUSH_2);
4559       STR_VTR_OP_CASE (POP_1);
4560       STR_VTR_OP_CASE (POP_2);
4561       STR_VTR_OP_CASE (TRANSLATE_1_1);
4562       STR_VTR_OP_CASE (TRANSLATE_1_2);
4563       STR_VTR_OP_CASE (TRANSLATE_2_1);
4564       STR_VTR_OP_CASE (TRANSLATE_2_2);
4565     }
4566
4567   return "UNKNOWN";
4568 }
4569
4570 static int
4571 dump_sub_interface_table (vat_main_t * vam)
4572 {
4573   const sw_interface_subif_t *sub = NULL;
4574
4575   if (vam->json_output)
4576     {
4577       clib_warning
4578         ("JSON output supported only for VPE API calls and dump_stats_table");
4579       return -99;
4580     }
4581
4582   print (vam->ofp,
4583          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4584          "Interface", "sw_if_index",
4585          "sub id", "dot1ad", "tags", "outer id",
4586          "inner id", "exact", "default", "outer any", "inner any");
4587
4588   vec_foreach (sub, vam->sw_if_subif_table)
4589   {
4590     print (vam->ofp,
4591            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4592            sub->interface_name,
4593            sub->sw_if_index,
4594            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4595            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4596            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4597            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4598     if (sub->vtr_op != L2_VTR_DISABLED)
4599       {
4600         print (vam->ofp,
4601                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4602                "tag1: %d tag2: %d ]",
4603                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4604                sub->vtr_tag1, sub->vtr_tag2);
4605       }
4606   }
4607
4608   return 0;
4609 }
4610
4611 static int
4612 name_sort_cmp (void *a1, void *a2)
4613 {
4614   name_sort_t *n1 = a1;
4615   name_sort_t *n2 = a2;
4616
4617   return strcmp ((char *) n1->name, (char *) n2->name);
4618 }
4619
4620 static int
4621 dump_interface_table (vat_main_t * vam)
4622 {
4623   hash_pair_t *p;
4624   name_sort_t *nses = 0, *ns;
4625
4626   if (vam->json_output)
4627     {
4628       clib_warning
4629         ("JSON output supported only for VPE API calls and dump_stats_table");
4630       return -99;
4631     }
4632
4633   /* *INDENT-OFF* */
4634   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4635   ({
4636     vec_add2 (nses, ns, 1);
4637     ns->name = (u8 *)(p->key);
4638     ns->value = (u32) p->value[0];
4639   }));
4640   /* *INDENT-ON* */
4641
4642   vec_sort_with_function (nses, name_sort_cmp);
4643
4644   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4645   vec_foreach (ns, nses)
4646   {
4647     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4648   }
4649   vec_free (nses);
4650   return 0;
4651 }
4652
4653 static int
4654 dump_ip_table (vat_main_t * vam, int is_ipv6)
4655 {
4656   const ip_details_t *det = NULL;
4657   const ip_address_details_t *address = NULL;
4658   u32 i = ~0;
4659
4660   print (vam->ofp, "%-12s", "sw_if_index");
4661
4662   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4663   {
4664     i++;
4665     if (!det->present)
4666       {
4667         continue;
4668       }
4669     print (vam->ofp, "%-12d", i);
4670     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4671     if (!det->addr)
4672       {
4673         continue;
4674       }
4675     vec_foreach (address, det->addr)
4676     {
4677       print (vam->ofp,
4678              "            %-30U%-13d",
4679              is_ipv6 ? format_ip6_address : format_ip4_address,
4680              address->ip, address->prefix_length);
4681     }
4682   }
4683
4684   return 0;
4685 }
4686
4687 static int
4688 dump_ipv4_table (vat_main_t * vam)
4689 {
4690   if (vam->json_output)
4691     {
4692       clib_warning
4693         ("JSON output supported only for VPE API calls and dump_stats_table");
4694       return -99;
4695     }
4696
4697   return dump_ip_table (vam, 0);
4698 }
4699
4700 static int
4701 dump_ipv6_table (vat_main_t * vam)
4702 {
4703   if (vam->json_output)
4704     {
4705       clib_warning
4706         ("JSON output supported only for VPE API calls and dump_stats_table");
4707       return -99;
4708     }
4709
4710   return dump_ip_table (vam, 1);
4711 }
4712
4713 static char *
4714 counter_type_to_str (u8 counter_type, u8 is_combined)
4715 {
4716   if (!is_combined)
4717     {
4718       switch (counter_type)
4719         {
4720         case VNET_INTERFACE_COUNTER_DROP:
4721           return "drop";
4722         case VNET_INTERFACE_COUNTER_PUNT:
4723           return "punt";
4724         case VNET_INTERFACE_COUNTER_IP4:
4725           return "ip4";
4726         case VNET_INTERFACE_COUNTER_IP6:
4727           return "ip6";
4728         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4729           return "rx-no-buf";
4730         case VNET_INTERFACE_COUNTER_RX_MISS:
4731           return "rx-miss";
4732         case VNET_INTERFACE_COUNTER_RX_ERROR:
4733           return "rx-error";
4734         case VNET_INTERFACE_COUNTER_TX_ERROR:
4735           return "tx-error";
4736         default:
4737           return "INVALID-COUNTER-TYPE";
4738         }
4739     }
4740   else
4741     {
4742       switch (counter_type)
4743         {
4744         case VNET_INTERFACE_COUNTER_RX:
4745           return "rx";
4746         case VNET_INTERFACE_COUNTER_TX:
4747           return "tx";
4748         default:
4749           return "INVALID-COUNTER-TYPE";
4750         }
4751     }
4752 }
4753
4754 static int
4755 dump_stats_table (vat_main_t * vam)
4756 {
4757   vat_json_node_t node;
4758   vat_json_node_t *msg_array;
4759   vat_json_node_t *msg;
4760   vat_json_node_t *counter_array;
4761   vat_json_node_t *counter;
4762   interface_counter_t c;
4763   u64 packets;
4764   ip4_fib_counter_t *c4;
4765   ip6_fib_counter_t *c6;
4766   ip4_nbr_counter_t *n4;
4767   ip6_nbr_counter_t *n6;
4768   int i, j;
4769
4770   if (!vam->json_output)
4771     {
4772       clib_warning ("dump_stats_table supported only in JSON format");
4773       return -99;
4774     }
4775
4776   vat_json_init_object (&node);
4777
4778   /* interface counters */
4779   msg_array = vat_json_object_add (&node, "interface_counters");
4780   vat_json_init_array (msg_array);
4781   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4782     {
4783       msg = vat_json_array_add (msg_array);
4784       vat_json_init_object (msg);
4785       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4786                                        (u8 *) counter_type_to_str (i, 0));
4787       vat_json_object_add_int (msg, "is_combined", 0);
4788       counter_array = vat_json_object_add (msg, "data");
4789       vat_json_init_array (counter_array);
4790       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4791         {
4792           packets = vam->simple_interface_counters[i][j];
4793           vat_json_array_add_uint (counter_array, packets);
4794         }
4795     }
4796   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4797     {
4798       msg = vat_json_array_add (msg_array);
4799       vat_json_init_object (msg);
4800       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4801                                        (u8 *) counter_type_to_str (i, 1));
4802       vat_json_object_add_int (msg, "is_combined", 1);
4803       counter_array = vat_json_object_add (msg, "data");
4804       vat_json_init_array (counter_array);
4805       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4806         {
4807           c = vam->combined_interface_counters[i][j];
4808           counter = vat_json_array_add (counter_array);
4809           vat_json_init_object (counter);
4810           vat_json_object_add_uint (counter, "packets", c.packets);
4811           vat_json_object_add_uint (counter, "bytes", c.bytes);
4812         }
4813     }
4814
4815   /* ip4 fib counters */
4816   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4817   vat_json_init_array (msg_array);
4818   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4819     {
4820       msg = vat_json_array_add (msg_array);
4821       vat_json_init_object (msg);
4822       vat_json_object_add_uint (msg, "vrf_id",
4823                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4824       counter_array = vat_json_object_add (msg, "c");
4825       vat_json_init_array (counter_array);
4826       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4827         {
4828           counter = vat_json_array_add (counter_array);
4829           vat_json_init_object (counter);
4830           c4 = &vam->ip4_fib_counters[i][j];
4831           vat_json_object_add_ip4 (counter, "address", c4->address);
4832           vat_json_object_add_uint (counter, "address_length",
4833                                     c4->address_length);
4834           vat_json_object_add_uint (counter, "packets", c4->packets);
4835           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4836         }
4837     }
4838
4839   /* ip6 fib counters */
4840   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4841   vat_json_init_array (msg_array);
4842   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4843     {
4844       msg = vat_json_array_add (msg_array);
4845       vat_json_init_object (msg);
4846       vat_json_object_add_uint (msg, "vrf_id",
4847                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4848       counter_array = vat_json_object_add (msg, "c");
4849       vat_json_init_array (counter_array);
4850       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4851         {
4852           counter = vat_json_array_add (counter_array);
4853           vat_json_init_object (counter);
4854           c6 = &vam->ip6_fib_counters[i][j];
4855           vat_json_object_add_ip6 (counter, "address", c6->address);
4856           vat_json_object_add_uint (counter, "address_length",
4857                                     c6->address_length);
4858           vat_json_object_add_uint (counter, "packets", c6->packets);
4859           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4860         }
4861     }
4862
4863   /* ip4 nbr counters */
4864   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4865   vat_json_init_array (msg_array);
4866   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4867     {
4868       msg = vat_json_array_add (msg_array);
4869       vat_json_init_object (msg);
4870       vat_json_object_add_uint (msg, "sw_if_index", i);
4871       counter_array = vat_json_object_add (msg, "c");
4872       vat_json_init_array (counter_array);
4873       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4874         {
4875           counter = vat_json_array_add (counter_array);
4876           vat_json_init_object (counter);
4877           n4 = &vam->ip4_nbr_counters[i][j];
4878           vat_json_object_add_ip4 (counter, "address", n4->address);
4879           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4880           vat_json_object_add_uint (counter, "packets", n4->packets);
4881           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4882         }
4883     }
4884
4885   /* ip6 nbr counters */
4886   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4887   vat_json_init_array (msg_array);
4888   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4889     {
4890       msg = vat_json_array_add (msg_array);
4891       vat_json_init_object (msg);
4892       vat_json_object_add_uint (msg, "sw_if_index", i);
4893       counter_array = vat_json_object_add (msg, "c");
4894       vat_json_init_array (counter_array);
4895       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4896         {
4897           counter = vat_json_array_add (counter_array);
4898           vat_json_init_object (counter);
4899           n6 = &vam->ip6_nbr_counters[i][j];
4900           vat_json_object_add_ip6 (counter, "address", n6->address);
4901           vat_json_object_add_uint (counter, "packets", n6->packets);
4902           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4903         }
4904     }
4905
4906   vat_json_print (vam->ofp, &node);
4907   vat_json_free (&node);
4908
4909   return 0;
4910 }
4911
4912 int
4913 exec (vat_main_t * vam)
4914 {
4915   api_main_t *am = &api_main;
4916   vl_api_cli_request_t *mp;
4917   f64 timeout;
4918   void *oldheap;
4919   u8 *cmd = 0;
4920   unformat_input_t *i = vam->input;
4921
4922   if (vec_len (i->buffer) == 0)
4923     return -1;
4924
4925   if (vam->exec_mode == 0 && unformat (i, "mode"))
4926     {
4927       vam->exec_mode = 1;
4928       return 0;
4929     }
4930   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4931     {
4932       vam->exec_mode = 0;
4933       return 0;
4934     }
4935
4936
4937   M (CLI_REQUEST, mp);
4938
4939   /*
4940    * Copy cmd into shared memory.
4941    * In order for the CLI command to work, it
4942    * must be a vector ending in \n, not a C-string ending
4943    * in \n\0.
4944    */
4945   pthread_mutex_lock (&am->vlib_rp->mutex);
4946   oldheap = svm_push_data_heap (am->vlib_rp);
4947
4948   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4949   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4950
4951   svm_pop_heap (oldheap);
4952   pthread_mutex_unlock (&am->vlib_rp->mutex);
4953
4954   mp->cmd_in_shmem = (u64) cmd;
4955   S (mp);
4956   timeout = vat_time_now (vam) + 10.0;
4957
4958   while (vat_time_now (vam) < timeout)
4959     {
4960       if (vam->result_ready == 1)
4961         {
4962           u8 *free_me;
4963           if (vam->shmem_result != NULL)
4964             print (vam->ofp, "%s", vam->shmem_result);
4965           pthread_mutex_lock (&am->vlib_rp->mutex);
4966           oldheap = svm_push_data_heap (am->vlib_rp);
4967
4968           free_me = (u8 *) vam->shmem_result;
4969           vec_free (free_me);
4970
4971           svm_pop_heap (oldheap);
4972           pthread_mutex_unlock (&am->vlib_rp->mutex);
4973           return 0;
4974         }
4975     }
4976   return -99;
4977 }
4978
4979 /*
4980  * Future replacement of exec() that passes CLI buffers directly in
4981  * the API messages instead of an additional shared memory area.
4982  */
4983 static int
4984 exec_inband (vat_main_t * vam)
4985 {
4986   vl_api_cli_inband_t *mp;
4987   unformat_input_t *i = vam->input;
4988   int ret;
4989
4990   if (vec_len (i->buffer) == 0)
4991     return -1;
4992
4993   if (vam->exec_mode == 0 && unformat (i, "mode"))
4994     {
4995       vam->exec_mode = 1;
4996       return 0;
4997     }
4998   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4999     {
5000       vam->exec_mode = 0;
5001       return 0;
5002     }
5003
5004   /*
5005    * In order for the CLI command to work, it
5006    * must be a vector ending in \n, not a C-string ending
5007    * in \n\0.
5008    */
5009   u32 len = vec_len (vam->input->buffer);
5010   M2 (CLI_INBAND, mp, len);
5011   clib_memcpy (mp->cmd, vam->input->buffer, len);
5012   mp->length = htonl (len);
5013
5014   S (mp);
5015   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5016   return ret;
5017 }
5018
5019 static int
5020 api_create_loopback (vat_main_t * vam)
5021 {
5022   unformat_input_t *i = vam->input;
5023   vl_api_create_loopback_t *mp;
5024   vl_api_create_loopback_instance_t *mp_lbi;
5025   u8 mac_address[6];
5026   u8 mac_set = 0;
5027   u8 is_specified = 0;
5028   u32 user_instance = 0;
5029   int ret;
5030
5031   memset (mac_address, 0, sizeof (mac_address));
5032
5033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5034     {
5035       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5036         mac_set = 1;
5037       if (unformat (i, "instance %d", &user_instance))
5038         is_specified = 1;
5039       else
5040         break;
5041     }
5042
5043   if (is_specified)
5044     {
5045       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5046       mp_lbi->is_specified = is_specified;
5047       if (is_specified)
5048         mp_lbi->user_instance = htonl (user_instance);
5049       if (mac_set)
5050         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5051       S (mp_lbi);
5052     }
5053   else
5054     {
5055       /* Construct the API message */
5056       M (CREATE_LOOPBACK, mp);
5057       if (mac_set)
5058         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5059       S (mp);
5060     }
5061
5062   W (ret);
5063   return ret;
5064 }
5065
5066 static int
5067 api_delete_loopback (vat_main_t * vam)
5068 {
5069   unformat_input_t *i = vam->input;
5070   vl_api_delete_loopback_t *mp;
5071   u32 sw_if_index = ~0;
5072   int ret;
5073
5074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5075     {
5076       if (unformat (i, "sw_if_index %d", &sw_if_index))
5077         ;
5078       else
5079         break;
5080     }
5081
5082   if (sw_if_index == ~0)
5083     {
5084       errmsg ("missing sw_if_index");
5085       return -99;
5086     }
5087
5088   /* Construct the API message */
5089   M (DELETE_LOOPBACK, mp);
5090   mp->sw_if_index = ntohl (sw_if_index);
5091
5092   S (mp);
5093   W (ret);
5094   return ret;
5095 }
5096
5097 static int
5098 api_want_stats (vat_main_t * vam)
5099 {
5100   unformat_input_t *i = vam->input;
5101   vl_api_want_stats_t *mp;
5102   int enable = -1;
5103   int ret;
5104
5105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5106     {
5107       if (unformat (i, "enable"))
5108         enable = 1;
5109       else if (unformat (i, "disable"))
5110         enable = 0;
5111       else
5112         break;
5113     }
5114
5115   if (enable == -1)
5116     {
5117       errmsg ("missing enable|disable");
5118       return -99;
5119     }
5120
5121   M (WANT_STATS, mp);
5122   mp->enable_disable = enable;
5123
5124   S (mp);
5125   W (ret);
5126   return ret;
5127 }
5128
5129 static int
5130 api_want_interface_events (vat_main_t * vam)
5131 {
5132   unformat_input_t *i = vam->input;
5133   vl_api_want_interface_events_t *mp;
5134   int enable = -1;
5135   int ret;
5136
5137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5138     {
5139       if (unformat (i, "enable"))
5140         enable = 1;
5141       else if (unformat (i, "disable"))
5142         enable = 0;
5143       else
5144         break;
5145     }
5146
5147   if (enable == -1)
5148     {
5149       errmsg ("missing enable|disable");
5150       return -99;
5151     }
5152
5153   M (WANT_INTERFACE_EVENTS, mp);
5154   mp->enable_disable = enable;
5155
5156   vam->interface_event_display = enable;
5157
5158   S (mp);
5159   W (ret);
5160   return ret;
5161 }
5162
5163
5164 /* Note: non-static, called once to set up the initial intfc table */
5165 int
5166 api_sw_interface_dump (vat_main_t * vam)
5167 {
5168   vl_api_sw_interface_dump_t *mp;
5169   vl_api_control_ping_t *mp_ping;
5170   hash_pair_t *p;
5171   name_sort_t *nses = 0, *ns;
5172   sw_interface_subif_t *sub = NULL;
5173   int ret;
5174
5175   /* Toss the old name table */
5176   /* *INDENT-OFF* */
5177   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5178   ({
5179     vec_add2 (nses, ns, 1);
5180     ns->name = (u8 *)(p->key);
5181     ns->value = (u32) p->value[0];
5182   }));
5183   /* *INDENT-ON* */
5184
5185   hash_free (vam->sw_if_index_by_interface_name);
5186
5187   vec_foreach (ns, nses) vec_free (ns->name);
5188
5189   vec_free (nses);
5190
5191   vec_foreach (sub, vam->sw_if_subif_table)
5192   {
5193     vec_free (sub->interface_name);
5194   }
5195   vec_free (vam->sw_if_subif_table);
5196
5197   /* recreate the interface name hash table */
5198   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5199
5200   /* Get list of ethernets */
5201   M (SW_INTERFACE_DUMP, mp);
5202   mp->name_filter_valid = 1;
5203   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5204   S (mp);
5205
5206   /* and local / loopback interfaces */
5207   M (SW_INTERFACE_DUMP, mp);
5208   mp->name_filter_valid = 1;
5209   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5210   S (mp);
5211
5212   /* and packet-generator interfaces */
5213   M (SW_INTERFACE_DUMP, mp);
5214   mp->name_filter_valid = 1;
5215   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5216   S (mp);
5217
5218   /* and vxlan-gpe tunnel interfaces */
5219   M (SW_INTERFACE_DUMP, mp);
5220   mp->name_filter_valid = 1;
5221   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5222            sizeof (mp->name_filter) - 1);
5223   S (mp);
5224
5225   /* and vxlan tunnel interfaces */
5226   M (SW_INTERFACE_DUMP, mp);
5227   mp->name_filter_valid = 1;
5228   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5229   S (mp);
5230
5231   /* and host (af_packet) interfaces */
5232   M (SW_INTERFACE_DUMP, mp);
5233   mp->name_filter_valid = 1;
5234   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5235   S (mp);
5236
5237   /* and l2tpv3 tunnel interfaces */
5238   M (SW_INTERFACE_DUMP, mp);
5239   mp->name_filter_valid = 1;
5240   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5241            sizeof (mp->name_filter) - 1);
5242   S (mp);
5243
5244   /* and GRE tunnel interfaces */
5245   M (SW_INTERFACE_DUMP, mp);
5246   mp->name_filter_valid = 1;
5247   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5248   S (mp);
5249
5250   /* and LISP-GPE interfaces */
5251   M (SW_INTERFACE_DUMP, mp);
5252   mp->name_filter_valid = 1;
5253   strncpy ((char *) mp->name_filter, "lisp_gpe",
5254            sizeof (mp->name_filter) - 1);
5255   S (mp);
5256
5257   /* and IPSEC tunnel interfaces */
5258   M (SW_INTERFACE_DUMP, mp);
5259   mp->name_filter_valid = 1;
5260   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5261   S (mp);
5262
5263   /* Use a control ping for synchronization */
5264   M (CONTROL_PING, mp_ping);
5265   S (mp_ping);
5266
5267   W (ret);
5268   return ret;
5269 }
5270
5271 static int
5272 api_sw_interface_set_flags (vat_main_t * vam)
5273 {
5274   unformat_input_t *i = vam->input;
5275   vl_api_sw_interface_set_flags_t *mp;
5276   u32 sw_if_index;
5277   u8 sw_if_index_set = 0;
5278   u8 admin_up = 0, link_up = 0;
5279   int ret;
5280
5281   /* Parse args required to build the message */
5282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5283     {
5284       if (unformat (i, "admin-up"))
5285         admin_up = 1;
5286       else if (unformat (i, "admin-down"))
5287         admin_up = 0;
5288       else if (unformat (i, "link-up"))
5289         link_up = 1;
5290       else if (unformat (i, "link-down"))
5291         link_up = 0;
5292       else
5293         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5294         sw_if_index_set = 1;
5295       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5296         sw_if_index_set = 1;
5297       else
5298         break;
5299     }
5300
5301   if (sw_if_index_set == 0)
5302     {
5303       errmsg ("missing interface name or sw_if_index");
5304       return -99;
5305     }
5306
5307   /* Construct the API message */
5308   M (SW_INTERFACE_SET_FLAGS, mp);
5309   mp->sw_if_index = ntohl (sw_if_index);
5310   mp->admin_up_down = admin_up;
5311   mp->link_up_down = link_up;
5312
5313   /* send it... */
5314   S (mp);
5315
5316   /* Wait for a reply, return the good/bad news... */
5317   W (ret);
5318   return ret;
5319 }
5320
5321 static int
5322 api_sw_interface_clear_stats (vat_main_t * vam)
5323 {
5324   unformat_input_t *i = vam->input;
5325   vl_api_sw_interface_clear_stats_t *mp;
5326   u32 sw_if_index;
5327   u8 sw_if_index_set = 0;
5328   int ret;
5329
5330   /* Parse args required to build the message */
5331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5332     {
5333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5334         sw_if_index_set = 1;
5335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5336         sw_if_index_set = 1;
5337       else
5338         break;
5339     }
5340
5341   /* Construct the API message */
5342   M (SW_INTERFACE_CLEAR_STATS, mp);
5343
5344   if (sw_if_index_set == 1)
5345     mp->sw_if_index = ntohl (sw_if_index);
5346   else
5347     mp->sw_if_index = ~0;
5348
5349   /* send it... */
5350   S (mp);
5351
5352   /* Wait for a reply, return the good/bad news... */
5353   W (ret);
5354   return ret;
5355 }
5356
5357 static int
5358 api_sw_interface_add_del_address (vat_main_t * vam)
5359 {
5360   unformat_input_t *i = vam->input;
5361   vl_api_sw_interface_add_del_address_t *mp;
5362   u32 sw_if_index;
5363   u8 sw_if_index_set = 0;
5364   u8 is_add = 1, del_all = 0;
5365   u32 address_length = 0;
5366   u8 v4_address_set = 0;
5367   u8 v6_address_set = 0;
5368   ip4_address_t v4address;
5369   ip6_address_t v6address;
5370   int ret;
5371
5372   /* Parse args required to build the message */
5373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5374     {
5375       if (unformat (i, "del-all"))
5376         del_all = 1;
5377       else if (unformat (i, "del"))
5378         is_add = 0;
5379       else
5380         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5381         sw_if_index_set = 1;
5382       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5383         sw_if_index_set = 1;
5384       else if (unformat (i, "%U/%d",
5385                          unformat_ip4_address, &v4address, &address_length))
5386         v4_address_set = 1;
5387       else if (unformat (i, "%U/%d",
5388                          unformat_ip6_address, &v6address, &address_length))
5389         v6_address_set = 1;
5390       else
5391         break;
5392     }
5393
5394   if (sw_if_index_set == 0)
5395     {
5396       errmsg ("missing interface name or sw_if_index");
5397       return -99;
5398     }
5399   if (v4_address_set && v6_address_set)
5400     {
5401       errmsg ("both v4 and v6 addresses set");
5402       return -99;
5403     }
5404   if (!v4_address_set && !v6_address_set && !del_all)
5405     {
5406       errmsg ("no addresses set");
5407       return -99;
5408     }
5409
5410   /* Construct the API message */
5411   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5412
5413   mp->sw_if_index = ntohl (sw_if_index);
5414   mp->is_add = is_add;
5415   mp->del_all = del_all;
5416   if (v6_address_set)
5417     {
5418       mp->is_ipv6 = 1;
5419       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5420     }
5421   else
5422     {
5423       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5424     }
5425   mp->address_length = address_length;
5426
5427   /* send it... */
5428   S (mp);
5429
5430   /* Wait for a reply, return good/bad news  */
5431   W (ret);
5432   return ret;
5433 }
5434
5435 static int
5436 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5437 {
5438   unformat_input_t *i = vam->input;
5439   vl_api_sw_interface_set_mpls_enable_t *mp;
5440   u32 sw_if_index;
5441   u8 sw_if_index_set = 0;
5442   u8 enable = 1;
5443   int ret;
5444
5445   /* Parse args required to build the message */
5446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5447     {
5448       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5449         sw_if_index_set = 1;
5450       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5451         sw_if_index_set = 1;
5452       else if (unformat (i, "disable"))
5453         enable = 0;
5454       else if (unformat (i, "dis"))
5455         enable = 0;
5456       else
5457         break;
5458     }
5459
5460   if (sw_if_index_set == 0)
5461     {
5462       errmsg ("missing interface name or sw_if_index");
5463       return -99;
5464     }
5465
5466   /* Construct the API message */
5467   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5468
5469   mp->sw_if_index = ntohl (sw_if_index);
5470   mp->enable = enable;
5471
5472   /* send it... */
5473   S (mp);
5474
5475   /* Wait for a reply... */
5476   W (ret);
5477   return ret;
5478 }
5479
5480 static int
5481 api_sw_interface_set_table (vat_main_t * vam)
5482 {
5483   unformat_input_t *i = vam->input;
5484   vl_api_sw_interface_set_table_t *mp;
5485   u32 sw_if_index, vrf_id = 0;
5486   u8 sw_if_index_set = 0;
5487   u8 is_ipv6 = 0;
5488   int ret;
5489
5490   /* Parse args required to build the message */
5491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5492     {
5493       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5494         sw_if_index_set = 1;
5495       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5496         sw_if_index_set = 1;
5497       else if (unformat (i, "vrf %d", &vrf_id))
5498         ;
5499       else if (unformat (i, "ipv6"))
5500         is_ipv6 = 1;
5501       else
5502         break;
5503     }
5504
5505   if (sw_if_index_set == 0)
5506     {
5507       errmsg ("missing interface name or sw_if_index");
5508       return -99;
5509     }
5510
5511   /* Construct the API message */
5512   M (SW_INTERFACE_SET_TABLE, mp);
5513
5514   mp->sw_if_index = ntohl (sw_if_index);
5515   mp->is_ipv6 = is_ipv6;
5516   mp->vrf_id = ntohl (vrf_id);
5517
5518   /* send it... */
5519   S (mp);
5520
5521   /* Wait for a reply... */
5522   W (ret);
5523   return ret;
5524 }
5525
5526 static void vl_api_sw_interface_get_table_reply_t_handler
5527   (vl_api_sw_interface_get_table_reply_t * mp)
5528 {
5529   vat_main_t *vam = &vat_main;
5530
5531   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5532
5533   vam->retval = ntohl (mp->retval);
5534   vam->result_ready = 1;
5535
5536 }
5537
5538 static void vl_api_sw_interface_get_table_reply_t_handler_json
5539   (vl_api_sw_interface_get_table_reply_t * mp)
5540 {
5541   vat_main_t *vam = &vat_main;
5542   vat_json_node_t node;
5543
5544   vat_json_init_object (&node);
5545   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5546   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5547
5548   vat_json_print (vam->ofp, &node);
5549   vat_json_free (&node);
5550
5551   vam->retval = ntohl (mp->retval);
5552   vam->result_ready = 1;
5553 }
5554
5555 static int
5556 api_sw_interface_get_table (vat_main_t * vam)
5557 {
5558   unformat_input_t *i = vam->input;
5559   vl_api_sw_interface_get_table_t *mp;
5560   u32 sw_if_index;
5561   u8 sw_if_index_set = 0;
5562   u8 is_ipv6 = 0;
5563   int ret;
5564
5565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5566     {
5567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5568         sw_if_index_set = 1;
5569       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5570         sw_if_index_set = 1;
5571       else if (unformat (i, "ipv6"))
5572         is_ipv6 = 1;
5573       else
5574         break;
5575     }
5576
5577   if (sw_if_index_set == 0)
5578     {
5579       errmsg ("missing interface name or sw_if_index");
5580       return -99;
5581     }
5582
5583   M (SW_INTERFACE_GET_TABLE, mp);
5584   mp->sw_if_index = htonl (sw_if_index);
5585   mp->is_ipv6 = is_ipv6;
5586
5587   S (mp);
5588   W (ret);
5589   return ret;
5590 }
5591
5592 static int
5593 api_sw_interface_set_vpath (vat_main_t * vam)
5594 {
5595   unformat_input_t *i = vam->input;
5596   vl_api_sw_interface_set_vpath_t *mp;
5597   u32 sw_if_index = 0;
5598   u8 sw_if_index_set = 0;
5599   u8 is_enable = 0;
5600   int ret;
5601
5602   /* Parse args required to build the message */
5603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5604     {
5605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5606         sw_if_index_set = 1;
5607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5608         sw_if_index_set = 1;
5609       else if (unformat (i, "enable"))
5610         is_enable = 1;
5611       else if (unformat (i, "disable"))
5612         is_enable = 0;
5613       else
5614         break;
5615     }
5616
5617   if (sw_if_index_set == 0)
5618     {
5619       errmsg ("missing interface name or sw_if_index");
5620       return -99;
5621     }
5622
5623   /* Construct the API message */
5624   M (SW_INTERFACE_SET_VPATH, mp);
5625
5626   mp->sw_if_index = ntohl (sw_if_index);
5627   mp->enable = is_enable;
5628
5629   /* send it... */
5630   S (mp);
5631
5632   /* Wait for a reply... */
5633   W (ret);
5634   return ret;
5635 }
5636
5637 static int
5638 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5639 {
5640   unformat_input_t *i = vam->input;
5641   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5642   u32 sw_if_index = 0;
5643   u8 sw_if_index_set = 0;
5644   u8 is_enable = 1;
5645   u8 is_ipv6 = 0;
5646   int ret;
5647
5648   /* Parse args required to build the message */
5649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5650     {
5651       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5652         sw_if_index_set = 1;
5653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5654         sw_if_index_set = 1;
5655       else if (unformat (i, "enable"))
5656         is_enable = 1;
5657       else if (unformat (i, "disable"))
5658         is_enable = 0;
5659       else if (unformat (i, "ip4"))
5660         is_ipv6 = 0;
5661       else if (unformat (i, "ip6"))
5662         is_ipv6 = 1;
5663       else
5664         break;
5665     }
5666
5667   if (sw_if_index_set == 0)
5668     {
5669       errmsg ("missing interface name or sw_if_index");
5670       return -99;
5671     }
5672
5673   /* Construct the API message */
5674   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5675
5676   mp->sw_if_index = ntohl (sw_if_index);
5677   mp->enable = is_enable;
5678   mp->is_ipv6 = is_ipv6;
5679
5680   /* send it... */
5681   S (mp);
5682
5683   /* Wait for a reply... */
5684   W (ret);
5685   return ret;
5686 }
5687
5688 static int
5689 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5690 {
5691   unformat_input_t *i = vam->input;
5692   vl_api_sw_interface_set_l2_xconnect_t *mp;
5693   u32 rx_sw_if_index;
5694   u8 rx_sw_if_index_set = 0;
5695   u32 tx_sw_if_index;
5696   u8 tx_sw_if_index_set = 0;
5697   u8 enable = 1;
5698   int ret;
5699
5700   /* Parse args required to build the message */
5701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5702     {
5703       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5704         rx_sw_if_index_set = 1;
5705       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5706         tx_sw_if_index_set = 1;
5707       else if (unformat (i, "rx"))
5708         {
5709           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710             {
5711               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5712                             &rx_sw_if_index))
5713                 rx_sw_if_index_set = 1;
5714             }
5715           else
5716             break;
5717         }
5718       else if (unformat (i, "tx"))
5719         {
5720           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5721             {
5722               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5723                             &tx_sw_if_index))
5724                 tx_sw_if_index_set = 1;
5725             }
5726           else
5727             break;
5728         }
5729       else if (unformat (i, "enable"))
5730         enable = 1;
5731       else if (unformat (i, "disable"))
5732         enable = 0;
5733       else
5734         break;
5735     }
5736
5737   if (rx_sw_if_index_set == 0)
5738     {
5739       errmsg ("missing rx interface name or rx_sw_if_index");
5740       return -99;
5741     }
5742
5743   if (enable && (tx_sw_if_index_set == 0))
5744     {
5745       errmsg ("missing tx interface name or tx_sw_if_index");
5746       return -99;
5747     }
5748
5749   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5750
5751   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5752   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5753   mp->enable = enable;
5754
5755   S (mp);
5756   W (ret);
5757   return ret;
5758 }
5759
5760 static int
5761 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5762 {
5763   unformat_input_t *i = vam->input;
5764   vl_api_sw_interface_set_l2_bridge_t *mp;
5765   u32 rx_sw_if_index;
5766   u8 rx_sw_if_index_set = 0;
5767   u32 bd_id;
5768   u8 bd_id_set = 0;
5769   u8 bvi = 0;
5770   u32 shg = 0;
5771   u8 enable = 1;
5772   int ret;
5773
5774   /* Parse args required to build the message */
5775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5776     {
5777       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5778         rx_sw_if_index_set = 1;
5779       else if (unformat (i, "bd_id %d", &bd_id))
5780         bd_id_set = 1;
5781       else
5782         if (unformat
5783             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5784         rx_sw_if_index_set = 1;
5785       else if (unformat (i, "shg %d", &shg))
5786         ;
5787       else if (unformat (i, "bvi"))
5788         bvi = 1;
5789       else if (unformat (i, "enable"))
5790         enable = 1;
5791       else if (unformat (i, "disable"))
5792         enable = 0;
5793       else
5794         break;
5795     }
5796
5797   if (rx_sw_if_index_set == 0)
5798     {
5799       errmsg ("missing rx interface name or sw_if_index");
5800       return -99;
5801     }
5802
5803   if (enable && (bd_id_set == 0))
5804     {
5805       errmsg ("missing bridge domain");
5806       return -99;
5807     }
5808
5809   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5810
5811   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5812   mp->bd_id = ntohl (bd_id);
5813   mp->shg = (u8) shg;
5814   mp->bvi = bvi;
5815   mp->enable = enable;
5816
5817   S (mp);
5818   W (ret);
5819   return ret;
5820 }
5821
5822 static int
5823 api_bridge_domain_dump (vat_main_t * vam)
5824 {
5825   unformat_input_t *i = vam->input;
5826   vl_api_bridge_domain_dump_t *mp;
5827   vl_api_control_ping_t *mp_ping;
5828   u32 bd_id = ~0;
5829   int ret;
5830
5831   /* Parse args required to build the message */
5832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5833     {
5834       if (unformat (i, "bd_id %d", &bd_id))
5835         ;
5836       else
5837         break;
5838     }
5839
5840   M (BRIDGE_DOMAIN_DUMP, mp);
5841   mp->bd_id = ntohl (bd_id);
5842   S (mp);
5843
5844   /* Use a control ping for synchronization */
5845   M (CONTROL_PING, mp_ping);
5846   S (mp_ping);
5847
5848   W (ret);
5849   return ret;
5850 }
5851
5852 static int
5853 api_bridge_domain_add_del (vat_main_t * vam)
5854 {
5855   unformat_input_t *i = vam->input;
5856   vl_api_bridge_domain_add_del_t *mp;
5857   u32 bd_id = ~0;
5858   u8 is_add = 1;
5859   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5860   u32 mac_age = 0;
5861   int ret;
5862
5863   /* Parse args required to build the message */
5864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5865     {
5866       if (unformat (i, "bd_id %d", &bd_id))
5867         ;
5868       else if (unformat (i, "flood %d", &flood))
5869         ;
5870       else if (unformat (i, "uu-flood %d", &uu_flood))
5871         ;
5872       else if (unformat (i, "forward %d", &forward))
5873         ;
5874       else if (unformat (i, "learn %d", &learn))
5875         ;
5876       else if (unformat (i, "arp-term %d", &arp_term))
5877         ;
5878       else if (unformat (i, "mac-age %d", &mac_age))
5879         ;
5880       else if (unformat (i, "del"))
5881         {
5882           is_add = 0;
5883           flood = uu_flood = forward = learn = 0;
5884         }
5885       else
5886         break;
5887     }
5888
5889   if (bd_id == ~0)
5890     {
5891       errmsg ("missing bridge domain");
5892       return -99;
5893     }
5894
5895   if (mac_age > 255)
5896     {
5897       errmsg ("mac age must be less than 256 ");
5898       return -99;
5899     }
5900
5901   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5902
5903   mp->bd_id = ntohl (bd_id);
5904   mp->flood = flood;
5905   mp->uu_flood = uu_flood;
5906   mp->forward = forward;
5907   mp->learn = learn;
5908   mp->arp_term = arp_term;
5909   mp->is_add = is_add;
5910   mp->mac_age = (u8) mac_age;
5911
5912   S (mp);
5913   W (ret);
5914   return ret;
5915 }
5916
5917 static int
5918 api_l2fib_add_del (vat_main_t * vam)
5919 {
5920   unformat_input_t *i = vam->input;
5921   vl_api_l2fib_add_del_t *mp;
5922   f64 timeout;
5923   u64 mac = 0;
5924   u8 mac_set = 0;
5925   u32 bd_id;
5926   u8 bd_id_set = 0;
5927   u32 sw_if_index = ~0;
5928   u8 sw_if_index_set = 0;
5929   u8 is_add = 1;
5930   u8 static_mac = 0;
5931   u8 filter_mac = 0;
5932   u8 bvi_mac = 0;
5933   int count = 1;
5934   f64 before = 0;
5935   int j;
5936
5937   /* Parse args required to build the message */
5938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5939     {
5940       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5941         mac_set = 1;
5942       else if (unformat (i, "bd_id %d", &bd_id))
5943         bd_id_set = 1;
5944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5945         sw_if_index_set = 1;
5946       else if (unformat (i, "sw_if"))
5947         {
5948           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5949             {
5950               if (unformat
5951                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5952                 sw_if_index_set = 1;
5953             }
5954           else
5955             break;
5956         }
5957       else if (unformat (i, "static"))
5958         static_mac = 1;
5959       else if (unformat (i, "filter"))
5960         {
5961           filter_mac = 1;
5962           static_mac = 1;
5963         }
5964       else if (unformat (i, "bvi"))
5965         {
5966           bvi_mac = 1;
5967           static_mac = 1;
5968         }
5969       else if (unformat (i, "del"))
5970         is_add = 0;
5971       else if (unformat (i, "count %d", &count))
5972         ;
5973       else
5974         break;
5975     }
5976
5977   if (mac_set == 0)
5978     {
5979       errmsg ("missing mac address");
5980       return -99;
5981     }
5982
5983   if (bd_id_set == 0)
5984     {
5985       errmsg ("missing bridge domain");
5986       return -99;
5987     }
5988
5989   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5990     {
5991       errmsg ("missing interface name or sw_if_index");
5992       return -99;
5993     }
5994
5995   if (count > 1)
5996     {
5997       /* Turn on async mode */
5998       vam->async_mode = 1;
5999       vam->async_errors = 0;
6000       before = vat_time_now (vam);
6001     }
6002
6003   for (j = 0; j < count; j++)
6004     {
6005       M (L2FIB_ADD_DEL, mp);
6006
6007       mp->mac = mac;
6008       mp->bd_id = ntohl (bd_id);
6009       mp->is_add = is_add;
6010
6011       if (is_add)
6012         {
6013           mp->sw_if_index = ntohl (sw_if_index);
6014           mp->static_mac = static_mac;
6015           mp->filter_mac = filter_mac;
6016           mp->bvi_mac = bvi_mac;
6017         }
6018       increment_mac_address (&mac);
6019       /* send it... */
6020       S (mp);
6021     }
6022
6023   if (count > 1)
6024     {
6025       vl_api_control_ping_t *mp_ping;
6026       f64 after;
6027
6028       /* Shut off async mode */
6029       vam->async_mode = 0;
6030
6031       M (CONTROL_PING, mp_ping);
6032       S (mp_ping);
6033
6034       timeout = vat_time_now (vam) + 1.0;
6035       while (vat_time_now (vam) < timeout)
6036         if (vam->result_ready == 1)
6037           goto out;
6038       vam->retval = -99;
6039
6040     out:
6041       if (vam->retval == -99)
6042         errmsg ("timeout");
6043
6044       if (vam->async_errors > 0)
6045         {
6046           errmsg ("%d asynchronous errors", vam->async_errors);
6047           vam->retval = -98;
6048         }
6049       vam->async_errors = 0;
6050       after = vat_time_now (vam);
6051
6052       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6053              count, after - before, count / (after - before));
6054     }
6055   else
6056     {
6057       int ret;
6058
6059       /* Wait for a reply... */
6060       W (ret);
6061       return ret;
6062     }
6063   /* Return the good/bad news */
6064   return (vam->retval);
6065 }
6066
6067 static int
6068 api_bridge_domain_set_mac_age (vat_main_t * vam)
6069 {
6070   unformat_input_t *i = vam->input;
6071   vl_api_bridge_domain_set_mac_age_t *mp;
6072   u32 bd_id = ~0;
6073   u32 mac_age = 0;
6074   int ret;
6075
6076   /* Parse args required to build the message */
6077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6078     {
6079       if (unformat (i, "bd_id %d", &bd_id));
6080       else if (unformat (i, "mac-age %d", &mac_age));
6081       else
6082         break;
6083     }
6084
6085   if (bd_id == ~0)
6086     {
6087       errmsg ("missing bridge domain");
6088       return -99;
6089     }
6090
6091   if (mac_age > 255)
6092     {
6093       errmsg ("mac age must be less than 256 ");
6094       return -99;
6095     }
6096
6097   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6098
6099   mp->bd_id = htonl (bd_id);
6100   mp->mac_age = (u8) mac_age;
6101
6102   S (mp);
6103   W (ret);
6104   return ret;
6105 }
6106
6107 static int
6108 api_l2_flags (vat_main_t * vam)
6109 {
6110   unformat_input_t *i = vam->input;
6111   vl_api_l2_flags_t *mp;
6112   u32 sw_if_index;
6113   u32 feature_bitmap = 0;
6114   u8 sw_if_index_set = 0;
6115   int ret;
6116
6117   /* Parse args required to build the message */
6118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6119     {
6120       if (unformat (i, "sw_if_index %d", &sw_if_index))
6121         sw_if_index_set = 1;
6122       else if (unformat (i, "sw_if"))
6123         {
6124           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6125             {
6126               if (unformat
6127                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6128                 sw_if_index_set = 1;
6129             }
6130           else
6131             break;
6132         }
6133       else if (unformat (i, "learn"))
6134         feature_bitmap |= L2INPUT_FEAT_LEARN;
6135       else if (unformat (i, "forward"))
6136         feature_bitmap |= L2INPUT_FEAT_FWD;
6137       else if (unformat (i, "flood"))
6138         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6139       else if (unformat (i, "uu-flood"))
6140         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6141       else
6142         break;
6143     }
6144
6145   if (sw_if_index_set == 0)
6146     {
6147       errmsg ("missing interface name or sw_if_index");
6148       return -99;
6149     }
6150
6151   M (L2_FLAGS, mp);
6152
6153   mp->sw_if_index = ntohl (sw_if_index);
6154   mp->feature_bitmap = ntohl (feature_bitmap);
6155
6156   S (mp);
6157   W (ret);
6158   return ret;
6159 }
6160
6161 static int
6162 api_bridge_flags (vat_main_t * vam)
6163 {
6164   unformat_input_t *i = vam->input;
6165   vl_api_bridge_flags_t *mp;
6166   u32 bd_id;
6167   u8 bd_id_set = 0;
6168   u8 is_set = 1;
6169   u32 flags = 0;
6170   int ret;
6171
6172   /* Parse args required to build the message */
6173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6174     {
6175       if (unformat (i, "bd_id %d", &bd_id))
6176         bd_id_set = 1;
6177       else if (unformat (i, "learn"))
6178         flags |= L2_LEARN;
6179       else if (unformat (i, "forward"))
6180         flags |= L2_FWD;
6181       else if (unformat (i, "flood"))
6182         flags |= L2_FLOOD;
6183       else if (unformat (i, "uu-flood"))
6184         flags |= L2_UU_FLOOD;
6185       else if (unformat (i, "arp-term"))
6186         flags |= L2_ARP_TERM;
6187       else if (unformat (i, "off"))
6188         is_set = 0;
6189       else if (unformat (i, "disable"))
6190         is_set = 0;
6191       else
6192         break;
6193     }
6194
6195   if (bd_id_set == 0)
6196     {
6197       errmsg ("missing bridge domain");
6198       return -99;
6199     }
6200
6201   M (BRIDGE_FLAGS, mp);
6202
6203   mp->bd_id = ntohl (bd_id);
6204   mp->feature_bitmap = ntohl (flags);
6205   mp->is_set = is_set;
6206
6207   S (mp);
6208   W (ret);
6209   return ret;
6210 }
6211
6212 static int
6213 api_bd_ip_mac_add_del (vat_main_t * vam)
6214 {
6215   unformat_input_t *i = vam->input;
6216   vl_api_bd_ip_mac_add_del_t *mp;
6217   u32 bd_id;
6218   u8 is_ipv6 = 0;
6219   u8 is_add = 1;
6220   u8 bd_id_set = 0;
6221   u8 ip_set = 0;
6222   u8 mac_set = 0;
6223   ip4_address_t v4addr;
6224   ip6_address_t v6addr;
6225   u8 macaddr[6];
6226   int ret;
6227
6228
6229   /* Parse args required to build the message */
6230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6231     {
6232       if (unformat (i, "bd_id %d", &bd_id))
6233         {
6234           bd_id_set++;
6235         }
6236       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6237         {
6238           ip_set++;
6239         }
6240       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6241         {
6242           ip_set++;
6243           is_ipv6++;
6244         }
6245       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6246         {
6247           mac_set++;
6248         }
6249       else if (unformat (i, "del"))
6250         is_add = 0;
6251       else
6252         break;
6253     }
6254
6255   if (bd_id_set == 0)
6256     {
6257       errmsg ("missing bridge domain");
6258       return -99;
6259     }
6260   else if (ip_set == 0)
6261     {
6262       errmsg ("missing IP address");
6263       return -99;
6264     }
6265   else if (mac_set == 0)
6266     {
6267       errmsg ("missing MAC address");
6268       return -99;
6269     }
6270
6271   M (BD_IP_MAC_ADD_DEL, mp);
6272
6273   mp->bd_id = ntohl (bd_id);
6274   mp->is_ipv6 = is_ipv6;
6275   mp->is_add = is_add;
6276   if (is_ipv6)
6277     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6278   else
6279     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6280   clib_memcpy (mp->mac_address, macaddr, 6);
6281   S (mp);
6282   W (ret);
6283   return ret;
6284 }
6285
6286 static int
6287 api_tap_connect (vat_main_t * vam)
6288 {
6289   unformat_input_t *i = vam->input;
6290   vl_api_tap_connect_t *mp;
6291   u8 mac_address[6];
6292   u8 random_mac = 1;
6293   u8 name_set = 0;
6294   u8 *tap_name;
6295   u8 *tag = 0;
6296   ip4_address_t ip4_address;
6297   u32 ip4_mask_width;
6298   int ip4_address_set = 0;
6299   ip6_address_t ip6_address;
6300   u32 ip6_mask_width;
6301   int ip6_address_set = 0;
6302   int ret;
6303
6304   memset (mac_address, 0, sizeof (mac_address));
6305
6306   /* Parse args required to build the message */
6307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6308     {
6309       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6310         {
6311           random_mac = 0;
6312         }
6313       else if (unformat (i, "random-mac"))
6314         random_mac = 1;
6315       else if (unformat (i, "tapname %s", &tap_name))
6316         name_set = 1;
6317       else if (unformat (i, "tag %s", &tag))
6318         ;
6319       else if (unformat (i, "address %U/%d",
6320                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6321         ip4_address_set = 1;
6322       else if (unformat (i, "address %U/%d",
6323                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6324         ip6_address_set = 1;
6325       else
6326         break;
6327     }
6328
6329   if (name_set == 0)
6330     {
6331       errmsg ("missing tap name");
6332       return -99;
6333     }
6334   if (vec_len (tap_name) > 63)
6335     {
6336       errmsg ("tap name too long");
6337       return -99;
6338     }
6339   vec_add1 (tap_name, 0);
6340
6341   if (vec_len (tag) > 63)
6342     {
6343       errmsg ("tag too long");
6344       return -99;
6345     }
6346
6347   /* Construct the API message */
6348   M (TAP_CONNECT, mp);
6349
6350   mp->use_random_mac = random_mac;
6351   clib_memcpy (mp->mac_address, mac_address, 6);
6352   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6353   if (tag)
6354     clib_memcpy (mp->tag, tag, vec_len (tag));
6355
6356   if (ip4_address_set)
6357     {
6358       mp->ip4_address_set = 1;
6359       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6360       mp->ip4_mask_width = ip4_mask_width;
6361     }
6362   if (ip6_address_set)
6363     {
6364       mp->ip6_address_set = 1;
6365       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6366       mp->ip6_mask_width = ip6_mask_width;
6367     }
6368
6369   vec_free (tap_name);
6370   vec_free (tag);
6371
6372   /* send it... */
6373   S (mp);
6374
6375   /* Wait for a reply... */
6376   W (ret);
6377   return ret;
6378 }
6379
6380 static int
6381 api_tap_modify (vat_main_t * vam)
6382 {
6383   unformat_input_t *i = vam->input;
6384   vl_api_tap_modify_t *mp;
6385   u8 mac_address[6];
6386   u8 random_mac = 1;
6387   u8 name_set = 0;
6388   u8 *tap_name;
6389   u32 sw_if_index = ~0;
6390   u8 sw_if_index_set = 0;
6391   int ret;
6392
6393   memset (mac_address, 0, sizeof (mac_address));
6394
6395   /* Parse args required to build the message */
6396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6397     {
6398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6399         sw_if_index_set = 1;
6400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6401         sw_if_index_set = 1;
6402       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6403         {
6404           random_mac = 0;
6405         }
6406       else if (unformat (i, "random-mac"))
6407         random_mac = 1;
6408       else if (unformat (i, "tapname %s", &tap_name))
6409         name_set = 1;
6410       else
6411         break;
6412     }
6413
6414   if (sw_if_index_set == 0)
6415     {
6416       errmsg ("missing vpp interface name");
6417       return -99;
6418     }
6419   if (name_set == 0)
6420     {
6421       errmsg ("missing tap name");
6422       return -99;
6423     }
6424   if (vec_len (tap_name) > 63)
6425     {
6426       errmsg ("tap name too long");
6427     }
6428   vec_add1 (tap_name, 0);
6429
6430   /* Construct the API message */
6431   M (TAP_MODIFY, mp);
6432
6433   mp->use_random_mac = random_mac;
6434   mp->sw_if_index = ntohl (sw_if_index);
6435   clib_memcpy (mp->mac_address, mac_address, 6);
6436   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6437   vec_free (tap_name);
6438
6439   /* send it... */
6440   S (mp);
6441
6442   /* Wait for a reply... */
6443   W (ret);
6444   return ret;
6445 }
6446
6447 static int
6448 api_tap_delete (vat_main_t * vam)
6449 {
6450   unformat_input_t *i = vam->input;
6451   vl_api_tap_delete_t *mp;
6452   u32 sw_if_index = ~0;
6453   u8 sw_if_index_set = 0;
6454   int ret;
6455
6456   /* Parse args required to build the message */
6457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6458     {
6459       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6460         sw_if_index_set = 1;
6461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6462         sw_if_index_set = 1;
6463       else
6464         break;
6465     }
6466
6467   if (sw_if_index_set == 0)
6468     {
6469       errmsg ("missing vpp interface name");
6470       return -99;
6471     }
6472
6473   /* Construct the API message */
6474   M (TAP_DELETE, mp);
6475
6476   mp->sw_if_index = ntohl (sw_if_index);
6477
6478   /* send it... */
6479   S (mp);
6480
6481   /* Wait for a reply... */
6482   W (ret);
6483   return ret;
6484 }
6485
6486 static int
6487 api_ip_add_del_route (vat_main_t * vam)
6488 {
6489   unformat_input_t *i = vam->input;
6490   vl_api_ip_add_del_route_t *mp;
6491   u32 sw_if_index = ~0, vrf_id = 0;
6492   u8 is_ipv6 = 0;
6493   u8 is_local = 0, is_drop = 0;
6494   u8 is_unreach = 0, is_prohibit = 0;
6495   u8 create_vrf_if_needed = 0;
6496   u8 is_add = 1;
6497   u32 next_hop_weight = 1;
6498   u8 not_last = 0;
6499   u8 is_multipath = 0;
6500   u8 address_set = 0;
6501   u8 address_length_set = 0;
6502   u32 next_hop_table_id = 0;
6503   u32 resolve_attempts = 0;
6504   u32 dst_address_length = 0;
6505   u8 next_hop_set = 0;
6506   ip4_address_t v4_dst_address, v4_next_hop_address;
6507   ip6_address_t v6_dst_address, v6_next_hop_address;
6508   int count = 1;
6509   int j;
6510   f64 before = 0;
6511   u32 random_add_del = 0;
6512   u32 *random_vector = 0;
6513   uword *random_hash;
6514   u32 random_seed = 0xdeaddabe;
6515   u32 classify_table_index = ~0;
6516   u8 is_classify = 0;
6517   u8 resolve_host = 0, resolve_attached = 0;
6518   mpls_label_t *next_hop_out_label_stack = NULL;
6519   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6520   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6521
6522   /* Parse args required to build the message */
6523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6524     {
6525       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6526         ;
6527       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6528         ;
6529       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6530         {
6531           address_set = 1;
6532           is_ipv6 = 0;
6533         }
6534       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6535         {
6536           address_set = 1;
6537           is_ipv6 = 1;
6538         }
6539       else if (unformat (i, "/%d", &dst_address_length))
6540         {
6541           address_length_set = 1;
6542         }
6543
6544       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6545                                          &v4_next_hop_address))
6546         {
6547           next_hop_set = 1;
6548         }
6549       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6550                                          &v6_next_hop_address))
6551         {
6552           next_hop_set = 1;
6553         }
6554       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6555         ;
6556       else if (unformat (i, "weight %d", &next_hop_weight))
6557         ;
6558       else if (unformat (i, "drop"))
6559         {
6560           is_drop = 1;
6561         }
6562       else if (unformat (i, "null-send-unreach"))
6563         {
6564           is_unreach = 1;
6565         }
6566       else if (unformat (i, "null-send-prohibit"))
6567         {
6568           is_prohibit = 1;
6569         }
6570       else if (unformat (i, "local"))
6571         {
6572           is_local = 1;
6573         }
6574       else if (unformat (i, "classify %d", &classify_table_index))
6575         {
6576           is_classify = 1;
6577         }
6578       else if (unformat (i, "del"))
6579         is_add = 0;
6580       else if (unformat (i, "add"))
6581         is_add = 1;
6582       else if (unformat (i, "not-last"))
6583         not_last = 1;
6584       else if (unformat (i, "resolve-via-host"))
6585         resolve_host = 1;
6586       else if (unformat (i, "resolve-via-attached"))
6587         resolve_attached = 1;
6588       else if (unformat (i, "multipath"))
6589         is_multipath = 1;
6590       else if (unformat (i, "vrf %d", &vrf_id))
6591         ;
6592       else if (unformat (i, "create-vrf"))
6593         create_vrf_if_needed = 1;
6594       else if (unformat (i, "count %d", &count))
6595         ;
6596       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6597         ;
6598       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6599         ;
6600       else if (unformat (i, "out-label %d", &next_hop_out_label))
6601         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6602       else if (unformat (i, "via-label %d", &next_hop_via_label))
6603         ;
6604       else if (unformat (i, "random"))
6605         random_add_del = 1;
6606       else if (unformat (i, "seed %d", &random_seed))
6607         ;
6608       else
6609         {
6610           clib_warning ("parse error '%U'", format_unformat_error, i);
6611           return -99;
6612         }
6613     }
6614
6615   if (!next_hop_set && !is_drop && !is_local &&
6616       !is_classify && !is_unreach && !is_prohibit &&
6617       MPLS_LABEL_INVALID == next_hop_via_label)
6618     {
6619       errmsg
6620         ("next hop / local / drop / unreach / prohibit / classify not set");
6621       return -99;
6622     }
6623
6624   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6625     {
6626       errmsg ("next hop and next-hop via label set");
6627       return -99;
6628     }
6629   if (address_set == 0)
6630     {
6631       errmsg ("missing addresses");
6632       return -99;
6633     }
6634
6635   if (address_length_set == 0)
6636     {
6637       errmsg ("missing address length");
6638       return -99;
6639     }
6640
6641   /* Generate a pile of unique, random routes */
6642   if (random_add_del)
6643     {
6644       u32 this_random_address;
6645       random_hash = hash_create (count, sizeof (uword));
6646
6647       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6648       for (j = 0; j <= count; j++)
6649         {
6650           do
6651             {
6652               this_random_address = random_u32 (&random_seed);
6653               this_random_address =
6654                 clib_host_to_net_u32 (this_random_address);
6655             }
6656           while (hash_get (random_hash, this_random_address));
6657           vec_add1 (random_vector, this_random_address);
6658           hash_set (random_hash, this_random_address, 1);
6659         }
6660       hash_free (random_hash);
6661       v4_dst_address.as_u32 = random_vector[0];
6662     }
6663
6664   if (count > 1)
6665     {
6666       /* Turn on async mode */
6667       vam->async_mode = 1;
6668       vam->async_errors = 0;
6669       before = vat_time_now (vam);
6670     }
6671
6672   for (j = 0; j < count; j++)
6673     {
6674       /* Construct the API message */
6675       M2 (IP_ADD_DEL_ROUTE, mp,
6676           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6677
6678       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6679       mp->table_id = ntohl (vrf_id);
6680       mp->create_vrf_if_needed = create_vrf_if_needed;
6681
6682       mp->is_add = is_add;
6683       mp->is_drop = is_drop;
6684       mp->is_unreach = is_unreach;
6685       mp->is_prohibit = is_prohibit;
6686       mp->is_ipv6 = is_ipv6;
6687       mp->is_local = is_local;
6688       mp->is_classify = is_classify;
6689       mp->is_multipath = is_multipath;
6690       mp->is_resolve_host = resolve_host;
6691       mp->is_resolve_attached = resolve_attached;
6692       mp->not_last = not_last;
6693       mp->next_hop_weight = next_hop_weight;
6694       mp->dst_address_length = dst_address_length;
6695       mp->next_hop_table_id = ntohl (next_hop_table_id);
6696       mp->classify_table_index = ntohl (classify_table_index);
6697       mp->next_hop_via_label = ntohl (next_hop_via_label);
6698       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6699       if (0 != mp->next_hop_n_out_labels)
6700         {
6701           memcpy (mp->next_hop_out_label_stack,
6702                   next_hop_out_label_stack,
6703                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6704           vec_free (next_hop_out_label_stack);
6705         }
6706
6707       if (is_ipv6)
6708         {
6709           clib_memcpy (mp->dst_address, &v6_dst_address,
6710                        sizeof (v6_dst_address));
6711           if (next_hop_set)
6712             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6713                          sizeof (v6_next_hop_address));
6714           increment_v6_address (&v6_dst_address);
6715         }
6716       else
6717         {
6718           clib_memcpy (mp->dst_address, &v4_dst_address,
6719                        sizeof (v4_dst_address));
6720           if (next_hop_set)
6721             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6722                          sizeof (v4_next_hop_address));
6723           if (random_add_del)
6724             v4_dst_address.as_u32 = random_vector[j + 1];
6725           else
6726             increment_v4_address (&v4_dst_address);
6727         }
6728       /* send it... */
6729       S (mp);
6730       /* If we receive SIGTERM, stop now... */
6731       if (vam->do_exit)
6732         break;
6733     }
6734
6735   /* When testing multiple add/del ops, use a control-ping to sync */
6736   if (count > 1)
6737     {
6738       vl_api_control_ping_t *mp_ping;
6739       f64 after;
6740       f64 timeout;
6741
6742       /* Shut off async mode */
6743       vam->async_mode = 0;
6744
6745       M (CONTROL_PING, mp_ping);
6746       S (mp_ping);
6747
6748       timeout = vat_time_now (vam) + 1.0;
6749       while (vat_time_now (vam) < timeout)
6750         if (vam->result_ready == 1)
6751           goto out;
6752       vam->retval = -99;
6753
6754     out:
6755       if (vam->retval == -99)
6756         errmsg ("timeout");
6757
6758       if (vam->async_errors > 0)
6759         {
6760           errmsg ("%d asynchronous errors", vam->async_errors);
6761           vam->retval = -98;
6762         }
6763       vam->async_errors = 0;
6764       after = vat_time_now (vam);
6765
6766       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6767       if (j > 0)
6768         count = j;
6769
6770       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6771              count, after - before, count / (after - before));
6772     }
6773   else
6774     {
6775       int ret;
6776
6777       /* Wait for a reply... */
6778       W (ret);
6779       return ret;
6780     }
6781
6782   /* Return the good/bad news */
6783   return (vam->retval);
6784 }
6785
6786 static int
6787 api_ip_mroute_add_del (vat_main_t * vam)
6788 {
6789   unformat_input_t *i = vam->input;
6790   vl_api_ip_mroute_add_del_t *mp;
6791   u32 sw_if_index = ~0, vrf_id = 0;
6792   u8 is_ipv6 = 0;
6793   u8 is_local = 0;
6794   u8 create_vrf_if_needed = 0;
6795   u8 is_add = 1;
6796   u8 address_set = 0;
6797   u32 grp_address_length = 0;
6798   ip4_address_t v4_grp_address, v4_src_address;
6799   ip6_address_t v6_grp_address, v6_src_address;
6800   mfib_itf_flags_t iflags = 0;
6801   mfib_entry_flags_t eflags = 0;
6802   int ret;
6803
6804   /* Parse args required to build the message */
6805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6806     {
6807       if (unformat (i, "sw_if_index %d", &sw_if_index))
6808         ;
6809       else if (unformat (i, "%U %U",
6810                          unformat_ip4_address, &v4_src_address,
6811                          unformat_ip4_address, &v4_grp_address))
6812         {
6813           grp_address_length = 64;
6814           address_set = 1;
6815           is_ipv6 = 0;
6816         }
6817       else if (unformat (i, "%U %U",
6818                          unformat_ip6_address, &v6_src_address,
6819                          unformat_ip6_address, &v6_grp_address))
6820         {
6821           grp_address_length = 256;
6822           address_set = 1;
6823           is_ipv6 = 1;
6824         }
6825       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6826         {
6827           memset (&v4_src_address, 0, sizeof (v4_src_address));
6828           grp_address_length = 32;
6829           address_set = 1;
6830           is_ipv6 = 0;
6831         }
6832       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6833         {
6834           memset (&v6_src_address, 0, sizeof (v6_src_address));
6835           grp_address_length = 128;
6836           address_set = 1;
6837           is_ipv6 = 1;
6838         }
6839       else if (unformat (i, "/%d", &grp_address_length))
6840         ;
6841       else if (unformat (i, "local"))
6842         {
6843           is_local = 1;
6844         }
6845       else if (unformat (i, "del"))
6846         is_add = 0;
6847       else if (unformat (i, "add"))
6848         is_add = 1;
6849       else if (unformat (i, "vrf %d", &vrf_id))
6850         ;
6851       else if (unformat (i, "create-vrf"))
6852         create_vrf_if_needed = 1;
6853       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6854         ;
6855       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6856         ;
6857       else
6858         {
6859           clib_warning ("parse error '%U'", format_unformat_error, i);
6860           return -99;
6861         }
6862     }
6863
6864   if (address_set == 0)
6865     {
6866       errmsg ("missing addresses\n");
6867       return -99;
6868     }
6869
6870   /* Construct the API message */
6871   M (IP_MROUTE_ADD_DEL, mp);
6872
6873   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6874   mp->table_id = ntohl (vrf_id);
6875   mp->create_vrf_if_needed = create_vrf_if_needed;
6876
6877   mp->is_add = is_add;
6878   mp->is_ipv6 = is_ipv6;
6879   mp->is_local = is_local;
6880   mp->itf_flags = ntohl (iflags);
6881   mp->entry_flags = ntohl (eflags);
6882   mp->grp_address_length = grp_address_length;
6883   mp->grp_address_length = ntohs (mp->grp_address_length);
6884
6885   if (is_ipv6)
6886     {
6887       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6888       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6889     }
6890   else
6891     {
6892       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6893       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6894
6895     }
6896
6897   /* send it... */
6898   S (mp);
6899   /* Wait for a reply... */
6900   W (ret);
6901   return ret;
6902 }
6903
6904 static int
6905 api_mpls_route_add_del (vat_main_t * vam)
6906 {
6907   unformat_input_t *i = vam->input;
6908   vl_api_mpls_route_add_del_t *mp;
6909   u32 sw_if_index = ~0, table_id = 0;
6910   u8 create_table_if_needed = 0;
6911   u8 is_add = 1;
6912   u32 next_hop_weight = 1;
6913   u8 is_multipath = 0;
6914   u32 next_hop_table_id = 0;
6915   u8 next_hop_set = 0;
6916   ip4_address_t v4_next_hop_address = {
6917     .as_u32 = 0,
6918   };
6919   ip6_address_t v6_next_hop_address = { {0} };
6920   int count = 1;
6921   int j;
6922   f64 before = 0;
6923   u32 classify_table_index = ~0;
6924   u8 is_classify = 0;
6925   u8 resolve_host = 0, resolve_attached = 0;
6926   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6927   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6928   mpls_label_t *next_hop_out_label_stack = NULL;
6929   mpls_label_t local_label = MPLS_LABEL_INVALID;
6930   u8 is_eos = 0;
6931   u8 next_hop_proto_is_ip4 = 1;
6932
6933   /* Parse args required to build the message */
6934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6935     {
6936       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6937         ;
6938       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6939         ;
6940       else if (unformat (i, "%d", &local_label))
6941         ;
6942       else if (unformat (i, "eos"))
6943         is_eos = 1;
6944       else if (unformat (i, "non-eos"))
6945         is_eos = 0;
6946       else if (unformat (i, "via %U", unformat_ip4_address,
6947                          &v4_next_hop_address))
6948         {
6949           next_hop_set = 1;
6950           next_hop_proto_is_ip4 = 1;
6951         }
6952       else if (unformat (i, "via %U", unformat_ip6_address,
6953                          &v6_next_hop_address))
6954         {
6955           next_hop_set = 1;
6956           next_hop_proto_is_ip4 = 0;
6957         }
6958       else if (unformat (i, "weight %d", &next_hop_weight))
6959         ;
6960       else if (unformat (i, "create-table"))
6961         create_table_if_needed = 1;
6962       else if (unformat (i, "classify %d", &classify_table_index))
6963         {
6964           is_classify = 1;
6965         }
6966       else if (unformat (i, "del"))
6967         is_add = 0;
6968       else if (unformat (i, "add"))
6969         is_add = 1;
6970       else if (unformat (i, "resolve-via-host"))
6971         resolve_host = 1;
6972       else if (unformat (i, "resolve-via-attached"))
6973         resolve_attached = 1;
6974       else if (unformat (i, "multipath"))
6975         is_multipath = 1;
6976       else if (unformat (i, "count %d", &count))
6977         ;
6978       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6979         {
6980           next_hop_set = 1;
6981           next_hop_proto_is_ip4 = 1;
6982         }
6983       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6984         {
6985           next_hop_set = 1;
6986           next_hop_proto_is_ip4 = 0;
6987         }
6988       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6989         ;
6990       else if (unformat (i, "via-label %d", &next_hop_via_label))
6991         ;
6992       else if (unformat (i, "out-label %d", &next_hop_out_label))
6993         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6994       else
6995         {
6996           clib_warning ("parse error '%U'", format_unformat_error, i);
6997           return -99;
6998         }
6999     }
7000
7001   if (!next_hop_set && !is_classify)
7002     {
7003       errmsg ("next hop / classify not set");
7004       return -99;
7005     }
7006
7007   if (MPLS_LABEL_INVALID == local_label)
7008     {
7009       errmsg ("missing label");
7010       return -99;
7011     }
7012
7013   if (count > 1)
7014     {
7015       /* Turn on async mode */
7016       vam->async_mode = 1;
7017       vam->async_errors = 0;
7018       before = vat_time_now (vam);
7019     }
7020
7021   for (j = 0; j < count; j++)
7022     {
7023       /* Construct the API message */
7024       M2 (MPLS_ROUTE_ADD_DEL, mp,
7025           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7026
7027       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7028       mp->mr_table_id = ntohl (table_id);
7029       mp->mr_create_table_if_needed = create_table_if_needed;
7030
7031       mp->mr_is_add = is_add;
7032       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7033       mp->mr_is_classify = is_classify;
7034       mp->mr_is_multipath = is_multipath;
7035       mp->mr_is_resolve_host = resolve_host;
7036       mp->mr_is_resolve_attached = resolve_attached;
7037       mp->mr_next_hop_weight = next_hop_weight;
7038       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7039       mp->mr_classify_table_index = ntohl (classify_table_index);
7040       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7041       mp->mr_label = ntohl (local_label);
7042       mp->mr_eos = is_eos;
7043
7044       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7045       if (0 != mp->mr_next_hop_n_out_labels)
7046         {
7047           memcpy (mp->mr_next_hop_out_label_stack,
7048                   next_hop_out_label_stack,
7049                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7050           vec_free (next_hop_out_label_stack);
7051         }
7052
7053       if (next_hop_set)
7054         {
7055           if (next_hop_proto_is_ip4)
7056             {
7057               clib_memcpy (mp->mr_next_hop,
7058                            &v4_next_hop_address,
7059                            sizeof (v4_next_hop_address));
7060             }
7061           else
7062             {
7063               clib_memcpy (mp->mr_next_hop,
7064                            &v6_next_hop_address,
7065                            sizeof (v6_next_hop_address));
7066             }
7067         }
7068       local_label++;
7069
7070       /* send it... */
7071       S (mp);
7072       /* If we receive SIGTERM, stop now... */
7073       if (vam->do_exit)
7074         break;
7075     }
7076
7077   /* When testing multiple add/del ops, use a control-ping to sync */
7078   if (count > 1)
7079     {
7080       vl_api_control_ping_t *mp_ping;
7081       f64 after;
7082       f64 timeout;
7083
7084       /* Shut off async mode */
7085       vam->async_mode = 0;
7086
7087       M (CONTROL_PING, mp_ping);
7088       S (mp_ping);
7089
7090       timeout = vat_time_now (vam) + 1.0;
7091       while (vat_time_now (vam) < timeout)
7092         if (vam->result_ready == 1)
7093           goto out;
7094       vam->retval = -99;
7095
7096     out:
7097       if (vam->retval == -99)
7098         errmsg ("timeout");
7099
7100       if (vam->async_errors > 0)
7101         {
7102           errmsg ("%d asynchronous errors", vam->async_errors);
7103           vam->retval = -98;
7104         }
7105       vam->async_errors = 0;
7106       after = vat_time_now (vam);
7107
7108       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7109       if (j > 0)
7110         count = j;
7111
7112       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7113              count, after - before, count / (after - before));
7114     }
7115   else
7116     {
7117       int ret;
7118
7119       /* Wait for a reply... */
7120       W (ret);
7121       return ret;
7122     }
7123
7124   /* Return the good/bad news */
7125   return (vam->retval);
7126 }
7127
7128 static int
7129 api_mpls_ip_bind_unbind (vat_main_t * vam)
7130 {
7131   unformat_input_t *i = vam->input;
7132   vl_api_mpls_ip_bind_unbind_t *mp;
7133   u32 ip_table_id = 0;
7134   u8 create_table_if_needed = 0;
7135   u8 is_bind = 1;
7136   u8 is_ip4 = 1;
7137   ip4_address_t v4_address;
7138   ip6_address_t v6_address;
7139   u32 address_length;
7140   u8 address_set = 0;
7141   mpls_label_t local_label = MPLS_LABEL_INVALID;
7142   int ret;
7143
7144   /* Parse args required to build the message */
7145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7146     {
7147       if (unformat (i, "%U/%d", unformat_ip4_address,
7148                     &v4_address, &address_length))
7149         {
7150           is_ip4 = 1;
7151           address_set = 1;
7152         }
7153       else if (unformat (i, "%U/%d", unformat_ip6_address,
7154                          &v6_address, &address_length))
7155         {
7156           is_ip4 = 0;
7157           address_set = 1;
7158         }
7159       else if (unformat (i, "%d", &local_label))
7160         ;
7161       else if (unformat (i, "create-table"))
7162         create_table_if_needed = 1;
7163       else if (unformat (i, "table-id %d", &ip_table_id))
7164         ;
7165       else if (unformat (i, "unbind"))
7166         is_bind = 0;
7167       else if (unformat (i, "bind"))
7168         is_bind = 1;
7169       else
7170         {
7171           clib_warning ("parse error '%U'", format_unformat_error, i);
7172           return -99;
7173         }
7174     }
7175
7176   if (!address_set)
7177     {
7178       errmsg ("IP addres not set");
7179       return -99;
7180     }
7181
7182   if (MPLS_LABEL_INVALID == local_label)
7183     {
7184       errmsg ("missing label");
7185       return -99;
7186     }
7187
7188   /* Construct the API message */
7189   M (MPLS_IP_BIND_UNBIND, mp);
7190
7191   mp->mb_create_table_if_needed = create_table_if_needed;
7192   mp->mb_is_bind = is_bind;
7193   mp->mb_is_ip4 = is_ip4;
7194   mp->mb_ip_table_id = ntohl (ip_table_id);
7195   mp->mb_mpls_table_id = 0;
7196   mp->mb_label = ntohl (local_label);
7197   mp->mb_address_length = address_length;
7198
7199   if (is_ip4)
7200     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7201   else
7202     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7203
7204   /* send it... */
7205   S (mp);
7206
7207   /* Wait for a reply... */
7208   W (ret);
7209   return ret;
7210 }
7211
7212 static int
7213 api_proxy_arp_add_del (vat_main_t * vam)
7214 {
7215   unformat_input_t *i = vam->input;
7216   vl_api_proxy_arp_add_del_t *mp;
7217   u32 vrf_id = 0;
7218   u8 is_add = 1;
7219   ip4_address_t lo, hi;
7220   u8 range_set = 0;
7221   int ret;
7222
7223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7224     {
7225       if (unformat (i, "vrf %d", &vrf_id))
7226         ;
7227       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7228                          unformat_ip4_address, &hi))
7229         range_set = 1;
7230       else if (unformat (i, "del"))
7231         is_add = 0;
7232       else
7233         {
7234           clib_warning ("parse error '%U'", format_unformat_error, i);
7235           return -99;
7236         }
7237     }
7238
7239   if (range_set == 0)
7240     {
7241       errmsg ("address range not set");
7242       return -99;
7243     }
7244
7245   M (PROXY_ARP_ADD_DEL, mp);
7246
7247   mp->vrf_id = ntohl (vrf_id);
7248   mp->is_add = is_add;
7249   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7250   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7251
7252   S (mp);
7253   W (ret);
7254   return ret;
7255 }
7256
7257 static int
7258 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7259 {
7260   unformat_input_t *i = vam->input;
7261   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7262   u32 sw_if_index;
7263   u8 enable = 1;
7264   u8 sw_if_index_set = 0;
7265   int ret;
7266
7267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7268     {
7269       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7270         sw_if_index_set = 1;
7271       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7272         sw_if_index_set = 1;
7273       else if (unformat (i, "enable"))
7274         enable = 1;
7275       else if (unformat (i, "disable"))
7276         enable = 0;
7277       else
7278         {
7279           clib_warning ("parse error '%U'", format_unformat_error, i);
7280           return -99;
7281         }
7282     }
7283
7284   if (sw_if_index_set == 0)
7285     {
7286       errmsg ("missing interface name or sw_if_index");
7287       return -99;
7288     }
7289
7290   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7291
7292   mp->sw_if_index = ntohl (sw_if_index);
7293   mp->enable_disable = enable;
7294
7295   S (mp);
7296   W (ret);
7297   return ret;
7298 }
7299
7300 static int
7301 api_mpls_tunnel_add_del (vat_main_t * vam)
7302 {
7303   unformat_input_t *i = vam->input;
7304   vl_api_mpls_tunnel_add_del_t *mp;
7305
7306   u8 is_add = 1;
7307   u8 l2_only = 0;
7308   u32 sw_if_index = ~0;
7309   u32 next_hop_sw_if_index = ~0;
7310   u32 next_hop_proto_is_ip4 = 1;
7311
7312   u32 next_hop_table_id = 0;
7313   ip4_address_t v4_next_hop_address = {
7314     .as_u32 = 0,
7315   };
7316   ip6_address_t v6_next_hop_address = { {0} };
7317   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7318   int ret;
7319
7320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7321     {
7322       if (unformat (i, "add"))
7323         is_add = 1;
7324       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7325         is_add = 0;
7326       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7327         ;
7328       else if (unformat (i, "via %U",
7329                          unformat_ip4_address, &v4_next_hop_address))
7330         {
7331           next_hop_proto_is_ip4 = 1;
7332         }
7333       else if (unformat (i, "via %U",
7334                          unformat_ip6_address, &v6_next_hop_address))
7335         {
7336           next_hop_proto_is_ip4 = 0;
7337         }
7338       else if (unformat (i, "l2-only"))
7339         l2_only = 1;
7340       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7341         ;
7342       else if (unformat (i, "out-label %d", &next_hop_out_label))
7343         vec_add1 (labels, ntohl (next_hop_out_label));
7344       else
7345         {
7346           clib_warning ("parse error '%U'", format_unformat_error, i);
7347           return -99;
7348         }
7349     }
7350
7351   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7352
7353   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7354   mp->mt_sw_if_index = ntohl (sw_if_index);
7355   mp->mt_is_add = is_add;
7356   mp->mt_l2_only = l2_only;
7357   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7358   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7359
7360   mp->mt_next_hop_n_out_labels = vec_len (labels);
7361
7362   if (0 != mp->mt_next_hop_n_out_labels)
7363     {
7364       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7365                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7366       vec_free (labels);
7367     }
7368
7369   if (next_hop_proto_is_ip4)
7370     {
7371       clib_memcpy (mp->mt_next_hop,
7372                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7373     }
7374   else
7375     {
7376       clib_memcpy (mp->mt_next_hop,
7377                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7378     }
7379
7380   S (mp);
7381   W (ret);
7382   return ret;
7383 }
7384
7385 static int
7386 api_sw_interface_set_unnumbered (vat_main_t * vam)
7387 {
7388   unformat_input_t *i = vam->input;
7389   vl_api_sw_interface_set_unnumbered_t *mp;
7390   u32 sw_if_index;
7391   u32 unnum_sw_index = ~0;
7392   u8 is_add = 1;
7393   u8 sw_if_index_set = 0;
7394   int ret;
7395
7396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7397     {
7398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7399         sw_if_index_set = 1;
7400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7401         sw_if_index_set = 1;
7402       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7403         ;
7404       else if (unformat (i, "del"))
7405         is_add = 0;
7406       else
7407         {
7408           clib_warning ("parse error '%U'", format_unformat_error, i);
7409           return -99;
7410         }
7411     }
7412
7413   if (sw_if_index_set == 0)
7414     {
7415       errmsg ("missing interface name or sw_if_index");
7416       return -99;
7417     }
7418
7419   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7420
7421   mp->sw_if_index = ntohl (sw_if_index);
7422   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7423   mp->is_add = is_add;
7424
7425   S (mp);
7426   W (ret);
7427   return ret;
7428 }
7429
7430 static int
7431 api_ip_neighbor_add_del (vat_main_t * vam)
7432 {
7433   unformat_input_t *i = vam->input;
7434   vl_api_ip_neighbor_add_del_t *mp;
7435   u32 sw_if_index;
7436   u8 sw_if_index_set = 0;
7437   u8 is_add = 1;
7438   u8 is_static = 0;
7439   u8 is_no_fib_entry = 0;
7440   u8 mac_address[6];
7441   u8 mac_set = 0;
7442   u8 v4_address_set = 0;
7443   u8 v6_address_set = 0;
7444   ip4_address_t v4address;
7445   ip6_address_t v6address;
7446   int ret;
7447
7448   memset (mac_address, 0, sizeof (mac_address));
7449
7450   /* Parse args required to build the message */
7451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7452     {
7453       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7454         {
7455           mac_set = 1;
7456         }
7457       else if (unformat (i, "del"))
7458         is_add = 0;
7459       else
7460         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7461         sw_if_index_set = 1;
7462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7463         sw_if_index_set = 1;
7464       else if (unformat (i, "is_static"))
7465         is_static = 1;
7466       else if (unformat (i, "no-fib-entry"))
7467         is_no_fib_entry = 1;
7468       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7469         v4_address_set = 1;
7470       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7471         v6_address_set = 1;
7472       else
7473         {
7474           clib_warning ("parse error '%U'", format_unformat_error, i);
7475           return -99;
7476         }
7477     }
7478
7479   if (sw_if_index_set == 0)
7480     {
7481       errmsg ("missing interface name or sw_if_index");
7482       return -99;
7483     }
7484   if (v4_address_set && v6_address_set)
7485     {
7486       errmsg ("both v4 and v6 addresses set");
7487       return -99;
7488     }
7489   if (!v4_address_set && !v6_address_set)
7490     {
7491       errmsg ("no address set");
7492       return -99;
7493     }
7494
7495   /* Construct the API message */
7496   M (IP_NEIGHBOR_ADD_DEL, mp);
7497
7498   mp->sw_if_index = ntohl (sw_if_index);
7499   mp->is_add = is_add;
7500   mp->is_static = is_static;
7501   mp->is_no_adj_fib = is_no_fib_entry;
7502   if (mac_set)
7503     clib_memcpy (mp->mac_address, mac_address, 6);
7504   if (v6_address_set)
7505     {
7506       mp->is_ipv6 = 1;
7507       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7508     }
7509   else
7510     {
7511       /* mp->is_ipv6 = 0; via memset in M macro above */
7512       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7513     }
7514
7515   /* send it... */
7516   S (mp);
7517
7518   /* Wait for a reply, return good/bad news  */
7519   W (ret);
7520   return ret;
7521 }
7522
7523 static int
7524 api_reset_vrf (vat_main_t * vam)
7525 {
7526   unformat_input_t *i = vam->input;
7527   vl_api_reset_vrf_t *mp;
7528   u32 vrf_id = 0;
7529   u8 is_ipv6 = 0;
7530   u8 vrf_id_set = 0;
7531   int ret;
7532
7533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7534     {
7535       if (unformat (i, "vrf %d", &vrf_id))
7536         vrf_id_set = 1;
7537       else if (unformat (i, "ipv6"))
7538         is_ipv6 = 1;
7539       else
7540         {
7541           clib_warning ("parse error '%U'", format_unformat_error, i);
7542           return -99;
7543         }
7544     }
7545
7546   if (vrf_id_set == 0)
7547     {
7548       errmsg ("missing vrf id");
7549       return -99;
7550     }
7551
7552   M (RESET_VRF, mp);
7553
7554   mp->vrf_id = ntohl (vrf_id);
7555   mp->is_ipv6 = is_ipv6;
7556
7557   S (mp);
7558   W (ret);
7559   return ret;
7560 }
7561
7562 static int
7563 api_create_vlan_subif (vat_main_t * vam)
7564 {
7565   unformat_input_t *i = vam->input;
7566   vl_api_create_vlan_subif_t *mp;
7567   u32 sw_if_index;
7568   u8 sw_if_index_set = 0;
7569   u32 vlan_id;
7570   u8 vlan_id_set = 0;
7571   int ret;
7572
7573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7574     {
7575       if (unformat (i, "sw_if_index %d", &sw_if_index))
7576         sw_if_index_set = 1;
7577       else
7578         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7579         sw_if_index_set = 1;
7580       else if (unformat (i, "vlan %d", &vlan_id))
7581         vlan_id_set = 1;
7582       else
7583         {
7584           clib_warning ("parse error '%U'", format_unformat_error, i);
7585           return -99;
7586         }
7587     }
7588
7589   if (sw_if_index_set == 0)
7590     {
7591       errmsg ("missing interface name or sw_if_index");
7592       return -99;
7593     }
7594
7595   if (vlan_id_set == 0)
7596     {
7597       errmsg ("missing vlan_id");
7598       return -99;
7599     }
7600   M (CREATE_VLAN_SUBIF, mp);
7601
7602   mp->sw_if_index = ntohl (sw_if_index);
7603   mp->vlan_id = ntohl (vlan_id);
7604
7605   S (mp);
7606   W (ret);
7607   return ret;
7608 }
7609
7610 #define foreach_create_subif_bit                \
7611 _(no_tags)                                      \
7612 _(one_tag)                                      \
7613 _(two_tags)                                     \
7614 _(dot1ad)                                       \
7615 _(exact_match)                                  \
7616 _(default_sub)                                  \
7617 _(outer_vlan_id_any)                            \
7618 _(inner_vlan_id_any)
7619
7620 static int
7621 api_create_subif (vat_main_t * vam)
7622 {
7623   unformat_input_t *i = vam->input;
7624   vl_api_create_subif_t *mp;
7625   u32 sw_if_index;
7626   u8 sw_if_index_set = 0;
7627   u32 sub_id;
7628   u8 sub_id_set = 0;
7629   u32 no_tags = 0;
7630   u32 one_tag = 0;
7631   u32 two_tags = 0;
7632   u32 dot1ad = 0;
7633   u32 exact_match = 0;
7634   u32 default_sub = 0;
7635   u32 outer_vlan_id_any = 0;
7636   u32 inner_vlan_id_any = 0;
7637   u32 tmp;
7638   u16 outer_vlan_id = 0;
7639   u16 inner_vlan_id = 0;
7640   int ret;
7641
7642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7643     {
7644       if (unformat (i, "sw_if_index %d", &sw_if_index))
7645         sw_if_index_set = 1;
7646       else
7647         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7648         sw_if_index_set = 1;
7649       else if (unformat (i, "sub_id %d", &sub_id))
7650         sub_id_set = 1;
7651       else if (unformat (i, "outer_vlan_id %d", &tmp))
7652         outer_vlan_id = tmp;
7653       else if (unformat (i, "inner_vlan_id %d", &tmp))
7654         inner_vlan_id = tmp;
7655
7656 #define _(a) else if (unformat (i, #a)) a = 1 ;
7657       foreach_create_subif_bit
7658 #undef _
7659         else
7660         {
7661           clib_warning ("parse error '%U'", format_unformat_error, i);
7662           return -99;
7663         }
7664     }
7665
7666   if (sw_if_index_set == 0)
7667     {
7668       errmsg ("missing interface name or sw_if_index");
7669       return -99;
7670     }
7671
7672   if (sub_id_set == 0)
7673     {
7674       errmsg ("missing sub_id");
7675       return -99;
7676     }
7677   M (CREATE_SUBIF, mp);
7678
7679   mp->sw_if_index = ntohl (sw_if_index);
7680   mp->sub_id = ntohl (sub_id);
7681
7682 #define _(a) mp->a = a;
7683   foreach_create_subif_bit;
7684 #undef _
7685
7686   mp->outer_vlan_id = ntohs (outer_vlan_id);
7687   mp->inner_vlan_id = ntohs (inner_vlan_id);
7688
7689   S (mp);
7690   W (ret);
7691   return ret;
7692 }
7693
7694 static int
7695 api_oam_add_del (vat_main_t * vam)
7696 {
7697   unformat_input_t *i = vam->input;
7698   vl_api_oam_add_del_t *mp;
7699   u32 vrf_id = 0;
7700   u8 is_add = 1;
7701   ip4_address_t src, dst;
7702   u8 src_set = 0;
7703   u8 dst_set = 0;
7704   int ret;
7705
7706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7707     {
7708       if (unformat (i, "vrf %d", &vrf_id))
7709         ;
7710       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7711         src_set = 1;
7712       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7713         dst_set = 1;
7714       else if (unformat (i, "del"))
7715         is_add = 0;
7716       else
7717         {
7718           clib_warning ("parse error '%U'", format_unformat_error, i);
7719           return -99;
7720         }
7721     }
7722
7723   if (src_set == 0)
7724     {
7725       errmsg ("missing src addr");
7726       return -99;
7727     }
7728
7729   if (dst_set == 0)
7730     {
7731       errmsg ("missing dst addr");
7732       return -99;
7733     }
7734
7735   M (OAM_ADD_DEL, mp);
7736
7737   mp->vrf_id = ntohl (vrf_id);
7738   mp->is_add = is_add;
7739   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7740   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7741
7742   S (mp);
7743   W (ret);
7744   return ret;
7745 }
7746
7747 static int
7748 api_reset_fib (vat_main_t * vam)
7749 {
7750   unformat_input_t *i = vam->input;
7751   vl_api_reset_fib_t *mp;
7752   u32 vrf_id = 0;
7753   u8 is_ipv6 = 0;
7754   u8 vrf_id_set = 0;
7755
7756   int ret;
7757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7758     {
7759       if (unformat (i, "vrf %d", &vrf_id))
7760         vrf_id_set = 1;
7761       else if (unformat (i, "ipv6"))
7762         is_ipv6 = 1;
7763       else
7764         {
7765           clib_warning ("parse error '%U'", format_unformat_error, i);
7766           return -99;
7767         }
7768     }
7769
7770   if (vrf_id_set == 0)
7771     {
7772       errmsg ("missing vrf id");
7773       return -99;
7774     }
7775
7776   M (RESET_FIB, mp);
7777
7778   mp->vrf_id = ntohl (vrf_id);
7779   mp->is_ipv6 = is_ipv6;
7780
7781   S (mp);
7782   W (ret);
7783   return ret;
7784 }
7785
7786 static int
7787 api_dhcp_proxy_config (vat_main_t * vam)
7788 {
7789   unformat_input_t *i = vam->input;
7790   vl_api_dhcp_proxy_config_t *mp;
7791   u32 rx_vrf_id = 0;
7792   u32 server_vrf_id = 0;
7793   u8 is_add = 1;
7794   u8 v4_address_set = 0;
7795   u8 v6_address_set = 0;
7796   ip4_address_t v4address;
7797   ip6_address_t v6address;
7798   u8 v4_src_address_set = 0;
7799   u8 v6_src_address_set = 0;
7800   ip4_address_t v4srcaddress;
7801   ip6_address_t v6srcaddress;
7802   int ret;
7803
7804   /* Parse args required to build the message */
7805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7806     {
7807       if (unformat (i, "del"))
7808         is_add = 0;
7809       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7810         ;
7811       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7812         ;
7813       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7814         v4_address_set = 1;
7815       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7816         v6_address_set = 1;
7817       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7818         v4_src_address_set = 1;
7819       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7820         v6_src_address_set = 1;
7821       else
7822         break;
7823     }
7824
7825   if (v4_address_set && v6_address_set)
7826     {
7827       errmsg ("both v4 and v6 server addresses set");
7828       return -99;
7829     }
7830   if (!v4_address_set && !v6_address_set)
7831     {
7832       errmsg ("no server addresses set");
7833       return -99;
7834     }
7835
7836   if (v4_src_address_set && v6_src_address_set)
7837     {
7838       errmsg ("both v4 and v6  src addresses set");
7839       return -99;
7840     }
7841   if (!v4_src_address_set && !v6_src_address_set)
7842     {
7843       errmsg ("no src addresses set");
7844       return -99;
7845     }
7846
7847   if (!(v4_src_address_set && v4_address_set) &&
7848       !(v6_src_address_set && v6_address_set))
7849     {
7850       errmsg ("no matching server and src addresses set");
7851       return -99;
7852     }
7853
7854   /* Construct the API message */
7855   M (DHCP_PROXY_CONFIG, mp);
7856
7857   mp->is_add = is_add;
7858   mp->rx_vrf_id = ntohl (rx_vrf_id);
7859   mp->server_vrf_id = ntohl (server_vrf_id);
7860   if (v6_address_set)
7861     {
7862       mp->is_ipv6 = 1;
7863       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7864       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7865     }
7866   else
7867     {
7868       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7869       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7870     }
7871
7872   /* send it... */
7873   S (mp);
7874
7875   /* Wait for a reply, return good/bad news  */
7876   W (ret);
7877   return ret;
7878 }
7879
7880 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7881 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7882
7883 static void
7884 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7885 {
7886   vat_main_t *vam = &vat_main;
7887   u32 i, count = mp->count;
7888   vl_api_dhcp_server_t *s;
7889
7890   if (mp->is_ipv6)
7891     print (vam->ofp,
7892            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7893            ntohl (mp->rx_vrf_id),
7894            format_ip6_address, mp->dhcp_src_address,
7895            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7896   else
7897     print (vam->ofp,
7898            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7899            ntohl (mp->rx_vrf_id),
7900            format_ip4_address, mp->dhcp_src_address,
7901            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7902
7903   for (i = 0; i < count; i++)
7904     {
7905       s = &mp->servers[i];
7906
7907       if (mp->is_ipv6)
7908         print (vam->ofp,
7909                " Server Table-ID %d, Server Address %U",
7910                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7911       else
7912         print (vam->ofp,
7913                " Server Table-ID %d, Server Address %U",
7914                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7915     }
7916 }
7917
7918 static void vl_api_dhcp_proxy_details_t_handler_json
7919   (vl_api_dhcp_proxy_details_t * mp)
7920 {
7921   vat_main_t *vam = &vat_main;
7922   vat_json_node_t *node = NULL;
7923   u32 i, count = mp->count;
7924   struct in_addr ip4;
7925   struct in6_addr ip6;
7926   vl_api_dhcp_server_t *s;
7927
7928   if (VAT_JSON_ARRAY != vam->json_tree.type)
7929     {
7930       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7931       vat_json_init_array (&vam->json_tree);
7932     }
7933   node = vat_json_array_add (&vam->json_tree);
7934
7935   vat_json_init_object (node);
7936   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7937   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7938   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7939
7940   if (mp->is_ipv6)
7941     {
7942       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7943       vat_json_object_add_ip6 (node, "src_address", ip6);
7944     }
7945   else
7946     {
7947       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7948       vat_json_object_add_ip4 (node, "src_address", ip4);
7949     }
7950
7951   for (i = 0; i < count; i++)
7952     {
7953       s = &mp->servers[i];
7954
7955       vat_json_object_add_uint (node, "server-table-id",
7956                                 ntohl (s->server_vrf_id));
7957
7958       if (mp->is_ipv6)
7959         {
7960           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
7961           vat_json_object_add_ip4 (node, "src_address", ip4);
7962         }
7963       else
7964         {
7965           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
7966           vat_json_object_add_ip6 (node, "server_address", ip6);
7967         }
7968     }
7969 }
7970
7971 static int
7972 api_dhcp_proxy_dump (vat_main_t * vam)
7973 {
7974   unformat_input_t *i = vam->input;
7975   vl_api_control_ping_t *mp_ping;
7976   vl_api_dhcp_proxy_dump_t *mp;
7977   u8 is_ipv6 = 0;
7978   int ret;
7979
7980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7981     {
7982       if (unformat (i, "ipv6"))
7983         is_ipv6 = 1;
7984       else
7985         {
7986           clib_warning ("parse error '%U'", format_unformat_error, i);
7987           return -99;
7988         }
7989     }
7990
7991   M (DHCP_PROXY_DUMP, mp);
7992
7993   mp->is_ip6 = is_ipv6;
7994   S (mp);
7995
7996   /* Use a control ping for synchronization */
7997   M (CONTROL_PING, mp_ping);
7998   S (mp_ping);
7999
8000   W (ret);
8001   return ret;
8002 }
8003
8004 static int
8005 api_dhcp_proxy_set_vss (vat_main_t * vam)
8006 {
8007   unformat_input_t *i = vam->input;
8008   vl_api_dhcp_proxy_set_vss_t *mp;
8009   u8 is_ipv6 = 0;
8010   u8 is_add = 1;
8011   u32 tbl_id;
8012   u8 tbl_id_set = 0;
8013   u32 oui;
8014   u8 oui_set = 0;
8015   u32 fib_id;
8016   u8 fib_id_set = 0;
8017   int ret;
8018
8019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8020     {
8021       if (unformat (i, "tbl_id %d", &tbl_id))
8022         tbl_id_set = 1;
8023       if (unformat (i, "fib_id %d", &fib_id))
8024         fib_id_set = 1;
8025       if (unformat (i, "oui %d", &oui))
8026         oui_set = 1;
8027       else if (unformat (i, "ipv6"))
8028         is_ipv6 = 1;
8029       else if (unformat (i, "del"))
8030         is_add = 0;
8031       else
8032         {
8033           clib_warning ("parse error '%U'", format_unformat_error, i);
8034           return -99;
8035         }
8036     }
8037
8038   if (tbl_id_set == 0)
8039     {
8040       errmsg ("missing tbl id");
8041       return -99;
8042     }
8043
8044   if (fib_id_set == 0)
8045     {
8046       errmsg ("missing fib id");
8047       return -99;
8048     }
8049   if (oui_set == 0)
8050     {
8051       errmsg ("missing oui");
8052       return -99;
8053     }
8054
8055   M (DHCP_PROXY_SET_VSS, mp);
8056   mp->tbl_id = ntohl (tbl_id);
8057   mp->fib_id = ntohl (fib_id);
8058   mp->oui = ntohl (oui);
8059   mp->is_ipv6 = is_ipv6;
8060   mp->is_add = is_add;
8061
8062   S (mp);
8063   W (ret);
8064   return ret;
8065 }
8066
8067 static int
8068 api_dhcp_client_config (vat_main_t * vam)
8069 {
8070   unformat_input_t *i = vam->input;
8071   vl_api_dhcp_client_config_t *mp;
8072   u32 sw_if_index;
8073   u8 sw_if_index_set = 0;
8074   u8 is_add = 1;
8075   u8 *hostname = 0;
8076   u8 disable_event = 0;
8077   int ret;
8078
8079   /* Parse args required to build the message */
8080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8081     {
8082       if (unformat (i, "del"))
8083         is_add = 0;
8084       else
8085         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8086         sw_if_index_set = 1;
8087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8088         sw_if_index_set = 1;
8089       else if (unformat (i, "hostname %s", &hostname))
8090         ;
8091       else if (unformat (i, "disable_event"))
8092         disable_event = 1;
8093       else
8094         break;
8095     }
8096
8097   if (sw_if_index_set == 0)
8098     {
8099       errmsg ("missing interface name or sw_if_index");
8100       return -99;
8101     }
8102
8103   if (vec_len (hostname) > 63)
8104     {
8105       errmsg ("hostname too long");
8106     }
8107   vec_add1 (hostname, 0);
8108
8109   /* Construct the API message */
8110   M (DHCP_CLIENT_CONFIG, mp);
8111
8112   mp->sw_if_index = htonl (sw_if_index);
8113   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8114   vec_free (hostname);
8115   mp->is_add = is_add;
8116   mp->want_dhcp_event = disable_event ? 0 : 1;
8117   mp->pid = htonl (getpid ());
8118
8119   /* send it... */
8120   S (mp);
8121
8122   /* Wait for a reply, return good/bad news  */
8123   W (ret);
8124   return ret;
8125 }
8126
8127 static int
8128 api_set_ip_flow_hash (vat_main_t * vam)
8129 {
8130   unformat_input_t *i = vam->input;
8131   vl_api_set_ip_flow_hash_t *mp;
8132   u32 vrf_id = 0;
8133   u8 is_ipv6 = 0;
8134   u8 vrf_id_set = 0;
8135   u8 src = 0;
8136   u8 dst = 0;
8137   u8 sport = 0;
8138   u8 dport = 0;
8139   u8 proto = 0;
8140   u8 reverse = 0;
8141   int ret;
8142
8143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8144     {
8145       if (unformat (i, "vrf %d", &vrf_id))
8146         vrf_id_set = 1;
8147       else if (unformat (i, "ipv6"))
8148         is_ipv6 = 1;
8149       else if (unformat (i, "src"))
8150         src = 1;
8151       else if (unformat (i, "dst"))
8152         dst = 1;
8153       else if (unformat (i, "sport"))
8154         sport = 1;
8155       else if (unformat (i, "dport"))
8156         dport = 1;
8157       else if (unformat (i, "proto"))
8158         proto = 1;
8159       else if (unformat (i, "reverse"))
8160         reverse = 1;
8161
8162       else
8163         {
8164           clib_warning ("parse error '%U'", format_unformat_error, i);
8165           return -99;
8166         }
8167     }
8168
8169   if (vrf_id_set == 0)
8170     {
8171       errmsg ("missing vrf id");
8172       return -99;
8173     }
8174
8175   M (SET_IP_FLOW_HASH, mp);
8176   mp->src = src;
8177   mp->dst = dst;
8178   mp->sport = sport;
8179   mp->dport = dport;
8180   mp->proto = proto;
8181   mp->reverse = reverse;
8182   mp->vrf_id = ntohl (vrf_id);
8183   mp->is_ipv6 = is_ipv6;
8184
8185   S (mp);
8186   W (ret);
8187   return ret;
8188 }
8189
8190 static int
8191 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8192 {
8193   unformat_input_t *i = vam->input;
8194   vl_api_sw_interface_ip6_enable_disable_t *mp;
8195   u32 sw_if_index;
8196   u8 sw_if_index_set = 0;
8197   u8 enable = 0;
8198   int ret;
8199
8200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8201     {
8202       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8203         sw_if_index_set = 1;
8204       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8205         sw_if_index_set = 1;
8206       else if (unformat (i, "enable"))
8207         enable = 1;
8208       else if (unformat (i, "disable"))
8209         enable = 0;
8210       else
8211         {
8212           clib_warning ("parse error '%U'", format_unformat_error, i);
8213           return -99;
8214         }
8215     }
8216
8217   if (sw_if_index_set == 0)
8218     {
8219       errmsg ("missing interface name or sw_if_index");
8220       return -99;
8221     }
8222
8223   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8224
8225   mp->sw_if_index = ntohl (sw_if_index);
8226   mp->enable = enable;
8227
8228   S (mp);
8229   W (ret);
8230   return ret;
8231 }
8232
8233 static int
8234 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8235 {
8236   unformat_input_t *i = vam->input;
8237   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8238   u32 sw_if_index;
8239   u8 sw_if_index_set = 0;
8240   u8 v6_address_set = 0;
8241   ip6_address_t v6address;
8242   int ret;
8243
8244   /* Parse args required to build the message */
8245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8246     {
8247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8248         sw_if_index_set = 1;
8249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8250         sw_if_index_set = 1;
8251       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8252         v6_address_set = 1;
8253       else
8254         break;
8255     }
8256
8257   if (sw_if_index_set == 0)
8258     {
8259       errmsg ("missing interface name or sw_if_index");
8260       return -99;
8261     }
8262   if (!v6_address_set)
8263     {
8264       errmsg ("no address set");
8265       return -99;
8266     }
8267
8268   /* Construct the API message */
8269   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8270
8271   mp->sw_if_index = ntohl (sw_if_index);
8272   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8273
8274   /* send it... */
8275   S (mp);
8276
8277   /* Wait for a reply, return good/bad news  */
8278   W (ret);
8279   return ret;
8280 }
8281
8282 static int
8283 api_ip6nd_proxy_add_del (vat_main_t * vam)
8284 {
8285   unformat_input_t *i = vam->input;
8286   vl_api_ip6nd_proxy_add_del_t *mp;
8287   u32 sw_if_index = ~0;
8288   u8 v6_address_set = 0;
8289   ip6_address_t v6address;
8290   u8 is_del = 0;
8291   int ret;
8292
8293   /* Parse args required to build the message */
8294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8295     {
8296       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8297         ;
8298       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8299         ;
8300       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8301         v6_address_set = 1;
8302       if (unformat (i, "del"))
8303         is_del = 1;
8304       else
8305         {
8306           clib_warning ("parse error '%U'", format_unformat_error, i);
8307           return -99;
8308         }
8309     }
8310
8311   if (sw_if_index == ~0)
8312     {
8313       errmsg ("missing interface name or sw_if_index");
8314       return -99;
8315     }
8316   if (!v6_address_set)
8317     {
8318       errmsg ("no address set");
8319       return -99;
8320     }
8321
8322   /* Construct the API message */
8323   M (IP6ND_PROXY_ADD_DEL, mp);
8324
8325   mp->is_del = is_del;
8326   mp->sw_if_index = ntohl (sw_if_index);
8327   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8328
8329   /* send it... */
8330   S (mp);
8331
8332   /* Wait for a reply, return good/bad news  */
8333   W (ret);
8334   return ret;
8335 }
8336
8337 static int
8338 api_ip6nd_proxy_dump (vat_main_t * vam)
8339 {
8340   vl_api_ip6nd_proxy_dump_t *mp;
8341   vl_api_control_ping_t *mp_ping;
8342   int ret;
8343
8344   M (IP6ND_PROXY_DUMP, mp);
8345
8346   S (mp);
8347
8348   /* Use a control ping for synchronization */
8349   M (CONTROL_PING, mp_ping);
8350   S (mp_ping);
8351
8352   W (ret);
8353   return ret;
8354 }
8355
8356 static void vl_api_ip6nd_proxy_details_t_handler
8357   (vl_api_ip6nd_proxy_details_t * mp)
8358 {
8359   vat_main_t *vam = &vat_main;
8360
8361   print (vam->ofp, "host %U sw_if_index %d",
8362          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8363 }
8364
8365 static void vl_api_ip6nd_proxy_details_t_handler_json
8366   (vl_api_ip6nd_proxy_details_t * mp)
8367 {
8368   vat_main_t *vam = &vat_main;
8369   struct in6_addr ip6;
8370   vat_json_node_t *node = NULL;
8371
8372   if (VAT_JSON_ARRAY != vam->json_tree.type)
8373     {
8374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8375       vat_json_init_array (&vam->json_tree);
8376     }
8377   node = vat_json_array_add (&vam->json_tree);
8378
8379   vat_json_init_object (node);
8380   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8381
8382   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8383   vat_json_object_add_ip6 (node, "host", ip6);
8384 }
8385
8386 static int
8387 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8388 {
8389   unformat_input_t *i = vam->input;
8390   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8391   u32 sw_if_index;
8392   u8 sw_if_index_set = 0;
8393   u32 address_length = 0;
8394   u8 v6_address_set = 0;
8395   ip6_address_t v6address;
8396   u8 use_default = 0;
8397   u8 no_advertise = 0;
8398   u8 off_link = 0;
8399   u8 no_autoconfig = 0;
8400   u8 no_onlink = 0;
8401   u8 is_no = 0;
8402   u32 val_lifetime = 0;
8403   u32 pref_lifetime = 0;
8404   int ret;
8405
8406   /* Parse args required to build the message */
8407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8408     {
8409       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8410         sw_if_index_set = 1;
8411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8412         sw_if_index_set = 1;
8413       else if (unformat (i, "%U/%d",
8414                          unformat_ip6_address, &v6address, &address_length))
8415         v6_address_set = 1;
8416       else if (unformat (i, "val_life %d", &val_lifetime))
8417         ;
8418       else if (unformat (i, "pref_life %d", &pref_lifetime))
8419         ;
8420       else if (unformat (i, "def"))
8421         use_default = 1;
8422       else if (unformat (i, "noadv"))
8423         no_advertise = 1;
8424       else if (unformat (i, "offl"))
8425         off_link = 1;
8426       else if (unformat (i, "noauto"))
8427         no_autoconfig = 1;
8428       else if (unformat (i, "nolink"))
8429         no_onlink = 1;
8430       else if (unformat (i, "isno"))
8431         is_no = 1;
8432       else
8433         {
8434           clib_warning ("parse error '%U'", format_unformat_error, i);
8435           return -99;
8436         }
8437     }
8438
8439   if (sw_if_index_set == 0)
8440     {
8441       errmsg ("missing interface name or sw_if_index");
8442       return -99;
8443     }
8444   if (!v6_address_set)
8445     {
8446       errmsg ("no address set");
8447       return -99;
8448     }
8449
8450   /* Construct the API message */
8451   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8452
8453   mp->sw_if_index = ntohl (sw_if_index);
8454   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8455   mp->address_length = address_length;
8456   mp->use_default = use_default;
8457   mp->no_advertise = no_advertise;
8458   mp->off_link = off_link;
8459   mp->no_autoconfig = no_autoconfig;
8460   mp->no_onlink = no_onlink;
8461   mp->is_no = is_no;
8462   mp->val_lifetime = ntohl (val_lifetime);
8463   mp->pref_lifetime = ntohl (pref_lifetime);
8464
8465   /* send it... */
8466   S (mp);
8467
8468   /* Wait for a reply, return good/bad news  */
8469   W (ret);
8470   return ret;
8471 }
8472
8473 static int
8474 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8475 {
8476   unformat_input_t *i = vam->input;
8477   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8478   u32 sw_if_index;
8479   u8 sw_if_index_set = 0;
8480   u8 suppress = 0;
8481   u8 managed = 0;
8482   u8 other = 0;
8483   u8 ll_option = 0;
8484   u8 send_unicast = 0;
8485   u8 cease = 0;
8486   u8 is_no = 0;
8487   u8 default_router = 0;
8488   u32 max_interval = 0;
8489   u32 min_interval = 0;
8490   u32 lifetime = 0;
8491   u32 initial_count = 0;
8492   u32 initial_interval = 0;
8493   int ret;
8494
8495
8496   /* Parse args required to build the message */
8497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8498     {
8499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8500         sw_if_index_set = 1;
8501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8502         sw_if_index_set = 1;
8503       else if (unformat (i, "maxint %d", &max_interval))
8504         ;
8505       else if (unformat (i, "minint %d", &min_interval))
8506         ;
8507       else if (unformat (i, "life %d", &lifetime))
8508         ;
8509       else if (unformat (i, "count %d", &initial_count))
8510         ;
8511       else if (unformat (i, "interval %d", &initial_interval))
8512         ;
8513       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8514         suppress = 1;
8515       else if (unformat (i, "managed"))
8516         managed = 1;
8517       else if (unformat (i, "other"))
8518         other = 1;
8519       else if (unformat (i, "ll"))
8520         ll_option = 1;
8521       else if (unformat (i, "send"))
8522         send_unicast = 1;
8523       else if (unformat (i, "cease"))
8524         cease = 1;
8525       else if (unformat (i, "isno"))
8526         is_no = 1;
8527       else if (unformat (i, "def"))
8528         default_router = 1;
8529       else
8530         {
8531           clib_warning ("parse error '%U'", format_unformat_error, i);
8532           return -99;
8533         }
8534     }
8535
8536   if (sw_if_index_set == 0)
8537     {
8538       errmsg ("missing interface name or sw_if_index");
8539       return -99;
8540     }
8541
8542   /* Construct the API message */
8543   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8544
8545   mp->sw_if_index = ntohl (sw_if_index);
8546   mp->max_interval = ntohl (max_interval);
8547   mp->min_interval = ntohl (min_interval);
8548   mp->lifetime = ntohl (lifetime);
8549   mp->initial_count = ntohl (initial_count);
8550   mp->initial_interval = ntohl (initial_interval);
8551   mp->suppress = suppress;
8552   mp->managed = managed;
8553   mp->other = other;
8554   mp->ll_option = ll_option;
8555   mp->send_unicast = send_unicast;
8556   mp->cease = cease;
8557   mp->is_no = is_no;
8558   mp->default_router = default_router;
8559
8560   /* send it... */
8561   S (mp);
8562
8563   /* Wait for a reply, return good/bad news  */
8564   W (ret);
8565   return ret;
8566 }
8567
8568 static int
8569 api_set_arp_neighbor_limit (vat_main_t * vam)
8570 {
8571   unformat_input_t *i = vam->input;
8572   vl_api_set_arp_neighbor_limit_t *mp;
8573   u32 arp_nbr_limit;
8574   u8 limit_set = 0;
8575   u8 is_ipv6 = 0;
8576   int ret;
8577
8578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8579     {
8580       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8581         limit_set = 1;
8582       else if (unformat (i, "ipv6"))
8583         is_ipv6 = 1;
8584       else
8585         {
8586           clib_warning ("parse error '%U'", format_unformat_error, i);
8587           return -99;
8588         }
8589     }
8590
8591   if (limit_set == 0)
8592     {
8593       errmsg ("missing limit value");
8594       return -99;
8595     }
8596
8597   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8598
8599   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8600   mp->is_ipv6 = is_ipv6;
8601
8602   S (mp);
8603   W (ret);
8604   return ret;
8605 }
8606
8607 static int
8608 api_l2_patch_add_del (vat_main_t * vam)
8609 {
8610   unformat_input_t *i = vam->input;
8611   vl_api_l2_patch_add_del_t *mp;
8612   u32 rx_sw_if_index;
8613   u8 rx_sw_if_index_set = 0;
8614   u32 tx_sw_if_index;
8615   u8 tx_sw_if_index_set = 0;
8616   u8 is_add = 1;
8617   int ret;
8618
8619   /* Parse args required to build the message */
8620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8621     {
8622       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8623         rx_sw_if_index_set = 1;
8624       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8625         tx_sw_if_index_set = 1;
8626       else if (unformat (i, "rx"))
8627         {
8628           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8629             {
8630               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8631                             &rx_sw_if_index))
8632                 rx_sw_if_index_set = 1;
8633             }
8634           else
8635             break;
8636         }
8637       else if (unformat (i, "tx"))
8638         {
8639           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8640             {
8641               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8642                             &tx_sw_if_index))
8643                 tx_sw_if_index_set = 1;
8644             }
8645           else
8646             break;
8647         }
8648       else if (unformat (i, "del"))
8649         is_add = 0;
8650       else
8651         break;
8652     }
8653
8654   if (rx_sw_if_index_set == 0)
8655     {
8656       errmsg ("missing rx interface name or rx_sw_if_index");
8657       return -99;
8658     }
8659
8660   if (tx_sw_if_index_set == 0)
8661     {
8662       errmsg ("missing tx interface name or tx_sw_if_index");
8663       return -99;
8664     }
8665
8666   M (L2_PATCH_ADD_DEL, mp);
8667
8668   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8669   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8670   mp->is_add = is_add;
8671
8672   S (mp);
8673   W (ret);
8674   return ret;
8675 }
8676
8677 u8 is_del;
8678 u8 localsid_addr[16];
8679 u8 end_psp;
8680 u8 behavior;
8681 u32 sw_if_index;
8682 u32 vlan_index;
8683 u32 fib_table;
8684 u8 nh_addr[16];
8685
8686 static int
8687 api_sr_localsid_add_del (vat_main_t * vam)
8688 {
8689   unformat_input_t *i = vam->input;
8690   vl_api_sr_localsid_add_del_t *mp;
8691
8692   u8 is_del;
8693   ip6_address_t localsid;
8694   u8 end_psp = 0;
8695   u8 behavior = ~0;
8696   u32 sw_if_index;
8697   u32 fib_table = ~(u32) 0;
8698   ip6_address_t next_hop;
8699
8700   bool nexthop_set = 0;
8701
8702   int ret;
8703
8704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8705     {
8706       if (unformat (i, "del"))
8707         is_del = 1;
8708       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8709       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8710         nexthop_set = 1;
8711       else if (unformat (i, "behavior %u", &behavior));
8712       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8713       else if (unformat (i, "fib-table %u", &fib_table));
8714       else if (unformat (i, "end.psp %u", &behavior));
8715       else
8716         break;
8717     }
8718
8719   M (SR_LOCALSID_ADD_DEL, mp);
8720
8721   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8722   if (nexthop_set)
8723     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8724   mp->behavior = behavior;
8725   mp->sw_if_index = ntohl (sw_if_index);
8726   mp->fib_table = ntohl (fib_table);
8727   mp->end_psp = end_psp;
8728   mp->is_del = is_del;
8729
8730   S (mp);
8731   W (ret);
8732   return ret;
8733 }
8734
8735 static int
8736 api_ioam_enable (vat_main_t * vam)
8737 {
8738   unformat_input_t *input = vam->input;
8739   vl_api_ioam_enable_t *mp;
8740   u32 id = 0;
8741   int has_trace_option = 0;
8742   int has_pot_option = 0;
8743   int has_seqno_option = 0;
8744   int has_analyse_option = 0;
8745   int ret;
8746
8747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8748     {
8749       if (unformat (input, "trace"))
8750         has_trace_option = 1;
8751       else if (unformat (input, "pot"))
8752         has_pot_option = 1;
8753       else if (unformat (input, "seqno"))
8754         has_seqno_option = 1;
8755       else if (unformat (input, "analyse"))
8756         has_analyse_option = 1;
8757       else
8758         break;
8759     }
8760   M (IOAM_ENABLE, mp);
8761   mp->id = htons (id);
8762   mp->seqno = has_seqno_option;
8763   mp->analyse = has_analyse_option;
8764   mp->pot_enable = has_pot_option;
8765   mp->trace_enable = has_trace_option;
8766
8767   S (mp);
8768   W (ret);
8769   return ret;
8770 }
8771
8772
8773 static int
8774 api_ioam_disable (vat_main_t * vam)
8775 {
8776   vl_api_ioam_disable_t *mp;
8777   int ret;
8778
8779   M (IOAM_DISABLE, mp);
8780   S (mp);
8781   W (ret);
8782   return ret;
8783 }
8784
8785 #define foreach_tcp_proto_field                 \
8786 _(src_port)                                     \
8787 _(dst_port)
8788
8789 #define foreach_udp_proto_field                 \
8790 _(src_port)                                     \
8791 _(dst_port)
8792
8793 #define foreach_ip4_proto_field                 \
8794 _(src_address)                                  \
8795 _(dst_address)                                  \
8796 _(tos)                                          \
8797 _(length)                                       \
8798 _(fragment_id)                                  \
8799 _(ttl)                                          \
8800 _(protocol)                                     \
8801 _(checksum)
8802
8803 typedef struct
8804 {
8805   u16 src_port, dst_port;
8806 } tcpudp_header_t;
8807
8808 #if VPP_API_TEST_BUILTIN == 0
8809 uword
8810 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8811 {
8812   u8 **maskp = va_arg (*args, u8 **);
8813   u8 *mask = 0;
8814   u8 found_something = 0;
8815   tcp_header_t *tcp;
8816
8817 #define _(a) u8 a=0;
8818   foreach_tcp_proto_field;
8819 #undef _
8820
8821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8822     {
8823       if (0);
8824 #define _(a) else if (unformat (input, #a)) a=1;
8825       foreach_tcp_proto_field
8826 #undef _
8827         else
8828         break;
8829     }
8830
8831 #define _(a) found_something += a;
8832   foreach_tcp_proto_field;
8833 #undef _
8834
8835   if (found_something == 0)
8836     return 0;
8837
8838   vec_validate (mask, sizeof (*tcp) - 1);
8839
8840   tcp = (tcp_header_t *) mask;
8841
8842 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8843   foreach_tcp_proto_field;
8844 #undef _
8845
8846   *maskp = mask;
8847   return 1;
8848 }
8849
8850 uword
8851 unformat_udp_mask (unformat_input_t * input, va_list * args)
8852 {
8853   u8 **maskp = va_arg (*args, u8 **);
8854   u8 *mask = 0;
8855   u8 found_something = 0;
8856   udp_header_t *udp;
8857
8858 #define _(a) u8 a=0;
8859   foreach_udp_proto_field;
8860 #undef _
8861
8862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8863     {
8864       if (0);
8865 #define _(a) else if (unformat (input, #a)) a=1;
8866       foreach_udp_proto_field
8867 #undef _
8868         else
8869         break;
8870     }
8871
8872 #define _(a) found_something += a;
8873   foreach_udp_proto_field;
8874 #undef _
8875
8876   if (found_something == 0)
8877     return 0;
8878
8879   vec_validate (mask, sizeof (*udp) - 1);
8880
8881   udp = (udp_header_t *) mask;
8882
8883 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8884   foreach_udp_proto_field;
8885 #undef _
8886
8887   *maskp = mask;
8888   return 1;
8889 }
8890
8891 uword
8892 unformat_l4_mask (unformat_input_t * input, va_list * args)
8893 {
8894   u8 **maskp = va_arg (*args, u8 **);
8895   u16 src_port = 0, dst_port = 0;
8896   tcpudp_header_t *tcpudp;
8897
8898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8899     {
8900       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8901         return 1;
8902       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8903         return 1;
8904       else if (unformat (input, "src_port"))
8905         src_port = 0xFFFF;
8906       else if (unformat (input, "dst_port"))
8907         dst_port = 0xFFFF;
8908       else
8909         return 0;
8910     }
8911
8912   if (!src_port && !dst_port)
8913     return 0;
8914
8915   u8 *mask = 0;
8916   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8917
8918   tcpudp = (tcpudp_header_t *) mask;
8919   tcpudp->src_port = src_port;
8920   tcpudp->dst_port = dst_port;
8921
8922   *maskp = mask;
8923
8924   return 1;
8925 }
8926
8927 uword
8928 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8929 {
8930   u8 **maskp = va_arg (*args, u8 **);
8931   u8 *mask = 0;
8932   u8 found_something = 0;
8933   ip4_header_t *ip;
8934
8935 #define _(a) u8 a=0;
8936   foreach_ip4_proto_field;
8937 #undef _
8938   u8 version = 0;
8939   u8 hdr_length = 0;
8940
8941
8942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8943     {
8944       if (unformat (input, "version"))
8945         version = 1;
8946       else if (unformat (input, "hdr_length"))
8947         hdr_length = 1;
8948       else if (unformat (input, "src"))
8949         src_address = 1;
8950       else if (unformat (input, "dst"))
8951         dst_address = 1;
8952       else if (unformat (input, "proto"))
8953         protocol = 1;
8954
8955 #define _(a) else if (unformat (input, #a)) a=1;
8956       foreach_ip4_proto_field
8957 #undef _
8958         else
8959         break;
8960     }
8961
8962 #define _(a) found_something += a;
8963   foreach_ip4_proto_field;
8964 #undef _
8965
8966   if (found_something == 0)
8967     return 0;
8968
8969   vec_validate (mask, sizeof (*ip) - 1);
8970
8971   ip = (ip4_header_t *) mask;
8972
8973 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8974   foreach_ip4_proto_field;
8975 #undef _
8976
8977   ip->ip_version_and_header_length = 0;
8978
8979   if (version)
8980     ip->ip_version_and_header_length |= 0xF0;
8981
8982   if (hdr_length)
8983     ip->ip_version_and_header_length |= 0x0F;
8984
8985   *maskp = mask;
8986   return 1;
8987 }
8988
8989 #define foreach_ip6_proto_field                 \
8990 _(src_address)                                  \
8991 _(dst_address)                                  \
8992 _(payload_length)                               \
8993 _(hop_limit)                                    \
8994 _(protocol)
8995
8996 uword
8997 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8998 {
8999   u8 **maskp = va_arg (*args, u8 **);
9000   u8 *mask = 0;
9001   u8 found_something = 0;
9002   ip6_header_t *ip;
9003   u32 ip_version_traffic_class_and_flow_label;
9004
9005 #define _(a) u8 a=0;
9006   foreach_ip6_proto_field;
9007 #undef _
9008   u8 version = 0;
9009   u8 traffic_class = 0;
9010   u8 flow_label = 0;
9011
9012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9013     {
9014       if (unformat (input, "version"))
9015         version = 1;
9016       else if (unformat (input, "traffic-class"))
9017         traffic_class = 1;
9018       else if (unformat (input, "flow-label"))
9019         flow_label = 1;
9020       else if (unformat (input, "src"))
9021         src_address = 1;
9022       else if (unformat (input, "dst"))
9023         dst_address = 1;
9024       else if (unformat (input, "proto"))
9025         protocol = 1;
9026
9027 #define _(a) else if (unformat (input, #a)) a=1;
9028       foreach_ip6_proto_field
9029 #undef _
9030         else
9031         break;
9032     }
9033
9034 #define _(a) found_something += a;
9035   foreach_ip6_proto_field;
9036 #undef _
9037
9038   if (found_something == 0)
9039     return 0;
9040
9041   vec_validate (mask, sizeof (*ip) - 1);
9042
9043   ip = (ip6_header_t *) mask;
9044
9045 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9046   foreach_ip6_proto_field;
9047 #undef _
9048
9049   ip_version_traffic_class_and_flow_label = 0;
9050
9051   if (version)
9052     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9053
9054   if (traffic_class)
9055     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9056
9057   if (flow_label)
9058     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9059
9060   ip->ip_version_traffic_class_and_flow_label =
9061     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9062
9063   *maskp = mask;
9064   return 1;
9065 }
9066
9067 uword
9068 unformat_l3_mask (unformat_input_t * input, va_list * args)
9069 {
9070   u8 **maskp = va_arg (*args, u8 **);
9071
9072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9073     {
9074       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9075         return 1;
9076       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9077         return 1;
9078       else
9079         break;
9080     }
9081   return 0;
9082 }
9083
9084 uword
9085 unformat_l2_mask (unformat_input_t * input, va_list * args)
9086 {
9087   u8 **maskp = va_arg (*args, u8 **);
9088   u8 *mask = 0;
9089   u8 src = 0;
9090   u8 dst = 0;
9091   u8 proto = 0;
9092   u8 tag1 = 0;
9093   u8 tag2 = 0;
9094   u8 ignore_tag1 = 0;
9095   u8 ignore_tag2 = 0;
9096   u8 cos1 = 0;
9097   u8 cos2 = 0;
9098   u8 dot1q = 0;
9099   u8 dot1ad = 0;
9100   int len = 14;
9101
9102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9103     {
9104       if (unformat (input, "src"))
9105         src = 1;
9106       else if (unformat (input, "dst"))
9107         dst = 1;
9108       else if (unformat (input, "proto"))
9109         proto = 1;
9110       else if (unformat (input, "tag1"))
9111         tag1 = 1;
9112       else if (unformat (input, "tag2"))
9113         tag2 = 1;
9114       else if (unformat (input, "ignore-tag1"))
9115         ignore_tag1 = 1;
9116       else if (unformat (input, "ignore-tag2"))
9117         ignore_tag2 = 1;
9118       else if (unformat (input, "cos1"))
9119         cos1 = 1;
9120       else if (unformat (input, "cos2"))
9121         cos2 = 1;
9122       else if (unformat (input, "dot1q"))
9123         dot1q = 1;
9124       else if (unformat (input, "dot1ad"))
9125         dot1ad = 1;
9126       else
9127         break;
9128     }
9129   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9130        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9131     return 0;
9132
9133   if (tag1 || ignore_tag1 || cos1 || dot1q)
9134     len = 18;
9135   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9136     len = 22;
9137
9138   vec_validate (mask, len - 1);
9139
9140   if (dst)
9141     memset (mask, 0xff, 6);
9142
9143   if (src)
9144     memset (mask + 6, 0xff, 6);
9145
9146   if (tag2 || dot1ad)
9147     {
9148       /* inner vlan tag */
9149       if (tag2)
9150         {
9151           mask[19] = 0xff;
9152           mask[18] = 0x0f;
9153         }
9154       if (cos2)
9155         mask[18] |= 0xe0;
9156       if (proto)
9157         mask[21] = mask[20] = 0xff;
9158       if (tag1)
9159         {
9160           mask[15] = 0xff;
9161           mask[14] = 0x0f;
9162         }
9163       if (cos1)
9164         mask[14] |= 0xe0;
9165       *maskp = mask;
9166       return 1;
9167     }
9168   if (tag1 | dot1q)
9169     {
9170       if (tag1)
9171         {
9172           mask[15] = 0xff;
9173           mask[14] = 0x0f;
9174         }
9175       if (cos1)
9176         mask[14] |= 0xe0;
9177       if (proto)
9178         mask[16] = mask[17] = 0xff;
9179
9180       *maskp = mask;
9181       return 1;
9182     }
9183   if (cos2)
9184     mask[18] |= 0xe0;
9185   if (cos1)
9186     mask[14] |= 0xe0;
9187   if (proto)
9188     mask[12] = mask[13] = 0xff;
9189
9190   *maskp = mask;
9191   return 1;
9192 }
9193
9194 uword
9195 unformat_classify_mask (unformat_input_t * input, va_list * args)
9196 {
9197   u8 **maskp = va_arg (*args, u8 **);
9198   u32 *skipp = va_arg (*args, u32 *);
9199   u32 *matchp = va_arg (*args, u32 *);
9200   u32 match;
9201   u8 *mask = 0;
9202   u8 *l2 = 0;
9203   u8 *l3 = 0;
9204   u8 *l4 = 0;
9205   int i;
9206
9207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9208     {
9209       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9210         ;
9211       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9212         ;
9213       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9214         ;
9215       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9216         ;
9217       else
9218         break;
9219     }
9220
9221   if (l4 && !l3)
9222     {
9223       vec_free (mask);
9224       vec_free (l2);
9225       vec_free (l4);
9226       return 0;
9227     }
9228
9229   if (mask || l2 || l3 || l4)
9230     {
9231       if (l2 || l3 || l4)
9232         {
9233           /* "With a free Ethernet header in every package" */
9234           if (l2 == 0)
9235             vec_validate (l2, 13);
9236           mask = l2;
9237           if (vec_len (l3))
9238             {
9239               vec_append (mask, l3);
9240               vec_free (l3);
9241             }
9242           if (vec_len (l4))
9243             {
9244               vec_append (mask, l4);
9245               vec_free (l4);
9246             }
9247         }
9248
9249       /* Scan forward looking for the first significant mask octet */
9250       for (i = 0; i < vec_len (mask); i++)
9251         if (mask[i])
9252           break;
9253
9254       /* compute (skip, match) params */
9255       *skipp = i / sizeof (u32x4);
9256       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9257
9258       /* Pad mask to an even multiple of the vector size */
9259       while (vec_len (mask) % sizeof (u32x4))
9260         vec_add1 (mask, 0);
9261
9262       match = vec_len (mask) / sizeof (u32x4);
9263
9264       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9265         {
9266           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9267           if (*tmp || *(tmp + 1))
9268             break;
9269           match--;
9270         }
9271       if (match == 0)
9272         clib_warning ("BUG: match 0");
9273
9274       _vec_len (mask) = match * sizeof (u32x4);
9275
9276       *matchp = match;
9277       *maskp = mask;
9278
9279       return 1;
9280     }
9281
9282   return 0;
9283 }
9284 #endif /* VPP_API_TEST_BUILTIN */
9285
9286 #define foreach_l2_next                         \
9287 _(drop, DROP)                                   \
9288 _(ethernet, ETHERNET_INPUT)                     \
9289 _(ip4, IP4_INPUT)                               \
9290 _(ip6, IP6_INPUT)
9291
9292 uword
9293 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9294 {
9295   u32 *miss_next_indexp = va_arg (*args, u32 *);
9296   u32 next_index = 0;
9297   u32 tmp;
9298
9299 #define _(n,N) \
9300   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9301   foreach_l2_next;
9302 #undef _
9303
9304   if (unformat (input, "%d", &tmp))
9305     {
9306       next_index = tmp;
9307       goto out;
9308     }
9309
9310   return 0;
9311
9312 out:
9313   *miss_next_indexp = next_index;
9314   return 1;
9315 }
9316
9317 #define foreach_ip_next                         \
9318 _(drop, DROP)                                   \
9319 _(local, LOCAL)                                 \
9320 _(rewrite, REWRITE)
9321
9322 uword
9323 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9324 {
9325   u32 *miss_next_indexp = va_arg (*args, u32 *);
9326   u32 next_index = 0;
9327   u32 tmp;
9328
9329 #define _(n,N) \
9330   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9331   foreach_ip_next;
9332 #undef _
9333
9334   if (unformat (input, "%d", &tmp))
9335     {
9336       next_index = tmp;
9337       goto out;
9338     }
9339
9340   return 0;
9341
9342 out:
9343   *miss_next_indexp = next_index;
9344   return 1;
9345 }
9346
9347 #define foreach_acl_next                        \
9348 _(deny, DENY)
9349
9350 uword
9351 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9352 {
9353   u32 *miss_next_indexp = va_arg (*args, u32 *);
9354   u32 next_index = 0;
9355   u32 tmp;
9356
9357 #define _(n,N) \
9358   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9359   foreach_acl_next;
9360 #undef _
9361
9362   if (unformat (input, "permit"))
9363     {
9364       next_index = ~0;
9365       goto out;
9366     }
9367   else if (unformat (input, "%d", &tmp))
9368     {
9369       next_index = tmp;
9370       goto out;
9371     }
9372
9373   return 0;
9374
9375 out:
9376   *miss_next_indexp = next_index;
9377   return 1;
9378 }
9379
9380 uword
9381 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9382 {
9383   u32 *r = va_arg (*args, u32 *);
9384
9385   if (unformat (input, "conform-color"))
9386     *r = POLICE_CONFORM;
9387   else if (unformat (input, "exceed-color"))
9388     *r = POLICE_EXCEED;
9389   else
9390     return 0;
9391
9392   return 1;
9393 }
9394
9395 static int
9396 api_classify_add_del_table (vat_main_t * vam)
9397 {
9398   unformat_input_t *i = vam->input;
9399   vl_api_classify_add_del_table_t *mp;
9400
9401   u32 nbuckets = 2;
9402   u32 skip = ~0;
9403   u32 match = ~0;
9404   int is_add = 1;
9405   int del_chain = 0;
9406   u32 table_index = ~0;
9407   u32 next_table_index = ~0;
9408   u32 miss_next_index = ~0;
9409   u32 memory_size = 32 << 20;
9410   u8 *mask = 0;
9411   u32 current_data_flag = 0;
9412   int current_data_offset = 0;
9413   int ret;
9414
9415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9416     {
9417       if (unformat (i, "del"))
9418         is_add = 0;
9419       else if (unformat (i, "del-chain"))
9420         {
9421           is_add = 0;
9422           del_chain = 1;
9423         }
9424       else if (unformat (i, "buckets %d", &nbuckets))
9425         ;
9426       else if (unformat (i, "memory_size %d", &memory_size))
9427         ;
9428       else if (unformat (i, "skip %d", &skip))
9429         ;
9430       else if (unformat (i, "match %d", &match))
9431         ;
9432       else if (unformat (i, "table %d", &table_index))
9433         ;
9434       else if (unformat (i, "mask %U", unformat_classify_mask,
9435                          &mask, &skip, &match))
9436         ;
9437       else if (unformat (i, "next-table %d", &next_table_index))
9438         ;
9439       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9440                          &miss_next_index))
9441         ;
9442       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9443                          &miss_next_index))
9444         ;
9445       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9446                          &miss_next_index))
9447         ;
9448       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9449         ;
9450       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9451         ;
9452       else
9453         break;
9454     }
9455
9456   if (is_add && mask == 0)
9457     {
9458       errmsg ("Mask required");
9459       return -99;
9460     }
9461
9462   if (is_add && skip == ~0)
9463     {
9464       errmsg ("skip count required");
9465       return -99;
9466     }
9467
9468   if (is_add && match == ~0)
9469     {
9470       errmsg ("match count required");
9471       return -99;
9472     }
9473
9474   if (!is_add && table_index == ~0)
9475     {
9476       errmsg ("table index required for delete");
9477       return -99;
9478     }
9479
9480   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9481
9482   mp->is_add = is_add;
9483   mp->del_chain = del_chain;
9484   mp->table_index = ntohl (table_index);
9485   mp->nbuckets = ntohl (nbuckets);
9486   mp->memory_size = ntohl (memory_size);
9487   mp->skip_n_vectors = ntohl (skip);
9488   mp->match_n_vectors = ntohl (match);
9489   mp->next_table_index = ntohl (next_table_index);
9490   mp->miss_next_index = ntohl (miss_next_index);
9491   mp->current_data_flag = ntohl (current_data_flag);
9492   mp->current_data_offset = ntohl (current_data_offset);
9493   clib_memcpy (mp->mask, mask, vec_len (mask));
9494
9495   vec_free (mask);
9496
9497   S (mp);
9498   W (ret);
9499   return ret;
9500 }
9501
9502 #if VPP_API_TEST_BUILTIN == 0
9503 uword
9504 unformat_l4_match (unformat_input_t * input, va_list * args)
9505 {
9506   u8 **matchp = va_arg (*args, u8 **);
9507
9508   u8 *proto_header = 0;
9509   int src_port = 0;
9510   int dst_port = 0;
9511
9512   tcpudp_header_t h;
9513
9514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9515     {
9516       if (unformat (input, "src_port %d", &src_port))
9517         ;
9518       else if (unformat (input, "dst_port %d", &dst_port))
9519         ;
9520       else
9521         return 0;
9522     }
9523
9524   h.src_port = clib_host_to_net_u16 (src_port);
9525   h.dst_port = clib_host_to_net_u16 (dst_port);
9526   vec_validate (proto_header, sizeof (h) - 1);
9527   memcpy (proto_header, &h, sizeof (h));
9528
9529   *matchp = proto_header;
9530
9531   return 1;
9532 }
9533
9534 uword
9535 unformat_ip4_match (unformat_input_t * input, va_list * args)
9536 {
9537   u8 **matchp = va_arg (*args, u8 **);
9538   u8 *match = 0;
9539   ip4_header_t *ip;
9540   int version = 0;
9541   u32 version_val;
9542   int hdr_length = 0;
9543   u32 hdr_length_val;
9544   int src = 0, dst = 0;
9545   ip4_address_t src_val, dst_val;
9546   int proto = 0;
9547   u32 proto_val;
9548   int tos = 0;
9549   u32 tos_val;
9550   int length = 0;
9551   u32 length_val;
9552   int fragment_id = 0;
9553   u32 fragment_id_val;
9554   int ttl = 0;
9555   int ttl_val;
9556   int checksum = 0;
9557   u32 checksum_val;
9558
9559   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9560     {
9561       if (unformat (input, "version %d", &version_val))
9562         version = 1;
9563       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9564         hdr_length = 1;
9565       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9566         src = 1;
9567       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9568         dst = 1;
9569       else if (unformat (input, "proto %d", &proto_val))
9570         proto = 1;
9571       else if (unformat (input, "tos %d", &tos_val))
9572         tos = 1;
9573       else if (unformat (input, "length %d", &length_val))
9574         length = 1;
9575       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9576         fragment_id = 1;
9577       else if (unformat (input, "ttl %d", &ttl_val))
9578         ttl = 1;
9579       else if (unformat (input, "checksum %d", &checksum_val))
9580         checksum = 1;
9581       else
9582         break;
9583     }
9584
9585   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9586       + ttl + checksum == 0)
9587     return 0;
9588
9589   /*
9590    * Aligned because we use the real comparison functions
9591    */
9592   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9593
9594   ip = (ip4_header_t *) match;
9595
9596   /* These are realistically matched in practice */
9597   if (src)
9598     ip->src_address.as_u32 = src_val.as_u32;
9599
9600   if (dst)
9601     ip->dst_address.as_u32 = dst_val.as_u32;
9602
9603   if (proto)
9604     ip->protocol = proto_val;
9605
9606
9607   /* These are not, but they're included for completeness */
9608   if (version)
9609     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9610
9611   if (hdr_length)
9612     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9613
9614   if (tos)
9615     ip->tos = tos_val;
9616
9617   if (length)
9618     ip->length = clib_host_to_net_u16 (length_val);
9619
9620   if (ttl)
9621     ip->ttl = ttl_val;
9622
9623   if (checksum)
9624     ip->checksum = clib_host_to_net_u16 (checksum_val);
9625
9626   *matchp = match;
9627   return 1;
9628 }
9629
9630 uword
9631 unformat_ip6_match (unformat_input_t * input, va_list * args)
9632 {
9633   u8 **matchp = va_arg (*args, u8 **);
9634   u8 *match = 0;
9635   ip6_header_t *ip;
9636   int version = 0;
9637   u32 version_val;
9638   u8 traffic_class = 0;
9639   u32 traffic_class_val = 0;
9640   u8 flow_label = 0;
9641   u8 flow_label_val;
9642   int src = 0, dst = 0;
9643   ip6_address_t src_val, dst_val;
9644   int proto = 0;
9645   u32 proto_val;
9646   int payload_length = 0;
9647   u32 payload_length_val;
9648   int hop_limit = 0;
9649   int hop_limit_val;
9650   u32 ip_version_traffic_class_and_flow_label;
9651
9652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9653     {
9654       if (unformat (input, "version %d", &version_val))
9655         version = 1;
9656       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9657         traffic_class = 1;
9658       else if (unformat (input, "flow_label %d", &flow_label_val))
9659         flow_label = 1;
9660       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9661         src = 1;
9662       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9663         dst = 1;
9664       else if (unformat (input, "proto %d", &proto_val))
9665         proto = 1;
9666       else if (unformat (input, "payload_length %d", &payload_length_val))
9667         payload_length = 1;
9668       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9669         hop_limit = 1;
9670       else
9671         break;
9672     }
9673
9674   if (version + traffic_class + flow_label + src + dst + proto +
9675       payload_length + hop_limit == 0)
9676     return 0;
9677
9678   /*
9679    * Aligned because we use the real comparison functions
9680    */
9681   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9682
9683   ip = (ip6_header_t *) match;
9684
9685   if (src)
9686     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9687
9688   if (dst)
9689     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9690
9691   if (proto)
9692     ip->protocol = proto_val;
9693
9694   ip_version_traffic_class_and_flow_label = 0;
9695
9696   if (version)
9697     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9698
9699   if (traffic_class)
9700     ip_version_traffic_class_and_flow_label |=
9701       (traffic_class_val & 0xFF) << 20;
9702
9703   if (flow_label)
9704     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9705
9706   ip->ip_version_traffic_class_and_flow_label =
9707     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9708
9709   if (payload_length)
9710     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9711
9712   if (hop_limit)
9713     ip->hop_limit = hop_limit_val;
9714
9715   *matchp = match;
9716   return 1;
9717 }
9718
9719 uword
9720 unformat_l3_match (unformat_input_t * input, va_list * args)
9721 {
9722   u8 **matchp = va_arg (*args, u8 **);
9723
9724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9725     {
9726       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9727         return 1;
9728       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9729         return 1;
9730       else
9731         break;
9732     }
9733   return 0;
9734 }
9735
9736 uword
9737 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9738 {
9739   u8 *tagp = va_arg (*args, u8 *);
9740   u32 tag;
9741
9742   if (unformat (input, "%d", &tag))
9743     {
9744       tagp[0] = (tag >> 8) & 0x0F;
9745       tagp[1] = tag & 0xFF;
9746       return 1;
9747     }
9748
9749   return 0;
9750 }
9751
9752 uword
9753 unformat_l2_match (unformat_input_t * input, va_list * args)
9754 {
9755   u8 **matchp = va_arg (*args, u8 **);
9756   u8 *match = 0;
9757   u8 src = 0;
9758   u8 src_val[6];
9759   u8 dst = 0;
9760   u8 dst_val[6];
9761   u8 proto = 0;
9762   u16 proto_val;
9763   u8 tag1 = 0;
9764   u8 tag1_val[2];
9765   u8 tag2 = 0;
9766   u8 tag2_val[2];
9767   int len = 14;
9768   u8 ignore_tag1 = 0;
9769   u8 ignore_tag2 = 0;
9770   u8 cos1 = 0;
9771   u8 cos2 = 0;
9772   u32 cos1_val = 0;
9773   u32 cos2_val = 0;
9774
9775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9776     {
9777       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9778         src = 1;
9779       else
9780         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9781         dst = 1;
9782       else if (unformat (input, "proto %U",
9783                          unformat_ethernet_type_host_byte_order, &proto_val))
9784         proto = 1;
9785       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9786         tag1 = 1;
9787       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9788         tag2 = 1;
9789       else if (unformat (input, "ignore-tag1"))
9790         ignore_tag1 = 1;
9791       else if (unformat (input, "ignore-tag2"))
9792         ignore_tag2 = 1;
9793       else if (unformat (input, "cos1 %d", &cos1_val))
9794         cos1 = 1;
9795       else if (unformat (input, "cos2 %d", &cos2_val))
9796         cos2 = 1;
9797       else
9798         break;
9799     }
9800   if ((src + dst + proto + tag1 + tag2 +
9801        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9802     return 0;
9803
9804   if (tag1 || ignore_tag1 || cos1)
9805     len = 18;
9806   if (tag2 || ignore_tag2 || cos2)
9807     len = 22;
9808
9809   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9810
9811   if (dst)
9812     clib_memcpy (match, dst_val, 6);
9813
9814   if (src)
9815     clib_memcpy (match + 6, src_val, 6);
9816
9817   if (tag2)
9818     {
9819       /* inner vlan tag */
9820       match[19] = tag2_val[1];
9821       match[18] = tag2_val[0];
9822       if (cos2)
9823         match[18] |= (cos2_val & 0x7) << 5;
9824       if (proto)
9825         {
9826           match[21] = proto_val & 0xff;
9827           match[20] = proto_val >> 8;
9828         }
9829       if (tag1)
9830         {
9831           match[15] = tag1_val[1];
9832           match[14] = tag1_val[0];
9833         }
9834       if (cos1)
9835         match[14] |= (cos1_val & 0x7) << 5;
9836       *matchp = match;
9837       return 1;
9838     }
9839   if (tag1)
9840     {
9841       match[15] = tag1_val[1];
9842       match[14] = tag1_val[0];
9843       if (proto)
9844         {
9845           match[17] = proto_val & 0xff;
9846           match[16] = proto_val >> 8;
9847         }
9848       if (cos1)
9849         match[14] |= (cos1_val & 0x7) << 5;
9850
9851       *matchp = match;
9852       return 1;
9853     }
9854   if (cos2)
9855     match[18] |= (cos2_val & 0x7) << 5;
9856   if (cos1)
9857     match[14] |= (cos1_val & 0x7) << 5;
9858   if (proto)
9859     {
9860       match[13] = proto_val & 0xff;
9861       match[12] = proto_val >> 8;
9862     }
9863
9864   *matchp = match;
9865   return 1;
9866 }
9867 #endif
9868
9869 uword
9870 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9871 {
9872   u8 **matchp = va_arg (*args, u8 **);
9873   u32 skip_n_vectors = va_arg (*args, u32);
9874   u32 match_n_vectors = va_arg (*args, u32);
9875
9876   u8 *match = 0;
9877   u8 *l2 = 0;
9878   u8 *l3 = 0;
9879   u8 *l4 = 0;
9880
9881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9882     {
9883       if (unformat (input, "hex %U", unformat_hex_string, &match))
9884         ;
9885       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9886         ;
9887       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9888         ;
9889       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9890         ;
9891       else
9892         break;
9893     }
9894
9895   if (l4 && !l3)
9896     {
9897       vec_free (match);
9898       vec_free (l2);
9899       vec_free (l4);
9900       return 0;
9901     }
9902
9903   if (match || l2 || l3 || l4)
9904     {
9905       if (l2 || l3 || l4)
9906         {
9907           /* "Win a free Ethernet header in every packet" */
9908           if (l2 == 0)
9909             vec_validate_aligned (l2, 13, sizeof (u32x4));
9910           match = l2;
9911           if (vec_len (l3))
9912             {
9913               vec_append_aligned (match, l3, sizeof (u32x4));
9914               vec_free (l3);
9915             }
9916           if (vec_len (l4))
9917             {
9918               vec_append_aligned (match, l4, sizeof (u32x4));
9919               vec_free (l4);
9920             }
9921         }
9922
9923       /* Make sure the vector is big enough even if key is all 0's */
9924       vec_validate_aligned
9925         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9926          sizeof (u32x4));
9927
9928       /* Set size, include skipped vectors */
9929       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9930
9931       *matchp = match;
9932
9933       return 1;
9934     }
9935
9936   return 0;
9937 }
9938
9939 static int
9940 api_classify_add_del_session (vat_main_t * vam)
9941 {
9942   unformat_input_t *i = vam->input;
9943   vl_api_classify_add_del_session_t *mp;
9944   int is_add = 1;
9945   u32 table_index = ~0;
9946   u32 hit_next_index = ~0;
9947   u32 opaque_index = ~0;
9948   u8 *match = 0;
9949   i32 advance = 0;
9950   u32 skip_n_vectors = 0;
9951   u32 match_n_vectors = 0;
9952   u32 action = 0;
9953   u32 metadata = 0;
9954   int ret;
9955
9956   /*
9957    * Warning: you have to supply skip_n and match_n
9958    * because the API client cant simply look at the classify
9959    * table object.
9960    */
9961
9962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9963     {
9964       if (unformat (i, "del"))
9965         is_add = 0;
9966       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9967                          &hit_next_index))
9968         ;
9969       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9970                          &hit_next_index))
9971         ;
9972       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9973                          &hit_next_index))
9974         ;
9975       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9976         ;
9977       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9978         ;
9979       else if (unformat (i, "opaque-index %d", &opaque_index))
9980         ;
9981       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9982         ;
9983       else if (unformat (i, "match_n %d", &match_n_vectors))
9984         ;
9985       else if (unformat (i, "match %U", api_unformat_classify_match,
9986                          &match, skip_n_vectors, match_n_vectors))
9987         ;
9988       else if (unformat (i, "advance %d", &advance))
9989         ;
9990       else if (unformat (i, "table-index %d", &table_index))
9991         ;
9992       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9993         action = 1;
9994       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9995         action = 2;
9996       else if (unformat (i, "action %d", &action))
9997         ;
9998       else if (unformat (i, "metadata %d", &metadata))
9999         ;
10000       else
10001         break;
10002     }
10003
10004   if (table_index == ~0)
10005     {
10006       errmsg ("Table index required");
10007       return -99;
10008     }
10009
10010   if (is_add && match == 0)
10011     {
10012       errmsg ("Match value required");
10013       return -99;
10014     }
10015
10016   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10017
10018   mp->is_add = is_add;
10019   mp->table_index = ntohl (table_index);
10020   mp->hit_next_index = ntohl (hit_next_index);
10021   mp->opaque_index = ntohl (opaque_index);
10022   mp->advance = ntohl (advance);
10023   mp->action = action;
10024   mp->metadata = ntohl (metadata);
10025   clib_memcpy (mp->match, match, vec_len (match));
10026   vec_free (match);
10027
10028   S (mp);
10029   W (ret);
10030   return ret;
10031 }
10032
10033 static int
10034 api_classify_set_interface_ip_table (vat_main_t * vam)
10035 {
10036   unformat_input_t *i = vam->input;
10037   vl_api_classify_set_interface_ip_table_t *mp;
10038   u32 sw_if_index;
10039   int sw_if_index_set;
10040   u32 table_index = ~0;
10041   u8 is_ipv6 = 0;
10042   int ret;
10043
10044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10045     {
10046       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10047         sw_if_index_set = 1;
10048       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10049         sw_if_index_set = 1;
10050       else if (unformat (i, "table %d", &table_index))
10051         ;
10052       else
10053         {
10054           clib_warning ("parse error '%U'", format_unformat_error, i);
10055           return -99;
10056         }
10057     }
10058
10059   if (sw_if_index_set == 0)
10060     {
10061       errmsg ("missing interface name or sw_if_index");
10062       return -99;
10063     }
10064
10065
10066   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10067
10068   mp->sw_if_index = ntohl (sw_if_index);
10069   mp->table_index = ntohl (table_index);
10070   mp->is_ipv6 = is_ipv6;
10071
10072   S (mp);
10073   W (ret);
10074   return ret;
10075 }
10076
10077 static int
10078 api_classify_set_interface_l2_tables (vat_main_t * vam)
10079 {
10080   unformat_input_t *i = vam->input;
10081   vl_api_classify_set_interface_l2_tables_t *mp;
10082   u32 sw_if_index;
10083   int sw_if_index_set;
10084   u32 ip4_table_index = ~0;
10085   u32 ip6_table_index = ~0;
10086   u32 other_table_index = ~0;
10087   u32 is_input = 1;
10088   int ret;
10089
10090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10091     {
10092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10093         sw_if_index_set = 1;
10094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10095         sw_if_index_set = 1;
10096       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10097         ;
10098       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10099         ;
10100       else if (unformat (i, "other-table %d", &other_table_index))
10101         ;
10102       else if (unformat (i, "is-input %d", &is_input))
10103         ;
10104       else
10105         {
10106           clib_warning ("parse error '%U'", format_unformat_error, i);
10107           return -99;
10108         }
10109     }
10110
10111   if (sw_if_index_set == 0)
10112     {
10113       errmsg ("missing interface name or sw_if_index");
10114       return -99;
10115     }
10116
10117
10118   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10119
10120   mp->sw_if_index = ntohl (sw_if_index);
10121   mp->ip4_table_index = ntohl (ip4_table_index);
10122   mp->ip6_table_index = ntohl (ip6_table_index);
10123   mp->other_table_index = ntohl (other_table_index);
10124   mp->is_input = (u8) is_input;
10125
10126   S (mp);
10127   W (ret);
10128   return ret;
10129 }
10130
10131 static int
10132 api_set_ipfix_exporter (vat_main_t * vam)
10133 {
10134   unformat_input_t *i = vam->input;
10135   vl_api_set_ipfix_exporter_t *mp;
10136   ip4_address_t collector_address;
10137   u8 collector_address_set = 0;
10138   u32 collector_port = ~0;
10139   ip4_address_t src_address;
10140   u8 src_address_set = 0;
10141   u32 vrf_id = ~0;
10142   u32 path_mtu = ~0;
10143   u32 template_interval = ~0;
10144   u8 udp_checksum = 0;
10145   int ret;
10146
10147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10148     {
10149       if (unformat (i, "collector_address %U", unformat_ip4_address,
10150                     &collector_address))
10151         collector_address_set = 1;
10152       else if (unformat (i, "collector_port %d", &collector_port))
10153         ;
10154       else if (unformat (i, "src_address %U", unformat_ip4_address,
10155                          &src_address))
10156         src_address_set = 1;
10157       else if (unformat (i, "vrf_id %d", &vrf_id))
10158         ;
10159       else if (unformat (i, "path_mtu %d", &path_mtu))
10160         ;
10161       else if (unformat (i, "template_interval %d", &template_interval))
10162         ;
10163       else if (unformat (i, "udp_checksum"))
10164         udp_checksum = 1;
10165       else
10166         break;
10167     }
10168
10169   if (collector_address_set == 0)
10170     {
10171       errmsg ("collector_address required");
10172       return -99;
10173     }
10174
10175   if (src_address_set == 0)
10176     {
10177       errmsg ("src_address required");
10178       return -99;
10179     }
10180
10181   M (SET_IPFIX_EXPORTER, mp);
10182
10183   memcpy (mp->collector_address, collector_address.data,
10184           sizeof (collector_address.data));
10185   mp->collector_port = htons ((u16) collector_port);
10186   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10187   mp->vrf_id = htonl (vrf_id);
10188   mp->path_mtu = htonl (path_mtu);
10189   mp->template_interval = htonl (template_interval);
10190   mp->udp_checksum = udp_checksum;
10191
10192   S (mp);
10193   W (ret);
10194   return ret;
10195 }
10196
10197 static int
10198 api_set_ipfix_classify_stream (vat_main_t * vam)
10199 {
10200   unformat_input_t *i = vam->input;
10201   vl_api_set_ipfix_classify_stream_t *mp;
10202   u32 domain_id = 0;
10203   u32 src_port = UDP_DST_PORT_ipfix;
10204   int ret;
10205
10206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10207     {
10208       if (unformat (i, "domain %d", &domain_id))
10209         ;
10210       else if (unformat (i, "src_port %d", &src_port))
10211         ;
10212       else
10213         {
10214           errmsg ("unknown input `%U'", format_unformat_error, i);
10215           return -99;
10216         }
10217     }
10218
10219   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10220
10221   mp->domain_id = htonl (domain_id);
10222   mp->src_port = htons ((u16) src_port);
10223
10224   S (mp);
10225   W (ret);
10226   return ret;
10227 }
10228
10229 static int
10230 api_ipfix_classify_table_add_del (vat_main_t * vam)
10231 {
10232   unformat_input_t *i = vam->input;
10233   vl_api_ipfix_classify_table_add_del_t *mp;
10234   int is_add = -1;
10235   u32 classify_table_index = ~0;
10236   u8 ip_version = 0;
10237   u8 transport_protocol = 255;
10238   int ret;
10239
10240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10241     {
10242       if (unformat (i, "add"))
10243         is_add = 1;
10244       else if (unformat (i, "del"))
10245         is_add = 0;
10246       else if (unformat (i, "table %d", &classify_table_index))
10247         ;
10248       else if (unformat (i, "ip4"))
10249         ip_version = 4;
10250       else if (unformat (i, "ip6"))
10251         ip_version = 6;
10252       else if (unformat (i, "tcp"))
10253         transport_protocol = 6;
10254       else if (unformat (i, "udp"))
10255         transport_protocol = 17;
10256       else
10257         {
10258           errmsg ("unknown input `%U'", format_unformat_error, i);
10259           return -99;
10260         }
10261     }
10262
10263   if (is_add == -1)
10264     {
10265       errmsg ("expecting: add|del");
10266       return -99;
10267     }
10268   if (classify_table_index == ~0)
10269     {
10270       errmsg ("classifier table not specified");
10271       return -99;
10272     }
10273   if (ip_version == 0)
10274     {
10275       errmsg ("IP version not specified");
10276       return -99;
10277     }
10278
10279   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10280
10281   mp->is_add = is_add;
10282   mp->table_id = htonl (classify_table_index);
10283   mp->ip_version = ip_version;
10284   mp->transport_protocol = transport_protocol;
10285
10286   S (mp);
10287   W (ret);
10288   return ret;
10289 }
10290
10291 static int
10292 api_get_node_index (vat_main_t * vam)
10293 {
10294   unformat_input_t *i = vam->input;
10295   vl_api_get_node_index_t *mp;
10296   u8 *name = 0;
10297   int ret;
10298
10299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10300     {
10301       if (unformat (i, "node %s", &name))
10302         ;
10303       else
10304         break;
10305     }
10306   if (name == 0)
10307     {
10308       errmsg ("node name required");
10309       return -99;
10310     }
10311   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10312     {
10313       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10314       return -99;
10315     }
10316
10317   M (GET_NODE_INDEX, mp);
10318   clib_memcpy (mp->node_name, name, vec_len (name));
10319   vec_free (name);
10320
10321   S (mp);
10322   W (ret);
10323   return ret;
10324 }
10325
10326 static int
10327 api_get_next_index (vat_main_t * vam)
10328 {
10329   unformat_input_t *i = vam->input;
10330   vl_api_get_next_index_t *mp;
10331   u8 *node_name = 0, *next_node_name = 0;
10332   int ret;
10333
10334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10335     {
10336       if (unformat (i, "node-name %s", &node_name))
10337         ;
10338       else if (unformat (i, "next-node-name %s", &next_node_name))
10339         break;
10340     }
10341
10342   if (node_name == 0)
10343     {
10344       errmsg ("node name required");
10345       return -99;
10346     }
10347   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10348     {
10349       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10350       return -99;
10351     }
10352
10353   if (next_node_name == 0)
10354     {
10355       errmsg ("next node name required");
10356       return -99;
10357     }
10358   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10359     {
10360       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10361       return -99;
10362     }
10363
10364   M (GET_NEXT_INDEX, mp);
10365   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10366   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10367   vec_free (node_name);
10368   vec_free (next_node_name);
10369
10370   S (mp);
10371   W (ret);
10372   return ret;
10373 }
10374
10375 static int
10376 api_add_node_next (vat_main_t * vam)
10377 {
10378   unformat_input_t *i = vam->input;
10379   vl_api_add_node_next_t *mp;
10380   u8 *name = 0;
10381   u8 *next = 0;
10382   int ret;
10383
10384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10385     {
10386       if (unformat (i, "node %s", &name))
10387         ;
10388       else if (unformat (i, "next %s", &next))
10389         ;
10390       else
10391         break;
10392     }
10393   if (name == 0)
10394     {
10395       errmsg ("node name required");
10396       return -99;
10397     }
10398   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10399     {
10400       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10401       return -99;
10402     }
10403   if (next == 0)
10404     {
10405       errmsg ("next node required");
10406       return -99;
10407     }
10408   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10409     {
10410       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10411       return -99;
10412     }
10413
10414   M (ADD_NODE_NEXT, mp);
10415   clib_memcpy (mp->node_name, name, vec_len (name));
10416   clib_memcpy (mp->next_name, next, vec_len (next));
10417   vec_free (name);
10418   vec_free (next);
10419
10420   S (mp);
10421   W (ret);
10422   return ret;
10423 }
10424
10425 static int
10426 api_l2tpv3_create_tunnel (vat_main_t * vam)
10427 {
10428   unformat_input_t *i = vam->input;
10429   ip6_address_t client_address, our_address;
10430   int client_address_set = 0;
10431   int our_address_set = 0;
10432   u32 local_session_id = 0;
10433   u32 remote_session_id = 0;
10434   u64 local_cookie = 0;
10435   u64 remote_cookie = 0;
10436   u8 l2_sublayer_present = 0;
10437   vl_api_l2tpv3_create_tunnel_t *mp;
10438   int ret;
10439
10440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10441     {
10442       if (unformat (i, "client_address %U", unformat_ip6_address,
10443                     &client_address))
10444         client_address_set = 1;
10445       else if (unformat (i, "our_address %U", unformat_ip6_address,
10446                          &our_address))
10447         our_address_set = 1;
10448       else if (unformat (i, "local_session_id %d", &local_session_id))
10449         ;
10450       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10451         ;
10452       else if (unformat (i, "local_cookie %lld", &local_cookie))
10453         ;
10454       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10455         ;
10456       else if (unformat (i, "l2-sublayer-present"))
10457         l2_sublayer_present = 1;
10458       else
10459         break;
10460     }
10461
10462   if (client_address_set == 0)
10463     {
10464       errmsg ("client_address required");
10465       return -99;
10466     }
10467
10468   if (our_address_set == 0)
10469     {
10470       errmsg ("our_address required");
10471       return -99;
10472     }
10473
10474   M (L2TPV3_CREATE_TUNNEL, mp);
10475
10476   clib_memcpy (mp->client_address, client_address.as_u8,
10477                sizeof (mp->client_address));
10478
10479   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10480
10481   mp->local_session_id = ntohl (local_session_id);
10482   mp->remote_session_id = ntohl (remote_session_id);
10483   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10484   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10485   mp->l2_sublayer_present = l2_sublayer_present;
10486   mp->is_ipv6 = 1;
10487
10488   S (mp);
10489   W (ret);
10490   return ret;
10491 }
10492
10493 static int
10494 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10495 {
10496   unformat_input_t *i = vam->input;
10497   u32 sw_if_index;
10498   u8 sw_if_index_set = 0;
10499   u64 new_local_cookie = 0;
10500   u64 new_remote_cookie = 0;
10501   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10502   int ret;
10503
10504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10505     {
10506       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10507         sw_if_index_set = 1;
10508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10509         sw_if_index_set = 1;
10510       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10511         ;
10512       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10513         ;
10514       else
10515         break;
10516     }
10517
10518   if (sw_if_index_set == 0)
10519     {
10520       errmsg ("missing interface name or sw_if_index");
10521       return -99;
10522     }
10523
10524   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10525
10526   mp->sw_if_index = ntohl (sw_if_index);
10527   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10528   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10529
10530   S (mp);
10531   W (ret);
10532   return ret;
10533 }
10534
10535 static int
10536 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10537 {
10538   unformat_input_t *i = vam->input;
10539   vl_api_l2tpv3_interface_enable_disable_t *mp;
10540   u32 sw_if_index;
10541   u8 sw_if_index_set = 0;
10542   u8 enable_disable = 1;
10543   int ret;
10544
10545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10546     {
10547       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10548         sw_if_index_set = 1;
10549       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10550         sw_if_index_set = 1;
10551       else if (unformat (i, "enable"))
10552         enable_disable = 1;
10553       else if (unformat (i, "disable"))
10554         enable_disable = 0;
10555       else
10556         break;
10557     }
10558
10559   if (sw_if_index_set == 0)
10560     {
10561       errmsg ("missing interface name or sw_if_index");
10562       return -99;
10563     }
10564
10565   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10566
10567   mp->sw_if_index = ntohl (sw_if_index);
10568   mp->enable_disable = enable_disable;
10569
10570   S (mp);
10571   W (ret);
10572   return ret;
10573 }
10574
10575 static int
10576 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10577 {
10578   unformat_input_t *i = vam->input;
10579   vl_api_l2tpv3_set_lookup_key_t *mp;
10580   u8 key = ~0;
10581   int ret;
10582
10583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10584     {
10585       if (unformat (i, "lookup_v6_src"))
10586         key = L2T_LOOKUP_SRC_ADDRESS;
10587       else if (unformat (i, "lookup_v6_dst"))
10588         key = L2T_LOOKUP_DST_ADDRESS;
10589       else if (unformat (i, "lookup_session_id"))
10590         key = L2T_LOOKUP_SESSION_ID;
10591       else
10592         break;
10593     }
10594
10595   if (key == (u8) ~ 0)
10596     {
10597       errmsg ("l2tp session lookup key unset");
10598       return -99;
10599     }
10600
10601   M (L2TPV3_SET_LOOKUP_KEY, mp);
10602
10603   mp->key = key;
10604
10605   S (mp);
10606   W (ret);
10607   return ret;
10608 }
10609
10610 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10611   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10612 {
10613   vat_main_t *vam = &vat_main;
10614
10615   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10616          format_ip6_address, mp->our_address,
10617          format_ip6_address, mp->client_address,
10618          clib_net_to_host_u32 (mp->sw_if_index));
10619
10620   print (vam->ofp,
10621          "   local cookies %016llx %016llx remote cookie %016llx",
10622          clib_net_to_host_u64 (mp->local_cookie[0]),
10623          clib_net_to_host_u64 (mp->local_cookie[1]),
10624          clib_net_to_host_u64 (mp->remote_cookie));
10625
10626   print (vam->ofp, "   local session-id %d remote session-id %d",
10627          clib_net_to_host_u32 (mp->local_session_id),
10628          clib_net_to_host_u32 (mp->remote_session_id));
10629
10630   print (vam->ofp, "   l2 specific sublayer %s\n",
10631          mp->l2_sublayer_present ? "preset" : "absent");
10632
10633 }
10634
10635 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10636   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10637 {
10638   vat_main_t *vam = &vat_main;
10639   vat_json_node_t *node = NULL;
10640   struct in6_addr addr;
10641
10642   if (VAT_JSON_ARRAY != vam->json_tree.type)
10643     {
10644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10645       vat_json_init_array (&vam->json_tree);
10646     }
10647   node = vat_json_array_add (&vam->json_tree);
10648
10649   vat_json_init_object (node);
10650
10651   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10652   vat_json_object_add_ip6 (node, "our_address", addr);
10653   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10654   vat_json_object_add_ip6 (node, "client_address", addr);
10655
10656   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10657   vat_json_init_array (lc);
10658   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10659   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10660   vat_json_object_add_uint (node, "remote_cookie",
10661                             clib_net_to_host_u64 (mp->remote_cookie));
10662
10663   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10664   vat_json_object_add_uint (node, "local_session_id",
10665                             clib_net_to_host_u32 (mp->local_session_id));
10666   vat_json_object_add_uint (node, "remote_session_id",
10667                             clib_net_to_host_u32 (mp->remote_session_id));
10668   vat_json_object_add_string_copy (node, "l2_sublayer",
10669                                    mp->l2_sublayer_present ? (u8 *) "present"
10670                                    : (u8 *) "absent");
10671 }
10672
10673 static int
10674 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10675 {
10676   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10677   vl_api_control_ping_t *mp_ping;
10678   int ret;
10679
10680   /* Get list of l2tpv3-tunnel interfaces */
10681   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10682   S (mp);
10683
10684   /* Use a control ping for synchronization */
10685   M (CONTROL_PING, mp_ping);
10686   S (mp_ping);
10687
10688   W (ret);
10689   return ret;
10690 }
10691
10692
10693 static void vl_api_sw_interface_tap_details_t_handler
10694   (vl_api_sw_interface_tap_details_t * mp)
10695 {
10696   vat_main_t *vam = &vat_main;
10697
10698   print (vam->ofp, "%-16s %d",
10699          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10700 }
10701
10702 static void vl_api_sw_interface_tap_details_t_handler_json
10703   (vl_api_sw_interface_tap_details_t * mp)
10704 {
10705   vat_main_t *vam = &vat_main;
10706   vat_json_node_t *node = NULL;
10707
10708   if (VAT_JSON_ARRAY != vam->json_tree.type)
10709     {
10710       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10711       vat_json_init_array (&vam->json_tree);
10712     }
10713   node = vat_json_array_add (&vam->json_tree);
10714
10715   vat_json_init_object (node);
10716   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10717   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10718 }
10719
10720 static int
10721 api_sw_interface_tap_dump (vat_main_t * vam)
10722 {
10723   vl_api_sw_interface_tap_dump_t *mp;
10724   vl_api_control_ping_t *mp_ping;
10725   int ret;
10726
10727   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10728   /* Get list of tap interfaces */
10729   M (SW_INTERFACE_TAP_DUMP, mp);
10730   S (mp);
10731
10732   /* Use a control ping for synchronization */
10733   M (CONTROL_PING, mp_ping);
10734   S (mp_ping);
10735
10736   W (ret);
10737   return ret;
10738 }
10739
10740 static uword unformat_vxlan_decap_next
10741   (unformat_input_t * input, va_list * args)
10742 {
10743   u32 *result = va_arg (*args, u32 *);
10744   u32 tmp;
10745
10746   if (unformat (input, "l2"))
10747     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10748   else if (unformat (input, "%d", &tmp))
10749     *result = tmp;
10750   else
10751     return 0;
10752   return 1;
10753 }
10754
10755 static int
10756 api_vxlan_add_del_tunnel (vat_main_t * vam)
10757 {
10758   unformat_input_t *line_input = vam->input;
10759   vl_api_vxlan_add_del_tunnel_t *mp;
10760   ip46_address_t src, dst;
10761   u8 is_add = 1;
10762   u8 ipv4_set = 0, ipv6_set = 0;
10763   u8 src_set = 0;
10764   u8 dst_set = 0;
10765   u8 grp_set = 0;
10766   u32 mcast_sw_if_index = ~0;
10767   u32 encap_vrf_id = 0;
10768   u32 decap_next_index = ~0;
10769   u32 vni = 0;
10770   int ret;
10771
10772   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10773   memset (&src, 0, sizeof src);
10774   memset (&dst, 0, sizeof dst);
10775
10776   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10777     {
10778       if (unformat (line_input, "del"))
10779         is_add = 0;
10780       else
10781         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10782         {
10783           ipv4_set = 1;
10784           src_set = 1;
10785         }
10786       else
10787         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10788         {
10789           ipv4_set = 1;
10790           dst_set = 1;
10791         }
10792       else
10793         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10794         {
10795           ipv6_set = 1;
10796           src_set = 1;
10797         }
10798       else
10799         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10800         {
10801           ipv6_set = 1;
10802           dst_set = 1;
10803         }
10804       else if (unformat (line_input, "group %U %U",
10805                          unformat_ip4_address, &dst.ip4,
10806                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10807         {
10808           grp_set = dst_set = 1;
10809           ipv4_set = 1;
10810         }
10811       else if (unformat (line_input, "group %U",
10812                          unformat_ip4_address, &dst.ip4))
10813         {
10814           grp_set = dst_set = 1;
10815           ipv4_set = 1;
10816         }
10817       else if (unformat (line_input, "group %U %U",
10818                          unformat_ip6_address, &dst.ip6,
10819                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10820         {
10821           grp_set = dst_set = 1;
10822           ipv6_set = 1;
10823         }
10824       else if (unformat (line_input, "group %U",
10825                          unformat_ip6_address, &dst.ip6))
10826         {
10827           grp_set = dst_set = 1;
10828           ipv6_set = 1;
10829         }
10830       else
10831         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10832         ;
10833       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10834         ;
10835       else if (unformat (line_input, "decap-next %U",
10836                          unformat_vxlan_decap_next, &decap_next_index))
10837         ;
10838       else if (unformat (line_input, "vni %d", &vni))
10839         ;
10840       else
10841         {
10842           errmsg ("parse error '%U'", format_unformat_error, line_input);
10843           return -99;
10844         }
10845     }
10846
10847   if (src_set == 0)
10848     {
10849       errmsg ("tunnel src address not specified");
10850       return -99;
10851     }
10852   if (dst_set == 0)
10853     {
10854       errmsg ("tunnel dst address not specified");
10855       return -99;
10856     }
10857
10858   if (grp_set && !ip46_address_is_multicast (&dst))
10859     {
10860       errmsg ("tunnel group address not multicast");
10861       return -99;
10862     }
10863   if (grp_set && mcast_sw_if_index == ~0)
10864     {
10865       errmsg ("tunnel nonexistent multicast device");
10866       return -99;
10867     }
10868   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10869     {
10870       errmsg ("tunnel dst address must be unicast");
10871       return -99;
10872     }
10873
10874
10875   if (ipv4_set && ipv6_set)
10876     {
10877       errmsg ("both IPv4 and IPv6 addresses specified");
10878       return -99;
10879     }
10880
10881   if ((vni == 0) || (vni >> 24))
10882     {
10883       errmsg ("vni not specified or out of range");
10884       return -99;
10885     }
10886
10887   M (VXLAN_ADD_DEL_TUNNEL, mp);
10888
10889   if (ipv6_set)
10890     {
10891       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10892       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10893     }
10894   else
10895     {
10896       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10897       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10898     }
10899   mp->encap_vrf_id = ntohl (encap_vrf_id);
10900   mp->decap_next_index = ntohl (decap_next_index);
10901   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10902   mp->vni = ntohl (vni);
10903   mp->is_add = is_add;
10904   mp->is_ipv6 = ipv6_set;
10905
10906   S (mp);
10907   W (ret);
10908   return ret;
10909 }
10910
10911 static void vl_api_vxlan_tunnel_details_t_handler
10912   (vl_api_vxlan_tunnel_details_t * mp)
10913 {
10914   vat_main_t *vam = &vat_main;
10915   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
10916   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
10917
10918   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10919          ntohl (mp->sw_if_index),
10920          format_ip46_address, &src, IP46_TYPE_ANY,
10921          format_ip46_address, &dst, IP46_TYPE_ANY,
10922          ntohl (mp->encap_vrf_id),
10923          ntohl (mp->decap_next_index), ntohl (mp->vni),
10924          ntohl (mp->mcast_sw_if_index));
10925 }
10926
10927 static void vl_api_vxlan_tunnel_details_t_handler_json
10928   (vl_api_vxlan_tunnel_details_t * mp)
10929 {
10930   vat_main_t *vam = &vat_main;
10931   vat_json_node_t *node = NULL;
10932
10933   if (VAT_JSON_ARRAY != vam->json_tree.type)
10934     {
10935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10936       vat_json_init_array (&vam->json_tree);
10937     }
10938   node = vat_json_array_add (&vam->json_tree);
10939
10940   vat_json_init_object (node);
10941   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10942   if (mp->is_ipv6)
10943     {
10944       struct in6_addr ip6;
10945
10946       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10947       vat_json_object_add_ip6 (node, "src_address", ip6);
10948       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10949       vat_json_object_add_ip6 (node, "dst_address", ip6);
10950     }
10951   else
10952     {
10953       struct in_addr ip4;
10954
10955       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10956       vat_json_object_add_ip4 (node, "src_address", ip4);
10957       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10958       vat_json_object_add_ip4 (node, "dst_address", ip4);
10959     }
10960   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10961   vat_json_object_add_uint (node, "decap_next_index",
10962                             ntohl (mp->decap_next_index));
10963   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10964   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10965   vat_json_object_add_uint (node, "mcast_sw_if_index",
10966                             ntohl (mp->mcast_sw_if_index));
10967 }
10968
10969 static int
10970 api_vxlan_tunnel_dump (vat_main_t * vam)
10971 {
10972   unformat_input_t *i = vam->input;
10973   vl_api_vxlan_tunnel_dump_t *mp;
10974   vl_api_control_ping_t *mp_ping;
10975   u32 sw_if_index;
10976   u8 sw_if_index_set = 0;
10977   int ret;
10978
10979   /* Parse args required to build the message */
10980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10981     {
10982       if (unformat (i, "sw_if_index %d", &sw_if_index))
10983         sw_if_index_set = 1;
10984       else
10985         break;
10986     }
10987
10988   if (sw_if_index_set == 0)
10989     {
10990       sw_if_index = ~0;
10991     }
10992
10993   if (!vam->json_output)
10994     {
10995       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10996              "sw_if_index", "src_address", "dst_address",
10997              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10998     }
10999
11000   /* Get list of vxlan-tunnel interfaces */
11001   M (VXLAN_TUNNEL_DUMP, mp);
11002
11003   mp->sw_if_index = htonl (sw_if_index);
11004
11005   S (mp);
11006
11007   /* Use a control ping for synchronization */
11008   M (CONTROL_PING, mp_ping);
11009   S (mp_ping);
11010
11011   W (ret);
11012   return ret;
11013 }
11014
11015 static int
11016 api_gre_add_del_tunnel (vat_main_t * vam)
11017 {
11018   unformat_input_t *line_input = vam->input;
11019   vl_api_gre_add_del_tunnel_t *mp;
11020   ip4_address_t src4, dst4;
11021   u8 is_add = 1;
11022   u8 teb = 0;
11023   u8 src_set = 0;
11024   u8 dst_set = 0;
11025   u32 outer_fib_id = 0;
11026   int ret;
11027
11028   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11029     {
11030       if (unformat (line_input, "del"))
11031         is_add = 0;
11032       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11033         src_set = 1;
11034       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11035         dst_set = 1;
11036       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11037         ;
11038       else if (unformat (line_input, "teb"))
11039         teb = 1;
11040       else
11041         {
11042           errmsg ("parse error '%U'", format_unformat_error, line_input);
11043           return -99;
11044         }
11045     }
11046
11047   if (src_set == 0)
11048     {
11049       errmsg ("tunnel src address not specified");
11050       return -99;
11051     }
11052   if (dst_set == 0)
11053     {
11054       errmsg ("tunnel dst address not specified");
11055       return -99;
11056     }
11057
11058
11059   M (GRE_ADD_DEL_TUNNEL, mp);
11060
11061   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
11062   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
11063   mp->outer_fib_id = ntohl (outer_fib_id);
11064   mp->is_add = is_add;
11065   mp->teb = teb;
11066
11067   S (mp);
11068   W (ret);
11069   return ret;
11070 }
11071
11072 static void vl_api_gre_tunnel_details_t_handler
11073   (vl_api_gre_tunnel_details_t * mp)
11074 {
11075   vat_main_t *vam = &vat_main;
11076
11077   print (vam->ofp, "%11d%15U%15U%6d%14d",
11078          ntohl (mp->sw_if_index),
11079          format_ip4_address, &mp->src_address,
11080          format_ip4_address, &mp->dst_address,
11081          mp->teb, ntohl (mp->outer_fib_id));
11082 }
11083
11084 static void vl_api_gre_tunnel_details_t_handler_json
11085   (vl_api_gre_tunnel_details_t * mp)
11086 {
11087   vat_main_t *vam = &vat_main;
11088   vat_json_node_t *node = NULL;
11089   struct in_addr ip4;
11090
11091   if (VAT_JSON_ARRAY != vam->json_tree.type)
11092     {
11093       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11094       vat_json_init_array (&vam->json_tree);
11095     }
11096   node = vat_json_array_add (&vam->json_tree);
11097
11098   vat_json_init_object (node);
11099   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11100   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11101   vat_json_object_add_ip4 (node, "src_address", ip4);
11102   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11103   vat_json_object_add_ip4 (node, "dst_address", ip4);
11104   vat_json_object_add_uint (node, "teb", mp->teb);
11105   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11106 }
11107
11108 static int
11109 api_gre_tunnel_dump (vat_main_t * vam)
11110 {
11111   unformat_input_t *i = vam->input;
11112   vl_api_gre_tunnel_dump_t *mp;
11113   vl_api_control_ping_t *mp_ping;
11114   u32 sw_if_index;
11115   u8 sw_if_index_set = 0;
11116   int ret;
11117
11118   /* Parse args required to build the message */
11119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11120     {
11121       if (unformat (i, "sw_if_index %d", &sw_if_index))
11122         sw_if_index_set = 1;
11123       else
11124         break;
11125     }
11126
11127   if (sw_if_index_set == 0)
11128     {
11129       sw_if_index = ~0;
11130     }
11131
11132   if (!vam->json_output)
11133     {
11134       print (vam->ofp, "%11s%15s%15s%6s%14s",
11135              "sw_if_index", "src_address", "dst_address", "teb",
11136              "outer_fib_id");
11137     }
11138
11139   /* Get list of gre-tunnel interfaces */
11140   M (GRE_TUNNEL_DUMP, mp);
11141
11142   mp->sw_if_index = htonl (sw_if_index);
11143
11144   S (mp);
11145
11146   /* Use a control ping for synchronization */
11147   M (CONTROL_PING, mp_ping);
11148   S (mp_ping);
11149
11150   W (ret);
11151   return ret;
11152 }
11153
11154 static int
11155 api_l2_fib_clear_table (vat_main_t * vam)
11156 {
11157 //  unformat_input_t * i = vam->input;
11158   vl_api_l2_fib_clear_table_t *mp;
11159   int ret;
11160
11161   M (L2_FIB_CLEAR_TABLE, mp);
11162
11163   S (mp);
11164   W (ret);
11165   return ret;
11166 }
11167
11168 static int
11169 api_l2_interface_efp_filter (vat_main_t * vam)
11170 {
11171   unformat_input_t *i = vam->input;
11172   vl_api_l2_interface_efp_filter_t *mp;
11173   u32 sw_if_index;
11174   u8 enable = 1;
11175   u8 sw_if_index_set = 0;
11176   int ret;
11177
11178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11179     {
11180       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11181         sw_if_index_set = 1;
11182       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11183         sw_if_index_set = 1;
11184       else if (unformat (i, "enable"))
11185         enable = 1;
11186       else if (unformat (i, "disable"))
11187         enable = 0;
11188       else
11189         {
11190           clib_warning ("parse error '%U'", format_unformat_error, i);
11191           return -99;
11192         }
11193     }
11194
11195   if (sw_if_index_set == 0)
11196     {
11197       errmsg ("missing sw_if_index");
11198       return -99;
11199     }
11200
11201   M (L2_INTERFACE_EFP_FILTER, mp);
11202
11203   mp->sw_if_index = ntohl (sw_if_index);
11204   mp->enable_disable = enable;
11205
11206   S (mp);
11207   W (ret);
11208   return ret;
11209 }
11210
11211 #define foreach_vtr_op                          \
11212 _("disable",  L2_VTR_DISABLED)                  \
11213 _("push-1",  L2_VTR_PUSH_1)                     \
11214 _("push-2",  L2_VTR_PUSH_2)                     \
11215 _("pop-1",  L2_VTR_POP_1)                       \
11216 _("pop-2",  L2_VTR_POP_2)                       \
11217 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11218 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11219 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11220 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11221
11222 static int
11223 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11224 {
11225   unformat_input_t *i = vam->input;
11226   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11227   u32 sw_if_index;
11228   u8 sw_if_index_set = 0;
11229   u8 vtr_op_set = 0;
11230   u32 vtr_op = 0;
11231   u32 push_dot1q = 1;
11232   u32 tag1 = ~0;
11233   u32 tag2 = ~0;
11234   int ret;
11235
11236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11237     {
11238       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11239         sw_if_index_set = 1;
11240       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11241         sw_if_index_set = 1;
11242       else if (unformat (i, "vtr_op %d", &vtr_op))
11243         vtr_op_set = 1;
11244 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11245       foreach_vtr_op
11246 #undef _
11247         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11248         ;
11249       else if (unformat (i, "tag1 %d", &tag1))
11250         ;
11251       else if (unformat (i, "tag2 %d", &tag2))
11252         ;
11253       else
11254         {
11255           clib_warning ("parse error '%U'", format_unformat_error, i);
11256           return -99;
11257         }
11258     }
11259
11260   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11261     {
11262       errmsg ("missing vtr operation or sw_if_index");
11263       return -99;
11264     }
11265
11266   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11267   mp->sw_if_index = ntohl (sw_if_index);
11268   mp->vtr_op = ntohl (vtr_op);
11269   mp->push_dot1q = ntohl (push_dot1q);
11270   mp->tag1 = ntohl (tag1);
11271   mp->tag2 = ntohl (tag2);
11272
11273   S (mp);
11274   W (ret);
11275   return ret;
11276 }
11277
11278 static int
11279 api_create_vhost_user_if (vat_main_t * vam)
11280 {
11281   unformat_input_t *i = vam->input;
11282   vl_api_create_vhost_user_if_t *mp;
11283   u8 *file_name;
11284   u8 is_server = 0;
11285   u8 file_name_set = 0;
11286   u32 custom_dev_instance = ~0;
11287   u8 hwaddr[6];
11288   u8 use_custom_mac = 0;
11289   u8 *tag = 0;
11290   int ret;
11291   u8 operation_mode = VHOST_USER_POLLING_MODE;
11292
11293   /* Shut up coverity */
11294   memset (hwaddr, 0, sizeof (hwaddr));
11295
11296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11297     {
11298       if (unformat (i, "socket %s", &file_name))
11299         {
11300           file_name_set = 1;
11301         }
11302       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11303         ;
11304       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11305         use_custom_mac = 1;
11306       else if (unformat (i, "server"))
11307         is_server = 1;
11308       else if (unformat (i, "tag %s", &tag))
11309         ;
11310       else if (unformat (i, "mode %U",
11311                          api_unformat_vhost_user_operation_mode,
11312                          &operation_mode))
11313         ;
11314       else
11315         break;
11316     }
11317
11318   if (file_name_set == 0)
11319     {
11320       errmsg ("missing socket file name");
11321       return -99;
11322     }
11323
11324   if (vec_len (file_name) > 255)
11325     {
11326       errmsg ("socket file name too long");
11327       return -99;
11328     }
11329   vec_add1 (file_name, 0);
11330
11331   M (CREATE_VHOST_USER_IF, mp);
11332
11333   mp->operation_mode = operation_mode;
11334   mp->is_server = is_server;
11335   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11336   vec_free (file_name);
11337   if (custom_dev_instance != ~0)
11338     {
11339       mp->renumber = 1;
11340       mp->custom_dev_instance = ntohl (custom_dev_instance);
11341     }
11342   mp->use_custom_mac = use_custom_mac;
11343   clib_memcpy (mp->mac_address, hwaddr, 6);
11344   if (tag)
11345     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11346   vec_free (tag);
11347
11348   S (mp);
11349   W (ret);
11350   return ret;
11351 }
11352
11353 static int
11354 api_modify_vhost_user_if (vat_main_t * vam)
11355 {
11356   unformat_input_t *i = vam->input;
11357   vl_api_modify_vhost_user_if_t *mp;
11358   u8 *file_name;
11359   u8 is_server = 0;
11360   u8 file_name_set = 0;
11361   u32 custom_dev_instance = ~0;
11362   u8 sw_if_index_set = 0;
11363   u32 sw_if_index = (u32) ~ 0;
11364   int ret;
11365   u8 operation_mode = VHOST_USER_POLLING_MODE;
11366
11367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11368     {
11369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11370         sw_if_index_set = 1;
11371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11372         sw_if_index_set = 1;
11373       else if (unformat (i, "socket %s", &file_name))
11374         {
11375           file_name_set = 1;
11376         }
11377       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11378         ;
11379       else if (unformat (i, "server"))
11380         is_server = 1;
11381       else if (unformat (i, "mode %U",
11382                          api_unformat_vhost_user_operation_mode,
11383                          &operation_mode))
11384         ;
11385       else
11386         break;
11387     }
11388
11389   if (sw_if_index_set == 0)
11390     {
11391       errmsg ("missing sw_if_index or interface name");
11392       return -99;
11393     }
11394
11395   if (file_name_set == 0)
11396     {
11397       errmsg ("missing socket file name");
11398       return -99;
11399     }
11400
11401   if (vec_len (file_name) > 255)
11402     {
11403       errmsg ("socket file name too long");
11404       return -99;
11405     }
11406   vec_add1 (file_name, 0);
11407
11408   M (MODIFY_VHOST_USER_IF, mp);
11409
11410   mp->operation_mode = operation_mode;
11411   mp->sw_if_index = ntohl (sw_if_index);
11412   mp->is_server = is_server;
11413   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11414   vec_free (file_name);
11415   if (custom_dev_instance != ~0)
11416     {
11417       mp->renumber = 1;
11418       mp->custom_dev_instance = ntohl (custom_dev_instance);
11419     }
11420
11421   S (mp);
11422   W (ret);
11423   return ret;
11424 }
11425
11426 static int
11427 api_delete_vhost_user_if (vat_main_t * vam)
11428 {
11429   unformat_input_t *i = vam->input;
11430   vl_api_delete_vhost_user_if_t *mp;
11431   u32 sw_if_index = ~0;
11432   u8 sw_if_index_set = 0;
11433   int ret;
11434
11435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11436     {
11437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11438         sw_if_index_set = 1;
11439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11440         sw_if_index_set = 1;
11441       else
11442         break;
11443     }
11444
11445   if (sw_if_index_set == 0)
11446     {
11447       errmsg ("missing sw_if_index or interface name");
11448       return -99;
11449     }
11450
11451
11452   M (DELETE_VHOST_USER_IF, mp);
11453
11454   mp->sw_if_index = ntohl (sw_if_index);
11455
11456   S (mp);
11457   W (ret);
11458   return ret;
11459 }
11460
11461 static void vl_api_sw_interface_vhost_user_details_t_handler
11462   (vl_api_sw_interface_vhost_user_details_t * mp)
11463 {
11464   vat_main_t *vam = &vat_main;
11465
11466   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
11467          (char *) mp->interface_name,
11468          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11469          clib_net_to_host_u64 (mp->features), mp->is_server,
11470          ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11471          mp->operation_mode, (char *) mp->sock_filename);
11472   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11473 }
11474
11475 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11476   (vl_api_sw_interface_vhost_user_details_t * mp)
11477 {
11478   vat_main_t *vam = &vat_main;
11479   vat_json_node_t *node = NULL;
11480
11481   if (VAT_JSON_ARRAY != vam->json_tree.type)
11482     {
11483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11484       vat_json_init_array (&vam->json_tree);
11485     }
11486   node = vat_json_array_add (&vam->json_tree);
11487
11488   vat_json_init_object (node);
11489   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11490   vat_json_object_add_string_copy (node, "interface_name",
11491                                    mp->interface_name);
11492   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11493                             ntohl (mp->virtio_net_hdr_sz));
11494   vat_json_object_add_uint (node, "features",
11495                             clib_net_to_host_u64 (mp->features));
11496   vat_json_object_add_uint (node, "is_server", mp->is_server);
11497   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11498   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11499   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11500   vat_json_object_add_uint (node, "mode", mp->operation_mode);
11501 }
11502
11503 static int
11504 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11505 {
11506   vl_api_sw_interface_vhost_user_dump_t *mp;
11507   vl_api_control_ping_t *mp_ping;
11508   int ret;
11509   print (vam->ofp,
11510          "Interface name            idx hdr_sz features server regions mode"
11511          "      filename");
11512
11513   /* Get list of vhost-user interfaces */
11514   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11515   S (mp);
11516
11517   /* Use a control ping for synchronization */
11518   M (CONTROL_PING, mp_ping);
11519   S (mp_ping);
11520
11521   W (ret);
11522   return ret;
11523 }
11524
11525 static int
11526 api_show_version (vat_main_t * vam)
11527 {
11528   vl_api_show_version_t *mp;
11529   int ret;
11530
11531   M (SHOW_VERSION, mp);
11532
11533   S (mp);
11534   W (ret);
11535   return ret;
11536 }
11537
11538
11539 static int
11540 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11541 {
11542   unformat_input_t *line_input = vam->input;
11543   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11544   ip4_address_t local4, remote4;
11545   ip6_address_t local6, remote6;
11546   u8 is_add = 1;
11547   u8 ipv4_set = 0, ipv6_set = 0;
11548   u8 local_set = 0;
11549   u8 remote_set = 0;
11550   u32 encap_vrf_id = 0;
11551   u32 decap_vrf_id = 0;
11552   u8 protocol = ~0;
11553   u32 vni;
11554   u8 vni_set = 0;
11555   int ret;
11556
11557   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11558     {
11559       if (unformat (line_input, "del"))
11560         is_add = 0;
11561       else if (unformat (line_input, "local %U",
11562                          unformat_ip4_address, &local4))
11563         {
11564           local_set = 1;
11565           ipv4_set = 1;
11566         }
11567       else if (unformat (line_input, "remote %U",
11568                          unformat_ip4_address, &remote4))
11569         {
11570           remote_set = 1;
11571           ipv4_set = 1;
11572         }
11573       else if (unformat (line_input, "local %U",
11574                          unformat_ip6_address, &local6))
11575         {
11576           local_set = 1;
11577           ipv6_set = 1;
11578         }
11579       else if (unformat (line_input, "remote %U",
11580                          unformat_ip6_address, &remote6))
11581         {
11582           remote_set = 1;
11583           ipv6_set = 1;
11584         }
11585       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11586         ;
11587       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11588         ;
11589       else if (unformat (line_input, "vni %d", &vni))
11590         vni_set = 1;
11591       else if (unformat (line_input, "next-ip4"))
11592         protocol = 1;
11593       else if (unformat (line_input, "next-ip6"))
11594         protocol = 2;
11595       else if (unformat (line_input, "next-ethernet"))
11596         protocol = 3;
11597       else if (unformat (line_input, "next-nsh"))
11598         protocol = 4;
11599       else
11600         {
11601           errmsg ("parse error '%U'", format_unformat_error, line_input);
11602           return -99;
11603         }
11604     }
11605
11606   if (local_set == 0)
11607     {
11608       errmsg ("tunnel local address not specified");
11609       return -99;
11610     }
11611   if (remote_set == 0)
11612     {
11613       errmsg ("tunnel remote address not specified");
11614       return -99;
11615     }
11616   if (ipv4_set && ipv6_set)
11617     {
11618       errmsg ("both IPv4 and IPv6 addresses specified");
11619       return -99;
11620     }
11621
11622   if (vni_set == 0)
11623     {
11624       errmsg ("vni not specified");
11625       return -99;
11626     }
11627
11628   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11629
11630
11631   if (ipv6_set)
11632     {
11633       clib_memcpy (&mp->local, &local6, sizeof (local6));
11634       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11635     }
11636   else
11637     {
11638       clib_memcpy (&mp->local, &local4, sizeof (local4));
11639       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11640     }
11641
11642   mp->encap_vrf_id = ntohl (encap_vrf_id);
11643   mp->decap_vrf_id = ntohl (decap_vrf_id);
11644   mp->protocol = protocol;
11645   mp->vni = ntohl (vni);
11646   mp->is_add = is_add;
11647   mp->is_ipv6 = ipv6_set;
11648
11649   S (mp);
11650   W (ret);
11651   return ret;
11652 }
11653
11654 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11655   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11656 {
11657   vat_main_t *vam = &vat_main;
11658
11659   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11660          ntohl (mp->sw_if_index),
11661          format_ip46_address, &(mp->local[0]),
11662          format_ip46_address, &(mp->remote[0]),
11663          ntohl (mp->vni),
11664          ntohl (mp->protocol),
11665          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11666 }
11667
11668 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11669   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11670 {
11671   vat_main_t *vam = &vat_main;
11672   vat_json_node_t *node = NULL;
11673   struct in_addr ip4;
11674   struct in6_addr ip6;
11675
11676   if (VAT_JSON_ARRAY != vam->json_tree.type)
11677     {
11678       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11679       vat_json_init_array (&vam->json_tree);
11680     }
11681   node = vat_json_array_add (&vam->json_tree);
11682
11683   vat_json_init_object (node);
11684   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11685   if (mp->is_ipv6)
11686     {
11687       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11688       vat_json_object_add_ip6 (node, "local", ip6);
11689       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11690       vat_json_object_add_ip6 (node, "remote", ip6);
11691     }
11692   else
11693     {
11694       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11695       vat_json_object_add_ip4 (node, "local", ip4);
11696       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11697       vat_json_object_add_ip4 (node, "remote", ip4);
11698     }
11699   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11700   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11701   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11702   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11703   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11704 }
11705
11706 static int
11707 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11708 {
11709   unformat_input_t *i = vam->input;
11710   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11711   vl_api_control_ping_t *mp_ping;
11712   u32 sw_if_index;
11713   u8 sw_if_index_set = 0;
11714   int ret;
11715
11716   /* Parse args required to build the message */
11717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11718     {
11719       if (unformat (i, "sw_if_index %d", &sw_if_index))
11720         sw_if_index_set = 1;
11721       else
11722         break;
11723     }
11724
11725   if (sw_if_index_set == 0)
11726     {
11727       sw_if_index = ~0;
11728     }
11729
11730   if (!vam->json_output)
11731     {
11732       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11733              "sw_if_index", "local", "remote", "vni",
11734              "protocol", "encap_vrf_id", "decap_vrf_id");
11735     }
11736
11737   /* Get list of vxlan-tunnel interfaces */
11738   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11739
11740   mp->sw_if_index = htonl (sw_if_index);
11741
11742   S (mp);
11743
11744   /* Use a control ping for synchronization */
11745   M (CONTROL_PING, mp_ping);
11746   S (mp_ping);
11747
11748   W (ret);
11749   return ret;
11750 }
11751
11752 u8 *
11753 format_l2_fib_mac_address (u8 * s, va_list * args)
11754 {
11755   u8 *a = va_arg (*args, u8 *);
11756
11757   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11758                  a[2], a[3], a[4], a[5], a[6], a[7]);
11759 }
11760
11761 static void vl_api_l2_fib_table_entry_t_handler
11762   (vl_api_l2_fib_table_entry_t * mp)
11763 {
11764   vat_main_t *vam = &vat_main;
11765
11766   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11767          "       %d       %d     %d",
11768          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11769          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11770          mp->bvi_mac);
11771 }
11772
11773 static void vl_api_l2_fib_table_entry_t_handler_json
11774   (vl_api_l2_fib_table_entry_t * mp)
11775 {
11776   vat_main_t *vam = &vat_main;
11777   vat_json_node_t *node = NULL;
11778
11779   if (VAT_JSON_ARRAY != vam->json_tree.type)
11780     {
11781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11782       vat_json_init_array (&vam->json_tree);
11783     }
11784   node = vat_json_array_add (&vam->json_tree);
11785
11786   vat_json_init_object (node);
11787   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11788   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11789   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11790   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11791   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11792   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11793 }
11794
11795 static int
11796 api_l2_fib_table_dump (vat_main_t * vam)
11797 {
11798   unformat_input_t *i = vam->input;
11799   vl_api_l2_fib_table_dump_t *mp;
11800   vl_api_control_ping_t *mp_ping;
11801   u32 bd_id;
11802   u8 bd_id_set = 0;
11803   int ret;
11804
11805   /* Parse args required to build the message */
11806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11807     {
11808       if (unformat (i, "bd_id %d", &bd_id))
11809         bd_id_set = 1;
11810       else
11811         break;
11812     }
11813
11814   if (bd_id_set == 0)
11815     {
11816       errmsg ("missing bridge domain");
11817       return -99;
11818     }
11819
11820   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11821
11822   /* Get list of l2 fib entries */
11823   M (L2_FIB_TABLE_DUMP, mp);
11824
11825   mp->bd_id = ntohl (bd_id);
11826   S (mp);
11827
11828   /* Use a control ping for synchronization */
11829   M (CONTROL_PING, mp_ping);
11830   S (mp_ping);
11831
11832   W (ret);
11833   return ret;
11834 }
11835
11836
11837 static int
11838 api_interface_name_renumber (vat_main_t * vam)
11839 {
11840   unformat_input_t *line_input = vam->input;
11841   vl_api_interface_name_renumber_t *mp;
11842   u32 sw_if_index = ~0;
11843   u32 new_show_dev_instance = ~0;
11844   int ret;
11845
11846   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11847     {
11848       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11849                     &sw_if_index))
11850         ;
11851       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11852         ;
11853       else if (unformat (line_input, "new_show_dev_instance %d",
11854                          &new_show_dev_instance))
11855         ;
11856       else
11857         break;
11858     }
11859
11860   if (sw_if_index == ~0)
11861     {
11862       errmsg ("missing interface name or sw_if_index");
11863       return -99;
11864     }
11865
11866   if (new_show_dev_instance == ~0)
11867     {
11868       errmsg ("missing new_show_dev_instance");
11869       return -99;
11870     }
11871
11872   M (INTERFACE_NAME_RENUMBER, mp);
11873
11874   mp->sw_if_index = ntohl (sw_if_index);
11875   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11876
11877   S (mp);
11878   W (ret);
11879   return ret;
11880 }
11881
11882 static int
11883 api_want_ip4_arp_events (vat_main_t * vam)
11884 {
11885   unformat_input_t *line_input = vam->input;
11886   vl_api_want_ip4_arp_events_t *mp;
11887   ip4_address_t address;
11888   int address_set = 0;
11889   u32 enable_disable = 1;
11890   int ret;
11891
11892   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11893     {
11894       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11895         address_set = 1;
11896       else if (unformat (line_input, "del"))
11897         enable_disable = 0;
11898       else
11899         break;
11900     }
11901
11902   if (address_set == 0)
11903     {
11904       errmsg ("missing addresses");
11905       return -99;
11906     }
11907
11908   M (WANT_IP4_ARP_EVENTS, mp);
11909   mp->enable_disable = enable_disable;
11910   mp->pid = htonl (getpid ());
11911   mp->address = address.as_u32;
11912
11913   S (mp);
11914   W (ret);
11915   return ret;
11916 }
11917
11918 static int
11919 api_want_ip6_nd_events (vat_main_t * vam)
11920 {
11921   unformat_input_t *line_input = vam->input;
11922   vl_api_want_ip6_nd_events_t *mp;
11923   ip6_address_t address;
11924   int address_set = 0;
11925   u32 enable_disable = 1;
11926   int ret;
11927
11928   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11929     {
11930       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11931         address_set = 1;
11932       else if (unformat (line_input, "del"))
11933         enable_disable = 0;
11934       else
11935         break;
11936     }
11937
11938   if (address_set == 0)
11939     {
11940       errmsg ("missing addresses");
11941       return -99;
11942     }
11943
11944   M (WANT_IP6_ND_EVENTS, mp);
11945   mp->enable_disable = enable_disable;
11946   mp->pid = htonl (getpid ());
11947   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11948
11949   S (mp);
11950   W (ret);
11951   return ret;
11952 }
11953
11954 static int
11955 api_input_acl_set_interface (vat_main_t * vam)
11956 {
11957   unformat_input_t *i = vam->input;
11958   vl_api_input_acl_set_interface_t *mp;
11959   u32 sw_if_index;
11960   int sw_if_index_set;
11961   u32 ip4_table_index = ~0;
11962   u32 ip6_table_index = ~0;
11963   u32 l2_table_index = ~0;
11964   u8 is_add = 1;
11965   int ret;
11966
11967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11968     {
11969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11970         sw_if_index_set = 1;
11971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11972         sw_if_index_set = 1;
11973       else if (unformat (i, "del"))
11974         is_add = 0;
11975       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11976         ;
11977       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11978         ;
11979       else if (unformat (i, "l2-table %d", &l2_table_index))
11980         ;
11981       else
11982         {
11983           clib_warning ("parse error '%U'", format_unformat_error, i);
11984           return -99;
11985         }
11986     }
11987
11988   if (sw_if_index_set == 0)
11989     {
11990       errmsg ("missing interface name or sw_if_index");
11991       return -99;
11992     }
11993
11994   M (INPUT_ACL_SET_INTERFACE, mp);
11995
11996   mp->sw_if_index = ntohl (sw_if_index);
11997   mp->ip4_table_index = ntohl (ip4_table_index);
11998   mp->ip6_table_index = ntohl (ip6_table_index);
11999   mp->l2_table_index = ntohl (l2_table_index);
12000   mp->is_add = is_add;
12001
12002   S (mp);
12003   W (ret);
12004   return ret;
12005 }
12006
12007 static int
12008 api_ip_address_dump (vat_main_t * vam)
12009 {
12010   unformat_input_t *i = vam->input;
12011   vl_api_ip_address_dump_t *mp;
12012   vl_api_control_ping_t *mp_ping;
12013   u32 sw_if_index = ~0;
12014   u8 sw_if_index_set = 0;
12015   u8 ipv4_set = 0;
12016   u8 ipv6_set = 0;
12017   int ret;
12018
12019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12020     {
12021       if (unformat (i, "sw_if_index %d", &sw_if_index))
12022         sw_if_index_set = 1;
12023       else
12024         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12025         sw_if_index_set = 1;
12026       else if (unformat (i, "ipv4"))
12027         ipv4_set = 1;
12028       else if (unformat (i, "ipv6"))
12029         ipv6_set = 1;
12030       else
12031         break;
12032     }
12033
12034   if (ipv4_set && ipv6_set)
12035     {
12036       errmsg ("ipv4 and ipv6 flags cannot be both set");
12037       return -99;
12038     }
12039
12040   if ((!ipv4_set) && (!ipv6_set))
12041     {
12042       errmsg ("no ipv4 nor ipv6 flag set");
12043       return -99;
12044     }
12045
12046   if (sw_if_index_set == 0)
12047     {
12048       errmsg ("missing interface name or sw_if_index");
12049       return -99;
12050     }
12051
12052   vam->current_sw_if_index = sw_if_index;
12053   vam->is_ipv6 = ipv6_set;
12054
12055   M (IP_ADDRESS_DUMP, mp);
12056   mp->sw_if_index = ntohl (sw_if_index);
12057   mp->is_ipv6 = ipv6_set;
12058   S (mp);
12059
12060   /* Use a control ping for synchronization */
12061   M (CONTROL_PING, mp_ping);
12062   S (mp_ping);
12063
12064   W (ret);
12065   return ret;
12066 }
12067
12068 static int
12069 api_ip_dump (vat_main_t * vam)
12070 {
12071   vl_api_ip_dump_t *mp;
12072   vl_api_control_ping_t *mp_ping;
12073   unformat_input_t *in = vam->input;
12074   int ipv4_set = 0;
12075   int ipv6_set = 0;
12076   int is_ipv6;
12077   int i;
12078   int ret;
12079
12080   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12081     {
12082       if (unformat (in, "ipv4"))
12083         ipv4_set = 1;
12084       else if (unformat (in, "ipv6"))
12085         ipv6_set = 1;
12086       else
12087         break;
12088     }
12089
12090   if (ipv4_set && ipv6_set)
12091     {
12092       errmsg ("ipv4 and ipv6 flags cannot be both set");
12093       return -99;
12094     }
12095
12096   if ((!ipv4_set) && (!ipv6_set))
12097     {
12098       errmsg ("no ipv4 nor ipv6 flag set");
12099       return -99;
12100     }
12101
12102   is_ipv6 = ipv6_set;
12103   vam->is_ipv6 = is_ipv6;
12104
12105   /* free old data */
12106   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12107     {
12108       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12109     }
12110   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12111
12112   M (IP_DUMP, mp);
12113   mp->is_ipv6 = ipv6_set;
12114   S (mp);
12115
12116   /* Use a control ping for synchronization */
12117   M (CONTROL_PING, mp_ping);
12118   S (mp_ping);
12119
12120   W (ret);
12121   return ret;
12122 }
12123
12124 static int
12125 api_ipsec_spd_add_del (vat_main_t * vam)
12126 {
12127   unformat_input_t *i = vam->input;
12128   vl_api_ipsec_spd_add_del_t *mp;
12129   u32 spd_id = ~0;
12130   u8 is_add = 1;
12131   int ret;
12132
12133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12134     {
12135       if (unformat (i, "spd_id %d", &spd_id))
12136         ;
12137       else if (unformat (i, "del"))
12138         is_add = 0;
12139       else
12140         {
12141           clib_warning ("parse error '%U'", format_unformat_error, i);
12142           return -99;
12143         }
12144     }
12145   if (spd_id == ~0)
12146     {
12147       errmsg ("spd_id must be set");
12148       return -99;
12149     }
12150
12151   M (IPSEC_SPD_ADD_DEL, mp);
12152
12153   mp->spd_id = ntohl (spd_id);
12154   mp->is_add = is_add;
12155
12156   S (mp);
12157   W (ret);
12158   return ret;
12159 }
12160
12161 static int
12162 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12163 {
12164   unformat_input_t *i = vam->input;
12165   vl_api_ipsec_interface_add_del_spd_t *mp;
12166   u32 sw_if_index;
12167   u8 sw_if_index_set = 0;
12168   u32 spd_id = (u32) ~ 0;
12169   u8 is_add = 1;
12170   int ret;
12171
12172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12173     {
12174       if (unformat (i, "del"))
12175         is_add = 0;
12176       else if (unformat (i, "spd_id %d", &spd_id))
12177         ;
12178       else
12179         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12180         sw_if_index_set = 1;
12181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12182         sw_if_index_set = 1;
12183       else
12184         {
12185           clib_warning ("parse error '%U'", format_unformat_error, i);
12186           return -99;
12187         }
12188
12189     }
12190
12191   if (spd_id == (u32) ~ 0)
12192     {
12193       errmsg ("spd_id must be set");
12194       return -99;
12195     }
12196
12197   if (sw_if_index_set == 0)
12198     {
12199       errmsg ("missing interface name or sw_if_index");
12200       return -99;
12201     }
12202
12203   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12204
12205   mp->spd_id = ntohl (spd_id);
12206   mp->sw_if_index = ntohl (sw_if_index);
12207   mp->is_add = is_add;
12208
12209   S (mp);
12210   W (ret);
12211   return ret;
12212 }
12213
12214 static int
12215 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12216 {
12217   unformat_input_t *i = vam->input;
12218   vl_api_ipsec_spd_add_del_entry_t *mp;
12219   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12220   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12221   i32 priority = 0;
12222   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12223   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12224   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12225   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12226   int ret;
12227
12228   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12229   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12230   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12231   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12232   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12233   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12234
12235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12236     {
12237       if (unformat (i, "del"))
12238         is_add = 0;
12239       if (unformat (i, "outbound"))
12240         is_outbound = 1;
12241       if (unformat (i, "inbound"))
12242         is_outbound = 0;
12243       else if (unformat (i, "spd_id %d", &spd_id))
12244         ;
12245       else if (unformat (i, "sa_id %d", &sa_id))
12246         ;
12247       else if (unformat (i, "priority %d", &priority))
12248         ;
12249       else if (unformat (i, "protocol %d", &protocol))
12250         ;
12251       else if (unformat (i, "lport_start %d", &lport_start))
12252         ;
12253       else if (unformat (i, "lport_stop %d", &lport_stop))
12254         ;
12255       else if (unformat (i, "rport_start %d", &rport_start))
12256         ;
12257       else if (unformat (i, "rport_stop %d", &rport_stop))
12258         ;
12259       else
12260         if (unformat
12261             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12262         {
12263           is_ipv6 = 0;
12264           is_ip_any = 0;
12265         }
12266       else
12267         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12268         {
12269           is_ipv6 = 0;
12270           is_ip_any = 0;
12271         }
12272       else
12273         if (unformat
12274             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12275         {
12276           is_ipv6 = 0;
12277           is_ip_any = 0;
12278         }
12279       else
12280         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12281         {
12282           is_ipv6 = 0;
12283           is_ip_any = 0;
12284         }
12285       else
12286         if (unformat
12287             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12288         {
12289           is_ipv6 = 1;
12290           is_ip_any = 0;
12291         }
12292       else
12293         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12294         {
12295           is_ipv6 = 1;
12296           is_ip_any = 0;
12297         }
12298       else
12299         if (unformat
12300             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12301         {
12302           is_ipv6 = 1;
12303           is_ip_any = 0;
12304         }
12305       else
12306         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12307         {
12308           is_ipv6 = 1;
12309           is_ip_any = 0;
12310         }
12311       else
12312         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12313         {
12314           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12315             {
12316               clib_warning ("unsupported action: 'resolve'");
12317               return -99;
12318             }
12319         }
12320       else
12321         {
12322           clib_warning ("parse error '%U'", format_unformat_error, i);
12323           return -99;
12324         }
12325
12326     }
12327
12328   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12329
12330   mp->spd_id = ntohl (spd_id);
12331   mp->priority = ntohl (priority);
12332   mp->is_outbound = is_outbound;
12333
12334   mp->is_ipv6 = is_ipv6;
12335   if (is_ipv6 || is_ip_any)
12336     {
12337       clib_memcpy (mp->remote_address_start, &raddr6_start,
12338                    sizeof (ip6_address_t));
12339       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12340                    sizeof (ip6_address_t));
12341       clib_memcpy (mp->local_address_start, &laddr6_start,
12342                    sizeof (ip6_address_t));
12343       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12344                    sizeof (ip6_address_t));
12345     }
12346   else
12347     {
12348       clib_memcpy (mp->remote_address_start, &raddr4_start,
12349                    sizeof (ip4_address_t));
12350       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12351                    sizeof (ip4_address_t));
12352       clib_memcpy (mp->local_address_start, &laddr4_start,
12353                    sizeof (ip4_address_t));
12354       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12355                    sizeof (ip4_address_t));
12356     }
12357   mp->protocol = (u8) protocol;
12358   mp->local_port_start = ntohs ((u16) lport_start);
12359   mp->local_port_stop = ntohs ((u16) lport_stop);
12360   mp->remote_port_start = ntohs ((u16) rport_start);
12361   mp->remote_port_stop = ntohs ((u16) rport_stop);
12362   mp->policy = (u8) policy;
12363   mp->sa_id = ntohl (sa_id);
12364   mp->is_add = is_add;
12365   mp->is_ip_any = is_ip_any;
12366   S (mp);
12367   W (ret);
12368   return ret;
12369 }
12370
12371 static int
12372 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12373 {
12374   unformat_input_t *i = vam->input;
12375   vl_api_ipsec_sad_add_del_entry_t *mp;
12376   u32 sad_id = 0, spi = 0;
12377   u8 *ck = 0, *ik = 0;
12378   u8 is_add = 1;
12379
12380   u8 protocol = IPSEC_PROTOCOL_AH;
12381   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12382   u32 crypto_alg = 0, integ_alg = 0;
12383   ip4_address_t tun_src4;
12384   ip4_address_t tun_dst4;
12385   ip6_address_t tun_src6;
12386   ip6_address_t tun_dst6;
12387   int ret;
12388
12389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12390     {
12391       if (unformat (i, "del"))
12392         is_add = 0;
12393       else if (unformat (i, "sad_id %d", &sad_id))
12394         ;
12395       else if (unformat (i, "spi %d", &spi))
12396         ;
12397       else if (unformat (i, "esp"))
12398         protocol = IPSEC_PROTOCOL_ESP;
12399       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12400         {
12401           is_tunnel = 1;
12402           is_tunnel_ipv6 = 0;
12403         }
12404       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12405         {
12406           is_tunnel = 1;
12407           is_tunnel_ipv6 = 0;
12408         }
12409       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12410         {
12411           is_tunnel = 1;
12412           is_tunnel_ipv6 = 1;
12413         }
12414       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12415         {
12416           is_tunnel = 1;
12417           is_tunnel_ipv6 = 1;
12418         }
12419       else
12420         if (unformat
12421             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12422         {
12423           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12424               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12425             {
12426               clib_warning ("unsupported crypto-alg: '%U'",
12427                             format_ipsec_crypto_alg, crypto_alg);
12428               return -99;
12429             }
12430         }
12431       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12432         ;
12433       else
12434         if (unformat
12435             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12436         {
12437           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12438               integ_alg >= IPSEC_INTEG_N_ALG)
12439             {
12440               clib_warning ("unsupported integ-alg: '%U'",
12441                             format_ipsec_integ_alg, integ_alg);
12442               return -99;
12443             }
12444         }
12445       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12446         ;
12447       else
12448         {
12449           clib_warning ("parse error '%U'", format_unformat_error, i);
12450           return -99;
12451         }
12452
12453     }
12454
12455   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12456
12457   mp->sad_id = ntohl (sad_id);
12458   mp->is_add = is_add;
12459   mp->protocol = protocol;
12460   mp->spi = ntohl (spi);
12461   mp->is_tunnel = is_tunnel;
12462   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12463   mp->crypto_algorithm = crypto_alg;
12464   mp->integrity_algorithm = integ_alg;
12465   mp->crypto_key_length = vec_len (ck);
12466   mp->integrity_key_length = vec_len (ik);
12467
12468   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12469     mp->crypto_key_length = sizeof (mp->crypto_key);
12470
12471   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12472     mp->integrity_key_length = sizeof (mp->integrity_key);
12473
12474   if (ck)
12475     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12476   if (ik)
12477     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12478
12479   if (is_tunnel)
12480     {
12481       if (is_tunnel_ipv6)
12482         {
12483           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12484                        sizeof (ip6_address_t));
12485           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12486                        sizeof (ip6_address_t));
12487         }
12488       else
12489         {
12490           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12491                        sizeof (ip4_address_t));
12492           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12493                        sizeof (ip4_address_t));
12494         }
12495     }
12496
12497   S (mp);
12498   W (ret);
12499   return ret;
12500 }
12501
12502 static int
12503 api_ipsec_sa_set_key (vat_main_t * vam)
12504 {
12505   unformat_input_t *i = vam->input;
12506   vl_api_ipsec_sa_set_key_t *mp;
12507   u32 sa_id;
12508   u8 *ck = 0, *ik = 0;
12509   int ret;
12510
12511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12512     {
12513       if (unformat (i, "sa_id %d", &sa_id))
12514         ;
12515       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12516         ;
12517       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12518         ;
12519       else
12520         {
12521           clib_warning ("parse error '%U'", format_unformat_error, i);
12522           return -99;
12523         }
12524     }
12525
12526   M (IPSEC_SA_SET_KEY, mp);
12527
12528   mp->sa_id = ntohl (sa_id);
12529   mp->crypto_key_length = vec_len (ck);
12530   mp->integrity_key_length = vec_len (ik);
12531
12532   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12533     mp->crypto_key_length = sizeof (mp->crypto_key);
12534
12535   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12536     mp->integrity_key_length = sizeof (mp->integrity_key);
12537
12538   if (ck)
12539     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12540   if (ik)
12541     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12542
12543   S (mp);
12544   W (ret);
12545   return ret;
12546 }
12547
12548 static int
12549 api_ikev2_profile_add_del (vat_main_t * vam)
12550 {
12551   unformat_input_t *i = vam->input;
12552   vl_api_ikev2_profile_add_del_t *mp;
12553   u8 is_add = 1;
12554   u8 *name = 0;
12555   int ret;
12556
12557   const char *valid_chars = "a-zA-Z0-9_";
12558
12559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12560     {
12561       if (unformat (i, "del"))
12562         is_add = 0;
12563       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12564         vec_add1 (name, 0);
12565       else
12566         {
12567           errmsg ("parse error '%U'", format_unformat_error, i);
12568           return -99;
12569         }
12570     }
12571
12572   if (!vec_len (name))
12573     {
12574       errmsg ("profile name must be specified");
12575       return -99;
12576     }
12577
12578   if (vec_len (name) > 64)
12579     {
12580       errmsg ("profile name too long");
12581       return -99;
12582     }
12583
12584   M (IKEV2_PROFILE_ADD_DEL, mp);
12585
12586   clib_memcpy (mp->name, name, vec_len (name));
12587   mp->is_add = is_add;
12588   vec_free (name);
12589
12590   S (mp);
12591   W (ret);
12592   return ret;
12593 }
12594
12595 static int
12596 api_ikev2_profile_set_auth (vat_main_t * vam)
12597 {
12598   unformat_input_t *i = vam->input;
12599   vl_api_ikev2_profile_set_auth_t *mp;
12600   u8 *name = 0;
12601   u8 *data = 0;
12602   u32 auth_method = 0;
12603   u8 is_hex = 0;
12604   int ret;
12605
12606   const char *valid_chars = "a-zA-Z0-9_";
12607
12608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12609     {
12610       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12611         vec_add1 (name, 0);
12612       else if (unformat (i, "auth_method %U",
12613                          unformat_ikev2_auth_method, &auth_method))
12614         ;
12615       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12616         is_hex = 1;
12617       else if (unformat (i, "auth_data %v", &data))
12618         ;
12619       else
12620         {
12621           errmsg ("parse error '%U'", format_unformat_error, i);
12622           return -99;
12623         }
12624     }
12625
12626   if (!vec_len (name))
12627     {
12628       errmsg ("profile name must be specified");
12629       return -99;
12630     }
12631
12632   if (vec_len (name) > 64)
12633     {
12634       errmsg ("profile name too long");
12635       return -99;
12636     }
12637
12638   if (!vec_len (data))
12639     {
12640       errmsg ("auth_data must be specified");
12641       return -99;
12642     }
12643
12644   if (!auth_method)
12645     {
12646       errmsg ("auth_method must be specified");
12647       return -99;
12648     }
12649
12650   M (IKEV2_PROFILE_SET_AUTH, mp);
12651
12652   mp->is_hex = is_hex;
12653   mp->auth_method = (u8) auth_method;
12654   mp->data_len = vec_len (data);
12655   clib_memcpy (mp->name, name, vec_len (name));
12656   clib_memcpy (mp->data, data, vec_len (data));
12657   vec_free (name);
12658   vec_free (data);
12659
12660   S (mp);
12661   W (ret);
12662   return ret;
12663 }
12664
12665 static int
12666 api_ikev2_profile_set_id (vat_main_t * vam)
12667 {
12668   unformat_input_t *i = vam->input;
12669   vl_api_ikev2_profile_set_id_t *mp;
12670   u8 *name = 0;
12671   u8 *data = 0;
12672   u8 is_local = 0;
12673   u32 id_type = 0;
12674   ip4_address_t ip4;
12675   int ret;
12676
12677   const char *valid_chars = "a-zA-Z0-9_";
12678
12679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12680     {
12681       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12682         vec_add1 (name, 0);
12683       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12684         ;
12685       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12686         {
12687           data = vec_new (u8, 4);
12688           clib_memcpy (data, ip4.as_u8, 4);
12689         }
12690       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12691         ;
12692       else if (unformat (i, "id_data %v", &data))
12693         ;
12694       else if (unformat (i, "local"))
12695         is_local = 1;
12696       else if (unformat (i, "remote"))
12697         is_local = 0;
12698       else
12699         {
12700           errmsg ("parse error '%U'", format_unformat_error, i);
12701           return -99;
12702         }
12703     }
12704
12705   if (!vec_len (name))
12706     {
12707       errmsg ("profile name must be specified");
12708       return -99;
12709     }
12710
12711   if (vec_len (name) > 64)
12712     {
12713       errmsg ("profile name too long");
12714       return -99;
12715     }
12716
12717   if (!vec_len (data))
12718     {
12719       errmsg ("id_data must be specified");
12720       return -99;
12721     }
12722
12723   if (!id_type)
12724     {
12725       errmsg ("id_type must be specified");
12726       return -99;
12727     }
12728
12729   M (IKEV2_PROFILE_SET_ID, mp);
12730
12731   mp->is_local = is_local;
12732   mp->id_type = (u8) id_type;
12733   mp->data_len = vec_len (data);
12734   clib_memcpy (mp->name, name, vec_len (name));
12735   clib_memcpy (mp->data, data, vec_len (data));
12736   vec_free (name);
12737   vec_free (data);
12738
12739   S (mp);
12740   W (ret);
12741   return ret;
12742 }
12743
12744 static int
12745 api_ikev2_profile_set_ts (vat_main_t * vam)
12746 {
12747   unformat_input_t *i = vam->input;
12748   vl_api_ikev2_profile_set_ts_t *mp;
12749   u8 *name = 0;
12750   u8 is_local = 0;
12751   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12752   ip4_address_t start_addr, end_addr;
12753
12754   const char *valid_chars = "a-zA-Z0-9_";
12755   int ret;
12756
12757   start_addr.as_u32 = 0;
12758   end_addr.as_u32 = (u32) ~ 0;
12759
12760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12761     {
12762       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12763         vec_add1 (name, 0);
12764       else if (unformat (i, "protocol %d", &proto))
12765         ;
12766       else if (unformat (i, "start_port %d", &start_port))
12767         ;
12768       else if (unformat (i, "end_port %d", &end_port))
12769         ;
12770       else
12771         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12772         ;
12773       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12774         ;
12775       else if (unformat (i, "local"))
12776         is_local = 1;
12777       else if (unformat (i, "remote"))
12778         is_local = 0;
12779       else
12780         {
12781           errmsg ("parse error '%U'", format_unformat_error, i);
12782           return -99;
12783         }
12784     }
12785
12786   if (!vec_len (name))
12787     {
12788       errmsg ("profile name must be specified");
12789       return -99;
12790     }
12791
12792   if (vec_len (name) > 64)
12793     {
12794       errmsg ("profile name too long");
12795       return -99;
12796     }
12797
12798   M (IKEV2_PROFILE_SET_TS, mp);
12799
12800   mp->is_local = is_local;
12801   mp->proto = (u8) proto;
12802   mp->start_port = (u16) start_port;
12803   mp->end_port = (u16) end_port;
12804   mp->start_addr = start_addr.as_u32;
12805   mp->end_addr = end_addr.as_u32;
12806   clib_memcpy (mp->name, name, vec_len (name));
12807   vec_free (name);
12808
12809   S (mp);
12810   W (ret);
12811   return ret;
12812 }
12813
12814 static int
12815 api_ikev2_set_local_key (vat_main_t * vam)
12816 {
12817   unformat_input_t *i = vam->input;
12818   vl_api_ikev2_set_local_key_t *mp;
12819   u8 *file = 0;
12820   int ret;
12821
12822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12823     {
12824       if (unformat (i, "file %v", &file))
12825         vec_add1 (file, 0);
12826       else
12827         {
12828           errmsg ("parse error '%U'", format_unformat_error, i);
12829           return -99;
12830         }
12831     }
12832
12833   if (!vec_len (file))
12834     {
12835       errmsg ("RSA key file must be specified");
12836       return -99;
12837     }
12838
12839   if (vec_len (file) > 256)
12840     {
12841       errmsg ("file name too long");
12842       return -99;
12843     }
12844
12845   M (IKEV2_SET_LOCAL_KEY, mp);
12846
12847   clib_memcpy (mp->key_file, file, vec_len (file));
12848   vec_free (file);
12849
12850   S (mp);
12851   W (ret);
12852   return ret;
12853 }
12854
12855 static int
12856 api_ikev2_set_responder (vat_main_t * vam)
12857 {
12858   unformat_input_t *i = vam->input;
12859   vl_api_ikev2_set_responder_t *mp;
12860   int ret;
12861   u8 *name = 0;
12862   u32 sw_if_index = ~0;
12863   ip4_address_t address;
12864
12865   const char *valid_chars = "a-zA-Z0-9_";
12866
12867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12868     {
12869       if (unformat
12870           (i, "%U interface %d address %U", unformat_token, valid_chars,
12871            &name, &sw_if_index, unformat_ip4_address, &address))
12872         vec_add1 (name, 0);
12873       else
12874         {
12875           errmsg ("parse error '%U'", format_unformat_error, i);
12876           return -99;
12877         }
12878     }
12879
12880   if (!vec_len (name))
12881     {
12882       errmsg ("profile name must be specified");
12883       return -99;
12884     }
12885
12886   if (vec_len (name) > 64)
12887     {
12888       errmsg ("profile name too long");
12889       return -99;
12890     }
12891
12892   M (IKEV2_SET_RESPONDER, mp);
12893
12894   clib_memcpy (mp->name, name, vec_len (name));
12895   vec_free (name);
12896
12897   mp->sw_if_index = sw_if_index;
12898   clib_memcpy (mp->address, &address, sizeof (address));
12899
12900   S (mp);
12901   W (ret);
12902   return ret;
12903 }
12904
12905 static int
12906 api_ikev2_set_ike_transforms (vat_main_t * vam)
12907 {
12908   unformat_input_t *i = vam->input;
12909   vl_api_ikev2_set_ike_transforms_t *mp;
12910   int ret;
12911   u8 *name = 0;
12912   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12913
12914   const char *valid_chars = "a-zA-Z0-9_";
12915
12916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12917     {
12918       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12919                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12920         vec_add1 (name, 0);
12921       else
12922         {
12923           errmsg ("parse error '%U'", format_unformat_error, i);
12924           return -99;
12925         }
12926     }
12927
12928   if (!vec_len (name))
12929     {
12930       errmsg ("profile name must be specified");
12931       return -99;
12932     }
12933
12934   if (vec_len (name) > 64)
12935     {
12936       errmsg ("profile name too long");
12937       return -99;
12938     }
12939
12940   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12941
12942   clib_memcpy (mp->name, name, vec_len (name));
12943   vec_free (name);
12944   mp->crypto_alg = crypto_alg;
12945   mp->crypto_key_size = crypto_key_size;
12946   mp->integ_alg = integ_alg;
12947   mp->dh_group = dh_group;
12948
12949   S (mp);
12950   W (ret);
12951   return ret;
12952 }
12953
12954
12955 static int
12956 api_ikev2_set_esp_transforms (vat_main_t * vam)
12957 {
12958   unformat_input_t *i = vam->input;
12959   vl_api_ikev2_set_esp_transforms_t *mp;
12960   int ret;
12961   u8 *name = 0;
12962   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12963
12964   const char *valid_chars = "a-zA-Z0-9_";
12965
12966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12967     {
12968       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12969                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12970         vec_add1 (name, 0);
12971       else
12972         {
12973           errmsg ("parse error '%U'", format_unformat_error, i);
12974           return -99;
12975         }
12976     }
12977
12978   if (!vec_len (name))
12979     {
12980       errmsg ("profile name must be specified");
12981       return -99;
12982     }
12983
12984   if (vec_len (name) > 64)
12985     {
12986       errmsg ("profile name too long");
12987       return -99;
12988     }
12989
12990   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12991
12992   clib_memcpy (mp->name, name, vec_len (name));
12993   vec_free (name);
12994   mp->crypto_alg = crypto_alg;
12995   mp->crypto_key_size = crypto_key_size;
12996   mp->integ_alg = integ_alg;
12997   mp->dh_group = dh_group;
12998
12999   S (mp);
13000   W (ret);
13001   return ret;
13002 }
13003
13004 static int
13005 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13006 {
13007   unformat_input_t *i = vam->input;
13008   vl_api_ikev2_set_sa_lifetime_t *mp;
13009   int ret;
13010   u8 *name = 0;
13011   u64 lifetime, lifetime_maxdata;
13012   u32 lifetime_jitter, handover;
13013
13014   const char *valid_chars = "a-zA-Z0-9_";
13015
13016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13017     {
13018       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13019                     &lifetime, &lifetime_jitter, &handover,
13020                     &lifetime_maxdata))
13021         vec_add1 (name, 0);
13022       else
13023         {
13024           errmsg ("parse error '%U'", format_unformat_error, i);
13025           return -99;
13026         }
13027     }
13028
13029   if (!vec_len (name))
13030     {
13031       errmsg ("profile name must be specified");
13032       return -99;
13033     }
13034
13035   if (vec_len (name) > 64)
13036     {
13037       errmsg ("profile name too long");
13038       return -99;
13039     }
13040
13041   M (IKEV2_SET_SA_LIFETIME, mp);
13042
13043   clib_memcpy (mp->name, name, vec_len (name));
13044   vec_free (name);
13045   mp->lifetime = lifetime;
13046   mp->lifetime_jitter = lifetime_jitter;
13047   mp->handover = handover;
13048   mp->lifetime_maxdata = lifetime_maxdata;
13049
13050   S (mp);
13051   W (ret);
13052   return ret;
13053 }
13054
13055 static int
13056 api_ikev2_initiate_sa_init (vat_main_t * vam)
13057 {
13058   unformat_input_t *i = vam->input;
13059   vl_api_ikev2_initiate_sa_init_t *mp;
13060   int ret;
13061   u8 *name = 0;
13062
13063   const char *valid_chars = "a-zA-Z0-9_";
13064
13065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13066     {
13067       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13068         vec_add1 (name, 0);
13069       else
13070         {
13071           errmsg ("parse error '%U'", format_unformat_error, i);
13072           return -99;
13073         }
13074     }
13075
13076   if (!vec_len (name))
13077     {
13078       errmsg ("profile name must be specified");
13079       return -99;
13080     }
13081
13082   if (vec_len (name) > 64)
13083     {
13084       errmsg ("profile name too long");
13085       return -99;
13086     }
13087
13088   M (IKEV2_INITIATE_SA_INIT, mp);
13089
13090   clib_memcpy (mp->name, name, vec_len (name));
13091   vec_free (name);
13092
13093   S (mp);
13094   W (ret);
13095   return ret;
13096 }
13097
13098 static int
13099 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13100 {
13101   unformat_input_t *i = vam->input;
13102   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13103   int ret;
13104   u64 ispi;
13105
13106
13107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13108     {
13109       if (unformat (i, "%lx", &ispi))
13110         ;
13111       else
13112         {
13113           errmsg ("parse error '%U'", format_unformat_error, i);
13114           return -99;
13115         }
13116     }
13117
13118   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13119
13120   mp->ispi = ispi;
13121
13122   S (mp);
13123   W (ret);
13124   return ret;
13125 }
13126
13127 static int
13128 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13129 {
13130   unformat_input_t *i = vam->input;
13131   vl_api_ikev2_initiate_del_child_sa_t *mp;
13132   int ret;
13133   u32 ispi;
13134
13135
13136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13137     {
13138       if (unformat (i, "%x", &ispi))
13139         ;
13140       else
13141         {
13142           errmsg ("parse error '%U'", format_unformat_error, i);
13143           return -99;
13144         }
13145     }
13146
13147   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13148
13149   mp->ispi = ispi;
13150
13151   S (mp);
13152   W (ret);
13153   return ret;
13154 }
13155
13156 static int
13157 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13158 {
13159   unformat_input_t *i = vam->input;
13160   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13161   int ret;
13162   u32 ispi;
13163
13164
13165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13166     {
13167       if (unformat (i, "%x", &ispi))
13168         ;
13169       else
13170         {
13171           errmsg ("parse error '%U'", format_unformat_error, i);
13172           return -99;
13173         }
13174     }
13175
13176   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13177
13178   mp->ispi = ispi;
13179
13180   S (mp);
13181   W (ret);
13182   return ret;
13183 }
13184
13185 /*
13186  * MAP
13187  */
13188 static int
13189 api_map_add_domain (vat_main_t * vam)
13190 {
13191   unformat_input_t *i = vam->input;
13192   vl_api_map_add_domain_t *mp;
13193
13194   ip4_address_t ip4_prefix;
13195   ip6_address_t ip6_prefix;
13196   ip6_address_t ip6_src;
13197   u32 num_m_args = 0;
13198   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13199     0, psid_length = 0;
13200   u8 is_translation = 0;
13201   u32 mtu = 0;
13202   u32 ip6_src_len = 128;
13203   int ret;
13204
13205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13206     {
13207       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13208                     &ip4_prefix, &ip4_prefix_len))
13209         num_m_args++;
13210       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13211                          &ip6_prefix, &ip6_prefix_len))
13212         num_m_args++;
13213       else
13214         if (unformat
13215             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13216              &ip6_src_len))
13217         num_m_args++;
13218       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13219         num_m_args++;
13220       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13221         num_m_args++;
13222       else if (unformat (i, "psid-offset %d", &psid_offset))
13223         num_m_args++;
13224       else if (unformat (i, "psid-len %d", &psid_length))
13225         num_m_args++;
13226       else if (unformat (i, "mtu %d", &mtu))
13227         num_m_args++;
13228       else if (unformat (i, "map-t"))
13229         is_translation = 1;
13230       else
13231         {
13232           clib_warning ("parse error '%U'", format_unformat_error, i);
13233           return -99;
13234         }
13235     }
13236
13237   if (num_m_args < 3)
13238     {
13239       errmsg ("mandatory argument(s) missing");
13240       return -99;
13241     }
13242
13243   /* Construct the API message */
13244   M (MAP_ADD_DOMAIN, mp);
13245
13246   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13247   mp->ip4_prefix_len = ip4_prefix_len;
13248
13249   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13250   mp->ip6_prefix_len = ip6_prefix_len;
13251
13252   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13253   mp->ip6_src_prefix_len = ip6_src_len;
13254
13255   mp->ea_bits_len = ea_bits_len;
13256   mp->psid_offset = psid_offset;
13257   mp->psid_length = psid_length;
13258   mp->is_translation = is_translation;
13259   mp->mtu = htons (mtu);
13260
13261   /* send it... */
13262   S (mp);
13263
13264   /* Wait for a reply, return good/bad news  */
13265   W (ret);
13266   return ret;
13267 }
13268
13269 static int
13270 api_map_del_domain (vat_main_t * vam)
13271 {
13272   unformat_input_t *i = vam->input;
13273   vl_api_map_del_domain_t *mp;
13274
13275   u32 num_m_args = 0;
13276   u32 index;
13277   int ret;
13278
13279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13280     {
13281       if (unformat (i, "index %d", &index))
13282         num_m_args++;
13283       else
13284         {
13285           clib_warning ("parse error '%U'", format_unformat_error, i);
13286           return -99;
13287         }
13288     }
13289
13290   if (num_m_args != 1)
13291     {
13292       errmsg ("mandatory argument(s) missing");
13293       return -99;
13294     }
13295
13296   /* Construct the API message */
13297   M (MAP_DEL_DOMAIN, mp);
13298
13299   mp->index = ntohl (index);
13300
13301   /* send it... */
13302   S (mp);
13303
13304   /* Wait for a reply, return good/bad news  */
13305   W (ret);
13306   return ret;
13307 }
13308
13309 static int
13310 api_map_add_del_rule (vat_main_t * vam)
13311 {
13312   unformat_input_t *i = vam->input;
13313   vl_api_map_add_del_rule_t *mp;
13314   u8 is_add = 1;
13315   ip6_address_t ip6_dst;
13316   u32 num_m_args = 0, index, psid = 0;
13317   int ret;
13318
13319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13320     {
13321       if (unformat (i, "index %d", &index))
13322         num_m_args++;
13323       else if (unformat (i, "psid %d", &psid))
13324         num_m_args++;
13325       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13326         num_m_args++;
13327       else if (unformat (i, "del"))
13328         {
13329           is_add = 0;
13330         }
13331       else
13332         {
13333           clib_warning ("parse error '%U'", format_unformat_error, i);
13334           return -99;
13335         }
13336     }
13337
13338   /* Construct the API message */
13339   M (MAP_ADD_DEL_RULE, mp);
13340
13341   mp->index = ntohl (index);
13342   mp->is_add = is_add;
13343   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13344   mp->psid = ntohs (psid);
13345
13346   /* send it... */
13347   S (mp);
13348
13349   /* Wait for a reply, return good/bad news  */
13350   W (ret);
13351   return ret;
13352 }
13353
13354 static int
13355 api_map_domain_dump (vat_main_t * vam)
13356 {
13357   vl_api_map_domain_dump_t *mp;
13358   vl_api_control_ping_t *mp_ping;
13359   int ret;
13360
13361   /* Construct the API message */
13362   M (MAP_DOMAIN_DUMP, mp);
13363
13364   /* send it... */
13365   S (mp);
13366
13367   /* Use a control ping for synchronization */
13368   M (CONTROL_PING, mp_ping);
13369   S (mp_ping);
13370
13371   W (ret);
13372   return ret;
13373 }
13374
13375 static int
13376 api_map_rule_dump (vat_main_t * vam)
13377 {
13378   unformat_input_t *i = vam->input;
13379   vl_api_map_rule_dump_t *mp;
13380   vl_api_control_ping_t *mp_ping;
13381   u32 domain_index = ~0;
13382   int ret;
13383
13384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13385     {
13386       if (unformat (i, "index %u", &domain_index))
13387         ;
13388       else
13389         break;
13390     }
13391
13392   if (domain_index == ~0)
13393     {
13394       clib_warning ("parse error: domain index expected");
13395       return -99;
13396     }
13397
13398   /* Construct the API message */
13399   M (MAP_RULE_DUMP, mp);
13400
13401   mp->domain_index = htonl (domain_index);
13402
13403   /* send it... */
13404   S (mp);
13405
13406   /* Use a control ping for synchronization */
13407   M (CONTROL_PING, mp_ping);
13408   S (mp_ping);
13409
13410   W (ret);
13411   return ret;
13412 }
13413
13414 static void vl_api_map_add_domain_reply_t_handler
13415   (vl_api_map_add_domain_reply_t * mp)
13416 {
13417   vat_main_t *vam = &vat_main;
13418   i32 retval = ntohl (mp->retval);
13419
13420   if (vam->async_mode)
13421     {
13422       vam->async_errors += (retval < 0);
13423     }
13424   else
13425     {
13426       vam->retval = retval;
13427       vam->result_ready = 1;
13428     }
13429 }
13430
13431 static void vl_api_map_add_domain_reply_t_handler_json
13432   (vl_api_map_add_domain_reply_t * mp)
13433 {
13434   vat_main_t *vam = &vat_main;
13435   vat_json_node_t node;
13436
13437   vat_json_init_object (&node);
13438   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13439   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13440
13441   vat_json_print (vam->ofp, &node);
13442   vat_json_free (&node);
13443
13444   vam->retval = ntohl (mp->retval);
13445   vam->result_ready = 1;
13446 }
13447
13448 static int
13449 api_get_first_msg_id (vat_main_t * vam)
13450 {
13451   vl_api_get_first_msg_id_t *mp;
13452   unformat_input_t *i = vam->input;
13453   u8 *name;
13454   u8 name_set = 0;
13455   int ret;
13456
13457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13458     {
13459       if (unformat (i, "client %s", &name))
13460         name_set = 1;
13461       else
13462         break;
13463     }
13464
13465   if (name_set == 0)
13466     {
13467       errmsg ("missing client name");
13468       return -99;
13469     }
13470   vec_add1 (name, 0);
13471
13472   if (vec_len (name) > 63)
13473     {
13474       errmsg ("client name too long");
13475       return -99;
13476     }
13477
13478   M (GET_FIRST_MSG_ID, mp);
13479   clib_memcpy (mp->name, name, vec_len (name));
13480   S (mp);
13481   W (ret);
13482   return ret;
13483 }
13484
13485 static int
13486 api_cop_interface_enable_disable (vat_main_t * vam)
13487 {
13488   unformat_input_t *line_input = vam->input;
13489   vl_api_cop_interface_enable_disable_t *mp;
13490   u32 sw_if_index = ~0;
13491   u8 enable_disable = 1;
13492   int ret;
13493
13494   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13495     {
13496       if (unformat (line_input, "disable"))
13497         enable_disable = 0;
13498       if (unformat (line_input, "enable"))
13499         enable_disable = 1;
13500       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13501                          vam, &sw_if_index))
13502         ;
13503       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13504         ;
13505       else
13506         break;
13507     }
13508
13509   if (sw_if_index == ~0)
13510     {
13511       errmsg ("missing interface name or sw_if_index");
13512       return -99;
13513     }
13514
13515   /* Construct the API message */
13516   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13517   mp->sw_if_index = ntohl (sw_if_index);
13518   mp->enable_disable = enable_disable;
13519
13520   /* send it... */
13521   S (mp);
13522   /* Wait for the reply */
13523   W (ret);
13524   return ret;
13525 }
13526
13527 static int
13528 api_cop_whitelist_enable_disable (vat_main_t * vam)
13529 {
13530   unformat_input_t *line_input = vam->input;
13531   vl_api_cop_whitelist_enable_disable_t *mp;
13532   u32 sw_if_index = ~0;
13533   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13534   u32 fib_id = 0;
13535   int ret;
13536
13537   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13538     {
13539       if (unformat (line_input, "ip4"))
13540         ip4 = 1;
13541       else if (unformat (line_input, "ip6"))
13542         ip6 = 1;
13543       else if (unformat (line_input, "default"))
13544         default_cop = 1;
13545       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13546                          vam, &sw_if_index))
13547         ;
13548       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13549         ;
13550       else if (unformat (line_input, "fib-id %d", &fib_id))
13551         ;
13552       else
13553         break;
13554     }
13555
13556   if (sw_if_index == ~0)
13557     {
13558       errmsg ("missing interface name or sw_if_index");
13559       return -99;
13560     }
13561
13562   /* Construct the API message */
13563   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13564   mp->sw_if_index = ntohl (sw_if_index);
13565   mp->fib_id = ntohl (fib_id);
13566   mp->ip4 = ip4;
13567   mp->ip6 = ip6;
13568   mp->default_cop = default_cop;
13569
13570   /* send it... */
13571   S (mp);
13572   /* Wait for the reply */
13573   W (ret);
13574   return ret;
13575 }
13576
13577 static int
13578 api_get_node_graph (vat_main_t * vam)
13579 {
13580   vl_api_get_node_graph_t *mp;
13581   int ret;
13582
13583   M (GET_NODE_GRAPH, mp);
13584
13585   /* send it... */
13586   S (mp);
13587   /* Wait for the reply */
13588   W (ret);
13589   return ret;
13590 }
13591
13592 /* *INDENT-OFF* */
13593 /** Used for parsing LISP eids */
13594 typedef CLIB_PACKED(struct{
13595   u8 addr[16];   /**< eid address */
13596   u32 len;       /**< prefix length if IP */
13597   u8 type;      /**< type of eid */
13598 }) lisp_eid_vat_t;
13599 /* *INDENT-ON* */
13600
13601 static uword
13602 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13603 {
13604   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13605
13606   memset (a, 0, sizeof (a[0]));
13607
13608   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13609     {
13610       a->type = 0;              /* ipv4 type */
13611     }
13612   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13613     {
13614       a->type = 1;              /* ipv6 type */
13615     }
13616   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13617     {
13618       a->type = 2;              /* mac type */
13619     }
13620   else
13621     {
13622       return 0;
13623     }
13624
13625   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13626     {
13627       return 0;
13628     }
13629
13630   return 1;
13631 }
13632
13633 static int
13634 lisp_eid_size_vat (u8 type)
13635 {
13636   switch (type)
13637     {
13638     case 0:
13639       return 4;
13640     case 1:
13641       return 16;
13642     case 2:
13643       return 6;
13644     }
13645   return 0;
13646 }
13647
13648 static void
13649 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13650 {
13651   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13652 }
13653
13654 static int
13655 api_one_add_del_locator_set (vat_main_t * vam)
13656 {
13657   unformat_input_t *input = vam->input;
13658   vl_api_one_add_del_locator_set_t *mp;
13659   u8 is_add = 1;
13660   u8 *locator_set_name = NULL;
13661   u8 locator_set_name_set = 0;
13662   vl_api_local_locator_t locator, *locators = 0;
13663   u32 sw_if_index, priority, weight;
13664   u32 data_len = 0;
13665
13666   int ret;
13667   /* Parse args required to build the message */
13668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13669     {
13670       if (unformat (input, "del"))
13671         {
13672           is_add = 0;
13673         }
13674       else if (unformat (input, "locator-set %s", &locator_set_name))
13675         {
13676           locator_set_name_set = 1;
13677         }
13678       else if (unformat (input, "sw_if_index %u p %u w %u",
13679                          &sw_if_index, &priority, &weight))
13680         {
13681           locator.sw_if_index = htonl (sw_if_index);
13682           locator.priority = priority;
13683           locator.weight = weight;
13684           vec_add1 (locators, locator);
13685         }
13686       else
13687         if (unformat
13688             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13689              &sw_if_index, &priority, &weight))
13690         {
13691           locator.sw_if_index = htonl (sw_if_index);
13692           locator.priority = priority;
13693           locator.weight = weight;
13694           vec_add1 (locators, locator);
13695         }
13696       else
13697         break;
13698     }
13699
13700   if (locator_set_name_set == 0)
13701     {
13702       errmsg ("missing locator-set name");
13703       vec_free (locators);
13704       return -99;
13705     }
13706
13707   if (vec_len (locator_set_name) > 64)
13708     {
13709       errmsg ("locator-set name too long");
13710       vec_free (locator_set_name);
13711       vec_free (locators);
13712       return -99;
13713     }
13714   vec_add1 (locator_set_name, 0);
13715
13716   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13717
13718   /* Construct the API message */
13719   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13720
13721   mp->is_add = is_add;
13722   clib_memcpy (mp->locator_set_name, locator_set_name,
13723                vec_len (locator_set_name));
13724   vec_free (locator_set_name);
13725
13726   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13727   if (locators)
13728     clib_memcpy (mp->locators, locators, data_len);
13729   vec_free (locators);
13730
13731   /* send it... */
13732   S (mp);
13733
13734   /* Wait for a reply... */
13735   W (ret);
13736   return ret;
13737 }
13738
13739 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13740
13741 static int
13742 api_one_add_del_locator (vat_main_t * vam)
13743 {
13744   unformat_input_t *input = vam->input;
13745   vl_api_one_add_del_locator_t *mp;
13746   u32 tmp_if_index = ~0;
13747   u32 sw_if_index = ~0;
13748   u8 sw_if_index_set = 0;
13749   u8 sw_if_index_if_name_set = 0;
13750   u32 priority = ~0;
13751   u8 priority_set = 0;
13752   u32 weight = ~0;
13753   u8 weight_set = 0;
13754   u8 is_add = 1;
13755   u8 *locator_set_name = NULL;
13756   u8 locator_set_name_set = 0;
13757   int ret;
13758
13759   /* Parse args required to build the message */
13760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13761     {
13762       if (unformat (input, "del"))
13763         {
13764           is_add = 0;
13765         }
13766       else if (unformat (input, "locator-set %s", &locator_set_name))
13767         {
13768           locator_set_name_set = 1;
13769         }
13770       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13771                          &tmp_if_index))
13772         {
13773           sw_if_index_if_name_set = 1;
13774           sw_if_index = tmp_if_index;
13775         }
13776       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13777         {
13778           sw_if_index_set = 1;
13779           sw_if_index = tmp_if_index;
13780         }
13781       else if (unformat (input, "p %d", &priority))
13782         {
13783           priority_set = 1;
13784         }
13785       else if (unformat (input, "w %d", &weight))
13786         {
13787           weight_set = 1;
13788         }
13789       else
13790         break;
13791     }
13792
13793   if (locator_set_name_set == 0)
13794     {
13795       errmsg ("missing locator-set name");
13796       return -99;
13797     }
13798
13799   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13800     {
13801       errmsg ("missing sw_if_index");
13802       vec_free (locator_set_name);
13803       return -99;
13804     }
13805
13806   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13807     {
13808       errmsg ("cannot use both params interface name and sw_if_index");
13809       vec_free (locator_set_name);
13810       return -99;
13811     }
13812
13813   if (priority_set == 0)
13814     {
13815       errmsg ("missing locator-set priority");
13816       vec_free (locator_set_name);
13817       return -99;
13818     }
13819
13820   if (weight_set == 0)
13821     {
13822       errmsg ("missing locator-set weight");
13823       vec_free (locator_set_name);
13824       return -99;
13825     }
13826
13827   if (vec_len (locator_set_name) > 64)
13828     {
13829       errmsg ("locator-set name too long");
13830       vec_free (locator_set_name);
13831       return -99;
13832     }
13833   vec_add1 (locator_set_name, 0);
13834
13835   /* Construct the API message */
13836   M (ONE_ADD_DEL_LOCATOR, mp);
13837
13838   mp->is_add = is_add;
13839   mp->sw_if_index = ntohl (sw_if_index);
13840   mp->priority = priority;
13841   mp->weight = weight;
13842   clib_memcpy (mp->locator_set_name, locator_set_name,
13843                vec_len (locator_set_name));
13844   vec_free (locator_set_name);
13845
13846   /* send it... */
13847   S (mp);
13848
13849   /* Wait for a reply... */
13850   W (ret);
13851   return ret;
13852 }
13853
13854 #define api_lisp_add_del_locator api_one_add_del_locator
13855
13856 uword
13857 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13858 {
13859   u32 *key_id = va_arg (*args, u32 *);
13860   u8 *s = 0;
13861
13862   if (unformat (input, "%s", &s))
13863     {
13864       if (!strcmp ((char *) s, "sha1"))
13865         key_id[0] = HMAC_SHA_1_96;
13866       else if (!strcmp ((char *) s, "sha256"))
13867         key_id[0] = HMAC_SHA_256_128;
13868       else
13869         {
13870           clib_warning ("invalid key_id: '%s'", s);
13871           key_id[0] = HMAC_NO_KEY;
13872         }
13873     }
13874   else
13875     return 0;
13876
13877   vec_free (s);
13878   return 1;
13879 }
13880
13881 static int
13882 api_one_add_del_local_eid (vat_main_t * vam)
13883 {
13884   unformat_input_t *input = vam->input;
13885   vl_api_one_add_del_local_eid_t *mp;
13886   u8 is_add = 1;
13887   u8 eid_set = 0;
13888   lisp_eid_vat_t _eid, *eid = &_eid;
13889   u8 *locator_set_name = 0;
13890   u8 locator_set_name_set = 0;
13891   u32 vni = 0;
13892   u16 key_id = 0;
13893   u8 *key = 0;
13894   int ret;
13895
13896   /* Parse args required to build the message */
13897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13898     {
13899       if (unformat (input, "del"))
13900         {
13901           is_add = 0;
13902         }
13903       else if (unformat (input, "vni %d", &vni))
13904         {
13905           ;
13906         }
13907       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13908         {
13909           eid_set = 1;
13910         }
13911       else if (unformat (input, "locator-set %s", &locator_set_name))
13912         {
13913           locator_set_name_set = 1;
13914         }
13915       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13916         ;
13917       else if (unformat (input, "secret-key %_%v%_", &key))
13918         ;
13919       else
13920         break;
13921     }
13922
13923   if (locator_set_name_set == 0)
13924     {
13925       errmsg ("missing locator-set name");
13926       return -99;
13927     }
13928
13929   if (0 == eid_set)
13930     {
13931       errmsg ("EID address not set!");
13932       vec_free (locator_set_name);
13933       return -99;
13934     }
13935
13936   if (key && (0 == key_id))
13937     {
13938       errmsg ("invalid key_id!");
13939       return -99;
13940     }
13941
13942   if (vec_len (key) > 64)
13943     {
13944       errmsg ("key too long");
13945       vec_free (key);
13946       return -99;
13947     }
13948
13949   if (vec_len (locator_set_name) > 64)
13950     {
13951       errmsg ("locator-set name too long");
13952       vec_free (locator_set_name);
13953       return -99;
13954     }
13955   vec_add1 (locator_set_name, 0);
13956
13957   /* Construct the API message */
13958   M (ONE_ADD_DEL_LOCAL_EID, mp);
13959
13960   mp->is_add = is_add;
13961   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13962   mp->eid_type = eid->type;
13963   mp->prefix_len = eid->len;
13964   mp->vni = clib_host_to_net_u32 (vni);
13965   mp->key_id = clib_host_to_net_u16 (key_id);
13966   clib_memcpy (mp->locator_set_name, locator_set_name,
13967                vec_len (locator_set_name));
13968   clib_memcpy (mp->key, key, vec_len (key));
13969
13970   vec_free (locator_set_name);
13971   vec_free (key);
13972
13973   /* send it... */
13974   S (mp);
13975
13976   /* Wait for a reply... */
13977   W (ret);
13978   return ret;
13979 }
13980
13981 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13982
13983 static int
13984 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13985 {
13986   u32 dp_table = 0, vni = 0;;
13987   unformat_input_t *input = vam->input;
13988   vl_api_gpe_add_del_fwd_entry_t *mp;
13989   u8 is_add = 1;
13990   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13991   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13992   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13993   u32 action = ~0, w;
13994   ip4_address_t rmt_rloc4, lcl_rloc4;
13995   ip6_address_t rmt_rloc6, lcl_rloc6;
13996   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13997   int ret;
13998
13999   memset (&rloc, 0, sizeof (rloc));
14000
14001   /* Parse args required to build the message */
14002   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14003     {
14004       if (unformat (input, "del"))
14005         is_add = 0;
14006       else if (unformat (input, "add"))
14007         is_add = 1;
14008       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14009         {
14010           rmt_eid_set = 1;
14011         }
14012       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14013         {
14014           lcl_eid_set = 1;
14015         }
14016       else if (unformat (input, "vrf %d", &dp_table))
14017         ;
14018       else if (unformat (input, "bd %d", &dp_table))
14019         ;
14020       else if (unformat (input, "vni %d", &vni))
14021         ;
14022       else if (unformat (input, "w %d", &w))
14023         {
14024           if (!curr_rloc)
14025             {
14026               errmsg ("No RLOC configured for setting priority/weight!");
14027               return -99;
14028             }
14029           curr_rloc->weight = w;
14030         }
14031       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14032                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14033         {
14034           rloc.is_ip4 = 1;
14035
14036           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14037           rloc.weight = 0;
14038           vec_add1 (lcl_locs, rloc);
14039
14040           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14041           vec_add1 (rmt_locs, rloc);
14042           /* weight saved in rmt loc */
14043           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14044         }
14045       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14046                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14047         {
14048           rloc.is_ip4 = 0;
14049           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14050           rloc.weight = 0;
14051           vec_add1 (lcl_locs, rloc);
14052
14053           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14054           vec_add1 (rmt_locs, rloc);
14055           /* weight saved in rmt loc */
14056           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14057         }
14058       else if (unformat (input, "action %d", &action))
14059         {
14060           ;
14061         }
14062       else
14063         {
14064           clib_warning ("parse error '%U'", format_unformat_error, input);
14065           return -99;
14066         }
14067     }
14068
14069   if (!rmt_eid_set)
14070     {
14071       errmsg ("remote eid addresses not set");
14072       return -99;
14073     }
14074
14075   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14076     {
14077       errmsg ("eid types don't match");
14078       return -99;
14079     }
14080
14081   if (0 == rmt_locs && (u32) ~ 0 == action)
14082     {
14083       errmsg ("action not set for negative mapping");
14084       return -99;
14085     }
14086
14087   /* Construct the API message */
14088   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14089       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14090
14091   mp->is_add = is_add;
14092   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14093   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14094   mp->eid_type = rmt_eid->type;
14095   mp->dp_table = clib_host_to_net_u32 (dp_table);
14096   mp->vni = clib_host_to_net_u32 (vni);
14097   mp->rmt_len = rmt_eid->len;
14098   mp->lcl_len = lcl_eid->len;
14099   mp->action = action;
14100
14101   if (0 != rmt_locs && 0 != lcl_locs)
14102     {
14103       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14104       clib_memcpy (mp->locs, lcl_locs,
14105                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14106
14107       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14108       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14109                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14110     }
14111   vec_free (lcl_locs);
14112   vec_free (rmt_locs);
14113
14114   /* send it... */
14115   S (mp);
14116
14117   /* Wait for a reply... */
14118   W (ret);
14119   return ret;
14120 }
14121
14122 static int
14123 api_one_add_del_map_server (vat_main_t * vam)
14124 {
14125   unformat_input_t *input = vam->input;
14126   vl_api_one_add_del_map_server_t *mp;
14127   u8 is_add = 1;
14128   u8 ipv4_set = 0;
14129   u8 ipv6_set = 0;
14130   ip4_address_t ipv4;
14131   ip6_address_t ipv6;
14132   int ret;
14133
14134   /* Parse args required to build the message */
14135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14136     {
14137       if (unformat (input, "del"))
14138         {
14139           is_add = 0;
14140         }
14141       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14142         {
14143           ipv4_set = 1;
14144         }
14145       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14146         {
14147           ipv6_set = 1;
14148         }
14149       else
14150         break;
14151     }
14152
14153   if (ipv4_set && ipv6_set)
14154     {
14155       errmsg ("both eid v4 and v6 addresses set");
14156       return -99;
14157     }
14158
14159   if (!ipv4_set && !ipv6_set)
14160     {
14161       errmsg ("eid addresses not set");
14162       return -99;
14163     }
14164
14165   /* Construct the API message */
14166   M (ONE_ADD_DEL_MAP_SERVER, mp);
14167
14168   mp->is_add = is_add;
14169   if (ipv6_set)
14170     {
14171       mp->is_ipv6 = 1;
14172       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14173     }
14174   else
14175     {
14176       mp->is_ipv6 = 0;
14177       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14178     }
14179
14180   /* send it... */
14181   S (mp);
14182
14183   /* Wait for a reply... */
14184   W (ret);
14185   return ret;
14186 }
14187
14188 #define api_lisp_add_del_map_server api_one_add_del_map_server
14189
14190 static int
14191 api_one_add_del_map_resolver (vat_main_t * vam)
14192 {
14193   unformat_input_t *input = vam->input;
14194   vl_api_one_add_del_map_resolver_t *mp;
14195   u8 is_add = 1;
14196   u8 ipv4_set = 0;
14197   u8 ipv6_set = 0;
14198   ip4_address_t ipv4;
14199   ip6_address_t ipv6;
14200   int ret;
14201
14202   /* Parse args required to build the message */
14203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14204     {
14205       if (unformat (input, "del"))
14206         {
14207           is_add = 0;
14208         }
14209       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14210         {
14211           ipv4_set = 1;
14212         }
14213       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14214         {
14215           ipv6_set = 1;
14216         }
14217       else
14218         break;
14219     }
14220
14221   if (ipv4_set && ipv6_set)
14222     {
14223       errmsg ("both eid v4 and v6 addresses set");
14224       return -99;
14225     }
14226
14227   if (!ipv4_set && !ipv6_set)
14228     {
14229       errmsg ("eid addresses not set");
14230       return -99;
14231     }
14232
14233   /* Construct the API message */
14234   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14235
14236   mp->is_add = is_add;
14237   if (ipv6_set)
14238     {
14239       mp->is_ipv6 = 1;
14240       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14241     }
14242   else
14243     {
14244       mp->is_ipv6 = 0;
14245       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14246     }
14247
14248   /* send it... */
14249   S (mp);
14250
14251   /* Wait for a reply... */
14252   W (ret);
14253   return ret;
14254 }
14255
14256 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14257
14258 static int
14259 api_lisp_gpe_enable_disable (vat_main_t * vam)
14260 {
14261   unformat_input_t *input = vam->input;
14262   vl_api_gpe_enable_disable_t *mp;
14263   u8 is_set = 0;
14264   u8 is_en = 1;
14265   int ret;
14266
14267   /* Parse args required to build the message */
14268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14269     {
14270       if (unformat (input, "enable"))
14271         {
14272           is_set = 1;
14273           is_en = 1;
14274         }
14275       else if (unformat (input, "disable"))
14276         {
14277           is_set = 1;
14278           is_en = 0;
14279         }
14280       else
14281         break;
14282     }
14283
14284   if (is_set == 0)
14285     {
14286       errmsg ("Value not set");
14287       return -99;
14288     }
14289
14290   /* Construct the API message */
14291   M (GPE_ENABLE_DISABLE, mp);
14292
14293   mp->is_en = is_en;
14294
14295   /* send it... */
14296   S (mp);
14297
14298   /* Wait for a reply... */
14299   W (ret);
14300   return ret;
14301 }
14302
14303 static int
14304 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14305 {
14306   unformat_input_t *input = vam->input;
14307   vl_api_one_rloc_probe_enable_disable_t *mp;
14308   u8 is_set = 0;
14309   u8 is_en = 0;
14310   int ret;
14311
14312   /* Parse args required to build the message */
14313   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14314     {
14315       if (unformat (input, "enable"))
14316         {
14317           is_set = 1;
14318           is_en = 1;
14319         }
14320       else if (unformat (input, "disable"))
14321         is_set = 1;
14322       else
14323         break;
14324     }
14325
14326   if (!is_set)
14327     {
14328       errmsg ("Value not set");
14329       return -99;
14330     }
14331
14332   /* Construct the API message */
14333   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14334
14335   mp->is_enabled = is_en;
14336
14337   /* send it... */
14338   S (mp);
14339
14340   /* Wait for a reply... */
14341   W (ret);
14342   return ret;
14343 }
14344
14345 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14346
14347 static int
14348 api_one_map_register_enable_disable (vat_main_t * vam)
14349 {
14350   unformat_input_t *input = vam->input;
14351   vl_api_one_map_register_enable_disable_t *mp;
14352   u8 is_set = 0;
14353   u8 is_en = 0;
14354   int ret;
14355
14356   /* Parse args required to build the message */
14357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14358     {
14359       if (unformat (input, "enable"))
14360         {
14361           is_set = 1;
14362           is_en = 1;
14363         }
14364       else if (unformat (input, "disable"))
14365         is_set = 1;
14366       else
14367         break;
14368     }
14369
14370   if (!is_set)
14371     {
14372       errmsg ("Value not set");
14373       return -99;
14374     }
14375
14376   /* Construct the API message */
14377   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14378
14379   mp->is_enabled = is_en;
14380
14381   /* send it... */
14382   S (mp);
14383
14384   /* Wait for a reply... */
14385   W (ret);
14386   return ret;
14387 }
14388
14389 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14390
14391 static int
14392 api_one_enable_disable (vat_main_t * vam)
14393 {
14394   unformat_input_t *input = vam->input;
14395   vl_api_one_enable_disable_t *mp;
14396   u8 is_set = 0;
14397   u8 is_en = 0;
14398   int ret;
14399
14400   /* Parse args required to build the message */
14401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14402     {
14403       if (unformat (input, "enable"))
14404         {
14405           is_set = 1;
14406           is_en = 1;
14407         }
14408       else if (unformat (input, "disable"))
14409         {
14410           is_set = 1;
14411         }
14412       else
14413         break;
14414     }
14415
14416   if (!is_set)
14417     {
14418       errmsg ("Value not set");
14419       return -99;
14420     }
14421
14422   /* Construct the API message */
14423   M (ONE_ENABLE_DISABLE, mp);
14424
14425   mp->is_en = is_en;
14426
14427   /* send it... */
14428   S (mp);
14429
14430   /* Wait for a reply... */
14431   W (ret);
14432   return ret;
14433 }
14434
14435 #define api_lisp_enable_disable api_one_enable_disable
14436
14437 static int
14438 api_show_one_map_register_state (vat_main_t * vam)
14439 {
14440   vl_api_show_one_map_register_state_t *mp;
14441   int ret;
14442
14443   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14444
14445   /* send */
14446   S (mp);
14447
14448   /* wait for reply */
14449   W (ret);
14450   return ret;
14451 }
14452
14453 #define api_show_lisp_map_register_state api_show_one_map_register_state
14454
14455 static int
14456 api_show_one_rloc_probe_state (vat_main_t * vam)
14457 {
14458   vl_api_show_one_rloc_probe_state_t *mp;
14459   int ret;
14460
14461   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14462
14463   /* send */
14464   S (mp);
14465
14466   /* wait for reply */
14467   W (ret);
14468   return ret;
14469 }
14470
14471 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14472
14473 static int
14474 api_one_stats_enable_disable (vat_main_t * vam)
14475 {
14476   vl_api_one_stats_enable_disable_t *mp;
14477   unformat_input_t *input = vam->input;
14478   u8 is_set = 0;
14479   u8 is_en = 0;
14480   int ret;
14481
14482   /* Parse args required to build the message */
14483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14484     {
14485       if (unformat (input, "enable"))
14486         {
14487           is_set = 1;
14488           is_en = 1;
14489         }
14490       else if (unformat (input, "disable"))
14491         {
14492           is_set = 1;
14493         }
14494       else
14495         break;
14496     }
14497
14498   if (!is_set)
14499     {
14500       errmsg ("Value not set");
14501       return -99;
14502     }
14503
14504   M (ONE_STATS_ENABLE_DISABLE, mp);
14505   mp->is_en = is_en;
14506
14507   /* send */
14508   S (mp);
14509
14510   /* wait for reply */
14511   W (ret);
14512   return ret;
14513 }
14514
14515 static int
14516 api_show_one_stats_enable_disable (vat_main_t * vam)
14517 {
14518   vl_api_show_one_stats_enable_disable_t *mp;
14519   int ret;
14520
14521   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14522
14523   /* send */
14524   S (mp);
14525
14526   /* wait for reply */
14527   W (ret);
14528   return ret;
14529 }
14530
14531 static int
14532 api_show_one_map_request_mode (vat_main_t * vam)
14533 {
14534   vl_api_show_one_map_request_mode_t *mp;
14535   int ret;
14536
14537   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14538
14539   /* send */
14540   S (mp);
14541
14542   /* wait for reply */
14543   W (ret);
14544   return ret;
14545 }
14546
14547 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14548
14549 static int
14550 api_one_map_request_mode (vat_main_t * vam)
14551 {
14552   unformat_input_t *input = vam->input;
14553   vl_api_one_map_request_mode_t *mp;
14554   u8 mode = 0;
14555   int ret;
14556
14557   /* Parse args required to build the message */
14558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14559     {
14560       if (unformat (input, "dst-only"))
14561         mode = 0;
14562       else if (unformat (input, "src-dst"))
14563         mode = 1;
14564       else
14565         {
14566           errmsg ("parse error '%U'", format_unformat_error, input);
14567           return -99;
14568         }
14569     }
14570
14571   M (ONE_MAP_REQUEST_MODE, mp);
14572
14573   mp->mode = mode;
14574
14575   /* send */
14576   S (mp);
14577
14578   /* wait for reply */
14579   W (ret);
14580   return ret;
14581 }
14582
14583 #define api_lisp_map_request_mode api_one_map_request_mode
14584
14585 /**
14586  * Enable/disable ONE proxy ITR.
14587  *
14588  * @param vam vpp API test context
14589  * @return return code
14590  */
14591 static int
14592 api_one_pitr_set_locator_set (vat_main_t * vam)
14593 {
14594   u8 ls_name_set = 0;
14595   unformat_input_t *input = vam->input;
14596   vl_api_one_pitr_set_locator_set_t *mp;
14597   u8 is_add = 1;
14598   u8 *ls_name = 0;
14599   int ret;
14600
14601   /* Parse args required to build the message */
14602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14603     {
14604       if (unformat (input, "del"))
14605         is_add = 0;
14606       else if (unformat (input, "locator-set %s", &ls_name))
14607         ls_name_set = 1;
14608       else
14609         {
14610           errmsg ("parse error '%U'", format_unformat_error, input);
14611           return -99;
14612         }
14613     }
14614
14615   if (!ls_name_set)
14616     {
14617       errmsg ("locator-set name not set!");
14618       return -99;
14619     }
14620
14621   M (ONE_PITR_SET_LOCATOR_SET, mp);
14622
14623   mp->is_add = is_add;
14624   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14625   vec_free (ls_name);
14626
14627   /* send */
14628   S (mp);
14629
14630   /* wait for reply */
14631   W (ret);
14632   return ret;
14633 }
14634
14635 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14636
14637 static int
14638 api_show_one_pitr (vat_main_t * vam)
14639 {
14640   vl_api_show_one_pitr_t *mp;
14641   int ret;
14642
14643   if (!vam->json_output)
14644     {
14645       print (vam->ofp, "%=20s", "lisp status:");
14646     }
14647
14648   M (SHOW_ONE_PITR, mp);
14649   /* send it... */
14650   S (mp);
14651
14652   /* Wait for a reply... */
14653   W (ret);
14654   return ret;
14655 }
14656
14657 #define api_show_lisp_pitr api_show_one_pitr
14658
14659 static int
14660 api_one_use_petr (vat_main_t * vam)
14661 {
14662   unformat_input_t *input = vam->input;
14663   vl_api_one_use_petr_t *mp;
14664   u8 is_add = 0;
14665   ip_address_t ip;
14666   int ret;
14667
14668   memset (&ip, 0, sizeof (ip));
14669
14670   /* Parse args required to build the message */
14671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14672     {
14673       if (unformat (input, "disable"))
14674         is_add = 0;
14675       else
14676         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14677         {
14678           is_add = 1;
14679           ip_addr_version (&ip) = IP4;
14680         }
14681       else
14682         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14683         {
14684           is_add = 1;
14685           ip_addr_version (&ip) = IP6;
14686         }
14687       else
14688         {
14689           errmsg ("parse error '%U'", format_unformat_error, input);
14690           return -99;
14691         }
14692     }
14693
14694   M (ONE_USE_PETR, mp);
14695
14696   mp->is_add = is_add;
14697   if (is_add)
14698     {
14699       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14700       if (mp->is_ip4)
14701         clib_memcpy (mp->address, &ip, 4);
14702       else
14703         clib_memcpy (mp->address, &ip, 16);
14704     }
14705
14706   /* send */
14707   S (mp);
14708
14709   /* wait for reply */
14710   W (ret);
14711   return ret;
14712 }
14713
14714 #define api_lisp_use_petr api_one_use_petr
14715
14716 static int
14717 api_show_one_use_petr (vat_main_t * vam)
14718 {
14719   vl_api_show_one_use_petr_t *mp;
14720   int ret;
14721
14722   if (!vam->json_output)
14723     {
14724       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14725     }
14726
14727   M (SHOW_ONE_USE_PETR, mp);
14728   /* send it... */
14729   S (mp);
14730
14731   /* Wait for a reply... */
14732   W (ret);
14733   return ret;
14734 }
14735
14736 #define api_show_lisp_use_petr api_show_one_use_petr
14737
14738 /**
14739  * Add/delete mapping between vni and vrf
14740  */
14741 static int
14742 api_one_eid_table_add_del_map (vat_main_t * vam)
14743 {
14744   unformat_input_t *input = vam->input;
14745   vl_api_one_eid_table_add_del_map_t *mp;
14746   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14747   u32 vni, vrf, bd_index;
14748   int ret;
14749
14750   /* Parse args required to build the message */
14751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14752     {
14753       if (unformat (input, "del"))
14754         is_add = 0;
14755       else if (unformat (input, "vrf %d", &vrf))
14756         vrf_set = 1;
14757       else if (unformat (input, "bd_index %d", &bd_index))
14758         bd_index_set = 1;
14759       else if (unformat (input, "vni %d", &vni))
14760         vni_set = 1;
14761       else
14762         break;
14763     }
14764
14765   if (!vni_set || (!vrf_set && !bd_index_set))
14766     {
14767       errmsg ("missing arguments!");
14768       return -99;
14769     }
14770
14771   if (vrf_set && bd_index_set)
14772     {
14773       errmsg ("error: both vrf and bd entered!");
14774       return -99;
14775     }
14776
14777   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14778
14779   mp->is_add = is_add;
14780   mp->vni = htonl (vni);
14781   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14782   mp->is_l2 = bd_index_set;
14783
14784   /* send */
14785   S (mp);
14786
14787   /* wait for reply */
14788   W (ret);
14789   return ret;
14790 }
14791
14792 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14793
14794 uword
14795 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14796 {
14797   u32 *action = va_arg (*args, u32 *);
14798   u8 *s = 0;
14799
14800   if (unformat (input, "%s", &s))
14801     {
14802       if (!strcmp ((char *) s, "no-action"))
14803         action[0] = 0;
14804       else if (!strcmp ((char *) s, "natively-forward"))
14805         action[0] = 1;
14806       else if (!strcmp ((char *) s, "send-map-request"))
14807         action[0] = 2;
14808       else if (!strcmp ((char *) s, "drop"))
14809         action[0] = 3;
14810       else
14811         {
14812           clib_warning ("invalid action: '%s'", s);
14813           action[0] = 3;
14814         }
14815     }
14816   else
14817     return 0;
14818
14819   vec_free (s);
14820   return 1;
14821 }
14822
14823 /**
14824  * Add/del remote mapping to/from ONE control plane
14825  *
14826  * @param vam vpp API test context
14827  * @return return code
14828  */
14829 static int
14830 api_one_add_del_remote_mapping (vat_main_t * vam)
14831 {
14832   unformat_input_t *input = vam->input;
14833   vl_api_one_add_del_remote_mapping_t *mp;
14834   u32 vni = 0;
14835   lisp_eid_vat_t _eid, *eid = &_eid;
14836   lisp_eid_vat_t _seid, *seid = &_seid;
14837   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14838   u32 action = ~0, p, w, data_len;
14839   ip4_address_t rloc4;
14840   ip6_address_t rloc6;
14841   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14842   int ret;
14843
14844   memset (&rloc, 0, sizeof (rloc));
14845
14846   /* Parse args required to build the message */
14847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14848     {
14849       if (unformat (input, "del-all"))
14850         {
14851           del_all = 1;
14852         }
14853       else if (unformat (input, "del"))
14854         {
14855           is_add = 0;
14856         }
14857       else if (unformat (input, "add"))
14858         {
14859           is_add = 1;
14860         }
14861       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14862         {
14863           eid_set = 1;
14864         }
14865       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14866         {
14867           seid_set = 1;
14868         }
14869       else if (unformat (input, "vni %d", &vni))
14870         {
14871           ;
14872         }
14873       else if (unformat (input, "p %d w %d", &p, &w))
14874         {
14875           if (!curr_rloc)
14876             {
14877               errmsg ("No RLOC configured for setting priority/weight!");
14878               return -99;
14879             }
14880           curr_rloc->priority = p;
14881           curr_rloc->weight = w;
14882         }
14883       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14884         {
14885           rloc.is_ip4 = 1;
14886           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14887           vec_add1 (rlocs, rloc);
14888           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14889         }
14890       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14891         {
14892           rloc.is_ip4 = 0;
14893           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14894           vec_add1 (rlocs, rloc);
14895           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14896         }
14897       else if (unformat (input, "action %U",
14898                          unformat_negative_mapping_action, &action))
14899         {
14900           ;
14901         }
14902       else
14903         {
14904           clib_warning ("parse error '%U'", format_unformat_error, input);
14905           return -99;
14906         }
14907     }
14908
14909   if (0 == eid_set)
14910     {
14911       errmsg ("missing params!");
14912       return -99;
14913     }
14914
14915   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14916     {
14917       errmsg ("no action set for negative map-reply!");
14918       return -99;
14919     }
14920
14921   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14922
14923   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14924   mp->is_add = is_add;
14925   mp->vni = htonl (vni);
14926   mp->action = (u8) action;
14927   mp->is_src_dst = seid_set;
14928   mp->eid_len = eid->len;
14929   mp->seid_len = seid->len;
14930   mp->del_all = del_all;
14931   mp->eid_type = eid->type;
14932   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14933   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14934
14935   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14936   clib_memcpy (mp->rlocs, rlocs, data_len);
14937   vec_free (rlocs);
14938
14939   /* send it... */
14940   S (mp);
14941
14942   /* Wait for a reply... */
14943   W (ret);
14944   return ret;
14945 }
14946
14947 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14948
14949 /**
14950  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14951  * forwarding entries in data-plane accordingly.
14952  *
14953  * @param vam vpp API test context
14954  * @return return code
14955  */
14956 static int
14957 api_one_add_del_adjacency (vat_main_t * vam)
14958 {
14959   unformat_input_t *input = vam->input;
14960   vl_api_one_add_del_adjacency_t *mp;
14961   u32 vni = 0;
14962   ip4_address_t leid4, reid4;
14963   ip6_address_t leid6, reid6;
14964   u8 reid_mac[6] = { 0 };
14965   u8 leid_mac[6] = { 0 };
14966   u8 reid_type, leid_type;
14967   u32 leid_len = 0, reid_len = 0, len;
14968   u8 is_add = 1;
14969   int ret;
14970
14971   leid_type = reid_type = (u8) ~ 0;
14972
14973   /* Parse args required to build the message */
14974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14975     {
14976       if (unformat (input, "del"))
14977         {
14978           is_add = 0;
14979         }
14980       else if (unformat (input, "add"))
14981         {
14982           is_add = 1;
14983         }
14984       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14985                          &reid4, &len))
14986         {
14987           reid_type = 0;        /* ipv4 */
14988           reid_len = len;
14989         }
14990       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14991                          &reid6, &len))
14992         {
14993           reid_type = 1;        /* ipv6 */
14994           reid_len = len;
14995         }
14996       else if (unformat (input, "reid %U", unformat_ethernet_address,
14997                          reid_mac))
14998         {
14999           reid_type = 2;        /* mac */
15000         }
15001       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15002                          &leid4, &len))
15003         {
15004           leid_type = 0;        /* ipv4 */
15005           leid_len = len;
15006         }
15007       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15008                          &leid6, &len))
15009         {
15010           leid_type = 1;        /* ipv6 */
15011           leid_len = len;
15012         }
15013       else if (unformat (input, "leid %U", unformat_ethernet_address,
15014                          leid_mac))
15015         {
15016           leid_type = 2;        /* mac */
15017         }
15018       else if (unformat (input, "vni %d", &vni))
15019         {
15020           ;
15021         }
15022       else
15023         {
15024           errmsg ("parse error '%U'", format_unformat_error, input);
15025           return -99;
15026         }
15027     }
15028
15029   if ((u8) ~ 0 == reid_type)
15030     {
15031       errmsg ("missing params!");
15032       return -99;
15033     }
15034
15035   if (leid_type != reid_type)
15036     {
15037       errmsg ("remote and local EIDs are of different types!");
15038       return -99;
15039     }
15040
15041   M (ONE_ADD_DEL_ADJACENCY, mp);
15042   mp->is_add = is_add;
15043   mp->vni = htonl (vni);
15044   mp->leid_len = leid_len;
15045   mp->reid_len = reid_len;
15046   mp->eid_type = reid_type;
15047
15048   switch (mp->eid_type)
15049     {
15050     case 0:
15051       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15052       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15053       break;
15054     case 1:
15055       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15056       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15057       break;
15058     case 2:
15059       clib_memcpy (mp->leid, leid_mac, 6);
15060       clib_memcpy (mp->reid, reid_mac, 6);
15061       break;
15062     default:
15063       errmsg ("unknown EID type %d!", mp->eid_type);
15064       return 0;
15065     }
15066
15067   /* send it... */
15068   S (mp);
15069
15070   /* Wait for a reply... */
15071   W (ret);
15072   return ret;
15073 }
15074
15075 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15076
15077 uword
15078 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15079 {
15080   u32 *mode = va_arg (*args, u32 *);
15081
15082   if (unformat (input, "lisp"))
15083     *mode = 0;
15084   else if (unformat (input, "vxlan"))
15085     *mode = 1;
15086   else
15087     return 0;
15088
15089   return 1;
15090 }
15091
15092 static int
15093 api_gpe_get_encap_mode (vat_main_t * vam)
15094 {
15095   vl_api_gpe_get_encap_mode_t *mp;
15096   int ret;
15097
15098   /* Construct the API message */
15099   M (GPE_GET_ENCAP_MODE, mp);
15100
15101   /* send it... */
15102   S (mp);
15103
15104   /* Wait for a reply... */
15105   W (ret);
15106   return ret;
15107 }
15108
15109 static int
15110 api_gpe_set_encap_mode (vat_main_t * vam)
15111 {
15112   unformat_input_t *input = vam->input;
15113   vl_api_gpe_set_encap_mode_t *mp;
15114   int ret;
15115   u32 mode = 0;
15116
15117   /* Parse args required to build the message */
15118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15119     {
15120       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15121         ;
15122       else
15123         break;
15124     }
15125
15126   /* Construct the API message */
15127   M (GPE_SET_ENCAP_MODE, mp);
15128
15129   mp->mode = mode;
15130
15131   /* send it... */
15132   S (mp);
15133
15134   /* Wait for a reply... */
15135   W (ret);
15136   return ret;
15137 }
15138
15139 static int
15140 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15141 {
15142   unformat_input_t *input = vam->input;
15143   vl_api_gpe_add_del_iface_t *mp;
15144   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15145   u32 dp_table = 0, vni = 0;
15146   int ret;
15147
15148   /* Parse args required to build the message */
15149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15150     {
15151       if (unformat (input, "up"))
15152         {
15153           action_set = 1;
15154           is_add = 1;
15155         }
15156       else if (unformat (input, "down"))
15157         {
15158           action_set = 1;
15159           is_add = 0;
15160         }
15161       else if (unformat (input, "table_id %d", &dp_table))
15162         {
15163           dp_table_set = 1;
15164         }
15165       else if (unformat (input, "bd_id %d", &dp_table))
15166         {
15167           dp_table_set = 1;
15168           is_l2 = 1;
15169         }
15170       else if (unformat (input, "vni %d", &vni))
15171         {
15172           vni_set = 1;
15173         }
15174       else
15175         break;
15176     }
15177
15178   if (action_set == 0)
15179     {
15180       errmsg ("Action not set");
15181       return -99;
15182     }
15183   if (dp_table_set == 0 || vni_set == 0)
15184     {
15185       errmsg ("vni and dp_table must be set");
15186       return -99;
15187     }
15188
15189   /* Construct the API message */
15190   M (GPE_ADD_DEL_IFACE, mp);
15191
15192   mp->is_add = is_add;
15193   mp->dp_table = dp_table;
15194   mp->is_l2 = is_l2;
15195   mp->vni = vni;
15196
15197   /* send it... */
15198   S (mp);
15199
15200   /* Wait for a reply... */
15201   W (ret);
15202   return ret;
15203 }
15204
15205 /**
15206  * Add/del map request itr rlocs from ONE control plane and updates
15207  *
15208  * @param vam vpp API test context
15209  * @return return code
15210  */
15211 static int
15212 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15213 {
15214   unformat_input_t *input = vam->input;
15215   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15216   u8 *locator_set_name = 0;
15217   u8 locator_set_name_set = 0;
15218   u8 is_add = 1;
15219   int ret;
15220
15221   /* Parse args required to build the message */
15222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15223     {
15224       if (unformat (input, "del"))
15225         {
15226           is_add = 0;
15227         }
15228       else if (unformat (input, "%_%v%_", &locator_set_name))
15229         {
15230           locator_set_name_set = 1;
15231         }
15232       else
15233         {
15234           clib_warning ("parse error '%U'", format_unformat_error, input);
15235           return -99;
15236         }
15237     }
15238
15239   if (is_add && !locator_set_name_set)
15240     {
15241       errmsg ("itr-rloc is not set!");
15242       return -99;
15243     }
15244
15245   if (is_add && vec_len (locator_set_name) > 64)
15246     {
15247       errmsg ("itr-rloc locator-set name too long");
15248       vec_free (locator_set_name);
15249       return -99;
15250     }
15251
15252   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15253   mp->is_add = is_add;
15254   if (is_add)
15255     {
15256       clib_memcpy (mp->locator_set_name, locator_set_name,
15257                    vec_len (locator_set_name));
15258     }
15259   else
15260     {
15261       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15262     }
15263   vec_free (locator_set_name);
15264
15265   /* send it... */
15266   S (mp);
15267
15268   /* Wait for a reply... */
15269   W (ret);
15270   return ret;
15271 }
15272
15273 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15274
15275 static int
15276 api_one_locator_dump (vat_main_t * vam)
15277 {
15278   unformat_input_t *input = vam->input;
15279   vl_api_one_locator_dump_t *mp;
15280   vl_api_control_ping_t *mp_ping;
15281   u8 is_index_set = 0, is_name_set = 0;
15282   u8 *ls_name = 0;
15283   u32 ls_index = ~0;
15284   int ret;
15285
15286   /* Parse args required to build the message */
15287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15288     {
15289       if (unformat (input, "ls_name %_%v%_", &ls_name))
15290         {
15291           is_name_set = 1;
15292         }
15293       else if (unformat (input, "ls_index %d", &ls_index))
15294         {
15295           is_index_set = 1;
15296         }
15297       else
15298         {
15299           errmsg ("parse error '%U'", format_unformat_error, input);
15300           return -99;
15301         }
15302     }
15303
15304   if (!is_index_set && !is_name_set)
15305     {
15306       errmsg ("error: expected one of index or name!");
15307       return -99;
15308     }
15309
15310   if (is_index_set && is_name_set)
15311     {
15312       errmsg ("error: only one param expected!");
15313       return -99;
15314     }
15315
15316   if (vec_len (ls_name) > 62)
15317     {
15318       errmsg ("error: locator set name too long!");
15319       return -99;
15320     }
15321
15322   if (!vam->json_output)
15323     {
15324       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15325     }
15326
15327   M (ONE_LOCATOR_DUMP, mp);
15328   mp->is_index_set = is_index_set;
15329
15330   if (is_index_set)
15331     mp->ls_index = clib_host_to_net_u32 (ls_index);
15332   else
15333     {
15334       vec_add1 (ls_name, 0);
15335       strncpy ((char *) mp->ls_name, (char *) ls_name,
15336                sizeof (mp->ls_name) - 1);
15337     }
15338
15339   /* send it... */
15340   S (mp);
15341
15342   /* Use a control ping for synchronization */
15343   M (CONTROL_PING, mp_ping);
15344   S (mp_ping);
15345
15346   /* Wait for a reply... */
15347   W (ret);
15348   return ret;
15349 }
15350
15351 #define api_lisp_locator_dump api_one_locator_dump
15352
15353 static int
15354 api_one_locator_set_dump (vat_main_t * vam)
15355 {
15356   vl_api_one_locator_set_dump_t *mp;
15357   vl_api_control_ping_t *mp_ping;
15358   unformat_input_t *input = vam->input;
15359   u8 filter = 0;
15360   int ret;
15361
15362   /* Parse args required to build the message */
15363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15364     {
15365       if (unformat (input, "local"))
15366         {
15367           filter = 1;
15368         }
15369       else if (unformat (input, "remote"))
15370         {
15371           filter = 2;
15372         }
15373       else
15374         {
15375           errmsg ("parse error '%U'", format_unformat_error, input);
15376           return -99;
15377         }
15378     }
15379
15380   if (!vam->json_output)
15381     {
15382       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15383     }
15384
15385   M (ONE_LOCATOR_SET_DUMP, mp);
15386
15387   mp->filter = filter;
15388
15389   /* send it... */
15390   S (mp);
15391
15392   /* Use a control ping for synchronization */
15393   M (CONTROL_PING, mp_ping);
15394   S (mp_ping);
15395
15396   /* Wait for a reply... */
15397   W (ret);
15398   return ret;
15399 }
15400
15401 #define api_lisp_locator_set_dump api_one_locator_set_dump
15402
15403 static int
15404 api_one_eid_table_map_dump (vat_main_t * vam)
15405 {
15406   u8 is_l2 = 0;
15407   u8 mode_set = 0;
15408   unformat_input_t *input = vam->input;
15409   vl_api_one_eid_table_map_dump_t *mp;
15410   vl_api_control_ping_t *mp_ping;
15411   int ret;
15412
15413   /* Parse args required to build the message */
15414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15415     {
15416       if (unformat (input, "l2"))
15417         {
15418           is_l2 = 1;
15419           mode_set = 1;
15420         }
15421       else if (unformat (input, "l3"))
15422         {
15423           is_l2 = 0;
15424           mode_set = 1;
15425         }
15426       else
15427         {
15428           errmsg ("parse error '%U'", format_unformat_error, input);
15429           return -99;
15430         }
15431     }
15432
15433   if (!mode_set)
15434     {
15435       errmsg ("expected one of 'l2' or 'l3' parameter!");
15436       return -99;
15437     }
15438
15439   if (!vam->json_output)
15440     {
15441       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15442     }
15443
15444   M (ONE_EID_TABLE_MAP_DUMP, mp);
15445   mp->is_l2 = is_l2;
15446
15447   /* send it... */
15448   S (mp);
15449
15450   /* Use a control ping for synchronization */
15451   M (CONTROL_PING, mp_ping);
15452   S (mp_ping);
15453
15454   /* Wait for a reply... */
15455   W (ret);
15456   return ret;
15457 }
15458
15459 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15460
15461 static int
15462 api_one_eid_table_vni_dump (vat_main_t * vam)
15463 {
15464   vl_api_one_eid_table_vni_dump_t *mp;
15465   vl_api_control_ping_t *mp_ping;
15466   int ret;
15467
15468   if (!vam->json_output)
15469     {
15470       print (vam->ofp, "VNI");
15471     }
15472
15473   M (ONE_EID_TABLE_VNI_DUMP, mp);
15474
15475   /* send it... */
15476   S (mp);
15477
15478   /* Use a control ping for synchronization */
15479   M (CONTROL_PING, mp_ping);
15480   S (mp_ping);
15481
15482   /* Wait for a reply... */
15483   W (ret);
15484   return ret;
15485 }
15486
15487 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15488
15489 static int
15490 api_one_eid_table_dump (vat_main_t * vam)
15491 {
15492   unformat_input_t *i = vam->input;
15493   vl_api_one_eid_table_dump_t *mp;
15494   vl_api_control_ping_t *mp_ping;
15495   struct in_addr ip4;
15496   struct in6_addr ip6;
15497   u8 mac[6];
15498   u8 eid_type = ~0, eid_set = 0;
15499   u32 prefix_length = ~0, t, vni = 0;
15500   u8 filter = 0;
15501   int ret;
15502
15503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15504     {
15505       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15506         {
15507           eid_set = 1;
15508           eid_type = 0;
15509           prefix_length = t;
15510         }
15511       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15512         {
15513           eid_set = 1;
15514           eid_type = 1;
15515           prefix_length = t;
15516         }
15517       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15518         {
15519           eid_set = 1;
15520           eid_type = 2;
15521         }
15522       else if (unformat (i, "vni %d", &t))
15523         {
15524           vni = t;
15525         }
15526       else if (unformat (i, "local"))
15527         {
15528           filter = 1;
15529         }
15530       else if (unformat (i, "remote"))
15531         {
15532           filter = 2;
15533         }
15534       else
15535         {
15536           errmsg ("parse error '%U'", format_unformat_error, i);
15537           return -99;
15538         }
15539     }
15540
15541   if (!vam->json_output)
15542     {
15543       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15544              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15545     }
15546
15547   M (ONE_EID_TABLE_DUMP, mp);
15548
15549   mp->filter = filter;
15550   if (eid_set)
15551     {
15552       mp->eid_set = 1;
15553       mp->vni = htonl (vni);
15554       mp->eid_type = eid_type;
15555       switch (eid_type)
15556         {
15557         case 0:
15558           mp->prefix_length = prefix_length;
15559           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15560           break;
15561         case 1:
15562           mp->prefix_length = prefix_length;
15563           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15564           break;
15565         case 2:
15566           clib_memcpy (mp->eid, mac, sizeof (mac));
15567           break;
15568         default:
15569           errmsg ("unknown EID type %d!", eid_type);
15570           return -99;
15571         }
15572     }
15573
15574   /* send it... */
15575   S (mp);
15576
15577   /* Use a control ping for synchronization */
15578   M (CONTROL_PING, mp_ping);
15579   S (mp_ping);
15580
15581   /* Wait for a reply... */
15582   W (ret);
15583   return ret;
15584 }
15585
15586 #define api_lisp_eid_table_dump api_one_eid_table_dump
15587
15588 static int
15589 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15590 {
15591   unformat_input_t *i = vam->input;
15592   vl_api_gpe_fwd_entries_get_t *mp;
15593   u8 vni_set = 0;
15594   u32 vni = ~0;
15595   int ret;
15596
15597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15598     {
15599       if (unformat (i, "vni %d", &vni))
15600         {
15601           vni_set = 1;
15602         }
15603       else
15604         {
15605           errmsg ("parse error '%U'", format_unformat_error, i);
15606           return -99;
15607         }
15608     }
15609
15610   if (!vni_set)
15611     {
15612       errmsg ("vni not set!");
15613       return -99;
15614     }
15615
15616   if (!vam->json_output)
15617     {
15618       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15619              "leid", "reid");
15620     }
15621
15622   M (GPE_FWD_ENTRIES_GET, mp);
15623   mp->vni = clib_host_to_net_u32 (vni);
15624
15625   /* send it... */
15626   S (mp);
15627
15628   /* Wait for a reply... */
15629   W (ret);
15630   return ret;
15631 }
15632
15633 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15634 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15635 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15636 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15637
15638 static int
15639 api_one_adjacencies_get (vat_main_t * vam)
15640 {
15641   unformat_input_t *i = vam->input;
15642   vl_api_one_adjacencies_get_t *mp;
15643   u8 vni_set = 0;
15644   u32 vni = ~0;
15645   int ret;
15646
15647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15648     {
15649       if (unformat (i, "vni %d", &vni))
15650         {
15651           vni_set = 1;
15652         }
15653       else
15654         {
15655           errmsg ("parse error '%U'", format_unformat_error, i);
15656           return -99;
15657         }
15658     }
15659
15660   if (!vni_set)
15661     {
15662       errmsg ("vni not set!");
15663       return -99;
15664     }
15665
15666   if (!vam->json_output)
15667     {
15668       print (vam->ofp, "%s %40s", "leid", "reid");
15669     }
15670
15671   M (ONE_ADJACENCIES_GET, mp);
15672   mp->vni = clib_host_to_net_u32 (vni);
15673
15674   /* send it... */
15675   S (mp);
15676
15677   /* Wait for a reply... */
15678   W (ret);
15679   return ret;
15680 }
15681
15682 #define api_lisp_adjacencies_get api_one_adjacencies_get
15683
15684 static int
15685 api_one_map_server_dump (vat_main_t * vam)
15686 {
15687   vl_api_one_map_server_dump_t *mp;
15688   vl_api_control_ping_t *mp_ping;
15689   int ret;
15690
15691   if (!vam->json_output)
15692     {
15693       print (vam->ofp, "%=20s", "Map server");
15694     }
15695
15696   M (ONE_MAP_SERVER_DUMP, mp);
15697   /* send it... */
15698   S (mp);
15699
15700   /* Use a control ping for synchronization */
15701   M (CONTROL_PING, mp_ping);
15702   S (mp_ping);
15703
15704   /* Wait for a reply... */
15705   W (ret);
15706   return ret;
15707 }
15708
15709 #define api_lisp_map_server_dump api_one_map_server_dump
15710
15711 static int
15712 api_one_map_resolver_dump (vat_main_t * vam)
15713 {
15714   vl_api_one_map_resolver_dump_t *mp;
15715   vl_api_control_ping_t *mp_ping;
15716   int ret;
15717
15718   if (!vam->json_output)
15719     {
15720       print (vam->ofp, "%=20s", "Map resolver");
15721     }
15722
15723   M (ONE_MAP_RESOLVER_DUMP, mp);
15724   /* send it... */
15725   S (mp);
15726
15727   /* Use a control ping for synchronization */
15728   M (CONTROL_PING, mp_ping);
15729   S (mp_ping);
15730
15731   /* Wait for a reply... */
15732   W (ret);
15733   return ret;
15734 }
15735
15736 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15737
15738 static int
15739 api_one_stats_dump (vat_main_t * vam)
15740 {
15741   vl_api_one_stats_dump_t *mp;
15742   vl_api_control_ping_t *mp_ping;
15743   int ret;
15744
15745   M (ONE_STATS_DUMP, mp);
15746   /* send it... */
15747   S (mp);
15748
15749   /* Use a control ping for synchronization */
15750   M (CONTROL_PING, mp_ping);
15751   S (mp_ping);
15752
15753   /* Wait for a reply... */
15754   W (ret);
15755   return ret;
15756 }
15757
15758 static int
15759 api_show_one_status (vat_main_t * vam)
15760 {
15761   vl_api_show_one_status_t *mp;
15762   int ret;
15763
15764   if (!vam->json_output)
15765     {
15766       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15767     }
15768
15769   M (SHOW_ONE_STATUS, mp);
15770   /* send it... */
15771   S (mp);
15772   /* Wait for a reply... */
15773   W (ret);
15774   return ret;
15775 }
15776
15777 #define api_show_lisp_status api_show_one_status
15778
15779 static int
15780 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15781 {
15782   vl_api_gpe_fwd_entry_path_dump_t *mp;
15783   vl_api_control_ping_t *mp_ping;
15784   unformat_input_t *i = vam->input;
15785   u32 fwd_entry_index = ~0;
15786   int ret;
15787
15788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15789     {
15790       if (unformat (i, "index %d", &fwd_entry_index))
15791         ;
15792       else
15793         break;
15794     }
15795
15796   if (~0 == fwd_entry_index)
15797     {
15798       errmsg ("no index specified!");
15799       return -99;
15800     }
15801
15802   if (!vam->json_output)
15803     {
15804       print (vam->ofp, "first line");
15805     }
15806
15807   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15808
15809   /* send it... */
15810   S (mp);
15811   /* Use a control ping for synchronization */
15812   M (CONTROL_PING, mp_ping);
15813   S (mp_ping);
15814
15815   /* Wait for a reply... */
15816   W (ret);
15817   return ret;
15818 }
15819
15820 static int
15821 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15822 {
15823   vl_api_one_get_map_request_itr_rlocs_t *mp;
15824   int ret;
15825
15826   if (!vam->json_output)
15827     {
15828       print (vam->ofp, "%=20s", "itr-rlocs:");
15829     }
15830
15831   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15832   /* send it... */
15833   S (mp);
15834   /* Wait for a reply... */
15835   W (ret);
15836   return ret;
15837 }
15838
15839 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15840
15841 static int
15842 api_af_packet_create (vat_main_t * vam)
15843 {
15844   unformat_input_t *i = vam->input;
15845   vl_api_af_packet_create_t *mp;
15846   u8 *host_if_name = 0;
15847   u8 hw_addr[6];
15848   u8 random_hw_addr = 1;
15849   int ret;
15850
15851   memset (hw_addr, 0, sizeof (hw_addr));
15852
15853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15854     {
15855       if (unformat (i, "name %s", &host_if_name))
15856         vec_add1 (host_if_name, 0);
15857       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15858         random_hw_addr = 0;
15859       else
15860         break;
15861     }
15862
15863   if (!vec_len (host_if_name))
15864     {
15865       errmsg ("host-interface name must be specified");
15866       return -99;
15867     }
15868
15869   if (vec_len (host_if_name) > 64)
15870     {
15871       errmsg ("host-interface name too long");
15872       return -99;
15873     }
15874
15875   M (AF_PACKET_CREATE, mp);
15876
15877   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15878   clib_memcpy (mp->hw_addr, hw_addr, 6);
15879   mp->use_random_hw_addr = random_hw_addr;
15880   vec_free (host_if_name);
15881
15882   S (mp);
15883
15884   /* *INDENT-OFF* */
15885   W2 (ret,
15886       ({
15887         if (ret == 0)
15888           fprintf (vam->ofp ? vam->ofp : stderr,
15889                    " new sw_if_index = %d\n", vam->sw_if_index);
15890       }));
15891   /* *INDENT-ON* */
15892   return ret;
15893 }
15894
15895 static int
15896 api_af_packet_delete (vat_main_t * vam)
15897 {
15898   unformat_input_t *i = vam->input;
15899   vl_api_af_packet_delete_t *mp;
15900   u8 *host_if_name = 0;
15901   int ret;
15902
15903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15904     {
15905       if (unformat (i, "name %s", &host_if_name))
15906         vec_add1 (host_if_name, 0);
15907       else
15908         break;
15909     }
15910
15911   if (!vec_len (host_if_name))
15912     {
15913       errmsg ("host-interface name must be specified");
15914       return -99;
15915     }
15916
15917   if (vec_len (host_if_name) > 64)
15918     {
15919       errmsg ("host-interface name too long");
15920       return -99;
15921     }
15922
15923   M (AF_PACKET_DELETE, mp);
15924
15925   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15926   vec_free (host_if_name);
15927
15928   S (mp);
15929   W (ret);
15930   return ret;
15931 }
15932
15933 static int
15934 api_policer_add_del (vat_main_t * vam)
15935 {
15936   unformat_input_t *i = vam->input;
15937   vl_api_policer_add_del_t *mp;
15938   u8 is_add = 1;
15939   u8 *name = 0;
15940   u32 cir = 0;
15941   u32 eir = 0;
15942   u64 cb = 0;
15943   u64 eb = 0;
15944   u8 rate_type = 0;
15945   u8 round_type = 0;
15946   u8 type = 0;
15947   u8 color_aware = 0;
15948   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15949   int ret;
15950
15951   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15952   conform_action.dscp = 0;
15953   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15954   exceed_action.dscp = 0;
15955   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15956   violate_action.dscp = 0;
15957
15958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15959     {
15960       if (unformat (i, "del"))
15961         is_add = 0;
15962       else if (unformat (i, "name %s", &name))
15963         vec_add1 (name, 0);
15964       else if (unformat (i, "cir %u", &cir))
15965         ;
15966       else if (unformat (i, "eir %u", &eir))
15967         ;
15968       else if (unformat (i, "cb %u", &cb))
15969         ;
15970       else if (unformat (i, "eb %u", &eb))
15971         ;
15972       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15973                          &rate_type))
15974         ;
15975       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15976                          &round_type))
15977         ;
15978       else if (unformat (i, "type %U", unformat_policer_type, &type))
15979         ;
15980       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15981                          &conform_action))
15982         ;
15983       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15984                          &exceed_action))
15985         ;
15986       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15987                          &violate_action))
15988         ;
15989       else if (unformat (i, "color-aware"))
15990         color_aware = 1;
15991       else
15992         break;
15993     }
15994
15995   if (!vec_len (name))
15996     {
15997       errmsg ("policer name must be specified");
15998       return -99;
15999     }
16000
16001   if (vec_len (name) > 64)
16002     {
16003       errmsg ("policer name too long");
16004       return -99;
16005     }
16006
16007   M (POLICER_ADD_DEL, mp);
16008
16009   clib_memcpy (mp->name, name, vec_len (name));
16010   vec_free (name);
16011   mp->is_add = is_add;
16012   mp->cir = cir;
16013   mp->eir = eir;
16014   mp->cb = cb;
16015   mp->eb = eb;
16016   mp->rate_type = rate_type;
16017   mp->round_type = round_type;
16018   mp->type = type;
16019   mp->conform_action_type = conform_action.action_type;
16020   mp->conform_dscp = conform_action.dscp;
16021   mp->exceed_action_type = exceed_action.action_type;
16022   mp->exceed_dscp = exceed_action.dscp;
16023   mp->violate_action_type = violate_action.action_type;
16024   mp->violate_dscp = violate_action.dscp;
16025   mp->color_aware = color_aware;
16026
16027   S (mp);
16028   W (ret);
16029   return ret;
16030 }
16031
16032 static int
16033 api_policer_dump (vat_main_t * vam)
16034 {
16035   unformat_input_t *i = vam->input;
16036   vl_api_policer_dump_t *mp;
16037   vl_api_control_ping_t *mp_ping;
16038   u8 *match_name = 0;
16039   u8 match_name_valid = 0;
16040   int ret;
16041
16042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16043     {
16044       if (unformat (i, "name %s", &match_name))
16045         {
16046           vec_add1 (match_name, 0);
16047           match_name_valid = 1;
16048         }
16049       else
16050         break;
16051     }
16052
16053   M (POLICER_DUMP, mp);
16054   mp->match_name_valid = match_name_valid;
16055   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16056   vec_free (match_name);
16057   /* send it... */
16058   S (mp);
16059
16060   /* Use a control ping for synchronization */
16061   M (CONTROL_PING, mp_ping);
16062   S (mp_ping);
16063
16064   /* Wait for a reply... */
16065   W (ret);
16066   return ret;
16067 }
16068
16069 static int
16070 api_policer_classify_set_interface (vat_main_t * vam)
16071 {
16072   unformat_input_t *i = vam->input;
16073   vl_api_policer_classify_set_interface_t *mp;
16074   u32 sw_if_index;
16075   int sw_if_index_set;
16076   u32 ip4_table_index = ~0;
16077   u32 ip6_table_index = ~0;
16078   u32 l2_table_index = ~0;
16079   u8 is_add = 1;
16080   int ret;
16081
16082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16083     {
16084       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16085         sw_if_index_set = 1;
16086       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16087         sw_if_index_set = 1;
16088       else if (unformat (i, "del"))
16089         is_add = 0;
16090       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16091         ;
16092       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16093         ;
16094       else if (unformat (i, "l2-table %d", &l2_table_index))
16095         ;
16096       else
16097         {
16098           clib_warning ("parse error '%U'", format_unformat_error, i);
16099           return -99;
16100         }
16101     }
16102
16103   if (sw_if_index_set == 0)
16104     {
16105       errmsg ("missing interface name or sw_if_index");
16106       return -99;
16107     }
16108
16109   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16110
16111   mp->sw_if_index = ntohl (sw_if_index);
16112   mp->ip4_table_index = ntohl (ip4_table_index);
16113   mp->ip6_table_index = ntohl (ip6_table_index);
16114   mp->l2_table_index = ntohl (l2_table_index);
16115   mp->is_add = is_add;
16116
16117   S (mp);
16118   W (ret);
16119   return ret;
16120 }
16121
16122 static int
16123 api_policer_classify_dump (vat_main_t * vam)
16124 {
16125   unformat_input_t *i = vam->input;
16126   vl_api_policer_classify_dump_t *mp;
16127   vl_api_control_ping_t *mp_ping;
16128   u8 type = POLICER_CLASSIFY_N_TABLES;
16129   int ret;
16130
16131   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16132     ;
16133   else
16134     {
16135       errmsg ("classify table type must be specified");
16136       return -99;
16137     }
16138
16139   if (!vam->json_output)
16140     {
16141       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16142     }
16143
16144   M (POLICER_CLASSIFY_DUMP, mp);
16145   mp->type = type;
16146   /* send it... */
16147   S (mp);
16148
16149   /* Use a control ping for synchronization */
16150   M (CONTROL_PING, mp_ping);
16151   S (mp_ping);
16152
16153   /* Wait for a reply... */
16154   W (ret);
16155   return ret;
16156 }
16157
16158 static int
16159 api_netmap_create (vat_main_t * vam)
16160 {
16161   unformat_input_t *i = vam->input;
16162   vl_api_netmap_create_t *mp;
16163   u8 *if_name = 0;
16164   u8 hw_addr[6];
16165   u8 random_hw_addr = 1;
16166   u8 is_pipe = 0;
16167   u8 is_master = 0;
16168   int ret;
16169
16170   memset (hw_addr, 0, sizeof (hw_addr));
16171
16172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16173     {
16174       if (unformat (i, "name %s", &if_name))
16175         vec_add1 (if_name, 0);
16176       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16177         random_hw_addr = 0;
16178       else if (unformat (i, "pipe"))
16179         is_pipe = 1;
16180       else if (unformat (i, "master"))
16181         is_master = 1;
16182       else if (unformat (i, "slave"))
16183         is_master = 0;
16184       else
16185         break;
16186     }
16187
16188   if (!vec_len (if_name))
16189     {
16190       errmsg ("interface name must be specified");
16191       return -99;
16192     }
16193
16194   if (vec_len (if_name) > 64)
16195     {
16196       errmsg ("interface name too long");
16197       return -99;
16198     }
16199
16200   M (NETMAP_CREATE, mp);
16201
16202   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16203   clib_memcpy (mp->hw_addr, hw_addr, 6);
16204   mp->use_random_hw_addr = random_hw_addr;
16205   mp->is_pipe = is_pipe;
16206   mp->is_master = is_master;
16207   vec_free (if_name);
16208
16209   S (mp);
16210   W (ret);
16211   return ret;
16212 }
16213
16214 static int
16215 api_netmap_delete (vat_main_t * vam)
16216 {
16217   unformat_input_t *i = vam->input;
16218   vl_api_netmap_delete_t *mp;
16219   u8 *if_name = 0;
16220   int ret;
16221
16222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16223     {
16224       if (unformat (i, "name %s", &if_name))
16225         vec_add1 (if_name, 0);
16226       else
16227         break;
16228     }
16229
16230   if (!vec_len (if_name))
16231     {
16232       errmsg ("interface name must be specified");
16233       return -99;
16234     }
16235
16236   if (vec_len (if_name) > 64)
16237     {
16238       errmsg ("interface name too long");
16239       return -99;
16240     }
16241
16242   M (NETMAP_DELETE, mp);
16243
16244   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16245   vec_free (if_name);
16246
16247   S (mp);
16248   W (ret);
16249   return ret;
16250 }
16251
16252 static void vl_api_mpls_tunnel_details_t_handler
16253   (vl_api_mpls_tunnel_details_t * mp)
16254 {
16255   vat_main_t *vam = &vat_main;
16256   i32 len = mp->mt_next_hop_n_labels;
16257   i32 i;
16258
16259   print (vam->ofp, "[%d]: via %U %d labels ",
16260          mp->tunnel_index,
16261          format_ip4_address, mp->mt_next_hop,
16262          ntohl (mp->mt_next_hop_sw_if_index));
16263   for (i = 0; i < len; i++)
16264     {
16265       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
16266     }
16267   print (vam->ofp, "");
16268 }
16269
16270 static void vl_api_mpls_tunnel_details_t_handler_json
16271   (vl_api_mpls_tunnel_details_t * mp)
16272 {
16273   vat_main_t *vam = &vat_main;
16274   vat_json_node_t *node = NULL;
16275   struct in_addr ip4;
16276   i32 i;
16277   i32 len = mp->mt_next_hop_n_labels;
16278
16279   if (VAT_JSON_ARRAY != vam->json_tree.type)
16280     {
16281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16282       vat_json_init_array (&vam->json_tree);
16283     }
16284   node = vat_json_array_add (&vam->json_tree);
16285
16286   vat_json_init_object (node);
16287   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
16288   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
16289   vat_json_object_add_ip4 (node, "next_hop", ip4);
16290   vat_json_object_add_uint (node, "next_hop_sw_if_index",
16291                             ntohl (mp->mt_next_hop_sw_if_index));
16292   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
16293   vat_json_object_add_uint (node, "label_count", len);
16294   for (i = 0; i < len; i++)
16295     {
16296       vat_json_object_add_uint (node, "label",
16297                                 ntohl (mp->mt_next_hop_out_labels[i]));
16298     }
16299 }
16300
16301 static int
16302 api_mpls_tunnel_dump (vat_main_t * vam)
16303 {
16304   vl_api_mpls_tunnel_dump_t *mp;
16305   vl_api_control_ping_t *mp_ping;
16306   i32 index = -1;
16307   int ret;
16308
16309   /* Parse args required to build the message */
16310   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16311     {
16312       if (!unformat (vam->input, "tunnel_index %d", &index))
16313         {
16314           index = -1;
16315           break;
16316         }
16317     }
16318
16319   print (vam->ofp, "  tunnel_index %d", index);
16320
16321   M (MPLS_TUNNEL_DUMP, mp);
16322   mp->tunnel_index = htonl (index);
16323   S (mp);
16324
16325   /* Use a control ping for synchronization */
16326   M (CONTROL_PING, mp_ping);
16327   S (mp_ping);
16328
16329   W (ret);
16330   return ret;
16331 }
16332
16333 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16334 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16335
16336 static void
16337 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16338 {
16339   vat_main_t *vam = &vat_main;
16340   int count = ntohl (mp->count);
16341   vl_api_fib_path2_t *fp;
16342   int i;
16343
16344   print (vam->ofp,
16345          "table-id %d, label %u, ess_bit %u",
16346          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16347   fp = mp->path;
16348   for (i = 0; i < count; i++)
16349     {
16350       if (fp->afi == IP46_TYPE_IP6)
16351         print (vam->ofp,
16352                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16353                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16354                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16355                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16356                format_ip6_address, fp->next_hop);
16357       else if (fp->afi == IP46_TYPE_IP4)
16358         print (vam->ofp,
16359                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16360                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16361                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16362                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16363                format_ip4_address, fp->next_hop);
16364       fp++;
16365     }
16366 }
16367
16368 static void vl_api_mpls_fib_details_t_handler_json
16369   (vl_api_mpls_fib_details_t * mp)
16370 {
16371   vat_main_t *vam = &vat_main;
16372   int count = ntohl (mp->count);
16373   vat_json_node_t *node = NULL;
16374   struct in_addr ip4;
16375   struct in6_addr ip6;
16376   vl_api_fib_path2_t *fp;
16377   int i;
16378
16379   if (VAT_JSON_ARRAY != vam->json_tree.type)
16380     {
16381       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16382       vat_json_init_array (&vam->json_tree);
16383     }
16384   node = vat_json_array_add (&vam->json_tree);
16385
16386   vat_json_init_object (node);
16387   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16388   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16389   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16390   vat_json_object_add_uint (node, "path_count", count);
16391   fp = mp->path;
16392   for (i = 0; i < count; i++)
16393     {
16394       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16395       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16396       vat_json_object_add_uint (node, "is_local", fp->is_local);
16397       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16398       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16399       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16400       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16401       if (fp->afi == IP46_TYPE_IP4)
16402         {
16403           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16404           vat_json_object_add_ip4 (node, "next_hop", ip4);
16405         }
16406       else if (fp->afi == IP46_TYPE_IP6)
16407         {
16408           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16409           vat_json_object_add_ip6 (node, "next_hop", ip6);
16410         }
16411     }
16412 }
16413
16414 static int
16415 api_mpls_fib_dump (vat_main_t * vam)
16416 {
16417   vl_api_mpls_fib_dump_t *mp;
16418   vl_api_control_ping_t *mp_ping;
16419   int ret;
16420
16421   M (MPLS_FIB_DUMP, mp);
16422   S (mp);
16423
16424   /* Use a control ping for synchronization */
16425   M (CONTROL_PING, mp_ping);
16426   S (mp_ping);
16427
16428   W (ret);
16429   return ret;
16430 }
16431
16432 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16433 #define vl_api_ip_fib_details_t_print vl_noop_handler
16434
16435 static void
16436 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16437 {
16438   vat_main_t *vam = &vat_main;
16439   int count = ntohl (mp->count);
16440   vl_api_fib_path_t *fp;
16441   int i;
16442
16443   print (vam->ofp,
16444          "table-id %d, prefix %U/%d",
16445          ntohl (mp->table_id), format_ip4_address, mp->address,
16446          mp->address_length);
16447   fp = mp->path;
16448   for (i = 0; i < count; i++)
16449     {
16450       if (fp->afi == IP46_TYPE_IP6)
16451         print (vam->ofp,
16452                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16453                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16454                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16455                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16456                format_ip6_address, fp->next_hop);
16457       else if (fp->afi == IP46_TYPE_IP4)
16458         print (vam->ofp,
16459                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16460                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16461                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16462                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16463                format_ip4_address, fp->next_hop);
16464       fp++;
16465     }
16466 }
16467
16468 static void vl_api_ip_fib_details_t_handler_json
16469   (vl_api_ip_fib_details_t * mp)
16470 {
16471   vat_main_t *vam = &vat_main;
16472   int count = ntohl (mp->count);
16473   vat_json_node_t *node = NULL;
16474   struct in_addr ip4;
16475   struct in6_addr ip6;
16476   vl_api_fib_path_t *fp;
16477   int i;
16478
16479   if (VAT_JSON_ARRAY != vam->json_tree.type)
16480     {
16481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16482       vat_json_init_array (&vam->json_tree);
16483     }
16484   node = vat_json_array_add (&vam->json_tree);
16485
16486   vat_json_init_object (node);
16487   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16488   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16489   vat_json_object_add_ip4 (node, "prefix", ip4);
16490   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16491   vat_json_object_add_uint (node, "path_count", count);
16492   fp = mp->path;
16493   for (i = 0; i < count; i++)
16494     {
16495       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16496       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16497       vat_json_object_add_uint (node, "is_local", fp->is_local);
16498       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16499       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16500       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16501       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16502       if (fp->afi == IP46_TYPE_IP4)
16503         {
16504           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16505           vat_json_object_add_ip4 (node, "next_hop", ip4);
16506         }
16507       else if (fp->afi == IP46_TYPE_IP6)
16508         {
16509           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16510           vat_json_object_add_ip6 (node, "next_hop", ip6);
16511         }
16512     }
16513 }
16514
16515 static int
16516 api_ip_fib_dump (vat_main_t * vam)
16517 {
16518   vl_api_ip_fib_dump_t *mp;
16519   vl_api_control_ping_t *mp_ping;
16520   int ret;
16521
16522   M (IP_FIB_DUMP, mp);
16523   S (mp);
16524
16525   /* Use a control ping for synchronization */
16526   M (CONTROL_PING, mp_ping);
16527   S (mp_ping);
16528
16529   W (ret);
16530   return ret;
16531 }
16532
16533 static int
16534 api_ip_mfib_dump (vat_main_t * vam)
16535 {
16536   vl_api_ip_mfib_dump_t *mp;
16537   vl_api_control_ping_t *mp_ping;
16538   int ret;
16539
16540   M (IP_MFIB_DUMP, mp);
16541   S (mp);
16542
16543   /* Use a control ping for synchronization */
16544   M (CONTROL_PING, mp_ping);
16545   S (mp_ping);
16546
16547   W (ret);
16548   return ret;
16549 }
16550
16551 static void vl_api_ip_neighbor_details_t_handler
16552   (vl_api_ip_neighbor_details_t * mp)
16553 {
16554   vat_main_t *vam = &vat_main;
16555
16556   print (vam->ofp, "%c %U %U",
16557          (mp->is_static) ? 'S' : 'D',
16558          format_ethernet_address, &mp->mac_address,
16559          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16560          &mp->ip_address);
16561 }
16562
16563 static void vl_api_ip_neighbor_details_t_handler_json
16564   (vl_api_ip_neighbor_details_t * mp)
16565 {
16566
16567   vat_main_t *vam = &vat_main;
16568   vat_json_node_t *node;
16569   struct in_addr ip4;
16570   struct in6_addr ip6;
16571
16572   if (VAT_JSON_ARRAY != vam->json_tree.type)
16573     {
16574       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16575       vat_json_init_array (&vam->json_tree);
16576     }
16577   node = vat_json_array_add (&vam->json_tree);
16578
16579   vat_json_init_object (node);
16580   vat_json_object_add_string_copy (node, "flag",
16581                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16582                                    "dynamic");
16583
16584   vat_json_object_add_string_copy (node, "link_layer",
16585                                    format (0, "%U", format_ethernet_address,
16586                                            &mp->mac_address));
16587
16588   if (mp->is_ipv6)
16589     {
16590       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16591       vat_json_object_add_ip6 (node, "ip_address", ip6);
16592     }
16593   else
16594     {
16595       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16596       vat_json_object_add_ip4 (node, "ip_address", ip4);
16597     }
16598 }
16599
16600 static int
16601 api_ip_neighbor_dump (vat_main_t * vam)
16602 {
16603   unformat_input_t *i = vam->input;
16604   vl_api_ip_neighbor_dump_t *mp;
16605   vl_api_control_ping_t *mp_ping;
16606   u8 is_ipv6 = 0;
16607   u32 sw_if_index = ~0;
16608   int ret;
16609
16610   /* Parse args required to build the message */
16611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16612     {
16613       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16614         ;
16615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16616         ;
16617       else if (unformat (i, "ip6"))
16618         is_ipv6 = 1;
16619       else
16620         break;
16621     }
16622
16623   if (sw_if_index == ~0)
16624     {
16625       errmsg ("missing interface name or sw_if_index");
16626       return -99;
16627     }
16628
16629   M (IP_NEIGHBOR_DUMP, mp);
16630   mp->is_ipv6 = (u8) is_ipv6;
16631   mp->sw_if_index = ntohl (sw_if_index);
16632   S (mp);
16633
16634   /* Use a control ping for synchronization */
16635   M (CONTROL_PING, mp_ping);
16636   S (mp_ping);
16637
16638   W (ret);
16639   return ret;
16640 }
16641
16642 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16643 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16644
16645 static void
16646 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16647 {
16648   vat_main_t *vam = &vat_main;
16649   int count = ntohl (mp->count);
16650   vl_api_fib_path_t *fp;
16651   int i;
16652
16653   print (vam->ofp,
16654          "table-id %d, prefix %U/%d",
16655          ntohl (mp->table_id), format_ip6_address, mp->address,
16656          mp->address_length);
16657   fp = mp->path;
16658   for (i = 0; i < count; i++)
16659     {
16660       if (fp->afi == IP46_TYPE_IP6)
16661         print (vam->ofp,
16662                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16663                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16664                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16665                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16666                format_ip6_address, fp->next_hop);
16667       else if (fp->afi == IP46_TYPE_IP4)
16668         print (vam->ofp,
16669                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16670                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16671                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16672                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16673                format_ip4_address, fp->next_hop);
16674       fp++;
16675     }
16676 }
16677
16678 static void vl_api_ip6_fib_details_t_handler_json
16679   (vl_api_ip6_fib_details_t * mp)
16680 {
16681   vat_main_t *vam = &vat_main;
16682   int count = ntohl (mp->count);
16683   vat_json_node_t *node = NULL;
16684   struct in_addr ip4;
16685   struct in6_addr ip6;
16686   vl_api_fib_path_t *fp;
16687   int i;
16688
16689   if (VAT_JSON_ARRAY != vam->json_tree.type)
16690     {
16691       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16692       vat_json_init_array (&vam->json_tree);
16693     }
16694   node = vat_json_array_add (&vam->json_tree);
16695
16696   vat_json_init_object (node);
16697   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16698   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16699   vat_json_object_add_ip6 (node, "prefix", ip6);
16700   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16701   vat_json_object_add_uint (node, "path_count", count);
16702   fp = mp->path;
16703   for (i = 0; i < count; i++)
16704     {
16705       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16706       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16707       vat_json_object_add_uint (node, "is_local", fp->is_local);
16708       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16709       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16710       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16711       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16712       if (fp->afi == IP46_TYPE_IP4)
16713         {
16714           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16715           vat_json_object_add_ip4 (node, "next_hop", ip4);
16716         }
16717       else if (fp->afi == IP46_TYPE_IP6)
16718         {
16719           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16720           vat_json_object_add_ip6 (node, "next_hop", ip6);
16721         }
16722     }
16723 }
16724
16725 static int
16726 api_ip6_fib_dump (vat_main_t * vam)
16727 {
16728   vl_api_ip6_fib_dump_t *mp;
16729   vl_api_control_ping_t *mp_ping;
16730   int ret;
16731
16732   M (IP6_FIB_DUMP, mp);
16733   S (mp);
16734
16735   /* Use a control ping for synchronization */
16736   M (CONTROL_PING, mp_ping);
16737   S (mp_ping);
16738
16739   W (ret);
16740   return ret;
16741 }
16742
16743 static int
16744 api_ip6_mfib_dump (vat_main_t * vam)
16745 {
16746   vl_api_ip6_mfib_dump_t *mp;
16747   vl_api_control_ping_t *mp_ping;
16748   int ret;
16749
16750   M (IP6_MFIB_DUMP, mp);
16751   S (mp);
16752
16753   /* Use a control ping for synchronization */
16754   M (CONTROL_PING, mp_ping);
16755   S (mp_ping);
16756
16757   W (ret);
16758   return ret;
16759 }
16760
16761 int
16762 api_classify_table_ids (vat_main_t * vam)
16763 {
16764   vl_api_classify_table_ids_t *mp;
16765   int ret;
16766
16767   /* Construct the API message */
16768   M (CLASSIFY_TABLE_IDS, mp);
16769   mp->context = 0;
16770
16771   S (mp);
16772   W (ret);
16773   return ret;
16774 }
16775
16776 int
16777 api_classify_table_by_interface (vat_main_t * vam)
16778 {
16779   unformat_input_t *input = vam->input;
16780   vl_api_classify_table_by_interface_t *mp;
16781
16782   u32 sw_if_index = ~0;
16783   int ret;
16784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16785     {
16786       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16787         ;
16788       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16789         ;
16790       else
16791         break;
16792     }
16793   if (sw_if_index == ~0)
16794     {
16795       errmsg ("missing interface name or sw_if_index");
16796       return -99;
16797     }
16798
16799   /* Construct the API message */
16800   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16801   mp->context = 0;
16802   mp->sw_if_index = ntohl (sw_if_index);
16803
16804   S (mp);
16805   W (ret);
16806   return ret;
16807 }
16808
16809 int
16810 api_classify_table_info (vat_main_t * vam)
16811 {
16812   unformat_input_t *input = vam->input;
16813   vl_api_classify_table_info_t *mp;
16814
16815   u32 table_id = ~0;
16816   int ret;
16817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16818     {
16819       if (unformat (input, "table_id %d", &table_id))
16820         ;
16821       else
16822         break;
16823     }
16824   if (table_id == ~0)
16825     {
16826       errmsg ("missing table id");
16827       return -99;
16828     }
16829
16830   /* Construct the API message */
16831   M (CLASSIFY_TABLE_INFO, mp);
16832   mp->context = 0;
16833   mp->table_id = ntohl (table_id);
16834
16835   S (mp);
16836   W (ret);
16837   return ret;
16838 }
16839
16840 int
16841 api_classify_session_dump (vat_main_t * vam)
16842 {
16843   unformat_input_t *input = vam->input;
16844   vl_api_classify_session_dump_t *mp;
16845   vl_api_control_ping_t *mp_ping;
16846
16847   u32 table_id = ~0;
16848   int ret;
16849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16850     {
16851       if (unformat (input, "table_id %d", &table_id))
16852         ;
16853       else
16854         break;
16855     }
16856   if (table_id == ~0)
16857     {
16858       errmsg ("missing table id");
16859       return -99;
16860     }
16861
16862   /* Construct the API message */
16863   M (CLASSIFY_SESSION_DUMP, mp);
16864   mp->context = 0;
16865   mp->table_id = ntohl (table_id);
16866   S (mp);
16867
16868   /* Use a control ping for synchronization */
16869   M (CONTROL_PING, mp_ping);
16870   S (mp_ping);
16871
16872   W (ret);
16873   return ret;
16874 }
16875
16876 static void
16877 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16878 {
16879   vat_main_t *vam = &vat_main;
16880
16881   print (vam->ofp, "collector_address %U, collector_port %d, "
16882          "src_address %U, vrf_id %d, path_mtu %u, "
16883          "template_interval %u, udp_checksum %d",
16884          format_ip4_address, mp->collector_address,
16885          ntohs (mp->collector_port),
16886          format_ip4_address, mp->src_address,
16887          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16888          ntohl (mp->template_interval), mp->udp_checksum);
16889
16890   vam->retval = 0;
16891   vam->result_ready = 1;
16892 }
16893
16894 static void
16895   vl_api_ipfix_exporter_details_t_handler_json
16896   (vl_api_ipfix_exporter_details_t * mp)
16897 {
16898   vat_main_t *vam = &vat_main;
16899   vat_json_node_t node;
16900   struct in_addr collector_address;
16901   struct in_addr src_address;
16902
16903   vat_json_init_object (&node);
16904   clib_memcpy (&collector_address, &mp->collector_address,
16905                sizeof (collector_address));
16906   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16907   vat_json_object_add_uint (&node, "collector_port",
16908                             ntohs (mp->collector_port));
16909   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16910   vat_json_object_add_ip4 (&node, "src_address", src_address);
16911   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16912   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16913   vat_json_object_add_uint (&node, "template_interval",
16914                             ntohl (mp->template_interval));
16915   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16916
16917   vat_json_print (vam->ofp, &node);
16918   vat_json_free (&node);
16919   vam->retval = 0;
16920   vam->result_ready = 1;
16921 }
16922
16923 int
16924 api_ipfix_exporter_dump (vat_main_t * vam)
16925 {
16926   vl_api_ipfix_exporter_dump_t *mp;
16927   int ret;
16928
16929   /* Construct the API message */
16930   M (IPFIX_EXPORTER_DUMP, mp);
16931   mp->context = 0;
16932
16933   S (mp);
16934   W (ret);
16935   return ret;
16936 }
16937
16938 static int
16939 api_ipfix_classify_stream_dump (vat_main_t * vam)
16940 {
16941   vl_api_ipfix_classify_stream_dump_t *mp;
16942   int ret;
16943
16944   /* Construct the API message */
16945   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16946   mp->context = 0;
16947
16948   S (mp);
16949   W (ret);
16950   return ret;
16951   /* NOTREACHED */
16952   return 0;
16953 }
16954
16955 static void
16956   vl_api_ipfix_classify_stream_details_t_handler
16957   (vl_api_ipfix_classify_stream_details_t * mp)
16958 {
16959   vat_main_t *vam = &vat_main;
16960   print (vam->ofp, "domain_id %d, src_port %d",
16961          ntohl (mp->domain_id), ntohs (mp->src_port));
16962   vam->retval = 0;
16963   vam->result_ready = 1;
16964 }
16965
16966 static void
16967   vl_api_ipfix_classify_stream_details_t_handler_json
16968   (vl_api_ipfix_classify_stream_details_t * mp)
16969 {
16970   vat_main_t *vam = &vat_main;
16971   vat_json_node_t node;
16972
16973   vat_json_init_object (&node);
16974   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16975   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16976
16977   vat_json_print (vam->ofp, &node);
16978   vat_json_free (&node);
16979   vam->retval = 0;
16980   vam->result_ready = 1;
16981 }
16982
16983 static int
16984 api_ipfix_classify_table_dump (vat_main_t * vam)
16985 {
16986   vl_api_ipfix_classify_table_dump_t *mp;
16987   vl_api_control_ping_t *mp_ping;
16988   int ret;
16989
16990   if (!vam->json_output)
16991     {
16992       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16993              "transport_protocol");
16994     }
16995
16996   /* Construct the API message */
16997   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16998
16999   /* send it... */
17000   S (mp);
17001
17002   /* Use a control ping for synchronization */
17003   M (CONTROL_PING, mp_ping);
17004   S (mp_ping);
17005
17006   W (ret);
17007   return ret;
17008 }
17009
17010 static void
17011   vl_api_ipfix_classify_table_details_t_handler
17012   (vl_api_ipfix_classify_table_details_t * mp)
17013 {
17014   vat_main_t *vam = &vat_main;
17015   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17016          mp->transport_protocol);
17017 }
17018
17019 static void
17020   vl_api_ipfix_classify_table_details_t_handler_json
17021   (vl_api_ipfix_classify_table_details_t * mp)
17022 {
17023   vat_json_node_t *node = NULL;
17024   vat_main_t *vam = &vat_main;
17025
17026   if (VAT_JSON_ARRAY != vam->json_tree.type)
17027     {
17028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17029       vat_json_init_array (&vam->json_tree);
17030     }
17031
17032   node = vat_json_array_add (&vam->json_tree);
17033   vat_json_init_object (node);
17034
17035   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17036   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17037   vat_json_object_add_uint (node, "transport_protocol",
17038                             mp->transport_protocol);
17039 }
17040
17041 static int
17042 api_sw_interface_span_enable_disable (vat_main_t * vam)
17043 {
17044   unformat_input_t *i = vam->input;
17045   vl_api_sw_interface_span_enable_disable_t *mp;
17046   u32 src_sw_if_index = ~0;
17047   u32 dst_sw_if_index = ~0;
17048   u8 state = 3;
17049   int ret;
17050
17051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17052     {
17053       if (unformat
17054           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17055         ;
17056       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17057         ;
17058       else
17059         if (unformat
17060             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17061         ;
17062       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17063         ;
17064       else if (unformat (i, "disable"))
17065         state = 0;
17066       else if (unformat (i, "rx"))
17067         state = 1;
17068       else if (unformat (i, "tx"))
17069         state = 2;
17070       else if (unformat (i, "both"))
17071         state = 3;
17072       else
17073         break;
17074     }
17075
17076   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17077
17078   mp->sw_if_index_from = htonl (src_sw_if_index);
17079   mp->sw_if_index_to = htonl (dst_sw_if_index);
17080   mp->state = state;
17081
17082   S (mp);
17083   W (ret);
17084   return ret;
17085 }
17086
17087 static void
17088 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17089                                             * mp)
17090 {
17091   vat_main_t *vam = &vat_main;
17092   u8 *sw_if_from_name = 0;
17093   u8 *sw_if_to_name = 0;
17094   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17095   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17096   char *states[] = { "none", "rx", "tx", "both" };
17097   hash_pair_t *p;
17098
17099   /* *INDENT-OFF* */
17100   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17101   ({
17102     if ((u32) p->value[0] == sw_if_index_from)
17103       {
17104         sw_if_from_name = (u8 *)(p->key);
17105         if (sw_if_to_name)
17106           break;
17107       }
17108     if ((u32) p->value[0] == sw_if_index_to)
17109       {
17110         sw_if_to_name = (u8 *)(p->key);
17111         if (sw_if_from_name)
17112           break;
17113       }
17114   }));
17115   /* *INDENT-ON* */
17116   print (vam->ofp, "%20s => %20s (%s)",
17117          sw_if_from_name, sw_if_to_name, states[mp->state]);
17118 }
17119
17120 static void
17121   vl_api_sw_interface_span_details_t_handler_json
17122   (vl_api_sw_interface_span_details_t * mp)
17123 {
17124   vat_main_t *vam = &vat_main;
17125   vat_json_node_t *node = NULL;
17126   u8 *sw_if_from_name = 0;
17127   u8 *sw_if_to_name = 0;
17128   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17129   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17130   hash_pair_t *p;
17131
17132   /* *INDENT-OFF* */
17133   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17134   ({
17135     if ((u32) p->value[0] == sw_if_index_from)
17136       {
17137         sw_if_from_name = (u8 *)(p->key);
17138         if (sw_if_to_name)
17139           break;
17140       }
17141     if ((u32) p->value[0] == sw_if_index_to)
17142       {
17143         sw_if_to_name = (u8 *)(p->key);
17144         if (sw_if_from_name)
17145           break;
17146       }
17147   }));
17148   /* *INDENT-ON* */
17149
17150   if (VAT_JSON_ARRAY != vam->json_tree.type)
17151     {
17152       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17153       vat_json_init_array (&vam->json_tree);
17154     }
17155   node = vat_json_array_add (&vam->json_tree);
17156
17157   vat_json_init_object (node);
17158   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17159   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17160   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17161   if (0 != sw_if_to_name)
17162     {
17163       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17164     }
17165   vat_json_object_add_uint (node, "state", mp->state);
17166 }
17167
17168 static int
17169 api_sw_interface_span_dump (vat_main_t * vam)
17170 {
17171   vl_api_sw_interface_span_dump_t *mp;
17172   vl_api_control_ping_t *mp_ping;
17173   int ret;
17174
17175   M (SW_INTERFACE_SPAN_DUMP, mp);
17176   S (mp);
17177
17178   /* Use a control ping for synchronization */
17179   M (CONTROL_PING, mp_ping);
17180   S (mp_ping);
17181
17182   W (ret);
17183   return ret;
17184 }
17185
17186 int
17187 api_pg_create_interface (vat_main_t * vam)
17188 {
17189   unformat_input_t *input = vam->input;
17190   vl_api_pg_create_interface_t *mp;
17191
17192   u32 if_id = ~0;
17193   int ret;
17194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17195     {
17196       if (unformat (input, "if_id %d", &if_id))
17197         ;
17198       else
17199         break;
17200     }
17201   if (if_id == ~0)
17202     {
17203       errmsg ("missing pg interface index");
17204       return -99;
17205     }
17206
17207   /* Construct the API message */
17208   M (PG_CREATE_INTERFACE, mp);
17209   mp->context = 0;
17210   mp->interface_id = ntohl (if_id);
17211
17212   S (mp);
17213   W (ret);
17214   return ret;
17215 }
17216
17217 int
17218 api_pg_capture (vat_main_t * vam)
17219 {
17220   unformat_input_t *input = vam->input;
17221   vl_api_pg_capture_t *mp;
17222
17223   u32 if_id = ~0;
17224   u8 enable = 1;
17225   u32 count = 1;
17226   u8 pcap_file_set = 0;
17227   u8 *pcap_file = 0;
17228   int ret;
17229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17230     {
17231       if (unformat (input, "if_id %d", &if_id))
17232         ;
17233       else if (unformat (input, "pcap %s", &pcap_file))
17234         pcap_file_set = 1;
17235       else if (unformat (input, "count %d", &count))
17236         ;
17237       else if (unformat (input, "disable"))
17238         enable = 0;
17239       else
17240         break;
17241     }
17242   if (if_id == ~0)
17243     {
17244       errmsg ("missing pg interface index");
17245       return -99;
17246     }
17247   if (pcap_file_set > 0)
17248     {
17249       if (vec_len (pcap_file) > 255)
17250         {
17251           errmsg ("pcap file name is too long");
17252           return -99;
17253         }
17254     }
17255
17256   u32 name_len = vec_len (pcap_file);
17257   /* Construct the API message */
17258   M (PG_CAPTURE, mp);
17259   mp->context = 0;
17260   mp->interface_id = ntohl (if_id);
17261   mp->is_enabled = enable;
17262   mp->count = ntohl (count);
17263   mp->pcap_name_length = ntohl (name_len);
17264   if (pcap_file_set != 0)
17265     {
17266       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17267     }
17268   vec_free (pcap_file);
17269
17270   S (mp);
17271   W (ret);
17272   return ret;
17273 }
17274
17275 int
17276 api_pg_enable_disable (vat_main_t * vam)
17277 {
17278   unformat_input_t *input = vam->input;
17279   vl_api_pg_enable_disable_t *mp;
17280
17281   u8 enable = 1;
17282   u8 stream_name_set = 0;
17283   u8 *stream_name = 0;
17284   int ret;
17285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17286     {
17287       if (unformat (input, "stream %s", &stream_name))
17288         stream_name_set = 1;
17289       else if (unformat (input, "disable"))
17290         enable = 0;
17291       else
17292         break;
17293     }
17294
17295   if (stream_name_set > 0)
17296     {
17297       if (vec_len (stream_name) > 255)
17298         {
17299           errmsg ("stream name too long");
17300           return -99;
17301         }
17302     }
17303
17304   u32 name_len = vec_len (stream_name);
17305   /* Construct the API message */
17306   M (PG_ENABLE_DISABLE, mp);
17307   mp->context = 0;
17308   mp->is_enabled = enable;
17309   if (stream_name_set != 0)
17310     {
17311       mp->stream_name_length = ntohl (name_len);
17312       clib_memcpy (mp->stream_name, stream_name, name_len);
17313     }
17314   vec_free (stream_name);
17315
17316   S (mp);
17317   W (ret);
17318   return ret;
17319 }
17320
17321 int
17322 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17323 {
17324   unformat_input_t *input = vam->input;
17325   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17326
17327   u16 *low_ports = 0;
17328   u16 *high_ports = 0;
17329   u16 this_low;
17330   u16 this_hi;
17331   ip4_address_t ip4_addr;
17332   ip6_address_t ip6_addr;
17333   u32 length;
17334   u32 tmp, tmp2;
17335   u8 prefix_set = 0;
17336   u32 vrf_id = ~0;
17337   u8 is_add = 1;
17338   u8 is_ipv6 = 0;
17339   int ret;
17340
17341   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17342     {
17343       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17344         {
17345           prefix_set = 1;
17346         }
17347       else
17348         if (unformat
17349             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17350         {
17351           prefix_set = 1;
17352           is_ipv6 = 1;
17353         }
17354       else if (unformat (input, "vrf %d", &vrf_id))
17355         ;
17356       else if (unformat (input, "del"))
17357         is_add = 0;
17358       else if (unformat (input, "port %d", &tmp))
17359         {
17360           if (tmp == 0 || tmp > 65535)
17361             {
17362               errmsg ("port %d out of range", tmp);
17363               return -99;
17364             }
17365           this_low = tmp;
17366           this_hi = this_low + 1;
17367           vec_add1 (low_ports, this_low);
17368           vec_add1 (high_ports, this_hi);
17369         }
17370       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17371         {
17372           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17373             {
17374               errmsg ("incorrect range parameters");
17375               return -99;
17376             }
17377           this_low = tmp;
17378           /* Note: in debug CLI +1 is added to high before
17379              passing to real fn that does "the work"
17380              (ip_source_and_port_range_check_add_del).
17381              This fn is a wrapper around the binary API fn a
17382              control plane will call, which expects this increment
17383              to have occurred. Hence letting the binary API control
17384              plane fn do the increment for consistency between VAT
17385              and other control planes.
17386            */
17387           this_hi = tmp2;
17388           vec_add1 (low_ports, this_low);
17389           vec_add1 (high_ports, this_hi);
17390         }
17391       else
17392         break;
17393     }
17394
17395   if (prefix_set == 0)
17396     {
17397       errmsg ("<address>/<mask> not specified");
17398       return -99;
17399     }
17400
17401   if (vrf_id == ~0)
17402     {
17403       errmsg ("VRF ID required, not specified");
17404       return -99;
17405     }
17406
17407   if (vrf_id == 0)
17408     {
17409       errmsg
17410         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17411       return -99;
17412     }
17413
17414   if (vec_len (low_ports) == 0)
17415     {
17416       errmsg ("At least one port or port range required");
17417       return -99;
17418     }
17419
17420   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17421
17422   mp->is_add = is_add;
17423
17424   if (is_ipv6)
17425     {
17426       mp->is_ipv6 = 1;
17427       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17428     }
17429   else
17430     {
17431       mp->is_ipv6 = 0;
17432       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17433     }
17434
17435   mp->mask_length = length;
17436   mp->number_of_ranges = vec_len (low_ports);
17437
17438   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17439   vec_free (low_ports);
17440
17441   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17442   vec_free (high_ports);
17443
17444   mp->vrf_id = ntohl (vrf_id);
17445
17446   S (mp);
17447   W (ret);
17448   return ret;
17449 }
17450
17451 int
17452 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17453 {
17454   unformat_input_t *input = vam->input;
17455   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17456   u32 sw_if_index = ~0;
17457   int vrf_set = 0;
17458   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17459   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17460   u8 is_add = 1;
17461   int ret;
17462
17463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17464     {
17465       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17466         ;
17467       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17468         ;
17469       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17470         vrf_set = 1;
17471       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17472         vrf_set = 1;
17473       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17474         vrf_set = 1;
17475       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17476         vrf_set = 1;
17477       else if (unformat (input, "del"))
17478         is_add = 0;
17479       else
17480         break;
17481     }
17482
17483   if (sw_if_index == ~0)
17484     {
17485       errmsg ("Interface required but not specified");
17486       return -99;
17487     }
17488
17489   if (vrf_set == 0)
17490     {
17491       errmsg ("VRF ID required but not specified");
17492       return -99;
17493     }
17494
17495   if (tcp_out_vrf_id == 0
17496       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17497     {
17498       errmsg
17499         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17500       return -99;
17501     }
17502
17503   /* Construct the API message */
17504   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17505
17506   mp->sw_if_index = ntohl (sw_if_index);
17507   mp->is_add = is_add;
17508   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17509   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17510   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17511   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17512
17513   /* send it... */
17514   S (mp);
17515
17516   /* Wait for a reply... */
17517   W (ret);
17518   return ret;
17519 }
17520
17521 static int
17522 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17523 {
17524   unformat_input_t *i = vam->input;
17525   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17526   u32 local_sa_id = 0;
17527   u32 remote_sa_id = 0;
17528   ip4_address_t src_address;
17529   ip4_address_t dst_address;
17530   u8 is_add = 1;
17531   int ret;
17532
17533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17534     {
17535       if (unformat (i, "local_sa %d", &local_sa_id))
17536         ;
17537       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17538         ;
17539       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17540         ;
17541       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17542         ;
17543       else if (unformat (i, "del"))
17544         is_add = 0;
17545       else
17546         {
17547           clib_warning ("parse error '%U'", format_unformat_error, i);
17548           return -99;
17549         }
17550     }
17551
17552   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17553
17554   mp->local_sa_id = ntohl (local_sa_id);
17555   mp->remote_sa_id = ntohl (remote_sa_id);
17556   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17557   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17558   mp->is_add = is_add;
17559
17560   S (mp);
17561   W (ret);
17562   return ret;
17563 }
17564
17565 static int
17566 api_punt (vat_main_t * vam)
17567 {
17568   unformat_input_t *i = vam->input;
17569   vl_api_punt_t *mp;
17570   u32 ipv = ~0;
17571   u32 protocol = ~0;
17572   u32 port = ~0;
17573   int is_add = 1;
17574   int ret;
17575
17576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17577     {
17578       if (unformat (i, "ip %d", &ipv))
17579         ;
17580       else if (unformat (i, "protocol %d", &protocol))
17581         ;
17582       else if (unformat (i, "port %d", &port))
17583         ;
17584       else if (unformat (i, "del"))
17585         is_add = 0;
17586       else
17587         {
17588           clib_warning ("parse error '%U'", format_unformat_error, i);
17589           return -99;
17590         }
17591     }
17592
17593   M (PUNT, mp);
17594
17595   mp->is_add = (u8) is_add;
17596   mp->ipv = (u8) ipv;
17597   mp->l4_protocol = (u8) protocol;
17598   mp->l4_port = htons ((u16) port);
17599
17600   S (mp);
17601   W (ret);
17602   return ret;
17603 }
17604
17605 static void vl_api_ipsec_gre_tunnel_details_t_handler
17606   (vl_api_ipsec_gre_tunnel_details_t * mp)
17607 {
17608   vat_main_t *vam = &vat_main;
17609
17610   print (vam->ofp, "%11d%15U%15U%14d%14d",
17611          ntohl (mp->sw_if_index),
17612          format_ip4_address, &mp->src_address,
17613          format_ip4_address, &mp->dst_address,
17614          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17615 }
17616
17617 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17618   (vl_api_ipsec_gre_tunnel_details_t * mp)
17619 {
17620   vat_main_t *vam = &vat_main;
17621   vat_json_node_t *node = NULL;
17622   struct in_addr ip4;
17623
17624   if (VAT_JSON_ARRAY != vam->json_tree.type)
17625     {
17626       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17627       vat_json_init_array (&vam->json_tree);
17628     }
17629   node = vat_json_array_add (&vam->json_tree);
17630
17631   vat_json_init_object (node);
17632   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17633   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17634   vat_json_object_add_ip4 (node, "src_address", ip4);
17635   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17636   vat_json_object_add_ip4 (node, "dst_address", ip4);
17637   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17638   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17639 }
17640
17641 static int
17642 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17643 {
17644   unformat_input_t *i = vam->input;
17645   vl_api_ipsec_gre_tunnel_dump_t *mp;
17646   vl_api_control_ping_t *mp_ping;
17647   u32 sw_if_index;
17648   u8 sw_if_index_set = 0;
17649   int ret;
17650
17651   /* Parse args required to build the message */
17652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17653     {
17654       if (unformat (i, "sw_if_index %d", &sw_if_index))
17655         sw_if_index_set = 1;
17656       else
17657         break;
17658     }
17659
17660   if (sw_if_index_set == 0)
17661     {
17662       sw_if_index = ~0;
17663     }
17664
17665   if (!vam->json_output)
17666     {
17667       print (vam->ofp, "%11s%15s%15s%14s%14s",
17668              "sw_if_index", "src_address", "dst_address",
17669              "local_sa_id", "remote_sa_id");
17670     }
17671
17672   /* Get list of gre-tunnel interfaces */
17673   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17674
17675   mp->sw_if_index = htonl (sw_if_index);
17676
17677   S (mp);
17678
17679   /* Use a control ping for synchronization */
17680   M (CONTROL_PING, mp_ping);
17681   S (mp_ping);
17682
17683   W (ret);
17684   return ret;
17685 }
17686
17687 static int
17688 api_delete_subif (vat_main_t * vam)
17689 {
17690   unformat_input_t *i = vam->input;
17691   vl_api_delete_subif_t *mp;
17692   u32 sw_if_index = ~0;
17693   int ret;
17694
17695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17696     {
17697       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17698         ;
17699       if (unformat (i, "sw_if_index %d", &sw_if_index))
17700         ;
17701       else
17702         break;
17703     }
17704
17705   if (sw_if_index == ~0)
17706     {
17707       errmsg ("missing sw_if_index");
17708       return -99;
17709     }
17710
17711   /* Construct the API message */
17712   M (DELETE_SUBIF, mp);
17713   mp->sw_if_index = ntohl (sw_if_index);
17714
17715   S (mp);
17716   W (ret);
17717   return ret;
17718 }
17719
17720 #define foreach_pbb_vtr_op      \
17721 _("disable",  L2_VTR_DISABLED)  \
17722 _("pop",  L2_VTR_POP_2)         \
17723 _("push",  L2_VTR_PUSH_2)
17724
17725 static int
17726 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17727 {
17728   unformat_input_t *i = vam->input;
17729   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17730   u32 sw_if_index = ~0, vtr_op = ~0;
17731   u16 outer_tag = ~0;
17732   u8 dmac[6], smac[6];
17733   u8 dmac_set = 0, smac_set = 0;
17734   u16 vlanid = 0;
17735   u32 sid = ~0;
17736   u32 tmp;
17737   int ret;
17738
17739   /* Shut up coverity */
17740   memset (dmac, 0, sizeof (dmac));
17741   memset (smac, 0, sizeof (smac));
17742
17743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17744     {
17745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17746         ;
17747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17748         ;
17749       else if (unformat (i, "vtr_op %d", &vtr_op))
17750         ;
17751 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17752       foreach_pbb_vtr_op
17753 #undef _
17754         else if (unformat (i, "translate_pbb_stag"))
17755         {
17756           if (unformat (i, "%d", &tmp))
17757             {
17758               vtr_op = L2_VTR_TRANSLATE_2_1;
17759               outer_tag = tmp;
17760             }
17761           else
17762             {
17763               errmsg
17764                 ("translate_pbb_stag operation requires outer tag definition");
17765               return -99;
17766             }
17767         }
17768       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17769         dmac_set++;
17770       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17771         smac_set++;
17772       else if (unformat (i, "sid %d", &sid))
17773         ;
17774       else if (unformat (i, "vlanid %d", &tmp))
17775         vlanid = tmp;
17776       else
17777         {
17778           clib_warning ("parse error '%U'", format_unformat_error, i);
17779           return -99;
17780         }
17781     }
17782
17783   if ((sw_if_index == ~0) || (vtr_op == ~0))
17784     {
17785       errmsg ("missing sw_if_index or vtr operation");
17786       return -99;
17787     }
17788   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17789       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17790     {
17791       errmsg
17792         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17793       return -99;
17794     }
17795
17796   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17797   mp->sw_if_index = ntohl (sw_if_index);
17798   mp->vtr_op = ntohl (vtr_op);
17799   mp->outer_tag = ntohs (outer_tag);
17800   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17801   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17802   mp->b_vlanid = ntohs (vlanid);
17803   mp->i_sid = ntohl (sid);
17804
17805   S (mp);
17806   W (ret);
17807   return ret;
17808 }
17809
17810 static int
17811 api_flow_classify_set_interface (vat_main_t * vam)
17812 {
17813   unformat_input_t *i = vam->input;
17814   vl_api_flow_classify_set_interface_t *mp;
17815   u32 sw_if_index;
17816   int sw_if_index_set;
17817   u32 ip4_table_index = ~0;
17818   u32 ip6_table_index = ~0;
17819   u8 is_add = 1;
17820   int ret;
17821
17822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17823     {
17824       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17825         sw_if_index_set = 1;
17826       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17827         sw_if_index_set = 1;
17828       else if (unformat (i, "del"))
17829         is_add = 0;
17830       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17831         ;
17832       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17833         ;
17834       else
17835         {
17836           clib_warning ("parse error '%U'", format_unformat_error, i);
17837           return -99;
17838         }
17839     }
17840
17841   if (sw_if_index_set == 0)
17842     {
17843       errmsg ("missing interface name or sw_if_index");
17844       return -99;
17845     }
17846
17847   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17848
17849   mp->sw_if_index = ntohl (sw_if_index);
17850   mp->ip4_table_index = ntohl (ip4_table_index);
17851   mp->ip6_table_index = ntohl (ip6_table_index);
17852   mp->is_add = is_add;
17853
17854   S (mp);
17855   W (ret);
17856   return ret;
17857 }
17858
17859 static int
17860 api_flow_classify_dump (vat_main_t * vam)
17861 {
17862   unformat_input_t *i = vam->input;
17863   vl_api_flow_classify_dump_t *mp;
17864   vl_api_control_ping_t *mp_ping;
17865   u8 type = FLOW_CLASSIFY_N_TABLES;
17866   int ret;
17867
17868   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17869     ;
17870   else
17871     {
17872       errmsg ("classify table type must be specified");
17873       return -99;
17874     }
17875
17876   if (!vam->json_output)
17877     {
17878       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17879     }
17880
17881   M (FLOW_CLASSIFY_DUMP, mp);
17882   mp->type = type;
17883   /* send it... */
17884   S (mp);
17885
17886   /* Use a control ping for synchronization */
17887   M (CONTROL_PING, mp_ping);
17888   S (mp_ping);
17889
17890   /* Wait for a reply... */
17891   W (ret);
17892   return ret;
17893 }
17894
17895 static int
17896 api_feature_enable_disable (vat_main_t * vam)
17897 {
17898   unformat_input_t *i = vam->input;
17899   vl_api_feature_enable_disable_t *mp;
17900   u8 *arc_name = 0;
17901   u8 *feature_name = 0;
17902   u32 sw_if_index = ~0;
17903   u8 enable = 1;
17904   int ret;
17905
17906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17907     {
17908       if (unformat (i, "arc_name %s", &arc_name))
17909         ;
17910       else if (unformat (i, "feature_name %s", &feature_name))
17911         ;
17912       else
17913         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17914         ;
17915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17916         ;
17917       else if (unformat (i, "disable"))
17918         enable = 0;
17919       else
17920         break;
17921     }
17922
17923   if (arc_name == 0)
17924     {
17925       errmsg ("missing arc name");
17926       return -99;
17927     }
17928   if (vec_len (arc_name) > 63)
17929     {
17930       errmsg ("arc name too long");
17931     }
17932
17933   if (feature_name == 0)
17934     {
17935       errmsg ("missing feature name");
17936       return -99;
17937     }
17938   if (vec_len (feature_name) > 63)
17939     {
17940       errmsg ("feature name too long");
17941     }
17942
17943   if (sw_if_index == ~0)
17944     {
17945       errmsg ("missing interface name or sw_if_index");
17946       return -99;
17947     }
17948
17949   /* Construct the API message */
17950   M (FEATURE_ENABLE_DISABLE, mp);
17951   mp->sw_if_index = ntohl (sw_if_index);
17952   mp->enable = enable;
17953   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17954   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17955   vec_free (arc_name);
17956   vec_free (feature_name);
17957
17958   S (mp);
17959   W (ret);
17960   return ret;
17961 }
17962
17963 static int
17964 api_sw_interface_tag_add_del (vat_main_t * vam)
17965 {
17966   unformat_input_t *i = vam->input;
17967   vl_api_sw_interface_tag_add_del_t *mp;
17968   u32 sw_if_index = ~0;
17969   u8 *tag = 0;
17970   u8 enable = 1;
17971   int ret;
17972
17973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17974     {
17975       if (unformat (i, "tag %s", &tag))
17976         ;
17977       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17978         ;
17979       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17980         ;
17981       else if (unformat (i, "del"))
17982         enable = 0;
17983       else
17984         break;
17985     }
17986
17987   if (sw_if_index == ~0)
17988     {
17989       errmsg ("missing interface name or sw_if_index");
17990       return -99;
17991     }
17992
17993   if (enable && (tag == 0))
17994     {
17995       errmsg ("no tag specified");
17996       return -99;
17997     }
17998
17999   /* Construct the API message */
18000   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18001   mp->sw_if_index = ntohl (sw_if_index);
18002   mp->is_add = enable;
18003   if (enable)
18004     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18005   vec_free (tag);
18006
18007   S (mp);
18008   W (ret);
18009   return ret;
18010 }
18011
18012 static void vl_api_l2_xconnect_details_t_handler
18013   (vl_api_l2_xconnect_details_t * mp)
18014 {
18015   vat_main_t *vam = &vat_main;
18016
18017   print (vam->ofp, "%15d%15d",
18018          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18019 }
18020
18021 static void vl_api_l2_xconnect_details_t_handler_json
18022   (vl_api_l2_xconnect_details_t * mp)
18023 {
18024   vat_main_t *vam = &vat_main;
18025   vat_json_node_t *node = NULL;
18026
18027   if (VAT_JSON_ARRAY != vam->json_tree.type)
18028     {
18029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18030       vat_json_init_array (&vam->json_tree);
18031     }
18032   node = vat_json_array_add (&vam->json_tree);
18033
18034   vat_json_init_object (node);
18035   vat_json_object_add_uint (node, "rx_sw_if_index",
18036                             ntohl (mp->rx_sw_if_index));
18037   vat_json_object_add_uint (node, "tx_sw_if_index",
18038                             ntohl (mp->tx_sw_if_index));
18039 }
18040
18041 static int
18042 api_l2_xconnect_dump (vat_main_t * vam)
18043 {
18044   vl_api_l2_xconnect_dump_t *mp;
18045   vl_api_control_ping_t *mp_ping;
18046   int ret;
18047
18048   if (!vam->json_output)
18049     {
18050       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18051     }
18052
18053   M (L2_XCONNECT_DUMP, mp);
18054
18055   S (mp);
18056
18057   /* Use a control ping for synchronization */
18058   M (CONTROL_PING, mp_ping);
18059   S (mp_ping);
18060
18061   W (ret);
18062   return ret;
18063 }
18064
18065 static int
18066 api_sw_interface_set_mtu (vat_main_t * vam)
18067 {
18068   unformat_input_t *i = vam->input;
18069   vl_api_sw_interface_set_mtu_t *mp;
18070   u32 sw_if_index = ~0;
18071   u32 mtu = 0;
18072   int ret;
18073
18074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18075     {
18076       if (unformat (i, "mtu %d", &mtu))
18077         ;
18078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18079         ;
18080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18081         ;
18082       else
18083         break;
18084     }
18085
18086   if (sw_if_index == ~0)
18087     {
18088       errmsg ("missing interface name or sw_if_index");
18089       return -99;
18090     }
18091
18092   if (mtu == 0)
18093     {
18094       errmsg ("no mtu specified");
18095       return -99;
18096     }
18097
18098   /* Construct the API message */
18099   M (SW_INTERFACE_SET_MTU, mp);
18100   mp->sw_if_index = ntohl (sw_if_index);
18101   mp->mtu = ntohs ((u16) mtu);
18102
18103   S (mp);
18104   W (ret);
18105   return ret;
18106 }
18107
18108
18109 static int
18110 q_or_quit (vat_main_t * vam)
18111 {
18112 #if VPP_API_TEST_BUILTIN == 0
18113   longjmp (vam->jump_buf, 1);
18114 #endif
18115   return 0;                     /* not so much */
18116 }
18117
18118 static int
18119 q (vat_main_t * vam)
18120 {
18121   return q_or_quit (vam);
18122 }
18123
18124 static int
18125 quit (vat_main_t * vam)
18126 {
18127   return q_or_quit (vam);
18128 }
18129
18130 static int
18131 comment (vat_main_t * vam)
18132 {
18133   return 0;
18134 }
18135
18136 static int
18137 cmd_cmp (void *a1, void *a2)
18138 {
18139   u8 **c1 = a1;
18140   u8 **c2 = a2;
18141
18142   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18143 }
18144
18145 static int
18146 help (vat_main_t * vam)
18147 {
18148   u8 **cmds = 0;
18149   u8 *name = 0;
18150   hash_pair_t *p;
18151   unformat_input_t *i = vam->input;
18152   int j;
18153
18154   if (unformat (i, "%s", &name))
18155     {
18156       uword *hs;
18157
18158       vec_add1 (name, 0);
18159
18160       hs = hash_get_mem (vam->help_by_name, name);
18161       if (hs)
18162         print (vam->ofp, "usage: %s %s", name, hs[0]);
18163       else
18164         print (vam->ofp, "No such msg / command '%s'", name);
18165       vec_free (name);
18166       return 0;
18167     }
18168
18169   print (vam->ofp, "Help is available for the following:");
18170
18171     /* *INDENT-OFF* */
18172     hash_foreach_pair (p, vam->function_by_name,
18173     ({
18174       vec_add1 (cmds, (u8 *)(p->key));
18175     }));
18176     /* *INDENT-ON* */
18177
18178   vec_sort_with_function (cmds, cmd_cmp);
18179
18180   for (j = 0; j < vec_len (cmds); j++)
18181     print (vam->ofp, "%s", cmds[j]);
18182
18183   vec_free (cmds);
18184   return 0;
18185 }
18186
18187 static int
18188 set (vat_main_t * vam)
18189 {
18190   u8 *name = 0, *value = 0;
18191   unformat_input_t *i = vam->input;
18192
18193   if (unformat (i, "%s", &name))
18194     {
18195       /* The input buffer is a vector, not a string. */
18196       value = vec_dup (i->buffer);
18197       vec_delete (value, i->index, 0);
18198       /* Almost certainly has a trailing newline */
18199       if (value[vec_len (value) - 1] == '\n')
18200         value[vec_len (value) - 1] = 0;
18201       /* Make sure it's a proper string, one way or the other */
18202       vec_add1 (value, 0);
18203       (void) clib_macro_set_value (&vam->macro_main,
18204                                    (char *) name, (char *) value);
18205     }
18206   else
18207     errmsg ("usage: set <name> <value>");
18208
18209   vec_free (name);
18210   vec_free (value);
18211   return 0;
18212 }
18213
18214 static int
18215 unset (vat_main_t * vam)
18216 {
18217   u8 *name = 0;
18218
18219   if (unformat (vam->input, "%s", &name))
18220     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18221       errmsg ("unset: %s wasn't set", name);
18222   vec_free (name);
18223   return 0;
18224 }
18225
18226 typedef struct
18227 {
18228   u8 *name;
18229   u8 *value;
18230 } macro_sort_t;
18231
18232
18233 static int
18234 macro_sort_cmp (void *a1, void *a2)
18235 {
18236   macro_sort_t *s1 = a1;
18237   macro_sort_t *s2 = a2;
18238
18239   return strcmp ((char *) (s1->name), (char *) (s2->name));
18240 }
18241
18242 static int
18243 dump_macro_table (vat_main_t * vam)
18244 {
18245   macro_sort_t *sort_me = 0, *sm;
18246   int i;
18247   hash_pair_t *p;
18248
18249     /* *INDENT-OFF* */
18250     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18251     ({
18252       vec_add2 (sort_me, sm, 1);
18253       sm->name = (u8 *)(p->key);
18254       sm->value = (u8 *) (p->value[0]);
18255     }));
18256     /* *INDENT-ON* */
18257
18258   vec_sort_with_function (sort_me, macro_sort_cmp);
18259
18260   if (vec_len (sort_me))
18261     print (vam->ofp, "%-15s%s", "Name", "Value");
18262   else
18263     print (vam->ofp, "The macro table is empty...");
18264
18265   for (i = 0; i < vec_len (sort_me); i++)
18266     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18267   return 0;
18268 }
18269
18270 static int
18271 dump_node_table (vat_main_t * vam)
18272 {
18273   int i, j;
18274   vlib_node_t *node, *next_node;
18275
18276   if (vec_len (vam->graph_nodes) == 0)
18277     {
18278       print (vam->ofp, "Node table empty, issue get_node_graph...");
18279       return 0;
18280     }
18281
18282   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18283     {
18284       node = vam->graph_nodes[i];
18285       print (vam->ofp, "[%d] %s", i, node->name);
18286       for (j = 0; j < vec_len (node->next_nodes); j++)
18287         {
18288           if (node->next_nodes[j] != ~0)
18289             {
18290               next_node = vam->graph_nodes[node->next_nodes[j]];
18291               print (vam->ofp, "  [%d] %s", j, next_node->name);
18292             }
18293         }
18294     }
18295   return 0;
18296 }
18297
18298 static int
18299 value_sort_cmp (void *a1, void *a2)
18300 {
18301   name_sort_t *n1 = a1;
18302   name_sort_t *n2 = a2;
18303
18304   if (n1->value < n2->value)
18305     return -1;
18306   if (n1->value > n2->value)
18307     return 1;
18308   return 0;
18309 }
18310
18311
18312 static int
18313 dump_msg_api_table (vat_main_t * vam)
18314 {
18315   api_main_t *am = &api_main;
18316   name_sort_t *nses = 0, *ns;
18317   hash_pair_t *hp;
18318   int i;
18319
18320   /* *INDENT-OFF* */
18321   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18322   ({
18323     vec_add2 (nses, ns, 1);
18324     ns->name = (u8 *)(hp->key);
18325     ns->value = (u32) hp->value[0];
18326   }));
18327   /* *INDENT-ON* */
18328
18329   vec_sort_with_function (nses, value_sort_cmp);
18330
18331   for (i = 0; i < vec_len (nses); i++)
18332     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18333   vec_free (nses);
18334   return 0;
18335 }
18336
18337 static int
18338 get_msg_id (vat_main_t * vam)
18339 {
18340   u8 *name_and_crc;
18341   u32 message_index;
18342
18343   if (unformat (vam->input, "%s", &name_and_crc))
18344     {
18345       message_index = vl_api_get_msg_index (name_and_crc);
18346       if (message_index == ~0)
18347         {
18348           print (vam->ofp, " '%s' not found", name_and_crc);
18349           return 0;
18350         }
18351       print (vam->ofp, " '%s' has message index %d",
18352              name_and_crc, message_index);
18353       return 0;
18354     }
18355   errmsg ("name_and_crc required...");
18356   return 0;
18357 }
18358
18359 static int
18360 search_node_table (vat_main_t * vam)
18361 {
18362   unformat_input_t *line_input = vam->input;
18363   u8 *node_to_find;
18364   int j;
18365   vlib_node_t *node, *next_node;
18366   uword *p;
18367
18368   if (vam->graph_node_index_by_name == 0)
18369     {
18370       print (vam->ofp, "Node table empty, issue get_node_graph...");
18371       return 0;
18372     }
18373
18374   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18375     {
18376       if (unformat (line_input, "%s", &node_to_find))
18377         {
18378           vec_add1 (node_to_find, 0);
18379           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18380           if (p == 0)
18381             {
18382               print (vam->ofp, "%s not found...", node_to_find);
18383               goto out;
18384             }
18385           node = vam->graph_nodes[p[0]];
18386           print (vam->ofp, "[%d] %s", p[0], node->name);
18387           for (j = 0; j < vec_len (node->next_nodes); j++)
18388             {
18389               if (node->next_nodes[j] != ~0)
18390                 {
18391                   next_node = vam->graph_nodes[node->next_nodes[j]];
18392                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18393                 }
18394             }
18395         }
18396
18397       else
18398         {
18399           clib_warning ("parse error '%U'", format_unformat_error,
18400                         line_input);
18401           return -99;
18402         }
18403
18404     out:
18405       vec_free (node_to_find);
18406
18407     }
18408
18409   return 0;
18410 }
18411
18412
18413 static int
18414 script (vat_main_t * vam)
18415 {
18416 #if (VPP_API_TEST_BUILTIN==0)
18417   u8 *s = 0;
18418   char *save_current_file;
18419   unformat_input_t save_input;
18420   jmp_buf save_jump_buf;
18421   u32 save_line_number;
18422
18423   FILE *new_fp, *save_ifp;
18424
18425   if (unformat (vam->input, "%s", &s))
18426     {
18427       new_fp = fopen ((char *) s, "r");
18428       if (new_fp == 0)
18429         {
18430           errmsg ("Couldn't open script file %s", s);
18431           vec_free (s);
18432           return -99;
18433         }
18434     }
18435   else
18436     {
18437       errmsg ("Missing script name");
18438       return -99;
18439     }
18440
18441   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18442   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18443   save_ifp = vam->ifp;
18444   save_line_number = vam->input_line_number;
18445   save_current_file = (char *) vam->current_file;
18446
18447   vam->input_line_number = 0;
18448   vam->ifp = new_fp;
18449   vam->current_file = s;
18450   do_one_file (vam);
18451
18452   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18453   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18454   vam->ifp = save_ifp;
18455   vam->input_line_number = save_line_number;
18456   vam->current_file = (u8 *) save_current_file;
18457   vec_free (s);
18458
18459   return 0;
18460 #else
18461   clib_warning ("use the exec command...");
18462   return -99;
18463 #endif
18464 }
18465
18466 static int
18467 echo (vat_main_t * vam)
18468 {
18469   print (vam->ofp, "%v", vam->input->buffer);
18470   return 0;
18471 }
18472
18473 /* List of API message constructors, CLI names map to api_xxx */
18474 #define foreach_vpe_api_msg                                             \
18475 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18476 _(sw_interface_dump,"")                                                 \
18477 _(sw_interface_set_flags,                                               \
18478   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18479 _(sw_interface_add_del_address,                                         \
18480   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18481 _(sw_interface_set_table,                                               \
18482   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18483 _(sw_interface_set_mpls_enable,                                         \
18484   "<intfc> | sw_if_index [disable | dis]")                              \
18485 _(sw_interface_set_vpath,                                               \
18486   "<intfc> | sw_if_index <id> enable | disable")                        \
18487 _(sw_interface_set_vxlan_bypass,                                        \
18488   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18489 _(sw_interface_set_l2_xconnect,                                         \
18490   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18491   "enable | disable")                                                   \
18492 _(sw_interface_set_l2_bridge,                                           \
18493   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18494   "[shg <split-horizon-group>] [bvi]\n"                                 \
18495   "enable | disable")                                                   \
18496 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255\n")\
18497 _(bridge_domain_add_del,                                                \
18498   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [del]\n") \
18499 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18500 _(l2fib_add_del,                                                        \
18501   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18502 _(l2_flags,                                                             \
18503   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18504 _(bridge_flags,                                                         \
18505   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18506 _(tap_connect,                                                          \
18507   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18508 _(tap_modify,                                                           \
18509   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18510 _(tap_delete,                                                           \
18511   "<vpp-if-name> | sw_if_index <id>")                                   \
18512 _(sw_interface_tap_dump, "")                                            \
18513 _(ip_add_del_route,                                                     \
18514   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18515   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18516   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18517   "[multipath] [count <n>]")                                            \
18518 _(ip_mroute_add_del,                                                    \
18519   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18520   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18521 _(mpls_route_add_del,                                                   \
18522   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18523   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18524   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18525   "[multipath] [count <n>]")                                            \
18526 _(mpls_ip_bind_unbind,                                                  \
18527   "<label> <addr/len>")                                                 \
18528 _(mpls_tunnel_add_del,                                                  \
18529   " via <addr> [table-id <n>]\n"                                        \
18530   "sw_if_index <id>] [l2]  [del]")                                      \
18531 _(proxy_arp_add_del,                                                    \
18532   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18533 _(proxy_arp_intfc_enable_disable,                                       \
18534   "<intfc> | sw_if_index <id> enable | disable")                        \
18535 _(sw_interface_set_unnumbered,                                          \
18536   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18537 _(ip_neighbor_add_del,                                                  \
18538   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18539   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18540 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18541 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18542 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18543   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18544   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18545   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18546 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18547 _(reset_fib, "vrf <n> [ipv6]")                                          \
18548 _(dhcp_proxy_config,                                                    \
18549   "svr <v46-address> src <v46-address>\n"                               \
18550    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18551 _(dhcp_proxy_set_vss,                                                   \
18552   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18553 _(dhcp_proxy_dump, "ip6")                                               \
18554 _(dhcp_client_config,                                                   \
18555   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18556 _(set_ip_flow_hash,                                                     \
18557   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18558 _(sw_interface_ip6_enable_disable,                                      \
18559   "<intfc> | sw_if_index <id> enable | disable")                        \
18560 _(sw_interface_ip6_set_link_local_address,                              \
18561   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18562 _(ip6nd_proxy_add_del,                                                  \
18563   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18564 _(ip6nd_proxy_dump, "")                                                 \
18565 _(sw_interface_ip6nd_ra_prefix,                                         \
18566   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18567   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18568   "[nolink] [isno]")                                                    \
18569 _(sw_interface_ip6nd_ra_config,                                         \
18570   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18571   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18572   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18573 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18574 _(l2_patch_add_del,                                                     \
18575   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18576   "enable | disable")                                                   \
18577 _(sr_localsid_add_del,                                                  \
18578   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18579   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18580 _(classify_add_del_table,                                               \
18581   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18582   " [del] [del-chain] mask <mask-value>\n"                              \
18583   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18584   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18585 _(classify_add_del_session,                                             \
18586   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18587   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18588   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18589   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18590 _(classify_set_interface_ip_table,                                      \
18591   "<intfc> | sw_if_index <nn> table <nn>")                              \
18592 _(classify_set_interface_l2_tables,                                     \
18593   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18594   "  [other-table <nn>]")                                               \
18595 _(get_node_index, "node <node-name")                                    \
18596 _(add_node_next, "node <node-name> next <next-node-name>")              \
18597 _(l2tpv3_create_tunnel,                                                 \
18598   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18599   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18600   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18601 _(l2tpv3_set_tunnel_cookies,                                            \
18602   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18603   "[new_remote_cookie <nn>]\n")                                         \
18604 _(l2tpv3_interface_enable_disable,                                      \
18605   "<intfc> | sw_if_index <nn> enable | disable")                        \
18606 _(l2tpv3_set_lookup_key,                                                \
18607   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18608 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18609 _(vxlan_add_del_tunnel,                                                 \
18610   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18611   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18612   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18613 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18614 _(gre_add_del_tunnel,                                                   \
18615   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18616 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18617 _(l2_fib_clear_table, "")                                               \
18618 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18619 _(l2_interface_vlan_tag_rewrite,                                        \
18620   "<intfc> | sw_if_index <nn> \n"                                       \
18621   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18622   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18623 _(create_vhost_user_if,                                                 \
18624         "socket <filename> [server] [renumber <dev_instance>] "         \
18625         "[mac <mac_address>] "                                          \
18626         "[mode <interrupt | polling>]")                                 \
18627 _(modify_vhost_user_if,                                                 \
18628         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18629         "[server] [renumber <dev_instance>] "                           \
18630         "[mode <interrupt | polling>]")                                 \
18631 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18632 _(sw_interface_vhost_user_dump, "")                                     \
18633 _(show_version, "")                                                     \
18634 _(vxlan_gpe_add_del_tunnel,                                             \
18635   "local <addr> remote <addr> vni <nn>\n"                               \
18636     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18637   "[next-ethernet] [next-nsh]\n")                                       \
18638 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18639 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18640 _(interface_name_renumber,                                              \
18641   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18642 _(input_acl_set_interface,                                              \
18643   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18644   "  [l2-table <nn>] [del]")                                            \
18645 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18646 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18647 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18648 _(ip_dump, "ipv4 | ipv6")                                               \
18649 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18650 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18651   "  spid_id <n> ")                                                     \
18652 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18653   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18654   "  integ_alg <alg> integ_key <hex>")                                  \
18655 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18656   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18657   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18658   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18659 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18660 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18661 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18662   "(auth_data 0x<data> | auth_data <data>)")                            \
18663 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18664   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18665 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18666   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18667   "(local|remote)")                                                     \
18668 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18669 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18670 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18671 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18672 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18673 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18674 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18675 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18676 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18677 _(delete_loopback,"sw_if_index <nn>")                                   \
18678 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18679 _(map_add_domain,                                                       \
18680   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18681   "ip6-src <ip6addr> "                                                  \
18682   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18683 _(map_del_domain, "index <n>")                                          \
18684 _(map_add_del_rule,                                                     \
18685   "index <n> psid <n> dst <ip6addr> [del]")                             \
18686 _(map_domain_dump, "")                                                  \
18687 _(map_rule_dump, "index <map-domain>")                                  \
18688 _(want_interface_events,  "enable|disable")                             \
18689 _(want_stats,"enable|disable")                                          \
18690 _(get_first_msg_id, "client <name>")                                    \
18691 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18692 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18693   "fib-id <nn> [ip4][ip6][default]")                                    \
18694 _(get_node_graph, " ")                                                  \
18695 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18696 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18697 _(ioam_disable, "")                                                     \
18698 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18699                             " sw_if_index <sw_if_index> p <priority> "  \
18700                             "w <weight>] [del]")                        \
18701 _(one_add_del_locator, "locator-set <locator_name> "                    \
18702                         "iface <intf> | sw_if_index <sw_if_index> "     \
18703                         "p <priority> w <weight> [del]")                \
18704 _(one_add_del_local_eid,"vni <vni> eid "                                \
18705                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18706                          "locator-set <locator_name> [del]"             \
18707                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18708 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18709 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18710 _(one_enable_disable, "enable|disable")                                 \
18711 _(one_map_register_enable_disable, "enable|disable")                    \
18712 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18713 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18714                                "[seid <seid>] "                         \
18715                                "rloc <locator> p <prio> "               \
18716                                "w <weight> [rloc <loc> ... ] "          \
18717                                "action <action> [del-all]")             \
18718 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18719                           "<local-eid>")                                \
18720 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18721 _(one_use_petr, "ip-address> | disable")                                \
18722 _(one_map_request_mode, "src-dst|dst-only")                             \
18723 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18724 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18725 _(one_locator_set_dump, "[local | remote]")                             \
18726 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18727 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18728                        "[local] | [remote]")                            \
18729 _(one_stats_enable_disable, "enable|disalbe")                           \
18730 _(show_one_stats_enable_disable, "")                                    \
18731 _(one_eid_table_vni_dump, "")                                           \
18732 _(one_eid_table_map_dump, "l2|l3")                                      \
18733 _(one_map_resolver_dump, "")                                            \
18734 _(one_map_server_dump, "")                                              \
18735 _(one_adjacencies_get, "vni <vni>")                                     \
18736 _(show_one_rloc_probe_state, "")                                        \
18737 _(show_one_map_register_state, "")                                      \
18738 _(show_one_status, "")                                                  \
18739 _(one_stats_dump, "")                                                   \
18740 _(one_get_map_request_itr_rlocs, "")                                    \
18741 _(show_one_pitr, "")                                                    \
18742 _(show_one_use_petr, "")                                                \
18743 _(show_one_map_request_mode, "")                                        \
18744 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18745                             " sw_if_index <sw_if_index> p <priority> "  \
18746                             "w <weight>] [del]")                        \
18747 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18748                         "iface <intf> | sw_if_index <sw_if_index> "     \
18749                         "p <priority> w <weight> [del]")                \
18750 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18751                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18752                          "locator-set <locator_name> [del]"             \
18753                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18754 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18755 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18756 _(lisp_enable_disable, "enable|disable")                                \
18757 _(lisp_map_register_enable_disable, "enable|disable")                   \
18758 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18759 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18760                                "[seid <seid>] "                         \
18761                                "rloc <locator> p <prio> "               \
18762                                "w <weight> [rloc <loc> ... ] "          \
18763                                "action <action> [del-all]")             \
18764 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18765                           "<local-eid>")                                \
18766 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18767 _(lisp_use_petr, "<ip-address> | disable")                              \
18768 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18769 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18770 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18771 _(lisp_locator_set_dump, "[local | remote]")                            \
18772 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18773 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18774                        "[local] | [remote]")                            \
18775 _(lisp_eid_table_vni_dump, "")                                          \
18776 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18777 _(lisp_map_resolver_dump, "")                                           \
18778 _(lisp_map_server_dump, "")                                             \
18779 _(lisp_adjacencies_get, "vni <vni>")                                    \
18780 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18781 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18782 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18783 _(gpe_get_encap_mode, "")                                               \
18784 _(lisp_gpe_add_del_iface, "up|down")                                    \
18785 _(lisp_gpe_enable_disable, "enable|disable")                            \
18786 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18787   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18788 _(show_lisp_rloc_probe_state, "")                                       \
18789 _(show_lisp_map_register_state, "")                                     \
18790 _(show_lisp_status, "")                                                 \
18791 _(lisp_get_map_request_itr_rlocs, "")                                   \
18792 _(show_lisp_pitr, "")                                                   \
18793 _(show_lisp_use_petr, "")                                               \
18794 _(show_lisp_map_request_mode, "")                                       \
18795 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18796 _(af_packet_delete, "name <host interface name>")                       \
18797 _(policer_add_del, "name <policer name> <params> [del]")                \
18798 _(policer_dump, "[name <policer name>]")                                \
18799 _(policer_classify_set_interface,                                       \
18800   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18801   "  [l2-table <nn>] [del]")                                            \
18802 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18803 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18804     "[master|slave]")                                                   \
18805 _(netmap_delete, "name <interface name>")                               \
18806 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18807 _(mpls_fib_dump, "")                                                    \
18808 _(classify_table_ids, "")                                               \
18809 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18810 _(classify_table_info, "table_id <nn>")                                 \
18811 _(classify_session_dump, "table_id <nn>")                               \
18812 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18813     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18814     "[template_interval <nn>] [udp_checksum]")                          \
18815 _(ipfix_exporter_dump, "")                                              \
18816 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18817 _(ipfix_classify_stream_dump, "")                                       \
18818 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18819 _(ipfix_classify_table_dump, "")                                        \
18820 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18821 _(sw_interface_span_dump, "")                                           \
18822 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18823 _(pg_create_interface, "if_id <nn>")                                    \
18824 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18825 _(pg_enable_disable, "[stream <id>] disable")                           \
18826 _(ip_source_and_port_range_check_add_del,                               \
18827   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18828 _(ip_source_and_port_range_check_interface_add_del,                     \
18829   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18830   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18831 _(ipsec_gre_add_del_tunnel,                                             \
18832   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18833 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18834 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18835 _(l2_interface_pbb_tag_rewrite,                                         \
18836   "<intfc> | sw_if_index <nn> \n"                                       \
18837   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18838   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18839 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18840 _(flow_classify_set_interface,                                          \
18841   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18842 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18843 _(ip_fib_dump, "")                                                      \
18844 _(ip_mfib_dump, "")                                                     \
18845 _(ip6_fib_dump, "")                                                     \
18846 _(ip6_mfib_dump, "")                                                    \
18847 _(feature_enable_disable, "arc_name <arc_name> "                        \
18848   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18849 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18850 "[disable]")                                                            \
18851 _(l2_xconnect_dump, "")                                                 \
18852 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18853 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18854 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18855
18856 /* List of command functions, CLI names map directly to functions */
18857 #define foreach_cli_function                                    \
18858 _(comment, "usage: comment <ignore-rest-of-line>")              \
18859 _(dump_interface_table, "usage: dump_interface_table")          \
18860 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18861 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18862 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18863 _(dump_stats_table, "usage: dump_stats_table")                  \
18864 _(dump_macro_table, "usage: dump_macro_table ")                 \
18865 _(dump_node_table, "usage: dump_node_table")                    \
18866 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18867 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18868 _(echo, "usage: echo <message>")                                \
18869 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18870 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18871 _(help, "usage: help")                                          \
18872 _(q, "usage: quit")                                             \
18873 _(quit, "usage: quit")                                          \
18874 _(search_node_table, "usage: search_node_table <name>...")      \
18875 _(set, "usage: set <variable-name> <value>")                    \
18876 _(script, "usage: script <file-name>")                          \
18877 _(unset, "usage: unset <variable-name>")
18878
18879 #define _(N,n)                                  \
18880     static void vl_api_##n##_t_handler_uni      \
18881     (vl_api_##n##_t * mp)                       \
18882     {                                           \
18883         vat_main_t * vam = &vat_main;           \
18884         if (vam->json_output) {                 \
18885             vl_api_##n##_t_handler_json(mp);    \
18886         } else {                                \
18887             vl_api_##n##_t_handler(mp);         \
18888         }                                       \
18889     }
18890 foreach_vpe_api_reply_msg;
18891 #if VPP_API_TEST_BUILTIN == 0
18892 foreach_standalone_reply_msg;
18893 #endif
18894 #undef _
18895
18896 void
18897 vat_api_hookup (vat_main_t * vam)
18898 {
18899 #define _(N,n)                                                  \
18900     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18901                            vl_api_##n##_t_handler_uni,          \
18902                            vl_noop_handler,                     \
18903                            vl_api_##n##_t_endian,               \
18904                            vl_api_##n##_t_print,                \
18905                            sizeof(vl_api_##n##_t), 1);
18906   foreach_vpe_api_reply_msg;
18907 #if VPP_API_TEST_BUILTIN == 0
18908   foreach_standalone_reply_msg;
18909 #endif
18910 #undef _
18911
18912 #if (VPP_API_TEST_BUILTIN==0)
18913   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18914
18915   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18916
18917   vam->function_by_name = hash_create_string (0, sizeof (uword));
18918
18919   vam->help_by_name = hash_create_string (0, sizeof (uword));
18920 #endif
18921
18922   /* API messages we can send */
18923 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18924   foreach_vpe_api_msg;
18925 #undef _
18926
18927   /* Help strings */
18928 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18929   foreach_vpe_api_msg;
18930 #undef _
18931
18932   /* CLI functions */
18933 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18934   foreach_cli_function;
18935 #undef _
18936
18937   /* Help strings */
18938 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18939   foreach_cli_function;
18940 #undef _
18941 }
18942
18943 #if VPP_API_TEST_BUILTIN
18944 static clib_error_t *
18945 vat_api_hookup_shim (vlib_main_t * vm)
18946 {
18947   vat_api_hookup (&vat_main);
18948   return 0;
18949 }
18950
18951 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18952 #endif
18953
18954 /*
18955  * fd.io coding-style-patch-verification: ON
18956  *
18957  * Local Variables:
18958  * eval: (c-set-style "gnu")
18959  * End:
18960  */