LISP-GPE: add dump call for VNIs in use
[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 = uword_to_pointer (mp->reply_in_shmem, u8 *);
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 = uword_to_pointer (mp->reply_in_shmem, u8 *);
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 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1327 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1328
1329 /*
1330  * Special-case: build the bridge domain table, maintain
1331  * the next bd id vbl.
1332  */
1333 static void vl_api_bridge_domain_details_t_handler
1334   (vl_api_bridge_domain_details_t * mp)
1335 {
1336   vat_main_t *vam = &vat_main;
1337   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1338   int i;
1339
1340   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1341          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1342
1343   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1344          ntohl (mp->bd_id), mp->learn, mp->forward,
1345          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1346
1347   if (n_sw_ifs)
1348     {
1349       vl_api_bridge_domain_sw_if_t *sw_ifs;
1350       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1351              "Interface Name");
1352
1353       sw_ifs = mp->sw_if_details;
1354       for (i = 0; i < n_sw_ifs; i++)
1355         {
1356           u8 *sw_if_name = 0;
1357           u32 sw_if_index;
1358           hash_pair_t *p;
1359
1360           sw_if_index = ntohl (sw_ifs->sw_if_index);
1361
1362           /* *INDENT-OFF* */
1363           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1364                              ({
1365                                if ((u32) p->value[0] == sw_if_index)
1366                                  {
1367                                    sw_if_name = (u8 *)(p->key);
1368                                    break;
1369                                  }
1370                              }));
1371           /* *INDENT-ON* */
1372           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1373                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1374                  "sw_if_index not found!");
1375
1376           sw_ifs++;
1377         }
1378     }
1379 }
1380
1381 static void vl_api_bridge_domain_details_t_handler_json
1382   (vl_api_bridge_domain_details_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   vat_json_node_t *node, *array = NULL;
1386   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1387
1388   if (VAT_JSON_ARRAY != vam->json_tree.type)
1389     {
1390       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1391       vat_json_init_array (&vam->json_tree);
1392     }
1393   node = vat_json_array_add (&vam->json_tree);
1394
1395   vat_json_init_object (node);
1396   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1397   vat_json_object_add_uint (node, "flood", mp->flood);
1398   vat_json_object_add_uint (node, "forward", mp->forward);
1399   vat_json_object_add_uint (node, "learn", mp->learn);
1400   vat_json_object_add_uint (node, "bvi_sw_if_index",
1401                             ntohl (mp->bvi_sw_if_index));
1402   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1403   array = vat_json_object_add (node, "sw_if");
1404   vat_json_init_array (array);
1405
1406
1407
1408   if (n_sw_ifs)
1409     {
1410       vl_api_bridge_domain_sw_if_t *sw_ifs;
1411       int i;
1412
1413       sw_ifs = mp->sw_if_details;
1414       for (i = 0; i < n_sw_ifs; i++)
1415         {
1416           node = vat_json_array_add (array);
1417           vat_json_init_object (node);
1418           vat_json_object_add_uint (node, "sw_if_index",
1419                                     ntohl (sw_ifs->sw_if_index));
1420           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1421           sw_ifs++;
1422         }
1423     }
1424 }
1425
1426 static void vl_api_control_ping_reply_t_handler
1427   (vl_api_control_ping_reply_t * mp)
1428 {
1429   vat_main_t *vam = &vat_main;
1430   i32 retval = ntohl (mp->retval);
1431   if (vam->async_mode)
1432     {
1433       vam->async_errors += (retval < 0);
1434     }
1435   else
1436     {
1437       vam->retval = retval;
1438       vam->result_ready = 1;
1439     }
1440 }
1441
1442 static void vl_api_control_ping_reply_t_handler_json
1443   (vl_api_control_ping_reply_t * mp)
1444 {
1445   vat_main_t *vam = &vat_main;
1446   i32 retval = ntohl (mp->retval);
1447
1448   if (VAT_JSON_NONE != vam->json_tree.type)
1449     {
1450       vat_json_print (vam->ofp, &vam->json_tree);
1451       vat_json_free (&vam->json_tree);
1452       vam->json_tree.type = VAT_JSON_NONE;
1453     }
1454   else
1455     {
1456       /* just print [] */
1457       vat_json_init_array (&vam->json_tree);
1458       vat_json_print (vam->ofp, &vam->json_tree);
1459       vam->json_tree.type = VAT_JSON_NONE;
1460     }
1461
1462   vam->retval = retval;
1463   vam->result_ready = 1;
1464 }
1465
1466 static void
1467   vl_api_bridge_domain_set_mac_age_reply_t_handler
1468   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   i32 retval = ntohl (mp->retval);
1472   if (vam->async_mode)
1473     {
1474       vam->async_errors += (retval < 0);
1475     }
1476   else
1477     {
1478       vam->retval = retval;
1479       vam->result_ready = 1;
1480     }
1481 }
1482
1483 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1484   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   vat_json_node_t node;
1488
1489   vat_json_init_object (&node);
1490   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1491
1492   vat_json_print (vam->ofp, &node);
1493   vat_json_free (&node);
1494
1495   vam->retval = ntohl (mp->retval);
1496   vam->result_ready = 1;
1497 }
1498
1499 static void
1500 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1501 {
1502   vat_main_t *vam = &vat_main;
1503   i32 retval = ntohl (mp->retval);
1504   if (vam->async_mode)
1505     {
1506       vam->async_errors += (retval < 0);
1507     }
1508   else
1509     {
1510       vam->retval = retval;
1511       vam->result_ready = 1;
1512     }
1513 }
1514
1515 static void vl_api_l2_flags_reply_t_handler_json
1516   (vl_api_l2_flags_reply_t * mp)
1517 {
1518   vat_main_t *vam = &vat_main;
1519   vat_json_node_t node;
1520
1521   vat_json_init_object (&node);
1522   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1523   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1524                             ntohl (mp->resulting_feature_bitmap));
1525
1526   vat_json_print (vam->ofp, &node);
1527   vat_json_free (&node);
1528
1529   vam->retval = ntohl (mp->retval);
1530   vam->result_ready = 1;
1531 }
1532
1533 static void vl_api_bridge_flags_reply_t_handler
1534   (vl_api_bridge_flags_reply_t * mp)
1535 {
1536   vat_main_t *vam = &vat_main;
1537   i32 retval = ntohl (mp->retval);
1538   if (vam->async_mode)
1539     {
1540       vam->async_errors += (retval < 0);
1541     }
1542   else
1543     {
1544       vam->retval = retval;
1545       vam->result_ready = 1;
1546     }
1547 }
1548
1549 static void vl_api_bridge_flags_reply_t_handler_json
1550   (vl_api_bridge_flags_reply_t * mp)
1551 {
1552   vat_main_t *vam = &vat_main;
1553   vat_json_node_t node;
1554
1555   vat_json_init_object (&node);
1556   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1557   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1558                             ntohl (mp->resulting_feature_bitmap));
1559
1560   vat_json_print (vam->ofp, &node);
1561   vat_json_free (&node);
1562
1563   vam->retval = ntohl (mp->retval);
1564   vam->result_ready = 1;
1565 }
1566
1567 static void vl_api_tap_connect_reply_t_handler
1568   (vl_api_tap_connect_reply_t * mp)
1569 {
1570   vat_main_t *vam = &vat_main;
1571   i32 retval = ntohl (mp->retval);
1572   if (vam->async_mode)
1573     {
1574       vam->async_errors += (retval < 0);
1575     }
1576   else
1577     {
1578       vam->retval = retval;
1579       vam->sw_if_index = ntohl (mp->sw_if_index);
1580       vam->result_ready = 1;
1581     }
1582
1583 }
1584
1585 static void vl_api_tap_connect_reply_t_handler_json
1586   (vl_api_tap_connect_reply_t * mp)
1587 {
1588   vat_main_t *vam = &vat_main;
1589   vat_json_node_t node;
1590
1591   vat_json_init_object (&node);
1592   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1593   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1594
1595   vat_json_print (vam->ofp, &node);
1596   vat_json_free (&node);
1597
1598   vam->retval = ntohl (mp->retval);
1599   vam->result_ready = 1;
1600
1601 }
1602
1603 static void
1604 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   i32 retval = ntohl (mp->retval);
1608   if (vam->async_mode)
1609     {
1610       vam->async_errors += (retval < 0);
1611     }
1612   else
1613     {
1614       vam->retval = retval;
1615       vam->sw_if_index = ntohl (mp->sw_if_index);
1616       vam->result_ready = 1;
1617     }
1618 }
1619
1620 static void vl_api_tap_modify_reply_t_handler_json
1621   (vl_api_tap_modify_reply_t * mp)
1622 {
1623   vat_main_t *vam = &vat_main;
1624   vat_json_node_t node;
1625
1626   vat_json_init_object (&node);
1627   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1628   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1629
1630   vat_json_print (vam->ofp, &node);
1631   vat_json_free (&node);
1632
1633   vam->retval = ntohl (mp->retval);
1634   vam->result_ready = 1;
1635 }
1636
1637 static void
1638 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   i32 retval = ntohl (mp->retval);
1642   if (vam->async_mode)
1643     {
1644       vam->async_errors += (retval < 0);
1645     }
1646   else
1647     {
1648       vam->retval = retval;
1649       vam->result_ready = 1;
1650     }
1651 }
1652
1653 static void vl_api_tap_delete_reply_t_handler_json
1654   (vl_api_tap_delete_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   vat_json_node_t node;
1658
1659   vat_json_init_object (&node);
1660   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1661
1662   vat_json_print (vam->ofp, &node);
1663   vat_json_free (&node);
1664
1665   vam->retval = ntohl (mp->retval);
1666   vam->result_ready = 1;
1667 }
1668
1669 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1670   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   i32 retval = ntohl (mp->retval);
1674   if (vam->async_mode)
1675     {
1676       vam->async_errors += (retval < 0);
1677     }
1678   else
1679     {
1680       vam->retval = retval;
1681       vam->result_ready = 1;
1682     }
1683 }
1684
1685 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1686   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1687 {
1688   vat_main_t *vam = &vat_main;
1689   vat_json_node_t node;
1690
1691   vat_json_init_object (&node);
1692   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1693   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1694                             ntohl (mp->sw_if_index));
1695
1696   vat_json_print (vam->ofp, &node);
1697   vat_json_free (&node);
1698
1699   vam->retval = ntohl (mp->retval);
1700   vam->result_ready = 1;
1701 }
1702
1703 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1704   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1705 {
1706   vat_main_t *vam = &vat_main;
1707   i32 retval = ntohl (mp->retval);
1708   if (vam->async_mode)
1709     {
1710       vam->async_errors += (retval < 0);
1711     }
1712   else
1713     {
1714       vam->retval = retval;
1715       vam->sw_if_index = ntohl (mp->sw_if_index);
1716       vam->result_ready = 1;
1717     }
1718 }
1719
1720 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1721   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1722 {
1723   vat_main_t *vam = &vat_main;
1724   vat_json_node_t node;
1725
1726   vat_json_init_object (&node);
1727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1729
1730   vat_json_print (vam->ofp, &node);
1731   vat_json_free (&node);
1732
1733   vam->retval = ntohl (mp->retval);
1734   vam->result_ready = 1;
1735 }
1736
1737
1738 static void vl_api_one_add_del_locator_set_reply_t_handler
1739   (vl_api_one_add_del_locator_set_reply_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   i32 retval = ntohl (mp->retval);
1743   if (vam->async_mode)
1744     {
1745       vam->async_errors += (retval < 0);
1746     }
1747   else
1748     {
1749       vam->retval = retval;
1750       vam->result_ready = 1;
1751     }
1752 }
1753
1754 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1755   (vl_api_one_add_del_locator_set_reply_t * mp)
1756 {
1757   vat_main_t *vam = &vat_main;
1758   vat_json_node_t node;
1759
1760   vat_json_init_object (&node);
1761   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1762   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1763
1764   vat_json_print (vam->ofp, &node);
1765   vat_json_free (&node);
1766
1767   vam->retval = ntohl (mp->retval);
1768   vam->result_ready = 1;
1769 }
1770
1771 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1772   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   i32 retval = ntohl (mp->retval);
1776   if (vam->async_mode)
1777     {
1778       vam->async_errors += (retval < 0);
1779     }
1780   else
1781     {
1782       vam->retval = retval;
1783       vam->sw_if_index = ntohl (mp->sw_if_index);
1784       vam->result_ready = 1;
1785     }
1786 }
1787
1788 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1789   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1790 {
1791   vat_main_t *vam = &vat_main;
1792   vat_json_node_t node;
1793
1794   vat_json_init_object (&node);
1795   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1796   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1797
1798   vat_json_print (vam->ofp, &node);
1799   vat_json_free (&node);
1800
1801   vam->retval = ntohl (mp->retval);
1802   vam->result_ready = 1;
1803 }
1804
1805 static void vl_api_gre_add_del_tunnel_reply_t_handler
1806   (vl_api_gre_add_del_tunnel_reply_t * mp)
1807 {
1808   vat_main_t *vam = &vat_main;
1809   i32 retval = ntohl (mp->retval);
1810   if (vam->async_mode)
1811     {
1812       vam->async_errors += (retval < 0);
1813     }
1814   else
1815     {
1816       vam->retval = retval;
1817       vam->sw_if_index = ntohl (mp->sw_if_index);
1818       vam->result_ready = 1;
1819     }
1820 }
1821
1822 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1823   (vl_api_gre_add_del_tunnel_reply_t * mp)
1824 {
1825   vat_main_t *vam = &vat_main;
1826   vat_json_node_t node;
1827
1828   vat_json_init_object (&node);
1829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1830   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1831
1832   vat_json_print (vam->ofp, &node);
1833   vat_json_free (&node);
1834
1835   vam->retval = ntohl (mp->retval);
1836   vam->result_ready = 1;
1837 }
1838
1839 static void vl_api_create_vhost_user_if_reply_t_handler
1840   (vl_api_create_vhost_user_if_reply_t * mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   i32 retval = ntohl (mp->retval);
1844   if (vam->async_mode)
1845     {
1846       vam->async_errors += (retval < 0);
1847     }
1848   else
1849     {
1850       vam->retval = retval;
1851       vam->sw_if_index = ntohl (mp->sw_if_index);
1852       vam->result_ready = 1;
1853     }
1854 }
1855
1856 static void vl_api_create_vhost_user_if_reply_t_handler_json
1857   (vl_api_create_vhost_user_if_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   vat_json_node_t node;
1861
1862   vat_json_init_object (&node);
1863   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1864   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1865
1866   vat_json_print (vam->ofp, &node);
1867   vat_json_free (&node);
1868
1869   vam->retval = ntohl (mp->retval);
1870   vam->result_ready = 1;
1871 }
1872
1873 static void vl_api_ip_address_details_t_handler
1874   (vl_api_ip_address_details_t * mp)
1875 {
1876   vat_main_t *vam = &vat_main;
1877   static ip_address_details_t empty_ip_address_details = { {0} };
1878   ip_address_details_t *address = NULL;
1879   ip_details_t *current_ip_details = NULL;
1880   ip_details_t *details = NULL;
1881
1882   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1883
1884   if (!details || vam->current_sw_if_index >= vec_len (details)
1885       || !details[vam->current_sw_if_index].present)
1886     {
1887       errmsg ("ip address details arrived but not stored");
1888       errmsg ("ip_dump should be called first");
1889       return;
1890     }
1891
1892   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1893
1894 #define addresses (current_ip_details->addr)
1895
1896   vec_validate_init_empty (addresses, vec_len (addresses),
1897                            empty_ip_address_details);
1898
1899   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1900
1901   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1902   address->prefix_length = mp->prefix_length;
1903 #undef addresses
1904 }
1905
1906 static void vl_api_ip_address_details_t_handler_json
1907   (vl_api_ip_address_details_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   vat_json_node_t *node = NULL;
1911   struct in6_addr ip6;
1912   struct in_addr ip4;
1913
1914   if (VAT_JSON_ARRAY != vam->json_tree.type)
1915     {
1916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1917       vat_json_init_array (&vam->json_tree);
1918     }
1919   node = vat_json_array_add (&vam->json_tree);
1920
1921   vat_json_init_object (node);
1922   if (vam->is_ipv6)
1923     {
1924       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1925       vat_json_object_add_ip6 (node, "ip", ip6);
1926     }
1927   else
1928     {
1929       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1930       vat_json_object_add_ip4 (node, "ip", ip4);
1931     }
1932   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1933 }
1934
1935 static void
1936 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1937 {
1938   vat_main_t *vam = &vat_main;
1939   static ip_details_t empty_ip_details = { 0 };
1940   ip_details_t *ip = NULL;
1941   u32 sw_if_index = ~0;
1942
1943   sw_if_index = ntohl (mp->sw_if_index);
1944
1945   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1946                            sw_if_index, empty_ip_details);
1947
1948   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1949                          sw_if_index);
1950
1951   ip->present = 1;
1952 }
1953
1954 static void
1955 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958
1959   if (VAT_JSON_ARRAY != vam->json_tree.type)
1960     {
1961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1962       vat_json_init_array (&vam->json_tree);
1963     }
1964   vat_json_array_add_uint (&vam->json_tree,
1965                            clib_net_to_host_u32 (mp->sw_if_index));
1966 }
1967
1968 static void vl_api_map_domain_details_t_handler_json
1969   (vl_api_map_domain_details_t * mp)
1970 {
1971   vat_json_node_t *node = NULL;
1972   vat_main_t *vam = &vat_main;
1973   struct in6_addr ip6;
1974   struct in_addr ip4;
1975
1976   if (VAT_JSON_ARRAY != vam->json_tree.type)
1977     {
1978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1979       vat_json_init_array (&vam->json_tree);
1980     }
1981
1982   node = vat_json_array_add (&vam->json_tree);
1983   vat_json_init_object (node);
1984
1985   vat_json_object_add_uint (node, "domain_index",
1986                             clib_net_to_host_u32 (mp->domain_index));
1987   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1988   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1989   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1990   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1991   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1992   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1993   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1994   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1995   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1996   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1997   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1998   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1999   vat_json_object_add_uint (node, "flags", mp->flags);
2000   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2001   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2002 }
2003
2004 static void vl_api_map_domain_details_t_handler
2005   (vl_api_map_domain_details_t * mp)
2006 {
2007   vat_main_t *vam = &vat_main;
2008
2009   if (mp->is_translation)
2010     {
2011       print (vam->ofp,
2012              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2013              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2014              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2015              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2016              clib_net_to_host_u32 (mp->domain_index));
2017     }
2018   else
2019     {
2020       print (vam->ofp,
2021              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2022              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2023              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2024              format_ip6_address, mp->ip6_src,
2025              clib_net_to_host_u32 (mp->domain_index));
2026     }
2027   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2028          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2029          mp->is_translation ? "map-t" : "");
2030 }
2031
2032 static void vl_api_map_rule_details_t_handler_json
2033   (vl_api_map_rule_details_t * mp)
2034 {
2035   struct in6_addr ip6;
2036   vat_json_node_t *node = NULL;
2037   vat_main_t *vam = &vat_main;
2038
2039   if (VAT_JSON_ARRAY != vam->json_tree.type)
2040     {
2041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2042       vat_json_init_array (&vam->json_tree);
2043     }
2044
2045   node = vat_json_array_add (&vam->json_tree);
2046   vat_json_init_object (node);
2047
2048   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2049   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2050   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2051 }
2052
2053 static void
2054 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2055 {
2056   vat_main_t *vam = &vat_main;
2057   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2058          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2059 }
2060
2061 static void
2062 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2063 {
2064   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2065           "router_addr %U host_mac %U",
2066           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2067           format_ip4_address, &mp->host_address,
2068           format_ip4_address, &mp->router_address,
2069           format_ethernet_address, mp->host_mac);
2070 }
2071
2072 static void vl_api_dhcp_compl_event_t_handler_json
2073   (vl_api_dhcp_compl_event_t * mp)
2074 {
2075   /* JSON output not supported */
2076 }
2077
2078 static void
2079 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2080                               u32 counter)
2081 {
2082   vat_main_t *vam = &vat_main;
2083   static u64 default_counter = 0;
2084
2085   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2086                            NULL);
2087   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2088                            sw_if_index, default_counter);
2089   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2090 }
2091
2092 static void
2093 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2094                                 interface_counter_t counter)
2095 {
2096   vat_main_t *vam = &vat_main;
2097   static interface_counter_t default_counter = { 0, };
2098
2099   vec_validate_init_empty (vam->combined_interface_counters,
2100                            vnet_counter_type, NULL);
2101   vec_validate_init_empty (vam->combined_interface_counters
2102                            [vnet_counter_type], sw_if_index, default_counter);
2103   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2104 }
2105
2106 static void vl_api_vnet_interface_simple_counters_t_handler
2107   (vl_api_vnet_interface_simple_counters_t * mp)
2108 {
2109   /* not supported */
2110 }
2111
2112 static void vl_api_vnet_interface_combined_counters_t_handler
2113   (vl_api_vnet_interface_combined_counters_t * mp)
2114 {
2115   /* not supported */
2116 }
2117
2118 static void vl_api_vnet_interface_simple_counters_t_handler_json
2119   (vl_api_vnet_interface_simple_counters_t * mp)
2120 {
2121   u64 *v_packets;
2122   u64 packets;
2123   u32 count;
2124   u32 first_sw_if_index;
2125   int i;
2126
2127   count = ntohl (mp->count);
2128   first_sw_if_index = ntohl (mp->first_sw_if_index);
2129
2130   v_packets = (u64 *) & mp->data;
2131   for (i = 0; i < count; i++)
2132     {
2133       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2134       set_simple_interface_counter (mp->vnet_counter_type,
2135                                     first_sw_if_index + i, packets);
2136       v_packets++;
2137     }
2138 }
2139
2140 static void vl_api_vnet_interface_combined_counters_t_handler_json
2141   (vl_api_vnet_interface_combined_counters_t * mp)
2142 {
2143   interface_counter_t counter;
2144   vlib_counter_t *v;
2145   u32 first_sw_if_index;
2146   int i;
2147   u32 count;
2148
2149   count = ntohl (mp->count);
2150   first_sw_if_index = ntohl (mp->first_sw_if_index);
2151
2152   v = (vlib_counter_t *) & mp->data;
2153   for (i = 0; i < count; i++)
2154     {
2155       counter.packets =
2156         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2157       counter.bytes =
2158         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2159       set_combined_interface_counter (mp->vnet_counter_type,
2160                                       first_sw_if_index + i, counter);
2161       v++;
2162     }
2163 }
2164
2165 static u32
2166 ip4_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->ip4_fib_counters_vrf_id_by_index); i++)
2172     {
2173       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2174         {
2175           return i;
2176         }
2177     }
2178   return ~0;
2179 }
2180
2181 static u32
2182 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   u32 i;
2186
2187   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2188     {
2189       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2190         {
2191           return i;
2192         }
2193     }
2194   return ~0;
2195 }
2196
2197 static void vl_api_vnet_ip4_fib_counters_t_handler
2198   (vl_api_vnet_ip4_fib_counters_t * mp)
2199 {
2200   /* not supported */
2201 }
2202
2203 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2204   (vl_api_vnet_ip4_fib_counters_t * mp)
2205 {
2206   vat_main_t *vam = &vat_main;
2207   vl_api_ip4_fib_counter_t *v;
2208   ip4_fib_counter_t *counter;
2209   struct in_addr ip4;
2210   u32 vrf_id;
2211   u32 vrf_index;
2212   u32 count;
2213   int i;
2214
2215   vrf_id = ntohl (mp->vrf_id);
2216   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2217   if (~0 == vrf_index)
2218     {
2219       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2220       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2221       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2222       vec_validate (vam->ip4_fib_counters, vrf_index);
2223       vam->ip4_fib_counters[vrf_index] = NULL;
2224     }
2225
2226   vec_free (vam->ip4_fib_counters[vrf_index]);
2227   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2228   count = ntohl (mp->count);
2229   for (i = 0; i < count; i++)
2230     {
2231       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2232       counter = &vam->ip4_fib_counters[vrf_index][i];
2233       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2234       counter->address = ip4;
2235       counter->address_length = v->address_length;
2236       counter->packets = clib_net_to_host_u64 (v->packets);
2237       counter->bytes = clib_net_to_host_u64 (v->bytes);
2238       v++;
2239     }
2240 }
2241
2242 static void vl_api_vnet_ip4_nbr_counters_t_handler
2243   (vl_api_vnet_ip4_nbr_counters_t * mp)
2244 {
2245   /* not supported */
2246 }
2247
2248 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2249   (vl_api_vnet_ip4_nbr_counters_t * mp)
2250 {
2251   vat_main_t *vam = &vat_main;
2252   vl_api_ip4_nbr_counter_t *v;
2253   ip4_nbr_counter_t *counter;
2254   u32 sw_if_index;
2255   u32 count;
2256   int i;
2257
2258   sw_if_index = ntohl (mp->sw_if_index);
2259   count = ntohl (mp->count);
2260   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2261
2262   if (mp->begin)
2263     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2264
2265   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2266   for (i = 0; i < count; i++)
2267     {
2268       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2269       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2270       counter->address.s_addr = v->address;
2271       counter->packets = clib_net_to_host_u64 (v->packets);
2272       counter->bytes = clib_net_to_host_u64 (v->bytes);
2273       counter->linkt = v->link_type;
2274       v++;
2275     }
2276 }
2277
2278 static void vl_api_vnet_ip6_fib_counters_t_handler
2279   (vl_api_vnet_ip6_fib_counters_t * mp)
2280 {
2281   /* not supported */
2282 }
2283
2284 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2285   (vl_api_vnet_ip6_fib_counters_t * mp)
2286 {
2287   vat_main_t *vam = &vat_main;
2288   vl_api_ip6_fib_counter_t *v;
2289   ip6_fib_counter_t *counter;
2290   struct in6_addr ip6;
2291   u32 vrf_id;
2292   u32 vrf_index;
2293   u32 count;
2294   int i;
2295
2296   vrf_id = ntohl (mp->vrf_id);
2297   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2298   if (~0 == vrf_index)
2299     {
2300       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2301       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2302       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2303       vec_validate (vam->ip6_fib_counters, vrf_index);
2304       vam->ip6_fib_counters[vrf_index] = NULL;
2305     }
2306
2307   vec_free (vam->ip6_fib_counters[vrf_index]);
2308   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2309   count = ntohl (mp->count);
2310   for (i = 0; i < count; i++)
2311     {
2312       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2313       counter = &vam->ip6_fib_counters[vrf_index][i];
2314       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2315       counter->address = ip6;
2316       counter->address_length = v->address_length;
2317       counter->packets = clib_net_to_host_u64 (v->packets);
2318       counter->bytes = clib_net_to_host_u64 (v->bytes);
2319       v++;
2320     }
2321 }
2322
2323 static void vl_api_vnet_ip6_nbr_counters_t_handler
2324   (vl_api_vnet_ip6_nbr_counters_t * mp)
2325 {
2326   /* not supported */
2327 }
2328
2329 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2330   (vl_api_vnet_ip6_nbr_counters_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   vl_api_ip6_nbr_counter_t *v;
2334   ip6_nbr_counter_t *counter;
2335   struct in6_addr ip6;
2336   u32 sw_if_index;
2337   u32 count;
2338   int i;
2339
2340   sw_if_index = ntohl (mp->sw_if_index);
2341   count = ntohl (mp->count);
2342   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2343
2344   if (mp->begin)
2345     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2346
2347   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2348   for (i = 0; i < count; i++)
2349     {
2350       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2351       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2352       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2353       counter->address = ip6;
2354       counter->packets = clib_net_to_host_u64 (v->packets);
2355       counter->bytes = clib_net_to_host_u64 (v->bytes);
2356       v++;
2357     }
2358 }
2359
2360 static void vl_api_get_first_msg_id_reply_t_handler
2361   (vl_api_get_first_msg_id_reply_t * mp)
2362 {
2363   vat_main_t *vam = &vat_main;
2364   i32 retval = ntohl (mp->retval);
2365
2366   if (vam->async_mode)
2367     {
2368       vam->async_errors += (retval < 0);
2369     }
2370   else
2371     {
2372       vam->retval = retval;
2373       vam->result_ready = 1;
2374     }
2375   if (retval >= 0)
2376     {
2377       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2378     }
2379 }
2380
2381 static void vl_api_get_first_msg_id_reply_t_handler_json
2382   (vl_api_get_first_msg_id_reply_t * mp)
2383 {
2384   vat_main_t *vam = &vat_main;
2385   vat_json_node_t node;
2386
2387   vat_json_init_object (&node);
2388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2389   vat_json_object_add_uint (&node, "first_msg_id",
2390                             (uint) ntohs (mp->first_msg_id));
2391
2392   vat_json_print (vam->ofp, &node);
2393   vat_json_free (&node);
2394
2395   vam->retval = ntohl (mp->retval);
2396   vam->result_ready = 1;
2397 }
2398
2399 static void vl_api_get_node_graph_reply_t_handler
2400   (vl_api_get_node_graph_reply_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   api_main_t *am = &api_main;
2404   i32 retval = ntohl (mp->retval);
2405   u8 *pvt_copy, *reply;
2406   void *oldheap;
2407   vlib_node_t *node;
2408   int i;
2409
2410   if (vam->async_mode)
2411     {
2412       vam->async_errors += (retval < 0);
2413     }
2414   else
2415     {
2416       vam->retval = retval;
2417       vam->result_ready = 1;
2418     }
2419
2420   /* "Should never happen..." */
2421   if (retval != 0)
2422     return;
2423
2424   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2425   pvt_copy = vec_dup (reply);
2426
2427   /* Toss the shared-memory original... */
2428   pthread_mutex_lock (&am->vlib_rp->mutex);
2429   oldheap = svm_push_data_heap (am->vlib_rp);
2430
2431   vec_free (reply);
2432
2433   svm_pop_heap (oldheap);
2434   pthread_mutex_unlock (&am->vlib_rp->mutex);
2435
2436   if (vam->graph_nodes)
2437     {
2438       hash_free (vam->graph_node_index_by_name);
2439
2440       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2441         {
2442           node = vam->graph_nodes[i];
2443           vec_free (node->name);
2444           vec_free (node->next_nodes);
2445           vec_free (node);
2446         }
2447       vec_free (vam->graph_nodes);
2448     }
2449
2450   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2451   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2452   vec_free (pvt_copy);
2453
2454   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2455     {
2456       node = vam->graph_nodes[i];
2457       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2458     }
2459 }
2460
2461 static void vl_api_get_node_graph_reply_t_handler_json
2462   (vl_api_get_node_graph_reply_t * mp)
2463 {
2464   vat_main_t *vam = &vat_main;
2465   api_main_t *am = &api_main;
2466   void *oldheap;
2467   vat_json_node_t node;
2468   u8 *reply;
2469
2470   /* $$$$ make this real? */
2471   vat_json_init_object (&node);
2472   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2473   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2474
2475   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2476
2477   /* Toss the shared-memory original... */
2478   pthread_mutex_lock (&am->vlib_rp->mutex);
2479   oldheap = svm_push_data_heap (am->vlib_rp);
2480
2481   vec_free (reply);
2482
2483   svm_pop_heap (oldheap);
2484   pthread_mutex_unlock (&am->vlib_rp->mutex);
2485
2486   vat_json_print (vam->ofp, &node);
2487   vat_json_free (&node);
2488
2489   vam->retval = ntohl (mp->retval);
2490   vam->result_ready = 1;
2491 }
2492
2493 static void
2494 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2495 {
2496   vat_main_t *vam = &vat_main;
2497   u8 *s = 0;
2498
2499   if (mp->local)
2500     {
2501       s = format (s, "%=16d%=16d%=16d",
2502                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2503     }
2504   else
2505     {
2506       s = format (s, "%=16U%=16d%=16d",
2507                   mp->is_ipv6 ? format_ip6_address :
2508                   format_ip4_address,
2509                   mp->ip_address, mp->priority, mp->weight);
2510     }
2511
2512   print (vam->ofp, "%v", s);
2513   vec_free (s);
2514 }
2515
2516 static void
2517 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2518 {
2519   vat_main_t *vam = &vat_main;
2520   vat_json_node_t *node = NULL;
2521   struct in6_addr ip6;
2522   struct in_addr ip4;
2523
2524   if (VAT_JSON_ARRAY != vam->json_tree.type)
2525     {
2526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2527       vat_json_init_array (&vam->json_tree);
2528     }
2529   node = vat_json_array_add (&vam->json_tree);
2530   vat_json_init_object (node);
2531
2532   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2533   vat_json_object_add_uint (node, "priority", mp->priority);
2534   vat_json_object_add_uint (node, "weight", mp->weight);
2535
2536   if (mp->local)
2537     vat_json_object_add_uint (node, "sw_if_index",
2538                               clib_net_to_host_u32 (mp->sw_if_index));
2539   else
2540     {
2541       if (mp->is_ipv6)
2542         {
2543           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2544           vat_json_object_add_ip6 (node, "address", ip6);
2545         }
2546       else
2547         {
2548           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2549           vat_json_object_add_ip4 (node, "address", ip4);
2550         }
2551     }
2552 }
2553
2554 static void
2555 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2556                                           mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   u8 *ls_name = 0;
2560
2561   ls_name = format (0, "%s", mp->ls_name);
2562
2563   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2564          ls_name);
2565   vec_free (ls_name);
2566 }
2567
2568 static void
2569   vl_api_one_locator_set_details_t_handler_json
2570   (vl_api_one_locator_set_details_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t *node = 0;
2574   u8 *ls_name = 0;
2575
2576   ls_name = format (0, "%s", mp->ls_name);
2577   vec_add1 (ls_name, 0);
2578
2579   if (VAT_JSON_ARRAY != vam->json_tree.type)
2580     {
2581       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2582       vat_json_init_array (&vam->json_tree);
2583     }
2584   node = vat_json_array_add (&vam->json_tree);
2585
2586   vat_json_init_object (node);
2587   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2588   vat_json_object_add_uint (node, "ls_index",
2589                             clib_net_to_host_u32 (mp->ls_index));
2590   vec_free (ls_name);
2591 }
2592
2593 static u8 *
2594 format_lisp_flat_eid (u8 * s, va_list * args)
2595 {
2596   u32 type = va_arg (*args, u32);
2597   u8 *eid = va_arg (*args, u8 *);
2598   u32 eid_len = va_arg (*args, u32);
2599
2600   switch (type)
2601     {
2602     case 0:
2603       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2604     case 1:
2605       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2606     case 2:
2607       return format (s, "%U", format_ethernet_address, eid);
2608     }
2609   return 0;
2610 }
2611
2612 static u8 *
2613 format_lisp_eid_vat (u8 * s, va_list * args)
2614 {
2615   u32 type = va_arg (*args, u32);
2616   u8 *eid = va_arg (*args, u8 *);
2617   u32 eid_len = va_arg (*args, u32);
2618   u8 *seid = va_arg (*args, u8 *);
2619   u32 seid_len = va_arg (*args, u32);
2620   u32 is_src_dst = va_arg (*args, u32);
2621
2622   if (is_src_dst)
2623     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2624
2625   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2626
2627   return s;
2628 }
2629
2630 static void
2631 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2632 {
2633   vat_main_t *vam = &vat_main;
2634   u8 *s = 0, *eid = 0;
2635
2636   if (~0 == mp->locator_set_index)
2637     s = format (0, "action: %d", mp->action);
2638   else
2639     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2640
2641   eid = format (0, "%U", format_lisp_eid_vat,
2642                 mp->eid_type,
2643                 mp->eid,
2644                 mp->eid_prefix_len,
2645                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2646   vec_add1 (eid, 0);
2647
2648   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2649          clib_net_to_host_u32 (mp->vni),
2650          eid,
2651          mp->is_local ? "local" : "remote",
2652          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2653          clib_net_to_host_u16 (mp->key_id), mp->key);
2654
2655   vec_free (s);
2656   vec_free (eid);
2657 }
2658
2659 static void
2660 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2661                                              * mp)
2662 {
2663   vat_main_t *vam = &vat_main;
2664   vat_json_node_t *node = 0;
2665   u8 *eid = 0;
2666
2667   if (VAT_JSON_ARRAY != vam->json_tree.type)
2668     {
2669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2670       vat_json_init_array (&vam->json_tree);
2671     }
2672   node = vat_json_array_add (&vam->json_tree);
2673
2674   vat_json_init_object (node);
2675   if (~0 == mp->locator_set_index)
2676     vat_json_object_add_uint (node, "action", mp->action);
2677   else
2678     vat_json_object_add_uint (node, "locator_set_index",
2679                               clib_net_to_host_u32 (mp->locator_set_index));
2680
2681   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2682   eid = format (0, "%U", format_lisp_eid_vat,
2683                 mp->eid_type,
2684                 mp->eid,
2685                 mp->eid_prefix_len,
2686                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2687   vec_add1 (eid, 0);
2688   vat_json_object_add_string_copy (node, "eid", eid);
2689   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2690   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2691   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2692
2693   if (mp->key_id)
2694     {
2695       vat_json_object_add_uint (node, "key_id",
2696                                 clib_net_to_host_u16 (mp->key_id));
2697       vat_json_object_add_string_copy (node, "key", mp->key);
2698     }
2699   vec_free (eid);
2700 }
2701
2702 static void
2703 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   u8 *seid = 0, *deid = 0;
2707   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2708
2709   deid = format (0, "%U", format_lisp_eid_vat,
2710                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2711
2712   seid = format (0, "%U", format_lisp_eid_vat,
2713                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2714
2715   vec_add1 (deid, 0);
2716   vec_add1 (seid, 0);
2717
2718   if (mp->is_ip4)
2719     format_ip_address_fcn = format_ip4_address;
2720   else
2721     format_ip_address_fcn = format_ip6_address;
2722
2723
2724   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2725          clib_net_to_host_u32 (mp->vni),
2726          seid, deid,
2727          format_ip_address_fcn, mp->lloc,
2728          format_ip_address_fcn, mp->rloc,
2729          clib_net_to_host_u32 (mp->pkt_count),
2730          clib_net_to_host_u32 (mp->bytes));
2731
2732   vec_free (deid);
2733   vec_free (seid);
2734 }
2735
2736 static void
2737 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2738 {
2739   struct in6_addr ip6;
2740   struct in_addr ip4;
2741   vat_main_t *vam = &vat_main;
2742   vat_json_node_t *node = 0;
2743   u8 *deid = 0, *seid = 0;
2744
2745   if (VAT_JSON_ARRAY != vam->json_tree.type)
2746     {
2747       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2748       vat_json_init_array (&vam->json_tree);
2749     }
2750   node = vat_json_array_add (&vam->json_tree);
2751
2752   vat_json_init_object (node);
2753   deid = format (0, "%U", format_lisp_eid_vat,
2754                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2755
2756   seid = format (0, "%U", format_lisp_eid_vat,
2757                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2758
2759   vec_add1 (deid, 0);
2760   vec_add1 (seid, 0);
2761
2762   vat_json_object_add_string_copy (node, "seid", seid);
2763   vat_json_object_add_string_copy (node, "deid", deid);
2764   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2765
2766   if (mp->is_ip4)
2767     {
2768       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2769       vat_json_object_add_ip4 (node, "lloc", ip4);
2770       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2771       vat_json_object_add_ip4 (node, "rloc", ip4);
2772     }
2773   else
2774     {
2775       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2776       vat_json_object_add_ip6 (node, "lloc", ip6);
2777       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2778       vat_json_object_add_ip6 (node, "rloc", ip6);
2779     }
2780   vat_json_object_add_uint (node, "pkt_count",
2781                             clib_net_to_host_u32 (mp->pkt_count));
2782   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2783
2784   vec_free (deid);
2785   vec_free (seid);
2786 }
2787
2788 static void
2789   vl_api_one_eid_table_map_details_t_handler
2790   (vl_api_one_eid_table_map_details_t * mp)
2791 {
2792   vat_main_t *vam = &vat_main;
2793
2794   u8 *line = format (0, "%=10d%=10d",
2795                      clib_net_to_host_u32 (mp->vni),
2796                      clib_net_to_host_u32 (mp->dp_table));
2797   print (vam->ofp, "%v", line);
2798   vec_free (line);
2799 }
2800
2801 static void
2802   vl_api_one_eid_table_map_details_t_handler_json
2803   (vl_api_one_eid_table_map_details_t * mp)
2804 {
2805   vat_main_t *vam = &vat_main;
2806   vat_json_node_t *node = NULL;
2807
2808   if (VAT_JSON_ARRAY != vam->json_tree.type)
2809     {
2810       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2811       vat_json_init_array (&vam->json_tree);
2812     }
2813   node = vat_json_array_add (&vam->json_tree);
2814   vat_json_init_object (node);
2815   vat_json_object_add_uint (node, "dp_table",
2816                             clib_net_to_host_u32 (mp->dp_table));
2817   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2818 }
2819
2820 static void
2821   vl_api_one_eid_table_vni_details_t_handler
2822   (vl_api_one_eid_table_vni_details_t * mp)
2823 {
2824   vat_main_t *vam = &vat_main;
2825
2826   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2827   print (vam->ofp, "%v", line);
2828   vec_free (line);
2829 }
2830
2831 static void
2832   vl_api_one_eid_table_vni_details_t_handler_json
2833   (vl_api_one_eid_table_vni_details_t * mp)
2834 {
2835   vat_main_t *vam = &vat_main;
2836   vat_json_node_t *node = NULL;
2837
2838   if (VAT_JSON_ARRAY != vam->json_tree.type)
2839     {
2840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2841       vat_json_init_array (&vam->json_tree);
2842     }
2843   node = vat_json_array_add (&vam->json_tree);
2844   vat_json_init_object (node);
2845   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2846 }
2847
2848 static void
2849   vl_api_show_one_map_register_state_reply_t_handler
2850   (vl_api_show_one_map_register_state_reply_t * mp)
2851 {
2852   vat_main_t *vam = &vat_main;
2853   int retval = clib_net_to_host_u32 (mp->retval);
2854
2855   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2856
2857   vam->retval = retval;
2858   vam->result_ready = 1;
2859 }
2860
2861 static void
2862   vl_api_show_one_map_register_state_reply_t_handler_json
2863   (vl_api_show_one_map_register_state_reply_t * mp)
2864 {
2865   vat_main_t *vam = &vat_main;
2866   vat_json_node_t _node, *node = &_node;
2867   int retval = clib_net_to_host_u32 (mp->retval);
2868
2869   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2870
2871   vat_json_init_object (node);
2872   vat_json_object_add_string_copy (node, "state", s);
2873
2874   vat_json_print (vam->ofp, node);
2875   vat_json_free (node);
2876
2877   vam->retval = retval;
2878   vam->result_ready = 1;
2879   vec_free (s);
2880 }
2881
2882 static void
2883   vl_api_show_one_rloc_probe_state_reply_t_handler
2884   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2885 {
2886   vat_main_t *vam = &vat_main;
2887   int retval = clib_net_to_host_u32 (mp->retval);
2888
2889   if (retval)
2890     goto end;
2891
2892   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2893 end:
2894   vam->retval = retval;
2895   vam->result_ready = 1;
2896 }
2897
2898 static void
2899   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2900   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2901 {
2902   vat_main_t *vam = &vat_main;
2903   vat_json_node_t _node, *node = &_node;
2904   int retval = clib_net_to_host_u32 (mp->retval);
2905
2906   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2907   vat_json_init_object (node);
2908   vat_json_object_add_string_copy (node, "state", s);
2909
2910   vat_json_print (vam->ofp, node);
2911   vat_json_free (node);
2912
2913   vam->retval = retval;
2914   vam->result_ready = 1;
2915   vec_free (s);
2916 }
2917
2918 static void
2919   vl_api_show_one_stats_enable_disable_reply_t_handler
2920   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2921 {
2922   vat_main_t *vam = &vat_main;
2923   int retval = clib_net_to_host_u32 (mp->retval);
2924
2925   if (retval)
2926     goto end;
2927
2928   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2929 end:
2930   vam->retval = retval;
2931   vam->result_ready = 1;
2932 }
2933
2934 static void
2935   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2936   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2937 {
2938   vat_main_t *vam = &vat_main;
2939   vat_json_node_t _node, *node = &_node;
2940   int retval = clib_net_to_host_u32 (mp->retval);
2941
2942   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2943   vat_json_init_object (node);
2944   vat_json_object_add_string_copy (node, "state", s);
2945
2946   vat_json_print (vam->ofp, node);
2947   vat_json_free (node);
2948
2949   vam->retval = retval;
2950   vam->result_ready = 1;
2951   vec_free (s);
2952 }
2953
2954 static void
2955 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2956 {
2957   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2958   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2959   e->vni = clib_net_to_host_u32 (e->vni);
2960 }
2961
2962 static void
2963   gpe_fwd_entries_get_reply_t_net_to_host
2964   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2965 {
2966   u32 i;
2967
2968   mp->count = clib_net_to_host_u32 (mp->count);
2969   for (i = 0; i < mp->count; i++)
2970     {
2971       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2972     }
2973 }
2974
2975 static u8 *
2976 format_gpe_encap_mode (u8 * s, va_list * args)
2977 {
2978   u32 mode = va_arg (*args, u32);
2979
2980   switch (mode)
2981     {
2982     case 0:
2983       return format (s, "lisp");
2984     case 1:
2985       return format (s, "vxlan");
2986     }
2987   return 0;
2988 }
2989
2990 static void
2991   vl_api_gpe_get_encap_mode_reply_t_handler
2992   (vl_api_gpe_get_encap_mode_reply_t * mp)
2993 {
2994   vat_main_t *vam = &vat_main;
2995
2996   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2997   vam->retval = ntohl (mp->retval);
2998   vam->result_ready = 1;
2999 }
3000
3001 static void
3002   vl_api_gpe_get_encap_mode_reply_t_handler_json
3003   (vl_api_gpe_get_encap_mode_reply_t * mp)
3004 {
3005   vat_main_t *vam = &vat_main;
3006   vat_json_node_t node;
3007
3008   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3009   vec_add1 (encap_mode, 0);
3010
3011   vat_json_init_object (&node);
3012   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3013
3014   vec_free (encap_mode);
3015   vat_json_print (vam->ofp, &node);
3016   vat_json_free (&node);
3017
3018   vam->retval = ntohl (mp->retval);
3019   vam->result_ready = 1;
3020 }
3021
3022 static void
3023   vl_api_gpe_fwd_entry_path_details_t_handler
3024   (vl_api_gpe_fwd_entry_path_details_t * mp)
3025 {
3026   vat_main_t *vam = &vat_main;
3027   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3028
3029   if (mp->lcl_loc.is_ip4)
3030     format_ip_address_fcn = format_ip4_address;
3031   else
3032     format_ip_address_fcn = format_ip6_address;
3033
3034   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3035          format_ip_address_fcn, &mp->lcl_loc,
3036          format_ip_address_fcn, &mp->rmt_loc);
3037 }
3038
3039 static void
3040 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3041 {
3042   struct in6_addr ip6;
3043   struct in_addr ip4;
3044
3045   if (loc->is_ip4)
3046     {
3047       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3048       vat_json_object_add_ip4 (n, "address", ip4);
3049     }
3050   else
3051     {
3052       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3053       vat_json_object_add_ip6 (n, "address", ip6);
3054     }
3055   vat_json_object_add_uint (n, "weight", loc->weight);
3056 }
3057
3058 static void
3059   vl_api_gpe_fwd_entry_path_details_t_handler_json
3060   (vl_api_gpe_fwd_entry_path_details_t * mp)
3061 {
3062   vat_main_t *vam = &vat_main;
3063   vat_json_node_t *node = NULL;
3064   vat_json_node_t *loc_node;
3065
3066   if (VAT_JSON_ARRAY != vam->json_tree.type)
3067     {
3068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3069       vat_json_init_array (&vam->json_tree);
3070     }
3071   node = vat_json_array_add (&vam->json_tree);
3072   vat_json_init_object (node);
3073
3074   loc_node = vat_json_object_add (node, "local_locator");
3075   vat_json_init_object (loc_node);
3076   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3077
3078   loc_node = vat_json_object_add (node, "remote_locator");
3079   vat_json_init_object (loc_node);
3080   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3081 }
3082
3083 static void
3084   vl_api_gpe_fwd_entries_get_reply_t_handler
3085   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   u32 i;
3089   int retval = clib_net_to_host_u32 (mp->retval);
3090   vl_api_gpe_fwd_entry_t *e;
3091
3092   if (retval)
3093     goto end;
3094
3095   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3096
3097   for (i = 0; i < mp->count; i++)
3098     {
3099       e = &mp->entries[i];
3100       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3101              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3102              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3103     }
3104
3105 end:
3106   vam->retval = retval;
3107   vam->result_ready = 1;
3108 }
3109
3110 static void
3111   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3112   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3113 {
3114   u8 *s = 0;
3115   vat_main_t *vam = &vat_main;
3116   vat_json_node_t *e = 0, root;
3117   u32 i;
3118   int retval = clib_net_to_host_u32 (mp->retval);
3119   vl_api_gpe_fwd_entry_t *fwd;
3120
3121   if (retval)
3122     goto end;
3123
3124   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3125   vat_json_init_array (&root);
3126
3127   for (i = 0; i < mp->count; i++)
3128     {
3129       e = vat_json_array_add (&root);
3130       fwd = &mp->entries[i];
3131
3132       vat_json_init_object (e);
3133       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3134       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3135       vat_json_object_add_int (e, "vni", fwd->vni);
3136       vat_json_object_add_int (e, "action", fwd->action);
3137
3138       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3139                   fwd->leid_prefix_len);
3140       vec_add1 (s, 0);
3141       vat_json_object_add_string_copy (e, "leid", s);
3142       vec_free (s);
3143
3144       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3145                   fwd->reid_prefix_len);
3146       vec_add1 (s, 0);
3147       vat_json_object_add_string_copy (e, "reid", s);
3148       vec_free (s);
3149     }
3150
3151   vat_json_print (vam->ofp, &root);
3152   vat_json_free (&root);
3153
3154 end:
3155   vam->retval = retval;
3156   vam->result_ready = 1;
3157 }
3158
3159 static void
3160   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3161   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3162 {
3163   vat_main_t *vam = &vat_main;
3164   u32 i, n;
3165   int retval = clib_net_to_host_u32 (mp->retval);
3166
3167   if (retval)
3168     goto end;
3169
3170   n = clib_net_to_host_u32 (mp->count);
3171
3172   for (i = 0; i < n; i++)
3173     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3174
3175 end:
3176   vam->retval = retval;
3177   vam->result_ready = 1;
3178 }
3179
3180 static void
3181   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3182   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3183 {
3184   vat_main_t *vam = &vat_main;
3185   vat_json_node_t root;
3186   u32 i, n;
3187   int retval = clib_net_to_host_u32 (mp->retval);
3188
3189   if (retval)
3190     goto end;
3191
3192   n = clib_net_to_host_u32 (mp->count);
3193   vat_json_init_array (&root);
3194
3195   for (i = 0; i < n; i++)
3196     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3197
3198   vat_json_print (vam->ofp, &root);
3199   vat_json_free (&root);
3200
3201 end:
3202   vam->retval = retval;
3203   vam->result_ready = 1;
3204 }
3205
3206 static void
3207   vl_api_one_adjacencies_get_reply_t_handler
3208   (vl_api_one_adjacencies_get_reply_t * mp)
3209 {
3210   vat_main_t *vam = &vat_main;
3211   u32 i, n;
3212   int retval = clib_net_to_host_u32 (mp->retval);
3213   vl_api_one_adjacency_t *a;
3214
3215   if (retval)
3216     goto end;
3217
3218   n = clib_net_to_host_u32 (mp->count);
3219
3220   for (i = 0; i < n; i++)
3221     {
3222       a = &mp->adjacencies[i];
3223       print (vam->ofp, "%U %40U",
3224              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3225              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3226     }
3227
3228 end:
3229   vam->retval = retval;
3230   vam->result_ready = 1;
3231 }
3232
3233 static void
3234   vl_api_one_adjacencies_get_reply_t_handler_json
3235   (vl_api_one_adjacencies_get_reply_t * mp)
3236 {
3237   u8 *s = 0;
3238   vat_main_t *vam = &vat_main;
3239   vat_json_node_t *e = 0, root;
3240   u32 i, n;
3241   int retval = clib_net_to_host_u32 (mp->retval);
3242   vl_api_one_adjacency_t *a;
3243
3244   if (retval)
3245     goto end;
3246
3247   n = clib_net_to_host_u32 (mp->count);
3248   vat_json_init_array (&root);
3249
3250   for (i = 0; i < n; i++)
3251     {
3252       e = vat_json_array_add (&root);
3253       a = &mp->adjacencies[i];
3254
3255       vat_json_init_object (e);
3256       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3257                   a->leid_prefix_len);
3258       vec_add1 (s, 0);
3259       vat_json_object_add_string_copy (e, "leid", s);
3260       vec_free (s);
3261
3262       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3263                   a->reid_prefix_len);
3264       vec_add1 (s, 0);
3265       vat_json_object_add_string_copy (e, "reid", s);
3266       vec_free (s);
3267     }
3268
3269   vat_json_print (vam->ofp, &root);
3270   vat_json_free (&root);
3271
3272 end:
3273   vam->retval = retval;
3274   vam->result_ready = 1;
3275 }
3276
3277 static void
3278 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281
3282   print (vam->ofp, "%=20U",
3283          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3284          mp->ip_address);
3285 }
3286
3287 static void
3288   vl_api_one_map_server_details_t_handler_json
3289   (vl_api_one_map_server_details_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   vat_json_node_t *node = NULL;
3293   struct in6_addr ip6;
3294   struct in_addr ip4;
3295
3296   if (VAT_JSON_ARRAY != vam->json_tree.type)
3297     {
3298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3299       vat_json_init_array (&vam->json_tree);
3300     }
3301   node = vat_json_array_add (&vam->json_tree);
3302
3303   vat_json_init_object (node);
3304   if (mp->is_ipv6)
3305     {
3306       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3307       vat_json_object_add_ip6 (node, "map-server", ip6);
3308     }
3309   else
3310     {
3311       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3312       vat_json_object_add_ip4 (node, "map-server", ip4);
3313     }
3314 }
3315
3316 static void
3317 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3318                                            * mp)
3319 {
3320   vat_main_t *vam = &vat_main;
3321
3322   print (vam->ofp, "%=20U",
3323          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3324          mp->ip_address);
3325 }
3326
3327 static void
3328   vl_api_one_map_resolver_details_t_handler_json
3329   (vl_api_one_map_resolver_details_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332   vat_json_node_t *node = NULL;
3333   struct in6_addr ip6;
3334   struct in_addr ip4;
3335
3336   if (VAT_JSON_ARRAY != vam->json_tree.type)
3337     {
3338       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3339       vat_json_init_array (&vam->json_tree);
3340     }
3341   node = vat_json_array_add (&vam->json_tree);
3342
3343   vat_json_init_object (node);
3344   if (mp->is_ipv6)
3345     {
3346       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3347       vat_json_object_add_ip6 (node, "map resolver", ip6);
3348     }
3349   else
3350     {
3351       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3352       vat_json_object_add_ip4 (node, "map resolver", ip4);
3353     }
3354 }
3355
3356 static void
3357 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3358 {
3359   vat_main_t *vam = &vat_main;
3360   i32 retval = ntohl (mp->retval);
3361
3362   if (0 <= retval)
3363     {
3364       print (vam->ofp, "feature: %s\ngpe: %s",
3365              mp->feature_status ? "enabled" : "disabled",
3366              mp->gpe_status ? "enabled" : "disabled");
3367     }
3368
3369   vam->retval = retval;
3370   vam->result_ready = 1;
3371 }
3372
3373 static void
3374   vl_api_show_one_status_reply_t_handler_json
3375   (vl_api_show_one_status_reply_t * mp)
3376 {
3377   vat_main_t *vam = &vat_main;
3378   vat_json_node_t node;
3379   u8 *gpe_status = NULL;
3380   u8 *feature_status = NULL;
3381
3382   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3383   feature_status = format (0, "%s",
3384                            mp->feature_status ? "enabled" : "disabled");
3385   vec_add1 (gpe_status, 0);
3386   vec_add1 (feature_status, 0);
3387
3388   vat_json_init_object (&node);
3389   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3390   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3391
3392   vec_free (gpe_status);
3393   vec_free (feature_status);
3394
3395   vat_json_print (vam->ofp, &node);
3396   vat_json_free (&node);
3397
3398   vam->retval = ntohl (mp->retval);
3399   vam->result_ready = 1;
3400 }
3401
3402 static void
3403   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3404   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3405 {
3406   vat_main_t *vam = &vat_main;
3407   i32 retval = ntohl (mp->retval);
3408
3409   if (retval >= 0)
3410     {
3411       print (vam->ofp, "%=20s", mp->locator_set_name);
3412     }
3413
3414   vam->retval = retval;
3415   vam->result_ready = 1;
3416 }
3417
3418 static void
3419   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3420   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3421 {
3422   vat_main_t *vam = &vat_main;
3423   vat_json_node_t *node = NULL;
3424
3425   if (VAT_JSON_ARRAY != vam->json_tree.type)
3426     {
3427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3428       vat_json_init_array (&vam->json_tree);
3429     }
3430   node = vat_json_array_add (&vam->json_tree);
3431
3432   vat_json_init_object (node);
3433   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3434
3435   vat_json_print (vam->ofp, node);
3436   vat_json_free (node);
3437
3438   vam->retval = ntohl (mp->retval);
3439   vam->result_ready = 1;
3440 }
3441
3442 static u8 *
3443 format_lisp_map_request_mode (u8 * s, va_list * args)
3444 {
3445   u32 mode = va_arg (*args, u32);
3446
3447   switch (mode)
3448     {
3449     case 0:
3450       return format (0, "dst-only");
3451     case 1:
3452       return format (0, "src-dst");
3453     }
3454   return 0;
3455 }
3456
3457 static void
3458   vl_api_show_one_map_request_mode_reply_t_handler
3459   (vl_api_show_one_map_request_mode_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   i32 retval = ntohl (mp->retval);
3463
3464   if (0 <= retval)
3465     {
3466       u32 mode = mp->mode;
3467       print (vam->ofp, "map_request_mode: %U",
3468              format_lisp_map_request_mode, mode);
3469     }
3470
3471   vam->retval = retval;
3472   vam->result_ready = 1;
3473 }
3474
3475 static void
3476   vl_api_show_one_map_request_mode_reply_t_handler_json
3477   (vl_api_show_one_map_request_mode_reply_t * mp)
3478 {
3479   vat_main_t *vam = &vat_main;
3480   vat_json_node_t node;
3481   u8 *s = 0;
3482   u32 mode;
3483
3484   mode = mp->mode;
3485   s = format (0, "%U", format_lisp_map_request_mode, mode);
3486   vec_add1 (s, 0);
3487
3488   vat_json_init_object (&node);
3489   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3490   vat_json_print (vam->ofp, &node);
3491   vat_json_free (&node);
3492
3493   vec_free (s);
3494   vam->retval = ntohl (mp->retval);
3495   vam->result_ready = 1;
3496 }
3497
3498 static void
3499   vl_api_show_one_use_petr_reply_t_handler
3500   (vl_api_show_one_use_petr_reply_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503   i32 retval = ntohl (mp->retval);
3504
3505   if (0 <= retval)
3506     {
3507       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3508       if (mp->status)
3509         {
3510           print (vam->ofp, "Proxy-ETR address; %U",
3511                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3512                  mp->address);
3513         }
3514     }
3515
3516   vam->retval = retval;
3517   vam->result_ready = 1;
3518 }
3519
3520 static void
3521   vl_api_show_one_use_petr_reply_t_handler_json
3522   (vl_api_show_one_use_petr_reply_t * mp)
3523 {
3524   vat_main_t *vam = &vat_main;
3525   vat_json_node_t node;
3526   u8 *status = 0;
3527   struct in_addr ip4;
3528   struct in6_addr ip6;
3529
3530   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3531   vec_add1 (status, 0);
3532
3533   vat_json_init_object (&node);
3534   vat_json_object_add_string_copy (&node, "status", status);
3535   if (mp->status)
3536     {
3537       if (mp->is_ip4)
3538         {
3539           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3540           vat_json_object_add_ip6 (&node, "address", ip6);
3541         }
3542       else
3543         {
3544           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3545           vat_json_object_add_ip4 (&node, "address", ip4);
3546         }
3547     }
3548
3549   vec_free (status);
3550
3551   vat_json_print (vam->ofp, &node);
3552   vat_json_free (&node);
3553
3554   vam->retval = ntohl (mp->retval);
3555   vam->result_ready = 1;
3556 }
3557
3558 static void
3559 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3560 {
3561   vat_main_t *vam = &vat_main;
3562   i32 retval = ntohl (mp->retval);
3563
3564   if (0 <= retval)
3565     {
3566       print (vam->ofp, "%-20s%-16s",
3567              mp->status ? "enabled" : "disabled",
3568              mp->status ? (char *) mp->locator_set_name : "");
3569     }
3570
3571   vam->retval = retval;
3572   vam->result_ready = 1;
3573 }
3574
3575 static void
3576 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3577 {
3578   vat_main_t *vam = &vat_main;
3579   vat_json_node_t node;
3580   u8 *status = 0;
3581
3582   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3583   vec_add1 (status, 0);
3584
3585   vat_json_init_object (&node);
3586   vat_json_object_add_string_copy (&node, "status", status);
3587   if (mp->status)
3588     {
3589       vat_json_object_add_string_copy (&node, "locator_set",
3590                                        mp->locator_set_name);
3591     }
3592
3593   vec_free (status);
3594
3595   vat_json_print (vam->ofp, &node);
3596   vat_json_free (&node);
3597
3598   vam->retval = ntohl (mp->retval);
3599   vam->result_ready = 1;
3600 }
3601
3602 static u8 *
3603 format_policer_type (u8 * s, va_list * va)
3604 {
3605   u32 i = va_arg (*va, u32);
3606
3607   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3608     s = format (s, "1r2c");
3609   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3610     s = format (s, "1r3c");
3611   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3612     s = format (s, "2r3c-2698");
3613   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3614     s = format (s, "2r3c-4115");
3615   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3616     s = format (s, "2r3c-mef5cf1");
3617   else
3618     s = format (s, "ILLEGAL");
3619   return s;
3620 }
3621
3622 static u8 *
3623 format_policer_rate_type (u8 * s, va_list * va)
3624 {
3625   u32 i = va_arg (*va, u32);
3626
3627   if (i == SSE2_QOS_RATE_KBPS)
3628     s = format (s, "kbps");
3629   else if (i == SSE2_QOS_RATE_PPS)
3630     s = format (s, "pps");
3631   else
3632     s = format (s, "ILLEGAL");
3633   return s;
3634 }
3635
3636 static u8 *
3637 format_policer_round_type (u8 * s, va_list * va)
3638 {
3639   u32 i = va_arg (*va, u32);
3640
3641   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3642     s = format (s, "closest");
3643   else if (i == SSE2_QOS_ROUND_TO_UP)
3644     s = format (s, "up");
3645   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3646     s = format (s, "down");
3647   else
3648     s = format (s, "ILLEGAL");
3649   return s;
3650 }
3651
3652 static u8 *
3653 format_policer_action_type (u8 * s, va_list * va)
3654 {
3655   u32 i = va_arg (*va, u32);
3656
3657   if (i == SSE2_QOS_ACTION_DROP)
3658     s = format (s, "drop");
3659   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3660     s = format (s, "transmit");
3661   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3662     s = format (s, "mark-and-transmit");
3663   else
3664     s = format (s, "ILLEGAL");
3665   return s;
3666 }
3667
3668 static u8 *
3669 format_dscp (u8 * s, va_list * va)
3670 {
3671   u32 i = va_arg (*va, u32);
3672   char *t = 0;
3673
3674   switch (i)
3675     {
3676 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3677       foreach_vnet_dscp
3678 #undef _
3679     default:
3680       return format (s, "ILLEGAL");
3681     }
3682   s = format (s, "%s", t);
3683   return s;
3684 }
3685
3686 static void
3687 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3688 {
3689   vat_main_t *vam = &vat_main;
3690   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3691
3692   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3693     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3694   else
3695     conform_dscp_str = format (0, "");
3696
3697   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3698     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3699   else
3700     exceed_dscp_str = format (0, "");
3701
3702   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3703     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3704   else
3705     violate_dscp_str = format (0, "");
3706
3707   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3708          "rate type %U, round type %U, %s rate, %s color-aware, "
3709          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3710          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3711          "conform action %U%s, exceed action %U%s, violate action %U%s",
3712          mp->name,
3713          format_policer_type, mp->type,
3714          ntohl (mp->cir),
3715          ntohl (mp->eir),
3716          clib_net_to_host_u64 (mp->cb),
3717          clib_net_to_host_u64 (mp->eb),
3718          format_policer_rate_type, mp->rate_type,
3719          format_policer_round_type, mp->round_type,
3720          mp->single_rate ? "single" : "dual",
3721          mp->color_aware ? "is" : "not",
3722          ntohl (mp->cir_tokens_per_period),
3723          ntohl (mp->pir_tokens_per_period),
3724          ntohl (mp->scale),
3725          ntohl (mp->current_limit),
3726          ntohl (mp->current_bucket),
3727          ntohl (mp->extended_limit),
3728          ntohl (mp->extended_bucket),
3729          clib_net_to_host_u64 (mp->last_update_time),
3730          format_policer_action_type, mp->conform_action_type,
3731          conform_dscp_str,
3732          format_policer_action_type, mp->exceed_action_type,
3733          exceed_dscp_str,
3734          format_policer_action_type, mp->violate_action_type,
3735          violate_dscp_str);
3736
3737   vec_free (conform_dscp_str);
3738   vec_free (exceed_dscp_str);
3739   vec_free (violate_dscp_str);
3740 }
3741
3742 static void vl_api_policer_details_t_handler_json
3743   (vl_api_policer_details_t * mp)
3744 {
3745   vat_main_t *vam = &vat_main;
3746   vat_json_node_t *node;
3747   u8 *rate_type_str, *round_type_str, *type_str;
3748   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3749
3750   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3751   round_type_str =
3752     format (0, "%U", format_policer_round_type, mp->round_type);
3753   type_str = format (0, "%U", format_policer_type, mp->type);
3754   conform_action_str = format (0, "%U", format_policer_action_type,
3755                                mp->conform_action_type);
3756   exceed_action_str = format (0, "%U", format_policer_action_type,
3757                               mp->exceed_action_type);
3758   violate_action_str = format (0, "%U", format_policer_action_type,
3759                                mp->violate_action_type);
3760
3761   if (VAT_JSON_ARRAY != vam->json_tree.type)
3762     {
3763       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3764       vat_json_init_array (&vam->json_tree);
3765     }
3766   node = vat_json_array_add (&vam->json_tree);
3767
3768   vat_json_init_object (node);
3769   vat_json_object_add_string_copy (node, "name", mp->name);
3770   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3771   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3772   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3773   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3774   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3775   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3776   vat_json_object_add_string_copy (node, "type", type_str);
3777   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3778   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3779   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3780   vat_json_object_add_uint (node, "cir_tokens_per_period",
3781                             ntohl (mp->cir_tokens_per_period));
3782   vat_json_object_add_uint (node, "eir_tokens_per_period",
3783                             ntohl (mp->pir_tokens_per_period));
3784   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3785   vat_json_object_add_uint (node, "current_bucket",
3786                             ntohl (mp->current_bucket));
3787   vat_json_object_add_uint (node, "extended_limit",
3788                             ntohl (mp->extended_limit));
3789   vat_json_object_add_uint (node, "extended_bucket",
3790                             ntohl (mp->extended_bucket));
3791   vat_json_object_add_uint (node, "last_update_time",
3792                             ntohl (mp->last_update_time));
3793   vat_json_object_add_string_copy (node, "conform_action",
3794                                    conform_action_str);
3795   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3796     {
3797       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3798       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3799       vec_free (dscp_str);
3800     }
3801   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3802   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3803     {
3804       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3805       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3806       vec_free (dscp_str);
3807     }
3808   vat_json_object_add_string_copy (node, "violate_action",
3809                                    violate_action_str);
3810   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3811     {
3812       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3813       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3814       vec_free (dscp_str);
3815     }
3816
3817   vec_free (rate_type_str);
3818   vec_free (round_type_str);
3819   vec_free (type_str);
3820   vec_free (conform_action_str);
3821   vec_free (exceed_action_str);
3822   vec_free (violate_action_str);
3823 }
3824
3825 static void
3826 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3827                                            mp)
3828 {
3829   vat_main_t *vam = &vat_main;
3830   int i, count = ntohl (mp->count);
3831
3832   if (count > 0)
3833     print (vam->ofp, "classify table ids (%d) : ", count);
3834   for (i = 0; i < count; i++)
3835     {
3836       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3837       print (vam->ofp, (i < count - 1) ? "," : "");
3838     }
3839   vam->retval = ntohl (mp->retval);
3840   vam->result_ready = 1;
3841 }
3842
3843 static void
3844   vl_api_classify_table_ids_reply_t_handler_json
3845   (vl_api_classify_table_ids_reply_t * mp)
3846 {
3847   vat_main_t *vam = &vat_main;
3848   int i, count = ntohl (mp->count);
3849
3850   if (count > 0)
3851     {
3852       vat_json_node_t node;
3853
3854       vat_json_init_object (&node);
3855       for (i = 0; i < count; i++)
3856         {
3857           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3858         }
3859       vat_json_print (vam->ofp, &node);
3860       vat_json_free (&node);
3861     }
3862   vam->retval = ntohl (mp->retval);
3863   vam->result_ready = 1;
3864 }
3865
3866 static void
3867   vl_api_classify_table_by_interface_reply_t_handler
3868   (vl_api_classify_table_by_interface_reply_t * mp)
3869 {
3870   vat_main_t *vam = &vat_main;
3871   u32 table_id;
3872
3873   table_id = ntohl (mp->l2_table_id);
3874   if (table_id != ~0)
3875     print (vam->ofp, "l2 table id : %d", table_id);
3876   else
3877     print (vam->ofp, "l2 table id : No input ACL tables configured");
3878   table_id = ntohl (mp->ip4_table_id);
3879   if (table_id != ~0)
3880     print (vam->ofp, "ip4 table id : %d", table_id);
3881   else
3882     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3883   table_id = ntohl (mp->ip6_table_id);
3884   if (table_id != ~0)
3885     print (vam->ofp, "ip6 table id : %d", table_id);
3886   else
3887     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3888   vam->retval = ntohl (mp->retval);
3889   vam->result_ready = 1;
3890 }
3891
3892 static void
3893   vl_api_classify_table_by_interface_reply_t_handler_json
3894   (vl_api_classify_table_by_interface_reply_t * mp)
3895 {
3896   vat_main_t *vam = &vat_main;
3897   vat_json_node_t node;
3898
3899   vat_json_init_object (&node);
3900
3901   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3902   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3903   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3904
3905   vat_json_print (vam->ofp, &node);
3906   vat_json_free (&node);
3907
3908   vam->retval = ntohl (mp->retval);
3909   vam->result_ready = 1;
3910 }
3911
3912 static void vl_api_policer_add_del_reply_t_handler
3913   (vl_api_policer_add_del_reply_t * mp)
3914 {
3915   vat_main_t *vam = &vat_main;
3916   i32 retval = ntohl (mp->retval);
3917   if (vam->async_mode)
3918     {
3919       vam->async_errors += (retval < 0);
3920     }
3921   else
3922     {
3923       vam->retval = retval;
3924       vam->result_ready = 1;
3925       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3926         /*
3927          * Note: this is just barely thread-safe, depends on
3928          * the main thread spinning waiting for an answer...
3929          */
3930         errmsg ("policer index %d", ntohl (mp->policer_index));
3931     }
3932 }
3933
3934 static void vl_api_policer_add_del_reply_t_handler_json
3935   (vl_api_policer_add_del_reply_t * mp)
3936 {
3937   vat_main_t *vam = &vat_main;
3938   vat_json_node_t node;
3939
3940   vat_json_init_object (&node);
3941   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3942   vat_json_object_add_uint (&node, "policer_index",
3943                             ntohl (mp->policer_index));
3944
3945   vat_json_print (vam->ofp, &node);
3946   vat_json_free (&node);
3947
3948   vam->retval = ntohl (mp->retval);
3949   vam->result_ready = 1;
3950 }
3951
3952 /* Format hex dump. */
3953 u8 *
3954 format_hex_bytes (u8 * s, va_list * va)
3955 {
3956   u8 *bytes = va_arg (*va, u8 *);
3957   int n_bytes = va_arg (*va, int);
3958   uword i;
3959
3960   /* Print short or long form depending on byte count. */
3961   uword short_form = n_bytes <= 32;
3962   uword indent = format_get_indent (s);
3963
3964   if (n_bytes == 0)
3965     return s;
3966
3967   for (i = 0; i < n_bytes; i++)
3968     {
3969       if (!short_form && (i % 32) == 0)
3970         s = format (s, "%08x: ", i);
3971       s = format (s, "%02x", bytes[i]);
3972       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3973         s = format (s, "\n%U", format_white_space, indent);
3974     }
3975
3976   return s;
3977 }
3978
3979 static void
3980 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3981                                             * mp)
3982 {
3983   vat_main_t *vam = &vat_main;
3984   i32 retval = ntohl (mp->retval);
3985   if (retval == 0)
3986     {
3987       print (vam->ofp, "classify table info :");
3988       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3989              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3990              ntohl (mp->miss_next_index));
3991       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3992              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3993              ntohl (mp->match_n_vectors));
3994       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3995              ntohl (mp->mask_length));
3996     }
3997   vam->retval = retval;
3998   vam->result_ready = 1;
3999 }
4000
4001 static void
4002   vl_api_classify_table_info_reply_t_handler_json
4003   (vl_api_classify_table_info_reply_t * mp)
4004 {
4005   vat_main_t *vam = &vat_main;
4006   vat_json_node_t node;
4007
4008   i32 retval = ntohl (mp->retval);
4009   if (retval == 0)
4010     {
4011       vat_json_init_object (&node);
4012
4013       vat_json_object_add_int (&node, "sessions",
4014                                ntohl (mp->active_sessions));
4015       vat_json_object_add_int (&node, "nexttbl",
4016                                ntohl (mp->next_table_index));
4017       vat_json_object_add_int (&node, "nextnode",
4018                                ntohl (mp->miss_next_index));
4019       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4020       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4021       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4022       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4023                       ntohl (mp->mask_length), 0);
4024       vat_json_object_add_string_copy (&node, "mask", s);
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
4034 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4035                                            mp)
4036 {
4037   vat_main_t *vam = &vat_main;
4038
4039   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4040          ntohl (mp->hit_next_index), ntohl (mp->advance),
4041          ntohl (mp->opaque_index));
4042   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4043          ntohl (mp->match_length));
4044 }
4045
4046 static void
4047   vl_api_classify_session_details_t_handler_json
4048   (vl_api_classify_session_details_t * mp)
4049 {
4050   vat_main_t *vam = &vat_main;
4051   vat_json_node_t *node = NULL;
4052
4053   if (VAT_JSON_ARRAY != vam->json_tree.type)
4054     {
4055       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4056       vat_json_init_array (&vam->json_tree);
4057     }
4058   node = vat_json_array_add (&vam->json_tree);
4059
4060   vat_json_init_object (node);
4061   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4062   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4063   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4064   u8 *s =
4065     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4066             0);
4067   vat_json_object_add_string_copy (node, "match", s);
4068 }
4069
4070 static void vl_api_pg_create_interface_reply_t_handler
4071   (vl_api_pg_create_interface_reply_t * mp)
4072 {
4073   vat_main_t *vam = &vat_main;
4074
4075   vam->retval = ntohl (mp->retval);
4076   vam->result_ready = 1;
4077 }
4078
4079 static void vl_api_pg_create_interface_reply_t_handler_json
4080   (vl_api_pg_create_interface_reply_t * mp)
4081 {
4082   vat_main_t *vam = &vat_main;
4083   vat_json_node_t node;
4084
4085   i32 retval = ntohl (mp->retval);
4086   if (retval == 0)
4087     {
4088       vat_json_init_object (&node);
4089
4090       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4091
4092       vat_json_print (vam->ofp, &node);
4093       vat_json_free (&node);
4094     }
4095   vam->retval = ntohl (mp->retval);
4096   vam->result_ready = 1;
4097 }
4098
4099 static void vl_api_policer_classify_details_t_handler
4100   (vl_api_policer_classify_details_t * mp)
4101 {
4102   vat_main_t *vam = &vat_main;
4103
4104   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4105          ntohl (mp->table_index));
4106 }
4107
4108 static void vl_api_policer_classify_details_t_handler_json
4109   (vl_api_policer_classify_details_t * mp)
4110 {
4111   vat_main_t *vam = &vat_main;
4112   vat_json_node_t *node;
4113
4114   if (VAT_JSON_ARRAY != vam->json_tree.type)
4115     {
4116       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4117       vat_json_init_array (&vam->json_tree);
4118     }
4119   node = vat_json_array_add (&vam->json_tree);
4120
4121   vat_json_init_object (node);
4122   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4123   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4124 }
4125
4126 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4127   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4128 {
4129   vat_main_t *vam = &vat_main;
4130   i32 retval = ntohl (mp->retval);
4131   if (vam->async_mode)
4132     {
4133       vam->async_errors += (retval < 0);
4134     }
4135   else
4136     {
4137       vam->retval = retval;
4138       vam->sw_if_index = ntohl (mp->sw_if_index);
4139       vam->result_ready = 1;
4140     }
4141 }
4142
4143 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4144   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4145 {
4146   vat_main_t *vam = &vat_main;
4147   vat_json_node_t node;
4148
4149   vat_json_init_object (&node);
4150   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4151   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4152
4153   vat_json_print (vam->ofp, &node);
4154   vat_json_free (&node);
4155
4156   vam->retval = ntohl (mp->retval);
4157   vam->result_ready = 1;
4158 }
4159
4160 static void vl_api_flow_classify_details_t_handler
4161   (vl_api_flow_classify_details_t * mp)
4162 {
4163   vat_main_t *vam = &vat_main;
4164
4165   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4166          ntohl (mp->table_index));
4167 }
4168
4169 static void vl_api_flow_classify_details_t_handler_json
4170   (vl_api_flow_classify_details_t * mp)
4171 {
4172   vat_main_t *vam = &vat_main;
4173   vat_json_node_t *node;
4174
4175   if (VAT_JSON_ARRAY != vam->json_tree.type)
4176     {
4177       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4178       vat_json_init_array (&vam->json_tree);
4179     }
4180   node = vat_json_array_add (&vam->json_tree);
4181
4182   vat_json_init_object (node);
4183   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4184   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4185 }
4186
4187 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4188 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4189 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4190 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4191 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4192 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4193 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4194 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4195 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4196 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4197 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4198 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4199 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4200 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4201
4202 /*
4203  * Generate boilerplate reply handlers, which
4204  * dig the return value out of the xxx_reply_t API message,
4205  * stick it into vam->retval, and set vam->result_ready
4206  *
4207  * Could also do this by pointing N message decode slots at
4208  * a single function, but that could break in subtle ways.
4209  */
4210
4211 #define foreach_standard_reply_retval_handler           \
4212 _(sw_interface_set_flags_reply)                         \
4213 _(sw_interface_add_del_address_reply)                   \
4214 _(sw_interface_set_table_reply)                         \
4215 _(sw_interface_set_mpls_enable_reply)                   \
4216 _(sw_interface_set_vpath_reply)                         \
4217 _(sw_interface_set_vxlan_bypass_reply)                  \
4218 _(sw_interface_set_l2_bridge_reply)                     \
4219 _(bridge_domain_add_del_reply)                          \
4220 _(sw_interface_set_l2_xconnect_reply)                   \
4221 _(l2fib_add_del_reply)                                  \
4222 _(l2fib_flush_int_reply)                                \
4223 _(l2fib_flush_bd_reply)                                 \
4224 _(ip_add_del_route_reply)                               \
4225 _(ip_mroute_add_del_reply)                              \
4226 _(mpls_route_add_del_reply)                             \
4227 _(mpls_ip_bind_unbind_reply)                            \
4228 _(proxy_arp_add_del_reply)                              \
4229 _(proxy_arp_intfc_enable_disable_reply)                 \
4230 _(sw_interface_set_unnumbered_reply)                    \
4231 _(ip_neighbor_add_del_reply)                            \
4232 _(reset_vrf_reply)                                      \
4233 _(oam_add_del_reply)                                    \
4234 _(reset_fib_reply)                                      \
4235 _(dhcp_proxy_config_reply)                              \
4236 _(dhcp_proxy_set_vss_reply)                             \
4237 _(dhcp_client_config_reply)                             \
4238 _(set_ip_flow_hash_reply)                               \
4239 _(sw_interface_ip6_enable_disable_reply)                \
4240 _(sw_interface_ip6_set_link_local_address_reply)        \
4241 _(ip6nd_proxy_add_del_reply)                            \
4242 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4243 _(sw_interface_ip6nd_ra_config_reply)                   \
4244 _(set_arp_neighbor_limit_reply)                         \
4245 _(l2_patch_add_del_reply)                               \
4246 _(sr_policy_add_reply)                                  \
4247 _(sr_policy_mod_reply)                                  \
4248 _(sr_policy_del_reply)                                  \
4249 _(sr_localsid_add_del_reply)                            \
4250 _(sr_steering_add_del_reply)                            \
4251 _(classify_add_del_session_reply)                       \
4252 _(classify_set_interface_ip_table_reply)                \
4253 _(classify_set_interface_l2_tables_reply)               \
4254 _(l2tpv3_set_tunnel_cookies_reply)                      \
4255 _(l2tpv3_interface_enable_disable_reply)                \
4256 _(l2tpv3_set_lookup_key_reply)                          \
4257 _(l2_fib_clear_table_reply)                             \
4258 _(l2_interface_efp_filter_reply)                        \
4259 _(l2_interface_vlan_tag_rewrite_reply)                  \
4260 _(modify_vhost_user_if_reply)                           \
4261 _(delete_vhost_user_if_reply)                           \
4262 _(want_ip4_arp_events_reply)                            \
4263 _(want_ip6_nd_events_reply)                             \
4264 _(input_acl_set_interface_reply)                        \
4265 _(ipsec_spd_add_del_reply)                              \
4266 _(ipsec_interface_add_del_spd_reply)                    \
4267 _(ipsec_spd_add_del_entry_reply)                        \
4268 _(ipsec_sad_add_del_entry_reply)                        \
4269 _(ipsec_sa_set_key_reply)                               \
4270 _(ipsec_tunnel_if_add_del_reply)                        \
4271 _(ikev2_profile_add_del_reply)                          \
4272 _(ikev2_profile_set_auth_reply)                         \
4273 _(ikev2_profile_set_id_reply)                           \
4274 _(ikev2_profile_set_ts_reply)                           \
4275 _(ikev2_set_local_key_reply)                            \
4276 _(ikev2_set_responder_reply)                            \
4277 _(ikev2_set_ike_transforms_reply)                       \
4278 _(ikev2_set_esp_transforms_reply)                       \
4279 _(ikev2_set_sa_lifetime_reply)                          \
4280 _(ikev2_initiate_sa_init_reply)                         \
4281 _(ikev2_initiate_del_ike_sa_reply)                      \
4282 _(ikev2_initiate_del_child_sa_reply)                    \
4283 _(ikev2_initiate_rekey_child_sa_reply)                  \
4284 _(delete_loopback_reply)                                \
4285 _(bd_ip_mac_add_del_reply)                              \
4286 _(map_del_domain_reply)                                 \
4287 _(map_add_del_rule_reply)                               \
4288 _(want_interface_events_reply)                          \
4289 _(want_stats_reply)                                     \
4290 _(cop_interface_enable_disable_reply)                   \
4291 _(cop_whitelist_enable_disable_reply)                   \
4292 _(sw_interface_clear_stats_reply)                       \
4293 _(ioam_enable_reply)                              \
4294 _(ioam_disable_reply)                              \
4295 _(one_add_del_locator_reply)                            \
4296 _(one_add_del_local_eid_reply)                          \
4297 _(one_add_del_remote_mapping_reply)                     \
4298 _(one_add_del_adjacency_reply)                          \
4299 _(one_add_del_map_resolver_reply)                       \
4300 _(one_add_del_map_server_reply)                         \
4301 _(one_enable_disable_reply)                             \
4302 _(one_rloc_probe_enable_disable_reply)                  \
4303 _(one_map_register_enable_disable_reply)                \
4304 _(one_pitr_set_locator_set_reply)                       \
4305 _(one_map_request_mode_reply)                           \
4306 _(one_add_del_map_request_itr_rlocs_reply)              \
4307 _(one_eid_table_add_del_map_reply)                      \
4308 _(one_use_petr_reply)                                   \
4309 _(one_stats_enable_disable_reply)                       \
4310 _(one_stats_flush_reply)                                \
4311 _(gpe_add_del_fwd_entry_reply)                          \
4312 _(gpe_enable_disable_reply)                             \
4313 _(gpe_set_encap_mode_reply)                             \
4314 _(gpe_add_del_iface_reply)                              \
4315 _(vxlan_gpe_add_del_tunnel_reply)                       \
4316 _(af_packet_delete_reply)                               \
4317 _(policer_classify_set_interface_reply)                 \
4318 _(netmap_create_reply)                                  \
4319 _(netmap_delete_reply)                                  \
4320 _(set_ipfix_exporter_reply)                             \
4321 _(set_ipfix_classify_stream_reply)                      \
4322 _(ipfix_classify_table_add_del_reply)                   \
4323 _(flow_classify_set_interface_reply)                    \
4324 _(sw_interface_span_enable_disable_reply)               \
4325 _(pg_capture_reply)                                     \
4326 _(pg_enable_disable_reply)                              \
4327 _(ip_source_and_port_range_check_add_del_reply)         \
4328 _(ip_source_and_port_range_check_interface_add_del_reply)\
4329 _(delete_subif_reply)                                   \
4330 _(l2_interface_pbb_tag_rewrite_reply)                   \
4331 _(punt_reply)                                           \
4332 _(feature_enable_disable_reply)                         \
4333 _(sw_interface_tag_add_del_reply)                       \
4334 _(sw_interface_set_mtu_reply)
4335
4336 #define _(n)                                    \
4337     static void vl_api_##n##_t_handler          \
4338     (vl_api_##n##_t * mp)                       \
4339     {                                           \
4340         vat_main_t * vam = &vat_main;           \
4341         i32 retval = ntohl(mp->retval);         \
4342         if (vam->async_mode) {                  \
4343             vam->async_errors += (retval < 0);  \
4344         } else {                                \
4345             vam->retval = retval;               \
4346             vam->result_ready = 1;              \
4347         }                                       \
4348     }
4349 foreach_standard_reply_retval_handler;
4350 #undef _
4351
4352 #define _(n)                                    \
4353     static void vl_api_##n##_t_handler_json     \
4354     (vl_api_##n##_t * mp)                       \
4355     {                                           \
4356         vat_main_t * vam = &vat_main;           \
4357         vat_json_node_t node;                   \
4358         vat_json_init_object(&node);            \
4359         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4360         vat_json_print(vam->ofp, &node);        \
4361         vam->retval = ntohl(mp->retval);        \
4362         vam->result_ready = 1;                  \
4363     }
4364 foreach_standard_reply_retval_handler;
4365 #undef _
4366
4367 /*
4368  * Table of message reply handlers, must include boilerplate handlers
4369  * we just generated
4370  */
4371
4372 #define foreach_vpe_api_reply_msg                                       \
4373 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4374 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4375 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4376 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4377 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4378 _(CLI_REPLY, cli_reply)                                                 \
4379 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4380 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4381   sw_interface_add_del_address_reply)                                   \
4382 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4383 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4384 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4385 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4386 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4387   sw_interface_set_l2_xconnect_reply)                                   \
4388 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4389   sw_interface_set_l2_bridge_reply)                                     \
4390 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4391 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4392 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4393 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4394 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4395 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4396 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4397 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4398 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4399 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4400 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4401 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4402 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4403 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4404 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4405 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4406 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4407 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4408   proxy_arp_intfc_enable_disable_reply)                                 \
4409 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4410 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4411   sw_interface_set_unnumbered_reply)                                    \
4412 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4413 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4414 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4415 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4416 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4417 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4418 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4419 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4420 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4421 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4422 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4423 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4424   sw_interface_ip6_enable_disable_reply)                                \
4425 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4426   sw_interface_ip6_set_link_local_address_reply)                        \
4427 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4428 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4429 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4430   sw_interface_ip6nd_ra_prefix_reply)                                   \
4431 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4432   sw_interface_ip6nd_ra_config_reply)                                   \
4433 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4434 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4435 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4436 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4437 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4438 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4439 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4440 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4441 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4442 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4443 classify_set_interface_ip_table_reply)                                  \
4444 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4445   classify_set_interface_l2_tables_reply)                               \
4446 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4447 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4448 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4449 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4450 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4451   l2tpv3_interface_enable_disable_reply)                                \
4452 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4453 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4454 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4455 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4456 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4457 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4458 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4459 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4460 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4461 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4462 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4463 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4464 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4465 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4466 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4467 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4468 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4469 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4470 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4471 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4472 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4473 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4474 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4475 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4476 _(IP_DETAILS, ip_details)                                               \
4477 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4478 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4479 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4480 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4481 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4482 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4483 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4484 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4485 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4486 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4487 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4488 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4489 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4490 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4491 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4492 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4493 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4494 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4495 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4496 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4497 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4498 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4499 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4500 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4501 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4502 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4503 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4504 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4505 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4506 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4507 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4508 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4509 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4510 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4511 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4512 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4513 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4514 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4515 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4516 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4517 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4518 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4519 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4520 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4521 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4522   one_map_register_enable_disable_reply)                                \
4523 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4524   one_rloc_probe_enable_disable_reply)                                  \
4525 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4526 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4527 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4528 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4529 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4530 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4531 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4532 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4533 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4534 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4535 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4536 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4537 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4538 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4539 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4540 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4541   show_one_stats_enable_disable_reply)                                  \
4542 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4543 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4544 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4545 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4546 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4547 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4548 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4549 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4550   gpe_fwd_entry_path_details)                                           \
4551 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4552 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4553   one_add_del_map_request_itr_rlocs_reply)                              \
4554 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4555   one_get_map_request_itr_rlocs_reply)                                  \
4556 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4557 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4558 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4559 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4560 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4561   show_one_map_register_state_reply)                                    \
4562 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4563 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4564 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4565 _(POLICER_DETAILS, policer_details)                                     \
4566 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4567 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4568 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4569 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4570 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4571 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4572 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4573 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4574 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4575 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4576 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4577 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4578 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4579 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4580 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4581 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4582 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4583 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4584 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4585 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4586 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4587 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4588 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4589 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4590 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4591  ip_source_and_port_range_check_add_del_reply)                          \
4592 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4593  ip_source_and_port_range_check_interface_add_del_reply)                \
4594 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4595 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4596 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4597 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4598 _(PUNT_REPLY, punt_reply)                                               \
4599 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4600 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4601 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4602 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4603 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4604 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4605 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4606 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4607
4608 #define foreach_standalone_reply_msg                                    \
4609 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4610 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4611 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4612 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4613 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4614 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4615 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4616
4617 typedef struct
4618 {
4619   u8 *name;
4620   u32 value;
4621 } name_sort_t;
4622
4623
4624 #define STR_VTR_OP_CASE(op)     \
4625     case L2_VTR_ ## op:         \
4626         return "" # op;
4627
4628 static const char *
4629 str_vtr_op (u32 vtr_op)
4630 {
4631   switch (vtr_op)
4632     {
4633       STR_VTR_OP_CASE (DISABLED);
4634       STR_VTR_OP_CASE (PUSH_1);
4635       STR_VTR_OP_CASE (PUSH_2);
4636       STR_VTR_OP_CASE (POP_1);
4637       STR_VTR_OP_CASE (POP_2);
4638       STR_VTR_OP_CASE (TRANSLATE_1_1);
4639       STR_VTR_OP_CASE (TRANSLATE_1_2);
4640       STR_VTR_OP_CASE (TRANSLATE_2_1);
4641       STR_VTR_OP_CASE (TRANSLATE_2_2);
4642     }
4643
4644   return "UNKNOWN";
4645 }
4646
4647 static int
4648 dump_sub_interface_table (vat_main_t * vam)
4649 {
4650   const sw_interface_subif_t *sub = NULL;
4651
4652   if (vam->json_output)
4653     {
4654       clib_warning
4655         ("JSON output supported only for VPE API calls and dump_stats_table");
4656       return -99;
4657     }
4658
4659   print (vam->ofp,
4660          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4661          "Interface", "sw_if_index",
4662          "sub id", "dot1ad", "tags", "outer id",
4663          "inner id", "exact", "default", "outer any", "inner any");
4664
4665   vec_foreach (sub, vam->sw_if_subif_table)
4666   {
4667     print (vam->ofp,
4668            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4669            sub->interface_name,
4670            sub->sw_if_index,
4671            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4672            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4673            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4674            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4675     if (sub->vtr_op != L2_VTR_DISABLED)
4676       {
4677         print (vam->ofp,
4678                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4679                "tag1: %d tag2: %d ]",
4680                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4681                sub->vtr_tag1, sub->vtr_tag2);
4682       }
4683   }
4684
4685   return 0;
4686 }
4687
4688 static int
4689 name_sort_cmp (void *a1, void *a2)
4690 {
4691   name_sort_t *n1 = a1;
4692   name_sort_t *n2 = a2;
4693
4694   return strcmp ((char *) n1->name, (char *) n2->name);
4695 }
4696
4697 static int
4698 dump_interface_table (vat_main_t * vam)
4699 {
4700   hash_pair_t *p;
4701   name_sort_t *nses = 0, *ns;
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   /* *INDENT-OFF* */
4711   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4712   ({
4713     vec_add2 (nses, ns, 1);
4714     ns->name = (u8 *)(p->key);
4715     ns->value = (u32) p->value[0];
4716   }));
4717   /* *INDENT-ON* */
4718
4719   vec_sort_with_function (nses, name_sort_cmp);
4720
4721   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4722   vec_foreach (ns, nses)
4723   {
4724     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4725   }
4726   vec_free (nses);
4727   return 0;
4728 }
4729
4730 static int
4731 dump_ip_table (vat_main_t * vam, int is_ipv6)
4732 {
4733   const ip_details_t *det = NULL;
4734   const ip_address_details_t *address = NULL;
4735   u32 i = ~0;
4736
4737   print (vam->ofp, "%-12s", "sw_if_index");
4738
4739   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4740   {
4741     i++;
4742     if (!det->present)
4743       {
4744         continue;
4745       }
4746     print (vam->ofp, "%-12d", i);
4747     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4748     if (!det->addr)
4749       {
4750         continue;
4751       }
4752     vec_foreach (address, det->addr)
4753     {
4754       print (vam->ofp,
4755              "            %-30U%-13d",
4756              is_ipv6 ? format_ip6_address : format_ip4_address,
4757              address->ip, address->prefix_length);
4758     }
4759   }
4760
4761   return 0;
4762 }
4763
4764 static int
4765 dump_ipv4_table (vat_main_t * vam)
4766 {
4767   if (vam->json_output)
4768     {
4769       clib_warning
4770         ("JSON output supported only for VPE API calls and dump_stats_table");
4771       return -99;
4772     }
4773
4774   return dump_ip_table (vam, 0);
4775 }
4776
4777 static int
4778 dump_ipv6_table (vat_main_t * vam)
4779 {
4780   if (vam->json_output)
4781     {
4782       clib_warning
4783         ("JSON output supported only for VPE API calls and dump_stats_table");
4784       return -99;
4785     }
4786
4787   return dump_ip_table (vam, 1);
4788 }
4789
4790 static char *
4791 counter_type_to_str (u8 counter_type, u8 is_combined)
4792 {
4793   if (!is_combined)
4794     {
4795       switch (counter_type)
4796         {
4797         case VNET_INTERFACE_COUNTER_DROP:
4798           return "drop";
4799         case VNET_INTERFACE_COUNTER_PUNT:
4800           return "punt";
4801         case VNET_INTERFACE_COUNTER_IP4:
4802           return "ip4";
4803         case VNET_INTERFACE_COUNTER_IP6:
4804           return "ip6";
4805         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4806           return "rx-no-buf";
4807         case VNET_INTERFACE_COUNTER_RX_MISS:
4808           return "rx-miss";
4809         case VNET_INTERFACE_COUNTER_RX_ERROR:
4810           return "rx-error";
4811         case VNET_INTERFACE_COUNTER_TX_ERROR:
4812           return "tx-error";
4813         default:
4814           return "INVALID-COUNTER-TYPE";
4815         }
4816     }
4817   else
4818     {
4819       switch (counter_type)
4820         {
4821         case VNET_INTERFACE_COUNTER_RX:
4822           return "rx";
4823         case VNET_INTERFACE_COUNTER_TX:
4824           return "tx";
4825         default:
4826           return "INVALID-COUNTER-TYPE";
4827         }
4828     }
4829 }
4830
4831 static int
4832 dump_stats_table (vat_main_t * vam)
4833 {
4834   vat_json_node_t node;
4835   vat_json_node_t *msg_array;
4836   vat_json_node_t *msg;
4837   vat_json_node_t *counter_array;
4838   vat_json_node_t *counter;
4839   interface_counter_t c;
4840   u64 packets;
4841   ip4_fib_counter_t *c4;
4842   ip6_fib_counter_t *c6;
4843   ip4_nbr_counter_t *n4;
4844   ip6_nbr_counter_t *n6;
4845   int i, j;
4846
4847   if (!vam->json_output)
4848     {
4849       clib_warning ("dump_stats_table supported only in JSON format");
4850       return -99;
4851     }
4852
4853   vat_json_init_object (&node);
4854
4855   /* interface counters */
4856   msg_array = vat_json_object_add (&node, "interface_counters");
4857   vat_json_init_array (msg_array);
4858   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4859     {
4860       msg = vat_json_array_add (msg_array);
4861       vat_json_init_object (msg);
4862       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4863                                        (u8 *) counter_type_to_str (i, 0));
4864       vat_json_object_add_int (msg, "is_combined", 0);
4865       counter_array = vat_json_object_add (msg, "data");
4866       vat_json_init_array (counter_array);
4867       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4868         {
4869           packets = vam->simple_interface_counters[i][j];
4870           vat_json_array_add_uint (counter_array, packets);
4871         }
4872     }
4873   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4874     {
4875       msg = vat_json_array_add (msg_array);
4876       vat_json_init_object (msg);
4877       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4878                                        (u8 *) counter_type_to_str (i, 1));
4879       vat_json_object_add_int (msg, "is_combined", 1);
4880       counter_array = vat_json_object_add (msg, "data");
4881       vat_json_init_array (counter_array);
4882       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4883         {
4884           c = vam->combined_interface_counters[i][j];
4885           counter = vat_json_array_add (counter_array);
4886           vat_json_init_object (counter);
4887           vat_json_object_add_uint (counter, "packets", c.packets);
4888           vat_json_object_add_uint (counter, "bytes", c.bytes);
4889         }
4890     }
4891
4892   /* ip4 fib counters */
4893   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4894   vat_json_init_array (msg_array);
4895   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4896     {
4897       msg = vat_json_array_add (msg_array);
4898       vat_json_init_object (msg);
4899       vat_json_object_add_uint (msg, "vrf_id",
4900                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4901       counter_array = vat_json_object_add (msg, "c");
4902       vat_json_init_array (counter_array);
4903       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4904         {
4905           counter = vat_json_array_add (counter_array);
4906           vat_json_init_object (counter);
4907           c4 = &vam->ip4_fib_counters[i][j];
4908           vat_json_object_add_ip4 (counter, "address", c4->address);
4909           vat_json_object_add_uint (counter, "address_length",
4910                                     c4->address_length);
4911           vat_json_object_add_uint (counter, "packets", c4->packets);
4912           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4913         }
4914     }
4915
4916   /* ip6 fib counters */
4917   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4918   vat_json_init_array (msg_array);
4919   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4920     {
4921       msg = vat_json_array_add (msg_array);
4922       vat_json_init_object (msg);
4923       vat_json_object_add_uint (msg, "vrf_id",
4924                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4925       counter_array = vat_json_object_add (msg, "c");
4926       vat_json_init_array (counter_array);
4927       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4928         {
4929           counter = vat_json_array_add (counter_array);
4930           vat_json_init_object (counter);
4931           c6 = &vam->ip6_fib_counters[i][j];
4932           vat_json_object_add_ip6 (counter, "address", c6->address);
4933           vat_json_object_add_uint (counter, "address_length",
4934                                     c6->address_length);
4935           vat_json_object_add_uint (counter, "packets", c6->packets);
4936           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4937         }
4938     }
4939
4940   /* ip4 nbr counters */
4941   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4942   vat_json_init_array (msg_array);
4943   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4944     {
4945       msg = vat_json_array_add (msg_array);
4946       vat_json_init_object (msg);
4947       vat_json_object_add_uint (msg, "sw_if_index", i);
4948       counter_array = vat_json_object_add (msg, "c");
4949       vat_json_init_array (counter_array);
4950       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4951         {
4952           counter = vat_json_array_add (counter_array);
4953           vat_json_init_object (counter);
4954           n4 = &vam->ip4_nbr_counters[i][j];
4955           vat_json_object_add_ip4 (counter, "address", n4->address);
4956           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4957           vat_json_object_add_uint (counter, "packets", n4->packets);
4958           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4959         }
4960     }
4961
4962   /* ip6 nbr counters */
4963   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4964   vat_json_init_array (msg_array);
4965   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4966     {
4967       msg = vat_json_array_add (msg_array);
4968       vat_json_init_object (msg);
4969       vat_json_object_add_uint (msg, "sw_if_index", i);
4970       counter_array = vat_json_object_add (msg, "c");
4971       vat_json_init_array (counter_array);
4972       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4973         {
4974           counter = vat_json_array_add (counter_array);
4975           vat_json_init_object (counter);
4976           n6 = &vam->ip6_nbr_counters[i][j];
4977           vat_json_object_add_ip6 (counter, "address", n6->address);
4978           vat_json_object_add_uint (counter, "packets", n6->packets);
4979           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4980         }
4981     }
4982
4983   vat_json_print (vam->ofp, &node);
4984   vat_json_free (&node);
4985
4986   return 0;
4987 }
4988
4989 int
4990 exec (vat_main_t * vam)
4991 {
4992   api_main_t *am = &api_main;
4993   vl_api_cli_t *mp;
4994   f64 timeout;
4995   void *oldheap;
4996   u8 *cmd = 0;
4997   unformat_input_t *i = vam->input;
4998
4999   if (vec_len (i->buffer) == 0)
5000     return -1;
5001
5002   if (vam->exec_mode == 0 && unformat (i, "mode"))
5003     {
5004       vam->exec_mode = 1;
5005       return 0;
5006     }
5007   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5008     {
5009       vam->exec_mode = 0;
5010       return 0;
5011     }
5012
5013
5014   M (CLI, mp);
5015
5016   /*
5017    * Copy cmd into shared memory.
5018    * In order for the CLI command to work, it
5019    * must be a vector ending in \n, not a C-string ending
5020    * in \n\0.
5021    */
5022   pthread_mutex_lock (&am->vlib_rp->mutex);
5023   oldheap = svm_push_data_heap (am->vlib_rp);
5024
5025   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5026   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5027
5028   svm_pop_heap (oldheap);
5029   pthread_mutex_unlock (&am->vlib_rp->mutex);
5030
5031   mp->cmd_in_shmem = pointer_to_uword (cmd);
5032   S (mp);
5033   timeout = vat_time_now (vam) + 10.0;
5034
5035   while (vat_time_now (vam) < timeout)
5036     {
5037       if (vam->result_ready == 1)
5038         {
5039           u8 *free_me;
5040           if (vam->shmem_result != NULL)
5041             print (vam->ofp, "%s", vam->shmem_result);
5042           pthread_mutex_lock (&am->vlib_rp->mutex);
5043           oldheap = svm_push_data_heap (am->vlib_rp);
5044
5045           free_me = (u8 *) vam->shmem_result;
5046           vec_free (free_me);
5047
5048           svm_pop_heap (oldheap);
5049           pthread_mutex_unlock (&am->vlib_rp->mutex);
5050           return 0;
5051         }
5052     }
5053   return -99;
5054 }
5055
5056 /*
5057  * Future replacement of exec() that passes CLI buffers directly in
5058  * the API messages instead of an additional shared memory area.
5059  */
5060 static int
5061 exec_inband (vat_main_t * vam)
5062 {
5063   vl_api_cli_inband_t *mp;
5064   unformat_input_t *i = vam->input;
5065   int ret;
5066
5067   if (vec_len (i->buffer) == 0)
5068     return -1;
5069
5070   if (vam->exec_mode == 0 && unformat (i, "mode"))
5071     {
5072       vam->exec_mode = 1;
5073       return 0;
5074     }
5075   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5076     {
5077       vam->exec_mode = 0;
5078       return 0;
5079     }
5080
5081   /*
5082    * In order for the CLI command to work, it
5083    * must be a vector ending in \n, not a C-string ending
5084    * in \n\0.
5085    */
5086   u32 len = vec_len (vam->input->buffer);
5087   M2 (CLI_INBAND, mp, len);
5088   clib_memcpy (mp->cmd, vam->input->buffer, len);
5089   mp->length = htonl (len);
5090
5091   S (mp);
5092   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5093   return ret;
5094 }
5095
5096 static int
5097 api_create_loopback (vat_main_t * vam)
5098 {
5099   unformat_input_t *i = vam->input;
5100   vl_api_create_loopback_t *mp;
5101   vl_api_create_loopback_instance_t *mp_lbi;
5102   u8 mac_address[6];
5103   u8 mac_set = 0;
5104   u8 is_specified = 0;
5105   u32 user_instance = 0;
5106   int ret;
5107
5108   memset (mac_address, 0, sizeof (mac_address));
5109
5110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5111     {
5112       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5113         mac_set = 1;
5114       if (unformat (i, "instance %d", &user_instance))
5115         is_specified = 1;
5116       else
5117         break;
5118     }
5119
5120   if (is_specified)
5121     {
5122       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5123       mp_lbi->is_specified = is_specified;
5124       if (is_specified)
5125         mp_lbi->user_instance = htonl (user_instance);
5126       if (mac_set)
5127         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5128       S (mp_lbi);
5129     }
5130   else
5131     {
5132       /* Construct the API message */
5133       M (CREATE_LOOPBACK, mp);
5134       if (mac_set)
5135         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5136       S (mp);
5137     }
5138
5139   W (ret);
5140   return ret;
5141 }
5142
5143 static int
5144 api_delete_loopback (vat_main_t * vam)
5145 {
5146   unformat_input_t *i = vam->input;
5147   vl_api_delete_loopback_t *mp;
5148   u32 sw_if_index = ~0;
5149   int ret;
5150
5151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5152     {
5153       if (unformat (i, "sw_if_index %d", &sw_if_index))
5154         ;
5155       else
5156         break;
5157     }
5158
5159   if (sw_if_index == ~0)
5160     {
5161       errmsg ("missing sw_if_index");
5162       return -99;
5163     }
5164
5165   /* Construct the API message */
5166   M (DELETE_LOOPBACK, mp);
5167   mp->sw_if_index = ntohl (sw_if_index);
5168
5169   S (mp);
5170   W (ret);
5171   return ret;
5172 }
5173
5174 static int
5175 api_want_stats (vat_main_t * vam)
5176 {
5177   unformat_input_t *i = vam->input;
5178   vl_api_want_stats_t *mp;
5179   int enable = -1;
5180   int ret;
5181
5182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5183     {
5184       if (unformat (i, "enable"))
5185         enable = 1;
5186       else if (unformat (i, "disable"))
5187         enable = 0;
5188       else
5189         break;
5190     }
5191
5192   if (enable == -1)
5193     {
5194       errmsg ("missing enable|disable");
5195       return -99;
5196     }
5197
5198   M (WANT_STATS, mp);
5199   mp->enable_disable = enable;
5200
5201   S (mp);
5202   W (ret);
5203   return ret;
5204 }
5205
5206 static int
5207 api_want_interface_events (vat_main_t * vam)
5208 {
5209   unformat_input_t *i = vam->input;
5210   vl_api_want_interface_events_t *mp;
5211   int enable = -1;
5212   int ret;
5213
5214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5215     {
5216       if (unformat (i, "enable"))
5217         enable = 1;
5218       else if (unformat (i, "disable"))
5219         enable = 0;
5220       else
5221         break;
5222     }
5223
5224   if (enable == -1)
5225     {
5226       errmsg ("missing enable|disable");
5227       return -99;
5228     }
5229
5230   M (WANT_INTERFACE_EVENTS, mp);
5231   mp->enable_disable = enable;
5232
5233   vam->interface_event_display = enable;
5234
5235   S (mp);
5236   W (ret);
5237   return ret;
5238 }
5239
5240
5241 /* Note: non-static, called once to set up the initial intfc table */
5242 int
5243 api_sw_interface_dump (vat_main_t * vam)
5244 {
5245   vl_api_sw_interface_dump_t *mp;
5246   vl_api_control_ping_t *mp_ping;
5247   hash_pair_t *p;
5248   name_sort_t *nses = 0, *ns;
5249   sw_interface_subif_t *sub = NULL;
5250   int ret;
5251
5252   /* Toss the old name table */
5253   /* *INDENT-OFF* */
5254   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5255   ({
5256     vec_add2 (nses, ns, 1);
5257     ns->name = (u8 *)(p->key);
5258     ns->value = (u32) p->value[0];
5259   }));
5260   /* *INDENT-ON* */
5261
5262   hash_free (vam->sw_if_index_by_interface_name);
5263
5264   vec_foreach (ns, nses) vec_free (ns->name);
5265
5266   vec_free (nses);
5267
5268   vec_foreach (sub, vam->sw_if_subif_table)
5269   {
5270     vec_free (sub->interface_name);
5271   }
5272   vec_free (vam->sw_if_subif_table);
5273
5274   /* recreate the interface name hash table */
5275   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5276
5277   /* Get list of ethernets */
5278   M (SW_INTERFACE_DUMP, mp);
5279   mp->name_filter_valid = 1;
5280   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5281   S (mp);
5282
5283   /* and local / loopback interfaces */
5284   M (SW_INTERFACE_DUMP, mp);
5285   mp->name_filter_valid = 1;
5286   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5287   S (mp);
5288
5289   /* and packet-generator interfaces */
5290   M (SW_INTERFACE_DUMP, mp);
5291   mp->name_filter_valid = 1;
5292   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5293   S (mp);
5294
5295   /* and vxlan-gpe tunnel interfaces */
5296   M (SW_INTERFACE_DUMP, mp);
5297   mp->name_filter_valid = 1;
5298   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5299            sizeof (mp->name_filter) - 1);
5300   S (mp);
5301
5302   /* and vxlan tunnel interfaces */
5303   M (SW_INTERFACE_DUMP, mp);
5304   mp->name_filter_valid = 1;
5305   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5306   S (mp);
5307
5308   /* and host (af_packet) interfaces */
5309   M (SW_INTERFACE_DUMP, mp);
5310   mp->name_filter_valid = 1;
5311   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5312   S (mp);
5313
5314   /* and l2tpv3 tunnel interfaces */
5315   M (SW_INTERFACE_DUMP, mp);
5316   mp->name_filter_valid = 1;
5317   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5318            sizeof (mp->name_filter) - 1);
5319   S (mp);
5320
5321   /* and GRE tunnel interfaces */
5322   M (SW_INTERFACE_DUMP, mp);
5323   mp->name_filter_valid = 1;
5324   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5325   S (mp);
5326
5327   /* and LISP-GPE interfaces */
5328   M (SW_INTERFACE_DUMP, mp);
5329   mp->name_filter_valid = 1;
5330   strncpy ((char *) mp->name_filter, "lisp_gpe",
5331            sizeof (mp->name_filter) - 1);
5332   S (mp);
5333
5334   /* and IPSEC tunnel interfaces */
5335   M (SW_INTERFACE_DUMP, mp);
5336   mp->name_filter_valid = 1;
5337   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5338   S (mp);
5339
5340   /* Use a control ping for synchronization */
5341   M (CONTROL_PING, mp_ping);
5342   S (mp_ping);
5343
5344   W (ret);
5345   return ret;
5346 }
5347
5348 static int
5349 api_sw_interface_set_flags (vat_main_t * vam)
5350 {
5351   unformat_input_t *i = vam->input;
5352   vl_api_sw_interface_set_flags_t *mp;
5353   u32 sw_if_index;
5354   u8 sw_if_index_set = 0;
5355   u8 admin_up = 0, link_up = 0;
5356   int ret;
5357
5358   /* Parse args required to build the message */
5359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5360     {
5361       if (unformat (i, "admin-up"))
5362         admin_up = 1;
5363       else if (unformat (i, "admin-down"))
5364         admin_up = 0;
5365       else if (unformat (i, "link-up"))
5366         link_up = 1;
5367       else if (unformat (i, "link-down"))
5368         link_up = 0;
5369       else
5370         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5371         sw_if_index_set = 1;
5372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5373         sw_if_index_set = 1;
5374       else
5375         break;
5376     }
5377
5378   if (sw_if_index_set == 0)
5379     {
5380       errmsg ("missing interface name or sw_if_index");
5381       return -99;
5382     }
5383
5384   /* Construct the API message */
5385   M (SW_INTERFACE_SET_FLAGS, mp);
5386   mp->sw_if_index = ntohl (sw_if_index);
5387   mp->admin_up_down = admin_up;
5388   mp->link_up_down = link_up;
5389
5390   /* send it... */
5391   S (mp);
5392
5393   /* Wait for a reply, return the good/bad news... */
5394   W (ret);
5395   return ret;
5396 }
5397
5398 static int
5399 api_sw_interface_clear_stats (vat_main_t * vam)
5400 {
5401   unformat_input_t *i = vam->input;
5402   vl_api_sw_interface_clear_stats_t *mp;
5403   u32 sw_if_index;
5404   u8 sw_if_index_set = 0;
5405   int ret;
5406
5407   /* Parse args required to build the message */
5408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5409     {
5410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5411         sw_if_index_set = 1;
5412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5413         sw_if_index_set = 1;
5414       else
5415         break;
5416     }
5417
5418   /* Construct the API message */
5419   M (SW_INTERFACE_CLEAR_STATS, mp);
5420
5421   if (sw_if_index_set == 1)
5422     mp->sw_if_index = ntohl (sw_if_index);
5423   else
5424     mp->sw_if_index = ~0;
5425
5426   /* send it... */
5427   S (mp);
5428
5429   /* Wait for a reply, return the good/bad news... */
5430   W (ret);
5431   return ret;
5432 }
5433
5434 static int
5435 api_sw_interface_add_del_address (vat_main_t * vam)
5436 {
5437   unformat_input_t *i = vam->input;
5438   vl_api_sw_interface_add_del_address_t *mp;
5439   u32 sw_if_index;
5440   u8 sw_if_index_set = 0;
5441   u8 is_add = 1, del_all = 0;
5442   u32 address_length = 0;
5443   u8 v4_address_set = 0;
5444   u8 v6_address_set = 0;
5445   ip4_address_t v4address;
5446   ip6_address_t v6address;
5447   int ret;
5448
5449   /* Parse args required to build the message */
5450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5451     {
5452       if (unformat (i, "del-all"))
5453         del_all = 1;
5454       else if (unformat (i, "del"))
5455         is_add = 0;
5456       else
5457         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5458         sw_if_index_set = 1;
5459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5460         sw_if_index_set = 1;
5461       else if (unformat (i, "%U/%d",
5462                          unformat_ip4_address, &v4address, &address_length))
5463         v4_address_set = 1;
5464       else if (unformat (i, "%U/%d",
5465                          unformat_ip6_address, &v6address, &address_length))
5466         v6_address_set = 1;
5467       else
5468         break;
5469     }
5470
5471   if (sw_if_index_set == 0)
5472     {
5473       errmsg ("missing interface name or sw_if_index");
5474       return -99;
5475     }
5476   if (v4_address_set && v6_address_set)
5477     {
5478       errmsg ("both v4 and v6 addresses set");
5479       return -99;
5480     }
5481   if (!v4_address_set && !v6_address_set && !del_all)
5482     {
5483       errmsg ("no addresses set");
5484       return -99;
5485     }
5486
5487   /* Construct the API message */
5488   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5489
5490   mp->sw_if_index = ntohl (sw_if_index);
5491   mp->is_add = is_add;
5492   mp->del_all = del_all;
5493   if (v6_address_set)
5494     {
5495       mp->is_ipv6 = 1;
5496       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5497     }
5498   else
5499     {
5500       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5501     }
5502   mp->address_length = address_length;
5503
5504   /* send it... */
5505   S (mp);
5506
5507   /* Wait for a reply, return good/bad news  */
5508   W (ret);
5509   return ret;
5510 }
5511
5512 static int
5513 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5514 {
5515   unformat_input_t *i = vam->input;
5516   vl_api_sw_interface_set_mpls_enable_t *mp;
5517   u32 sw_if_index;
5518   u8 sw_if_index_set = 0;
5519   u8 enable = 1;
5520   int ret;
5521
5522   /* Parse args required to build the message */
5523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5524     {
5525       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5526         sw_if_index_set = 1;
5527       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5528         sw_if_index_set = 1;
5529       else if (unformat (i, "disable"))
5530         enable = 0;
5531       else if (unformat (i, "dis"))
5532         enable = 0;
5533       else
5534         break;
5535     }
5536
5537   if (sw_if_index_set == 0)
5538     {
5539       errmsg ("missing interface name or sw_if_index");
5540       return -99;
5541     }
5542
5543   /* Construct the API message */
5544   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5545
5546   mp->sw_if_index = ntohl (sw_if_index);
5547   mp->enable = enable;
5548
5549   /* send it... */
5550   S (mp);
5551
5552   /* Wait for a reply... */
5553   W (ret);
5554   return ret;
5555 }
5556
5557 static int
5558 api_sw_interface_set_table (vat_main_t * vam)
5559 {
5560   unformat_input_t *i = vam->input;
5561   vl_api_sw_interface_set_table_t *mp;
5562   u32 sw_if_index, vrf_id = 0;
5563   u8 sw_if_index_set = 0;
5564   u8 is_ipv6 = 0;
5565   int ret;
5566
5567   /* Parse args required to build the message */
5568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5569     {
5570       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5571         sw_if_index_set = 1;
5572       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5573         sw_if_index_set = 1;
5574       else if (unformat (i, "vrf %d", &vrf_id))
5575         ;
5576       else if (unformat (i, "ipv6"))
5577         is_ipv6 = 1;
5578       else
5579         break;
5580     }
5581
5582   if (sw_if_index_set == 0)
5583     {
5584       errmsg ("missing interface name or sw_if_index");
5585       return -99;
5586     }
5587
5588   /* Construct the API message */
5589   M (SW_INTERFACE_SET_TABLE, mp);
5590
5591   mp->sw_if_index = ntohl (sw_if_index);
5592   mp->is_ipv6 = is_ipv6;
5593   mp->vrf_id = ntohl (vrf_id);
5594
5595   /* send it... */
5596   S (mp);
5597
5598   /* Wait for a reply... */
5599   W (ret);
5600   return ret;
5601 }
5602
5603 static void vl_api_sw_interface_get_table_reply_t_handler
5604   (vl_api_sw_interface_get_table_reply_t * mp)
5605 {
5606   vat_main_t *vam = &vat_main;
5607
5608   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5609
5610   vam->retval = ntohl (mp->retval);
5611   vam->result_ready = 1;
5612
5613 }
5614
5615 static void vl_api_sw_interface_get_table_reply_t_handler_json
5616   (vl_api_sw_interface_get_table_reply_t * mp)
5617 {
5618   vat_main_t *vam = &vat_main;
5619   vat_json_node_t node;
5620
5621   vat_json_init_object (&node);
5622   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5623   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5624
5625   vat_json_print (vam->ofp, &node);
5626   vat_json_free (&node);
5627
5628   vam->retval = ntohl (mp->retval);
5629   vam->result_ready = 1;
5630 }
5631
5632 static int
5633 api_sw_interface_get_table (vat_main_t * vam)
5634 {
5635   unformat_input_t *i = vam->input;
5636   vl_api_sw_interface_get_table_t *mp;
5637   u32 sw_if_index;
5638   u8 sw_if_index_set = 0;
5639   u8 is_ipv6 = 0;
5640   int ret;
5641
5642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5643     {
5644       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5645         sw_if_index_set = 1;
5646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5647         sw_if_index_set = 1;
5648       else if (unformat (i, "ipv6"))
5649         is_ipv6 = 1;
5650       else
5651         break;
5652     }
5653
5654   if (sw_if_index_set == 0)
5655     {
5656       errmsg ("missing interface name or sw_if_index");
5657       return -99;
5658     }
5659
5660   M (SW_INTERFACE_GET_TABLE, mp);
5661   mp->sw_if_index = htonl (sw_if_index);
5662   mp->is_ipv6 = is_ipv6;
5663
5664   S (mp);
5665   W (ret);
5666   return ret;
5667 }
5668
5669 static int
5670 api_sw_interface_set_vpath (vat_main_t * vam)
5671 {
5672   unformat_input_t *i = vam->input;
5673   vl_api_sw_interface_set_vpath_t *mp;
5674   u32 sw_if_index = 0;
5675   u8 sw_if_index_set = 0;
5676   u8 is_enable = 0;
5677   int ret;
5678
5679   /* Parse args required to build the message */
5680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5681     {
5682       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5683         sw_if_index_set = 1;
5684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5685         sw_if_index_set = 1;
5686       else if (unformat (i, "enable"))
5687         is_enable = 1;
5688       else if (unformat (i, "disable"))
5689         is_enable = 0;
5690       else
5691         break;
5692     }
5693
5694   if (sw_if_index_set == 0)
5695     {
5696       errmsg ("missing interface name or sw_if_index");
5697       return -99;
5698     }
5699
5700   /* Construct the API message */
5701   M (SW_INTERFACE_SET_VPATH, mp);
5702
5703   mp->sw_if_index = ntohl (sw_if_index);
5704   mp->enable = is_enable;
5705
5706   /* send it... */
5707   S (mp);
5708
5709   /* Wait for a reply... */
5710   W (ret);
5711   return ret;
5712 }
5713
5714 static int
5715 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5716 {
5717   unformat_input_t *i = vam->input;
5718   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5719   u32 sw_if_index = 0;
5720   u8 sw_if_index_set = 0;
5721   u8 is_enable = 1;
5722   u8 is_ipv6 = 0;
5723   int ret;
5724
5725   /* Parse args required to build the message */
5726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5727     {
5728       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5729         sw_if_index_set = 1;
5730       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5731         sw_if_index_set = 1;
5732       else if (unformat (i, "enable"))
5733         is_enable = 1;
5734       else if (unformat (i, "disable"))
5735         is_enable = 0;
5736       else if (unformat (i, "ip4"))
5737         is_ipv6 = 0;
5738       else if (unformat (i, "ip6"))
5739         is_ipv6 = 1;
5740       else
5741         break;
5742     }
5743
5744   if (sw_if_index_set == 0)
5745     {
5746       errmsg ("missing interface name or sw_if_index");
5747       return -99;
5748     }
5749
5750   /* Construct the API message */
5751   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5752
5753   mp->sw_if_index = ntohl (sw_if_index);
5754   mp->enable = is_enable;
5755   mp->is_ipv6 = is_ipv6;
5756
5757   /* send it... */
5758   S (mp);
5759
5760   /* Wait for a reply... */
5761   W (ret);
5762   return ret;
5763 }
5764
5765 static int
5766 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5767 {
5768   unformat_input_t *i = vam->input;
5769   vl_api_sw_interface_set_l2_xconnect_t *mp;
5770   u32 rx_sw_if_index;
5771   u8 rx_sw_if_index_set = 0;
5772   u32 tx_sw_if_index;
5773   u8 tx_sw_if_index_set = 0;
5774   u8 enable = 1;
5775   int ret;
5776
5777   /* Parse args required to build the message */
5778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5779     {
5780       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5781         rx_sw_if_index_set = 1;
5782       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5783         tx_sw_if_index_set = 1;
5784       else if (unformat (i, "rx"))
5785         {
5786           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5787             {
5788               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5789                             &rx_sw_if_index))
5790                 rx_sw_if_index_set = 1;
5791             }
5792           else
5793             break;
5794         }
5795       else if (unformat (i, "tx"))
5796         {
5797           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5798             {
5799               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5800                             &tx_sw_if_index))
5801                 tx_sw_if_index_set = 1;
5802             }
5803           else
5804             break;
5805         }
5806       else if (unformat (i, "enable"))
5807         enable = 1;
5808       else if (unformat (i, "disable"))
5809         enable = 0;
5810       else
5811         break;
5812     }
5813
5814   if (rx_sw_if_index_set == 0)
5815     {
5816       errmsg ("missing rx interface name or rx_sw_if_index");
5817       return -99;
5818     }
5819
5820   if (enable && (tx_sw_if_index_set == 0))
5821     {
5822       errmsg ("missing tx interface name or tx_sw_if_index");
5823       return -99;
5824     }
5825
5826   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5827
5828   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5829   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5830   mp->enable = enable;
5831
5832   S (mp);
5833   W (ret);
5834   return ret;
5835 }
5836
5837 static int
5838 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5839 {
5840   unformat_input_t *i = vam->input;
5841   vl_api_sw_interface_set_l2_bridge_t *mp;
5842   u32 rx_sw_if_index;
5843   u8 rx_sw_if_index_set = 0;
5844   u32 bd_id;
5845   u8 bd_id_set = 0;
5846   u8 bvi = 0;
5847   u32 shg = 0;
5848   u8 enable = 1;
5849   int ret;
5850
5851   /* Parse args required to build the message */
5852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5853     {
5854       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5855         rx_sw_if_index_set = 1;
5856       else if (unformat (i, "bd_id %d", &bd_id))
5857         bd_id_set = 1;
5858       else
5859         if (unformat
5860             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5861         rx_sw_if_index_set = 1;
5862       else if (unformat (i, "shg %d", &shg))
5863         ;
5864       else if (unformat (i, "bvi"))
5865         bvi = 1;
5866       else if (unformat (i, "enable"))
5867         enable = 1;
5868       else if (unformat (i, "disable"))
5869         enable = 0;
5870       else
5871         break;
5872     }
5873
5874   if (rx_sw_if_index_set == 0)
5875     {
5876       errmsg ("missing rx interface name or sw_if_index");
5877       return -99;
5878     }
5879
5880   if (enable && (bd_id_set == 0))
5881     {
5882       errmsg ("missing bridge domain");
5883       return -99;
5884     }
5885
5886   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5887
5888   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5889   mp->bd_id = ntohl (bd_id);
5890   mp->shg = (u8) shg;
5891   mp->bvi = bvi;
5892   mp->enable = enable;
5893
5894   S (mp);
5895   W (ret);
5896   return ret;
5897 }
5898
5899 static int
5900 api_bridge_domain_dump (vat_main_t * vam)
5901 {
5902   unformat_input_t *i = vam->input;
5903   vl_api_bridge_domain_dump_t *mp;
5904   vl_api_control_ping_t *mp_ping;
5905   u32 bd_id = ~0;
5906   int ret;
5907
5908   /* Parse args required to build the message */
5909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5910     {
5911       if (unformat (i, "bd_id %d", &bd_id))
5912         ;
5913       else
5914         break;
5915     }
5916
5917   M (BRIDGE_DOMAIN_DUMP, mp);
5918   mp->bd_id = ntohl (bd_id);
5919   S (mp);
5920
5921   /* Use a control ping for synchronization */
5922   M (CONTROL_PING, mp_ping);
5923   S (mp_ping);
5924
5925   W (ret);
5926   return ret;
5927 }
5928
5929 static int
5930 api_bridge_domain_add_del (vat_main_t * vam)
5931 {
5932   unformat_input_t *i = vam->input;
5933   vl_api_bridge_domain_add_del_t *mp;
5934   u32 bd_id = ~0;
5935   u8 is_add = 1;
5936   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5937   u32 mac_age = 0;
5938   int ret;
5939
5940   /* Parse args required to build the message */
5941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5942     {
5943       if (unformat (i, "bd_id %d", &bd_id))
5944         ;
5945       else if (unformat (i, "flood %d", &flood))
5946         ;
5947       else if (unformat (i, "uu-flood %d", &uu_flood))
5948         ;
5949       else if (unformat (i, "forward %d", &forward))
5950         ;
5951       else if (unformat (i, "learn %d", &learn))
5952         ;
5953       else if (unformat (i, "arp-term %d", &arp_term))
5954         ;
5955       else if (unformat (i, "mac-age %d", &mac_age))
5956         ;
5957       else if (unformat (i, "del"))
5958         {
5959           is_add = 0;
5960           flood = uu_flood = forward = learn = 0;
5961         }
5962       else
5963         break;
5964     }
5965
5966   if (bd_id == ~0)
5967     {
5968       errmsg ("missing bridge domain");
5969       return -99;
5970     }
5971
5972   if (mac_age > 255)
5973     {
5974       errmsg ("mac age must be less than 256 ");
5975       return -99;
5976     }
5977
5978   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5979
5980   mp->bd_id = ntohl (bd_id);
5981   mp->flood = flood;
5982   mp->uu_flood = uu_flood;
5983   mp->forward = forward;
5984   mp->learn = learn;
5985   mp->arp_term = arp_term;
5986   mp->is_add = is_add;
5987   mp->mac_age = (u8) mac_age;
5988
5989   S (mp);
5990   W (ret);
5991   return ret;
5992 }
5993
5994 static int
5995 api_l2fib_flush_bd (vat_main_t * vam)
5996 {
5997   unformat_input_t *i = vam->input;
5998   vl_api_l2fib_flush_bd_t *mp;
5999   u32 bd_id = ~0;
6000   int ret;
6001
6002   /* Parse args required to build the message */
6003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6004     {
6005       if (unformat (i, "bd_id %d", &bd_id));
6006       else
6007         break;
6008     }
6009
6010   if (bd_id == ~0)
6011     {
6012       errmsg ("missing bridge domain");
6013       return -99;
6014     }
6015
6016   M (L2FIB_FLUSH_BD, mp);
6017
6018   mp->bd_id = htonl (bd_id);
6019
6020   S (mp);
6021   W (ret);
6022   return ret;
6023 }
6024
6025 static int
6026 api_l2fib_flush_int (vat_main_t * vam)
6027 {
6028   unformat_input_t *i = vam->input;
6029   vl_api_l2fib_flush_int_t *mp;
6030   u32 sw_if_index = ~0;
6031   int ret;
6032
6033   /* Parse args required to build the message */
6034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6035     {
6036       if (unformat (i, "sw_if_index %d", &sw_if_index));
6037       else
6038         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6039       else
6040         break;
6041     }
6042
6043   if (sw_if_index == ~0)
6044     {
6045       errmsg ("missing interface name or sw_if_index");
6046       return -99;
6047     }
6048
6049   M (L2FIB_FLUSH_INT, mp);
6050
6051   mp->sw_if_index = ntohl (sw_if_index);
6052
6053   S (mp);
6054   W (ret);
6055   return ret;
6056 }
6057
6058 static int
6059 api_l2fib_add_del (vat_main_t * vam)
6060 {
6061   unformat_input_t *i = vam->input;
6062   vl_api_l2fib_add_del_t *mp;
6063   f64 timeout;
6064   u64 mac = 0;
6065   u8 mac_set = 0;
6066   u32 bd_id;
6067   u8 bd_id_set = 0;
6068   u32 sw_if_index = ~0;
6069   u8 sw_if_index_set = 0;
6070   u8 is_add = 1;
6071   u8 static_mac = 0;
6072   u8 filter_mac = 0;
6073   u8 bvi_mac = 0;
6074   int count = 1;
6075   f64 before = 0;
6076   int j;
6077
6078   /* Parse args required to build the message */
6079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6080     {
6081       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6082         mac_set = 1;
6083       else if (unformat (i, "bd_id %d", &bd_id))
6084         bd_id_set = 1;
6085       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6086         sw_if_index_set = 1;
6087       else if (unformat (i, "sw_if"))
6088         {
6089           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6090             {
6091               if (unformat
6092                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6093                 sw_if_index_set = 1;
6094             }
6095           else
6096             break;
6097         }
6098       else if (unformat (i, "static"))
6099         static_mac = 1;
6100       else if (unformat (i, "filter"))
6101         {
6102           filter_mac = 1;
6103           static_mac = 1;
6104         }
6105       else if (unformat (i, "bvi"))
6106         {
6107           bvi_mac = 1;
6108           static_mac = 1;
6109         }
6110       else if (unformat (i, "del"))
6111         is_add = 0;
6112       else if (unformat (i, "count %d", &count))
6113         ;
6114       else
6115         break;
6116     }
6117
6118   if (mac_set == 0)
6119     {
6120       errmsg ("missing mac address");
6121       return -99;
6122     }
6123
6124   if (bd_id_set == 0)
6125     {
6126       errmsg ("missing bridge domain");
6127       return -99;
6128     }
6129
6130   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6131     {
6132       errmsg ("missing interface name or sw_if_index");
6133       return -99;
6134     }
6135
6136   if (count > 1)
6137     {
6138       /* Turn on async mode */
6139       vam->async_mode = 1;
6140       vam->async_errors = 0;
6141       before = vat_time_now (vam);
6142     }
6143
6144   for (j = 0; j < count; j++)
6145     {
6146       M (L2FIB_ADD_DEL, mp);
6147
6148       mp->mac = mac;
6149       mp->bd_id = ntohl (bd_id);
6150       mp->is_add = is_add;
6151
6152       if (is_add)
6153         {
6154           mp->sw_if_index = ntohl (sw_if_index);
6155           mp->static_mac = static_mac;
6156           mp->filter_mac = filter_mac;
6157           mp->bvi_mac = bvi_mac;
6158         }
6159       increment_mac_address (&mac);
6160       /* send it... */
6161       S (mp);
6162     }
6163
6164   if (count > 1)
6165     {
6166       vl_api_control_ping_t *mp_ping;
6167       f64 after;
6168
6169       /* Shut off async mode */
6170       vam->async_mode = 0;
6171
6172       M (CONTROL_PING, mp_ping);
6173       S (mp_ping);
6174
6175       timeout = vat_time_now (vam) + 1.0;
6176       while (vat_time_now (vam) < timeout)
6177         if (vam->result_ready == 1)
6178           goto out;
6179       vam->retval = -99;
6180
6181     out:
6182       if (vam->retval == -99)
6183         errmsg ("timeout");
6184
6185       if (vam->async_errors > 0)
6186         {
6187           errmsg ("%d asynchronous errors", vam->async_errors);
6188           vam->retval = -98;
6189         }
6190       vam->async_errors = 0;
6191       after = vat_time_now (vam);
6192
6193       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6194              count, after - before, count / (after - before));
6195     }
6196   else
6197     {
6198       int ret;
6199
6200       /* Wait for a reply... */
6201       W (ret);
6202       return ret;
6203     }
6204   /* Return the good/bad news */
6205   return (vam->retval);
6206 }
6207
6208 static int
6209 api_bridge_domain_set_mac_age (vat_main_t * vam)
6210 {
6211   unformat_input_t *i = vam->input;
6212   vl_api_bridge_domain_set_mac_age_t *mp;
6213   u32 bd_id = ~0;
6214   u32 mac_age = 0;
6215   int ret;
6216
6217   /* Parse args required to build the message */
6218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6219     {
6220       if (unformat (i, "bd_id %d", &bd_id));
6221       else if (unformat (i, "mac-age %d", &mac_age));
6222       else
6223         break;
6224     }
6225
6226   if (bd_id == ~0)
6227     {
6228       errmsg ("missing bridge domain");
6229       return -99;
6230     }
6231
6232   if (mac_age > 255)
6233     {
6234       errmsg ("mac age must be less than 256 ");
6235       return -99;
6236     }
6237
6238   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6239
6240   mp->bd_id = htonl (bd_id);
6241   mp->mac_age = (u8) mac_age;
6242
6243   S (mp);
6244   W (ret);
6245   return ret;
6246 }
6247
6248 static int
6249 api_l2_flags (vat_main_t * vam)
6250 {
6251   unformat_input_t *i = vam->input;
6252   vl_api_l2_flags_t *mp;
6253   u32 sw_if_index;
6254   u32 feature_bitmap = 0;
6255   u8 sw_if_index_set = 0;
6256   int ret;
6257
6258   /* Parse args required to build the message */
6259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6260     {
6261       if (unformat (i, "sw_if_index %d", &sw_if_index))
6262         sw_if_index_set = 1;
6263       else if (unformat (i, "sw_if"))
6264         {
6265           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6266             {
6267               if (unformat
6268                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6269                 sw_if_index_set = 1;
6270             }
6271           else
6272             break;
6273         }
6274       else if (unformat (i, "learn"))
6275         feature_bitmap |= L2INPUT_FEAT_LEARN;
6276       else if (unformat (i, "forward"))
6277         feature_bitmap |= L2INPUT_FEAT_FWD;
6278       else if (unformat (i, "flood"))
6279         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6280       else if (unformat (i, "uu-flood"))
6281         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6282       else
6283         break;
6284     }
6285
6286   if (sw_if_index_set == 0)
6287     {
6288       errmsg ("missing interface name or sw_if_index");
6289       return -99;
6290     }
6291
6292   M (L2_FLAGS, mp);
6293
6294   mp->sw_if_index = ntohl (sw_if_index);
6295   mp->feature_bitmap = ntohl (feature_bitmap);
6296
6297   S (mp);
6298   W (ret);
6299   return ret;
6300 }
6301
6302 static int
6303 api_bridge_flags (vat_main_t * vam)
6304 {
6305   unformat_input_t *i = vam->input;
6306   vl_api_bridge_flags_t *mp;
6307   u32 bd_id;
6308   u8 bd_id_set = 0;
6309   u8 is_set = 1;
6310   u32 flags = 0;
6311   int ret;
6312
6313   /* Parse args required to build the message */
6314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6315     {
6316       if (unformat (i, "bd_id %d", &bd_id))
6317         bd_id_set = 1;
6318       else if (unformat (i, "learn"))
6319         flags |= L2_LEARN;
6320       else if (unformat (i, "forward"))
6321         flags |= L2_FWD;
6322       else if (unformat (i, "flood"))
6323         flags |= L2_FLOOD;
6324       else if (unformat (i, "uu-flood"))
6325         flags |= L2_UU_FLOOD;
6326       else if (unformat (i, "arp-term"))
6327         flags |= L2_ARP_TERM;
6328       else if (unformat (i, "off"))
6329         is_set = 0;
6330       else if (unformat (i, "disable"))
6331         is_set = 0;
6332       else
6333         break;
6334     }
6335
6336   if (bd_id_set == 0)
6337     {
6338       errmsg ("missing bridge domain");
6339       return -99;
6340     }
6341
6342   M (BRIDGE_FLAGS, mp);
6343
6344   mp->bd_id = ntohl (bd_id);
6345   mp->feature_bitmap = ntohl (flags);
6346   mp->is_set = is_set;
6347
6348   S (mp);
6349   W (ret);
6350   return ret;
6351 }
6352
6353 static int
6354 api_bd_ip_mac_add_del (vat_main_t * vam)
6355 {
6356   unformat_input_t *i = vam->input;
6357   vl_api_bd_ip_mac_add_del_t *mp;
6358   u32 bd_id;
6359   u8 is_ipv6 = 0;
6360   u8 is_add = 1;
6361   u8 bd_id_set = 0;
6362   u8 ip_set = 0;
6363   u8 mac_set = 0;
6364   ip4_address_t v4addr;
6365   ip6_address_t v6addr;
6366   u8 macaddr[6];
6367   int ret;
6368
6369
6370   /* Parse args required to build the message */
6371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6372     {
6373       if (unformat (i, "bd_id %d", &bd_id))
6374         {
6375           bd_id_set++;
6376         }
6377       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6378         {
6379           ip_set++;
6380         }
6381       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6382         {
6383           ip_set++;
6384           is_ipv6++;
6385         }
6386       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6387         {
6388           mac_set++;
6389         }
6390       else if (unformat (i, "del"))
6391         is_add = 0;
6392       else
6393         break;
6394     }
6395
6396   if (bd_id_set == 0)
6397     {
6398       errmsg ("missing bridge domain");
6399       return -99;
6400     }
6401   else if (ip_set == 0)
6402     {
6403       errmsg ("missing IP address");
6404       return -99;
6405     }
6406   else if (mac_set == 0)
6407     {
6408       errmsg ("missing MAC address");
6409       return -99;
6410     }
6411
6412   M (BD_IP_MAC_ADD_DEL, mp);
6413
6414   mp->bd_id = ntohl (bd_id);
6415   mp->is_ipv6 = is_ipv6;
6416   mp->is_add = is_add;
6417   if (is_ipv6)
6418     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6419   else
6420     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6421   clib_memcpy (mp->mac_address, macaddr, 6);
6422   S (mp);
6423   W (ret);
6424   return ret;
6425 }
6426
6427 static int
6428 api_tap_connect (vat_main_t * vam)
6429 {
6430   unformat_input_t *i = vam->input;
6431   vl_api_tap_connect_t *mp;
6432   u8 mac_address[6];
6433   u8 random_mac = 1;
6434   u8 name_set = 0;
6435   u8 *tap_name;
6436   u8 *tag = 0;
6437   ip4_address_t ip4_address;
6438   u32 ip4_mask_width;
6439   int ip4_address_set = 0;
6440   ip6_address_t ip6_address;
6441   u32 ip6_mask_width;
6442   int ip6_address_set = 0;
6443   int ret;
6444
6445   memset (mac_address, 0, sizeof (mac_address));
6446
6447   /* Parse args required to build the message */
6448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6449     {
6450       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6451         {
6452           random_mac = 0;
6453         }
6454       else if (unformat (i, "random-mac"))
6455         random_mac = 1;
6456       else if (unformat (i, "tapname %s", &tap_name))
6457         name_set = 1;
6458       else if (unformat (i, "tag %s", &tag))
6459         ;
6460       else if (unformat (i, "address %U/%d",
6461                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6462         ip4_address_set = 1;
6463       else if (unformat (i, "address %U/%d",
6464                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6465         ip6_address_set = 1;
6466       else
6467         break;
6468     }
6469
6470   if (name_set == 0)
6471     {
6472       errmsg ("missing tap name");
6473       return -99;
6474     }
6475   if (vec_len (tap_name) > 63)
6476     {
6477       errmsg ("tap name too long");
6478       return -99;
6479     }
6480   vec_add1 (tap_name, 0);
6481
6482   if (vec_len (tag) > 63)
6483     {
6484       errmsg ("tag too long");
6485       return -99;
6486     }
6487
6488   /* Construct the API message */
6489   M (TAP_CONNECT, mp);
6490
6491   mp->use_random_mac = random_mac;
6492   clib_memcpy (mp->mac_address, mac_address, 6);
6493   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6494   if (tag)
6495     clib_memcpy (mp->tag, tag, vec_len (tag));
6496
6497   if (ip4_address_set)
6498     {
6499       mp->ip4_address_set = 1;
6500       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6501       mp->ip4_mask_width = ip4_mask_width;
6502     }
6503   if (ip6_address_set)
6504     {
6505       mp->ip6_address_set = 1;
6506       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6507       mp->ip6_mask_width = ip6_mask_width;
6508     }
6509
6510   vec_free (tap_name);
6511   vec_free (tag);
6512
6513   /* send it... */
6514   S (mp);
6515
6516   /* Wait for a reply... */
6517   W (ret);
6518   return ret;
6519 }
6520
6521 static int
6522 api_tap_modify (vat_main_t * vam)
6523 {
6524   unformat_input_t *i = vam->input;
6525   vl_api_tap_modify_t *mp;
6526   u8 mac_address[6];
6527   u8 random_mac = 1;
6528   u8 name_set = 0;
6529   u8 *tap_name;
6530   u32 sw_if_index = ~0;
6531   u8 sw_if_index_set = 0;
6532   int ret;
6533
6534   memset (mac_address, 0, sizeof (mac_address));
6535
6536   /* Parse args required to build the message */
6537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6538     {
6539       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6540         sw_if_index_set = 1;
6541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6542         sw_if_index_set = 1;
6543       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6544         {
6545           random_mac = 0;
6546         }
6547       else if (unformat (i, "random-mac"))
6548         random_mac = 1;
6549       else if (unformat (i, "tapname %s", &tap_name))
6550         name_set = 1;
6551       else
6552         break;
6553     }
6554
6555   if (sw_if_index_set == 0)
6556     {
6557       errmsg ("missing vpp interface name");
6558       return -99;
6559     }
6560   if (name_set == 0)
6561     {
6562       errmsg ("missing tap name");
6563       return -99;
6564     }
6565   if (vec_len (tap_name) > 63)
6566     {
6567       errmsg ("tap name too long");
6568     }
6569   vec_add1 (tap_name, 0);
6570
6571   /* Construct the API message */
6572   M (TAP_MODIFY, mp);
6573
6574   mp->use_random_mac = random_mac;
6575   mp->sw_if_index = ntohl (sw_if_index);
6576   clib_memcpy (mp->mac_address, mac_address, 6);
6577   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6578   vec_free (tap_name);
6579
6580   /* send it... */
6581   S (mp);
6582
6583   /* Wait for a reply... */
6584   W (ret);
6585   return ret;
6586 }
6587
6588 static int
6589 api_tap_delete (vat_main_t * vam)
6590 {
6591   unformat_input_t *i = vam->input;
6592   vl_api_tap_delete_t *mp;
6593   u32 sw_if_index = ~0;
6594   u8 sw_if_index_set = 0;
6595   int ret;
6596
6597   /* Parse args required to build the message */
6598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6599     {
6600       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6601         sw_if_index_set = 1;
6602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6603         sw_if_index_set = 1;
6604       else
6605         break;
6606     }
6607
6608   if (sw_if_index_set == 0)
6609     {
6610       errmsg ("missing vpp interface name");
6611       return -99;
6612     }
6613
6614   /* Construct the API message */
6615   M (TAP_DELETE, mp);
6616
6617   mp->sw_if_index = ntohl (sw_if_index);
6618
6619   /* send it... */
6620   S (mp);
6621
6622   /* Wait for a reply... */
6623   W (ret);
6624   return ret;
6625 }
6626
6627 static int
6628 api_ip_add_del_route (vat_main_t * vam)
6629 {
6630   unformat_input_t *i = vam->input;
6631   vl_api_ip_add_del_route_t *mp;
6632   u32 sw_if_index = ~0, vrf_id = 0;
6633   u8 is_ipv6 = 0;
6634   u8 is_local = 0, is_drop = 0;
6635   u8 is_unreach = 0, is_prohibit = 0;
6636   u8 create_vrf_if_needed = 0;
6637   u8 is_add = 1;
6638   u32 next_hop_weight = 1;
6639   u8 not_last = 0;
6640   u8 is_multipath = 0;
6641   u8 address_set = 0;
6642   u8 address_length_set = 0;
6643   u32 next_hop_table_id = 0;
6644   u32 resolve_attempts = 0;
6645   u32 dst_address_length = 0;
6646   u8 next_hop_set = 0;
6647   ip4_address_t v4_dst_address, v4_next_hop_address;
6648   ip6_address_t v6_dst_address, v6_next_hop_address;
6649   int count = 1;
6650   int j;
6651   f64 before = 0;
6652   u32 random_add_del = 0;
6653   u32 *random_vector = 0;
6654   uword *random_hash;
6655   u32 random_seed = 0xdeaddabe;
6656   u32 classify_table_index = ~0;
6657   u8 is_classify = 0;
6658   u8 resolve_host = 0, resolve_attached = 0;
6659   mpls_label_t *next_hop_out_label_stack = NULL;
6660   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6661   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6662
6663   /* Parse args required to build the message */
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6667         ;
6668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6669         ;
6670       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6671         {
6672           address_set = 1;
6673           is_ipv6 = 0;
6674         }
6675       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6676         {
6677           address_set = 1;
6678           is_ipv6 = 1;
6679         }
6680       else if (unformat (i, "/%d", &dst_address_length))
6681         {
6682           address_length_set = 1;
6683         }
6684
6685       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6686                                          &v4_next_hop_address))
6687         {
6688           next_hop_set = 1;
6689         }
6690       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6691                                          &v6_next_hop_address))
6692         {
6693           next_hop_set = 1;
6694         }
6695       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6696         ;
6697       else if (unformat (i, "weight %d", &next_hop_weight))
6698         ;
6699       else if (unformat (i, "drop"))
6700         {
6701           is_drop = 1;
6702         }
6703       else if (unformat (i, "null-send-unreach"))
6704         {
6705           is_unreach = 1;
6706         }
6707       else if (unformat (i, "null-send-prohibit"))
6708         {
6709           is_prohibit = 1;
6710         }
6711       else if (unformat (i, "local"))
6712         {
6713           is_local = 1;
6714         }
6715       else if (unformat (i, "classify %d", &classify_table_index))
6716         {
6717           is_classify = 1;
6718         }
6719       else if (unformat (i, "del"))
6720         is_add = 0;
6721       else if (unformat (i, "add"))
6722         is_add = 1;
6723       else if (unformat (i, "not-last"))
6724         not_last = 1;
6725       else if (unformat (i, "resolve-via-host"))
6726         resolve_host = 1;
6727       else if (unformat (i, "resolve-via-attached"))
6728         resolve_attached = 1;
6729       else if (unformat (i, "multipath"))
6730         is_multipath = 1;
6731       else if (unformat (i, "vrf %d", &vrf_id))
6732         ;
6733       else if (unformat (i, "create-vrf"))
6734         create_vrf_if_needed = 1;
6735       else if (unformat (i, "count %d", &count))
6736         ;
6737       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6738         ;
6739       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6740         ;
6741       else if (unformat (i, "out-label %d", &next_hop_out_label))
6742         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6743       else if (unformat (i, "via-label %d", &next_hop_via_label))
6744         ;
6745       else if (unformat (i, "random"))
6746         random_add_del = 1;
6747       else if (unformat (i, "seed %d", &random_seed))
6748         ;
6749       else
6750         {
6751           clib_warning ("parse error '%U'", format_unformat_error, i);
6752           return -99;
6753         }
6754     }
6755
6756   if (!next_hop_set && !is_drop && !is_local &&
6757       !is_classify && !is_unreach && !is_prohibit &&
6758       MPLS_LABEL_INVALID == next_hop_via_label)
6759     {
6760       errmsg
6761         ("next hop / local / drop / unreach / prohibit / classify not set");
6762       return -99;
6763     }
6764
6765   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6766     {
6767       errmsg ("next hop and next-hop via label set");
6768       return -99;
6769     }
6770   if (address_set == 0)
6771     {
6772       errmsg ("missing addresses");
6773       return -99;
6774     }
6775
6776   if (address_length_set == 0)
6777     {
6778       errmsg ("missing address length");
6779       return -99;
6780     }
6781
6782   /* Generate a pile of unique, random routes */
6783   if (random_add_del)
6784     {
6785       u32 this_random_address;
6786       random_hash = hash_create (count, sizeof (uword));
6787
6788       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6789       for (j = 0; j <= count; j++)
6790         {
6791           do
6792             {
6793               this_random_address = random_u32 (&random_seed);
6794               this_random_address =
6795                 clib_host_to_net_u32 (this_random_address);
6796             }
6797           while (hash_get (random_hash, this_random_address));
6798           vec_add1 (random_vector, this_random_address);
6799           hash_set (random_hash, this_random_address, 1);
6800         }
6801       hash_free (random_hash);
6802       v4_dst_address.as_u32 = random_vector[0];
6803     }
6804
6805   if (count > 1)
6806     {
6807       /* Turn on async mode */
6808       vam->async_mode = 1;
6809       vam->async_errors = 0;
6810       before = vat_time_now (vam);
6811     }
6812
6813   for (j = 0; j < count; j++)
6814     {
6815       /* Construct the API message */
6816       M2 (IP_ADD_DEL_ROUTE, mp,
6817           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6818
6819       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6820       mp->table_id = ntohl (vrf_id);
6821       mp->create_vrf_if_needed = create_vrf_if_needed;
6822
6823       mp->is_add = is_add;
6824       mp->is_drop = is_drop;
6825       mp->is_unreach = is_unreach;
6826       mp->is_prohibit = is_prohibit;
6827       mp->is_ipv6 = is_ipv6;
6828       mp->is_local = is_local;
6829       mp->is_classify = is_classify;
6830       mp->is_multipath = is_multipath;
6831       mp->is_resolve_host = resolve_host;
6832       mp->is_resolve_attached = resolve_attached;
6833       mp->not_last = not_last;
6834       mp->next_hop_weight = next_hop_weight;
6835       mp->dst_address_length = dst_address_length;
6836       mp->next_hop_table_id = ntohl (next_hop_table_id);
6837       mp->classify_table_index = ntohl (classify_table_index);
6838       mp->next_hop_via_label = ntohl (next_hop_via_label);
6839       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6840       if (0 != mp->next_hop_n_out_labels)
6841         {
6842           memcpy (mp->next_hop_out_label_stack,
6843                   next_hop_out_label_stack,
6844                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6845           vec_free (next_hop_out_label_stack);
6846         }
6847
6848       if (is_ipv6)
6849         {
6850           clib_memcpy (mp->dst_address, &v6_dst_address,
6851                        sizeof (v6_dst_address));
6852           if (next_hop_set)
6853             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6854                          sizeof (v6_next_hop_address));
6855           increment_v6_address (&v6_dst_address);
6856         }
6857       else
6858         {
6859           clib_memcpy (mp->dst_address, &v4_dst_address,
6860                        sizeof (v4_dst_address));
6861           if (next_hop_set)
6862             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6863                          sizeof (v4_next_hop_address));
6864           if (random_add_del)
6865             v4_dst_address.as_u32 = random_vector[j + 1];
6866           else
6867             increment_v4_address (&v4_dst_address);
6868         }
6869       /* send it... */
6870       S (mp);
6871       /* If we receive SIGTERM, stop now... */
6872       if (vam->do_exit)
6873         break;
6874     }
6875
6876   /* When testing multiple add/del ops, use a control-ping to sync */
6877   if (count > 1)
6878     {
6879       vl_api_control_ping_t *mp_ping;
6880       f64 after;
6881       f64 timeout;
6882
6883       /* Shut off async mode */
6884       vam->async_mode = 0;
6885
6886       M (CONTROL_PING, mp_ping);
6887       S (mp_ping);
6888
6889       timeout = vat_time_now (vam) + 1.0;
6890       while (vat_time_now (vam) < timeout)
6891         if (vam->result_ready == 1)
6892           goto out;
6893       vam->retval = -99;
6894
6895     out:
6896       if (vam->retval == -99)
6897         errmsg ("timeout");
6898
6899       if (vam->async_errors > 0)
6900         {
6901           errmsg ("%d asynchronous errors", vam->async_errors);
6902           vam->retval = -98;
6903         }
6904       vam->async_errors = 0;
6905       after = vat_time_now (vam);
6906
6907       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6908       if (j > 0)
6909         count = j;
6910
6911       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6912              count, after - before, count / (after - before));
6913     }
6914   else
6915     {
6916       int ret;
6917
6918       /* Wait for a reply... */
6919       W (ret);
6920       return ret;
6921     }
6922
6923   /* Return the good/bad news */
6924   return (vam->retval);
6925 }
6926
6927 static int
6928 api_ip_mroute_add_del (vat_main_t * vam)
6929 {
6930   unformat_input_t *i = vam->input;
6931   vl_api_ip_mroute_add_del_t *mp;
6932   u32 sw_if_index = ~0, vrf_id = 0;
6933   u8 is_ipv6 = 0;
6934   u8 is_local = 0;
6935   u8 create_vrf_if_needed = 0;
6936   u8 is_add = 1;
6937   u8 address_set = 0;
6938   u32 grp_address_length = 0;
6939   ip4_address_t v4_grp_address, v4_src_address;
6940   ip6_address_t v6_grp_address, v6_src_address;
6941   mfib_itf_flags_t iflags = 0;
6942   mfib_entry_flags_t eflags = 0;
6943   int ret;
6944
6945   /* Parse args required to build the message */
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "sw_if_index %d", &sw_if_index))
6949         ;
6950       else if (unformat (i, "%U %U",
6951                          unformat_ip4_address, &v4_src_address,
6952                          unformat_ip4_address, &v4_grp_address))
6953         {
6954           grp_address_length = 64;
6955           address_set = 1;
6956           is_ipv6 = 0;
6957         }
6958       else if (unformat (i, "%U %U",
6959                          unformat_ip6_address, &v6_src_address,
6960                          unformat_ip6_address, &v6_grp_address))
6961         {
6962           grp_address_length = 256;
6963           address_set = 1;
6964           is_ipv6 = 1;
6965         }
6966       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6967         {
6968           memset (&v4_src_address, 0, sizeof (v4_src_address));
6969           grp_address_length = 32;
6970           address_set = 1;
6971           is_ipv6 = 0;
6972         }
6973       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6974         {
6975           memset (&v6_src_address, 0, sizeof (v6_src_address));
6976           grp_address_length = 128;
6977           address_set = 1;
6978           is_ipv6 = 1;
6979         }
6980       else if (unformat (i, "/%d", &grp_address_length))
6981         ;
6982       else if (unformat (i, "local"))
6983         {
6984           is_local = 1;
6985         }
6986       else if (unformat (i, "del"))
6987         is_add = 0;
6988       else if (unformat (i, "add"))
6989         is_add = 1;
6990       else if (unformat (i, "vrf %d", &vrf_id))
6991         ;
6992       else if (unformat (i, "create-vrf"))
6993         create_vrf_if_needed = 1;
6994       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6995         ;
6996       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6997         ;
6998       else
6999         {
7000           clib_warning ("parse error '%U'", format_unformat_error, i);
7001           return -99;
7002         }
7003     }
7004
7005   if (address_set == 0)
7006     {
7007       errmsg ("missing addresses\n");
7008       return -99;
7009     }
7010
7011   /* Construct the API message */
7012   M (IP_MROUTE_ADD_DEL, mp);
7013
7014   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7015   mp->table_id = ntohl (vrf_id);
7016   mp->create_vrf_if_needed = create_vrf_if_needed;
7017
7018   mp->is_add = is_add;
7019   mp->is_ipv6 = is_ipv6;
7020   mp->is_local = is_local;
7021   mp->itf_flags = ntohl (iflags);
7022   mp->entry_flags = ntohl (eflags);
7023   mp->grp_address_length = grp_address_length;
7024   mp->grp_address_length = ntohs (mp->grp_address_length);
7025
7026   if (is_ipv6)
7027     {
7028       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7029       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7030     }
7031   else
7032     {
7033       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7034       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7035
7036     }
7037
7038   /* send it... */
7039   S (mp);
7040   /* Wait for a reply... */
7041   W (ret);
7042   return ret;
7043 }
7044
7045 static int
7046 api_mpls_route_add_del (vat_main_t * vam)
7047 {
7048   unformat_input_t *i = vam->input;
7049   vl_api_mpls_route_add_del_t *mp;
7050   u32 sw_if_index = ~0, table_id = 0;
7051   u8 create_table_if_needed = 0;
7052   u8 is_add = 1;
7053   u32 next_hop_weight = 1;
7054   u8 is_multipath = 0;
7055   u32 next_hop_table_id = 0;
7056   u8 next_hop_set = 0;
7057   ip4_address_t v4_next_hop_address = {
7058     .as_u32 = 0,
7059   };
7060   ip6_address_t v6_next_hop_address = { {0} };
7061   int count = 1;
7062   int j;
7063   f64 before = 0;
7064   u32 classify_table_index = ~0;
7065   u8 is_classify = 0;
7066   u8 resolve_host = 0, resolve_attached = 0;
7067   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7068   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7069   mpls_label_t *next_hop_out_label_stack = NULL;
7070   mpls_label_t local_label = MPLS_LABEL_INVALID;
7071   u8 is_eos = 0;
7072   u8 next_hop_proto_is_ip4 = 1;
7073
7074   /* Parse args required to build the message */
7075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7076     {
7077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7078         ;
7079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7080         ;
7081       else if (unformat (i, "%d", &local_label))
7082         ;
7083       else if (unformat (i, "eos"))
7084         is_eos = 1;
7085       else if (unformat (i, "non-eos"))
7086         is_eos = 0;
7087       else if (unformat (i, "via %U", unformat_ip4_address,
7088                          &v4_next_hop_address))
7089         {
7090           next_hop_set = 1;
7091           next_hop_proto_is_ip4 = 1;
7092         }
7093       else if (unformat (i, "via %U", unformat_ip6_address,
7094                          &v6_next_hop_address))
7095         {
7096           next_hop_set = 1;
7097           next_hop_proto_is_ip4 = 0;
7098         }
7099       else if (unformat (i, "weight %d", &next_hop_weight))
7100         ;
7101       else if (unformat (i, "create-table"))
7102         create_table_if_needed = 1;
7103       else if (unformat (i, "classify %d", &classify_table_index))
7104         {
7105           is_classify = 1;
7106         }
7107       else if (unformat (i, "del"))
7108         is_add = 0;
7109       else if (unformat (i, "add"))
7110         is_add = 1;
7111       else if (unformat (i, "resolve-via-host"))
7112         resolve_host = 1;
7113       else if (unformat (i, "resolve-via-attached"))
7114         resolve_attached = 1;
7115       else if (unformat (i, "multipath"))
7116         is_multipath = 1;
7117       else if (unformat (i, "count %d", &count))
7118         ;
7119       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7120         {
7121           next_hop_set = 1;
7122           next_hop_proto_is_ip4 = 1;
7123         }
7124       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7125         {
7126           next_hop_set = 1;
7127           next_hop_proto_is_ip4 = 0;
7128         }
7129       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7130         ;
7131       else if (unformat (i, "via-label %d", &next_hop_via_label))
7132         ;
7133       else if (unformat (i, "out-label %d", &next_hop_out_label))
7134         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7135       else
7136         {
7137           clib_warning ("parse error '%U'", format_unformat_error, i);
7138           return -99;
7139         }
7140     }
7141
7142   if (!next_hop_set && !is_classify)
7143     {
7144       errmsg ("next hop / classify not set");
7145       return -99;
7146     }
7147
7148   if (MPLS_LABEL_INVALID == local_label)
7149     {
7150       errmsg ("missing label");
7151       return -99;
7152     }
7153
7154   if (count > 1)
7155     {
7156       /* Turn on async mode */
7157       vam->async_mode = 1;
7158       vam->async_errors = 0;
7159       before = vat_time_now (vam);
7160     }
7161
7162   for (j = 0; j < count; j++)
7163     {
7164       /* Construct the API message */
7165       M2 (MPLS_ROUTE_ADD_DEL, mp,
7166           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7167
7168       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7169       mp->mr_table_id = ntohl (table_id);
7170       mp->mr_create_table_if_needed = create_table_if_needed;
7171
7172       mp->mr_is_add = is_add;
7173       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7174       mp->mr_is_classify = is_classify;
7175       mp->mr_is_multipath = is_multipath;
7176       mp->mr_is_resolve_host = resolve_host;
7177       mp->mr_is_resolve_attached = resolve_attached;
7178       mp->mr_next_hop_weight = next_hop_weight;
7179       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7180       mp->mr_classify_table_index = ntohl (classify_table_index);
7181       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7182       mp->mr_label = ntohl (local_label);
7183       mp->mr_eos = is_eos;
7184
7185       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7186       if (0 != mp->mr_next_hop_n_out_labels)
7187         {
7188           memcpy (mp->mr_next_hop_out_label_stack,
7189                   next_hop_out_label_stack,
7190                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7191           vec_free (next_hop_out_label_stack);
7192         }
7193
7194       if (next_hop_set)
7195         {
7196           if (next_hop_proto_is_ip4)
7197             {
7198               clib_memcpy (mp->mr_next_hop,
7199                            &v4_next_hop_address,
7200                            sizeof (v4_next_hop_address));
7201             }
7202           else
7203             {
7204               clib_memcpy (mp->mr_next_hop,
7205                            &v6_next_hop_address,
7206                            sizeof (v6_next_hop_address));
7207             }
7208         }
7209       local_label++;
7210
7211       /* send it... */
7212       S (mp);
7213       /* If we receive SIGTERM, stop now... */
7214       if (vam->do_exit)
7215         break;
7216     }
7217
7218   /* When testing multiple add/del ops, use a control-ping to sync */
7219   if (count > 1)
7220     {
7221       vl_api_control_ping_t *mp_ping;
7222       f64 after;
7223       f64 timeout;
7224
7225       /* Shut off async mode */
7226       vam->async_mode = 0;
7227
7228       M (CONTROL_PING, mp_ping);
7229       S (mp_ping);
7230
7231       timeout = vat_time_now (vam) + 1.0;
7232       while (vat_time_now (vam) < timeout)
7233         if (vam->result_ready == 1)
7234           goto out;
7235       vam->retval = -99;
7236
7237     out:
7238       if (vam->retval == -99)
7239         errmsg ("timeout");
7240
7241       if (vam->async_errors > 0)
7242         {
7243           errmsg ("%d asynchronous errors", vam->async_errors);
7244           vam->retval = -98;
7245         }
7246       vam->async_errors = 0;
7247       after = vat_time_now (vam);
7248
7249       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7250       if (j > 0)
7251         count = j;
7252
7253       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7254              count, after - before, count / (after - before));
7255     }
7256   else
7257     {
7258       int ret;
7259
7260       /* Wait for a reply... */
7261       W (ret);
7262       return ret;
7263     }
7264
7265   /* Return the good/bad news */
7266   return (vam->retval);
7267 }
7268
7269 static int
7270 api_mpls_ip_bind_unbind (vat_main_t * vam)
7271 {
7272   unformat_input_t *i = vam->input;
7273   vl_api_mpls_ip_bind_unbind_t *mp;
7274   u32 ip_table_id = 0;
7275   u8 create_table_if_needed = 0;
7276   u8 is_bind = 1;
7277   u8 is_ip4 = 1;
7278   ip4_address_t v4_address;
7279   ip6_address_t v6_address;
7280   u32 address_length;
7281   u8 address_set = 0;
7282   mpls_label_t local_label = MPLS_LABEL_INVALID;
7283   int ret;
7284
7285   /* Parse args required to build the message */
7286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7287     {
7288       if (unformat (i, "%U/%d", unformat_ip4_address,
7289                     &v4_address, &address_length))
7290         {
7291           is_ip4 = 1;
7292           address_set = 1;
7293         }
7294       else if (unformat (i, "%U/%d", unformat_ip6_address,
7295                          &v6_address, &address_length))
7296         {
7297           is_ip4 = 0;
7298           address_set = 1;
7299         }
7300       else if (unformat (i, "%d", &local_label))
7301         ;
7302       else if (unformat (i, "create-table"))
7303         create_table_if_needed = 1;
7304       else if (unformat (i, "table-id %d", &ip_table_id))
7305         ;
7306       else if (unformat (i, "unbind"))
7307         is_bind = 0;
7308       else if (unformat (i, "bind"))
7309         is_bind = 1;
7310       else
7311         {
7312           clib_warning ("parse error '%U'", format_unformat_error, i);
7313           return -99;
7314         }
7315     }
7316
7317   if (!address_set)
7318     {
7319       errmsg ("IP addres not set");
7320       return -99;
7321     }
7322
7323   if (MPLS_LABEL_INVALID == local_label)
7324     {
7325       errmsg ("missing label");
7326       return -99;
7327     }
7328
7329   /* Construct the API message */
7330   M (MPLS_IP_BIND_UNBIND, mp);
7331
7332   mp->mb_create_table_if_needed = create_table_if_needed;
7333   mp->mb_is_bind = is_bind;
7334   mp->mb_is_ip4 = is_ip4;
7335   mp->mb_ip_table_id = ntohl (ip_table_id);
7336   mp->mb_mpls_table_id = 0;
7337   mp->mb_label = ntohl (local_label);
7338   mp->mb_address_length = address_length;
7339
7340   if (is_ip4)
7341     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7342   else
7343     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7344
7345   /* send it... */
7346   S (mp);
7347
7348   /* Wait for a reply... */
7349   W (ret);
7350   return ret;
7351 }
7352
7353 static int
7354 api_proxy_arp_add_del (vat_main_t * vam)
7355 {
7356   unformat_input_t *i = vam->input;
7357   vl_api_proxy_arp_add_del_t *mp;
7358   u32 vrf_id = 0;
7359   u8 is_add = 1;
7360   ip4_address_t lo, hi;
7361   u8 range_set = 0;
7362   int ret;
7363
7364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7365     {
7366       if (unformat (i, "vrf %d", &vrf_id))
7367         ;
7368       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7369                          unformat_ip4_address, &hi))
7370         range_set = 1;
7371       else if (unformat (i, "del"))
7372         is_add = 0;
7373       else
7374         {
7375           clib_warning ("parse error '%U'", format_unformat_error, i);
7376           return -99;
7377         }
7378     }
7379
7380   if (range_set == 0)
7381     {
7382       errmsg ("address range not set");
7383       return -99;
7384     }
7385
7386   M (PROXY_ARP_ADD_DEL, mp);
7387
7388   mp->vrf_id = ntohl (vrf_id);
7389   mp->is_add = is_add;
7390   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7391   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7392
7393   S (mp);
7394   W (ret);
7395   return ret;
7396 }
7397
7398 static int
7399 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7400 {
7401   unformat_input_t *i = vam->input;
7402   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7403   u32 sw_if_index;
7404   u8 enable = 1;
7405   u8 sw_if_index_set = 0;
7406   int ret;
7407
7408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7409     {
7410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7411         sw_if_index_set = 1;
7412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7413         sw_if_index_set = 1;
7414       else if (unformat (i, "enable"))
7415         enable = 1;
7416       else if (unformat (i, "disable"))
7417         enable = 0;
7418       else
7419         {
7420           clib_warning ("parse error '%U'", format_unformat_error, i);
7421           return -99;
7422         }
7423     }
7424
7425   if (sw_if_index_set == 0)
7426     {
7427       errmsg ("missing interface name or sw_if_index");
7428       return -99;
7429     }
7430
7431   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7432
7433   mp->sw_if_index = ntohl (sw_if_index);
7434   mp->enable_disable = enable;
7435
7436   S (mp);
7437   W (ret);
7438   return ret;
7439 }
7440
7441 static int
7442 api_mpls_tunnel_add_del (vat_main_t * vam)
7443 {
7444   unformat_input_t *i = vam->input;
7445   vl_api_mpls_tunnel_add_del_t *mp;
7446
7447   u8 is_add = 1;
7448   u8 l2_only = 0;
7449   u32 sw_if_index = ~0;
7450   u32 next_hop_sw_if_index = ~0;
7451   u32 next_hop_proto_is_ip4 = 1;
7452
7453   u32 next_hop_table_id = 0;
7454   ip4_address_t v4_next_hop_address = {
7455     .as_u32 = 0,
7456   };
7457   ip6_address_t v6_next_hop_address = { {0} };
7458   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7459   int ret;
7460
7461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7462     {
7463       if (unformat (i, "add"))
7464         is_add = 1;
7465       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7466         is_add = 0;
7467       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7468         ;
7469       else if (unformat (i, "via %U",
7470                          unformat_ip4_address, &v4_next_hop_address))
7471         {
7472           next_hop_proto_is_ip4 = 1;
7473         }
7474       else if (unformat (i, "via %U",
7475                          unformat_ip6_address, &v6_next_hop_address))
7476         {
7477           next_hop_proto_is_ip4 = 0;
7478         }
7479       else if (unformat (i, "l2-only"))
7480         l2_only = 1;
7481       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7482         ;
7483       else if (unformat (i, "out-label %d", &next_hop_out_label))
7484         vec_add1 (labels, ntohl (next_hop_out_label));
7485       else
7486         {
7487           clib_warning ("parse error '%U'", format_unformat_error, i);
7488           return -99;
7489         }
7490     }
7491
7492   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7493
7494   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7495   mp->mt_sw_if_index = ntohl (sw_if_index);
7496   mp->mt_is_add = is_add;
7497   mp->mt_l2_only = l2_only;
7498   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7499   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7500
7501   mp->mt_next_hop_n_out_labels = vec_len (labels);
7502
7503   if (0 != mp->mt_next_hop_n_out_labels)
7504     {
7505       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7506                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7507       vec_free (labels);
7508     }
7509
7510   if (next_hop_proto_is_ip4)
7511     {
7512       clib_memcpy (mp->mt_next_hop,
7513                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7514     }
7515   else
7516     {
7517       clib_memcpy (mp->mt_next_hop,
7518                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7519     }
7520
7521   S (mp);
7522   W (ret);
7523   return ret;
7524 }
7525
7526 static int
7527 api_sw_interface_set_unnumbered (vat_main_t * vam)
7528 {
7529   unformat_input_t *i = vam->input;
7530   vl_api_sw_interface_set_unnumbered_t *mp;
7531   u32 sw_if_index;
7532   u32 unnum_sw_index = ~0;
7533   u8 is_add = 1;
7534   u8 sw_if_index_set = 0;
7535   int ret;
7536
7537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7538     {
7539       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7540         sw_if_index_set = 1;
7541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7542         sw_if_index_set = 1;
7543       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7544         ;
7545       else if (unformat (i, "del"))
7546         is_add = 0;
7547       else
7548         {
7549           clib_warning ("parse error '%U'", format_unformat_error, i);
7550           return -99;
7551         }
7552     }
7553
7554   if (sw_if_index_set == 0)
7555     {
7556       errmsg ("missing interface name or sw_if_index");
7557       return -99;
7558     }
7559
7560   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7561
7562   mp->sw_if_index = ntohl (sw_if_index);
7563   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7564   mp->is_add = is_add;
7565
7566   S (mp);
7567   W (ret);
7568   return ret;
7569 }
7570
7571 static int
7572 api_ip_neighbor_add_del (vat_main_t * vam)
7573 {
7574   unformat_input_t *i = vam->input;
7575   vl_api_ip_neighbor_add_del_t *mp;
7576   u32 sw_if_index;
7577   u8 sw_if_index_set = 0;
7578   u8 is_add = 1;
7579   u8 is_static = 0;
7580   u8 is_no_fib_entry = 0;
7581   u8 mac_address[6];
7582   u8 mac_set = 0;
7583   u8 v4_address_set = 0;
7584   u8 v6_address_set = 0;
7585   ip4_address_t v4address;
7586   ip6_address_t v6address;
7587   int ret;
7588
7589   memset (mac_address, 0, sizeof (mac_address));
7590
7591   /* Parse args required to build the message */
7592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7593     {
7594       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7595         {
7596           mac_set = 1;
7597         }
7598       else if (unformat (i, "del"))
7599         is_add = 0;
7600       else
7601         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7602         sw_if_index_set = 1;
7603       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7604         sw_if_index_set = 1;
7605       else if (unformat (i, "is_static"))
7606         is_static = 1;
7607       else if (unformat (i, "no-fib-entry"))
7608         is_no_fib_entry = 1;
7609       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7610         v4_address_set = 1;
7611       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7612         v6_address_set = 1;
7613       else
7614         {
7615           clib_warning ("parse error '%U'", format_unformat_error, i);
7616           return -99;
7617         }
7618     }
7619
7620   if (sw_if_index_set == 0)
7621     {
7622       errmsg ("missing interface name or sw_if_index");
7623       return -99;
7624     }
7625   if (v4_address_set && v6_address_set)
7626     {
7627       errmsg ("both v4 and v6 addresses set");
7628       return -99;
7629     }
7630   if (!v4_address_set && !v6_address_set)
7631     {
7632       errmsg ("no address set");
7633       return -99;
7634     }
7635
7636   /* Construct the API message */
7637   M (IP_NEIGHBOR_ADD_DEL, mp);
7638
7639   mp->sw_if_index = ntohl (sw_if_index);
7640   mp->is_add = is_add;
7641   mp->is_static = is_static;
7642   mp->is_no_adj_fib = is_no_fib_entry;
7643   if (mac_set)
7644     clib_memcpy (mp->mac_address, mac_address, 6);
7645   if (v6_address_set)
7646     {
7647       mp->is_ipv6 = 1;
7648       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7649     }
7650   else
7651     {
7652       /* mp->is_ipv6 = 0; via memset in M macro above */
7653       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7654     }
7655
7656   /* send it... */
7657   S (mp);
7658
7659   /* Wait for a reply, return good/bad news  */
7660   W (ret);
7661   return ret;
7662 }
7663
7664 static int
7665 api_reset_vrf (vat_main_t * vam)
7666 {
7667   unformat_input_t *i = vam->input;
7668   vl_api_reset_vrf_t *mp;
7669   u32 vrf_id = 0;
7670   u8 is_ipv6 = 0;
7671   u8 vrf_id_set = 0;
7672   int ret;
7673
7674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7675     {
7676       if (unformat (i, "vrf %d", &vrf_id))
7677         vrf_id_set = 1;
7678       else if (unformat (i, "ipv6"))
7679         is_ipv6 = 1;
7680       else
7681         {
7682           clib_warning ("parse error '%U'", format_unformat_error, i);
7683           return -99;
7684         }
7685     }
7686
7687   if (vrf_id_set == 0)
7688     {
7689       errmsg ("missing vrf id");
7690       return -99;
7691     }
7692
7693   M (RESET_VRF, mp);
7694
7695   mp->vrf_id = ntohl (vrf_id);
7696   mp->is_ipv6 = is_ipv6;
7697
7698   S (mp);
7699   W (ret);
7700   return ret;
7701 }
7702
7703 static int
7704 api_create_vlan_subif (vat_main_t * vam)
7705 {
7706   unformat_input_t *i = vam->input;
7707   vl_api_create_vlan_subif_t *mp;
7708   u32 sw_if_index;
7709   u8 sw_if_index_set = 0;
7710   u32 vlan_id;
7711   u8 vlan_id_set = 0;
7712   int ret;
7713
7714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7715     {
7716       if (unformat (i, "sw_if_index %d", &sw_if_index))
7717         sw_if_index_set = 1;
7718       else
7719         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7720         sw_if_index_set = 1;
7721       else if (unformat (i, "vlan %d", &vlan_id))
7722         vlan_id_set = 1;
7723       else
7724         {
7725           clib_warning ("parse error '%U'", format_unformat_error, i);
7726           return -99;
7727         }
7728     }
7729
7730   if (sw_if_index_set == 0)
7731     {
7732       errmsg ("missing interface name or sw_if_index");
7733       return -99;
7734     }
7735
7736   if (vlan_id_set == 0)
7737     {
7738       errmsg ("missing vlan_id");
7739       return -99;
7740     }
7741   M (CREATE_VLAN_SUBIF, mp);
7742
7743   mp->sw_if_index = ntohl (sw_if_index);
7744   mp->vlan_id = ntohl (vlan_id);
7745
7746   S (mp);
7747   W (ret);
7748   return ret;
7749 }
7750
7751 #define foreach_create_subif_bit                \
7752 _(no_tags)                                      \
7753 _(one_tag)                                      \
7754 _(two_tags)                                     \
7755 _(dot1ad)                                       \
7756 _(exact_match)                                  \
7757 _(default_sub)                                  \
7758 _(outer_vlan_id_any)                            \
7759 _(inner_vlan_id_any)
7760
7761 static int
7762 api_create_subif (vat_main_t * vam)
7763 {
7764   unformat_input_t *i = vam->input;
7765   vl_api_create_subif_t *mp;
7766   u32 sw_if_index;
7767   u8 sw_if_index_set = 0;
7768   u32 sub_id;
7769   u8 sub_id_set = 0;
7770   u32 no_tags = 0;
7771   u32 one_tag = 0;
7772   u32 two_tags = 0;
7773   u32 dot1ad = 0;
7774   u32 exact_match = 0;
7775   u32 default_sub = 0;
7776   u32 outer_vlan_id_any = 0;
7777   u32 inner_vlan_id_any = 0;
7778   u32 tmp;
7779   u16 outer_vlan_id = 0;
7780   u16 inner_vlan_id = 0;
7781   int ret;
7782
7783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7784     {
7785       if (unformat (i, "sw_if_index %d", &sw_if_index))
7786         sw_if_index_set = 1;
7787       else
7788         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7789         sw_if_index_set = 1;
7790       else if (unformat (i, "sub_id %d", &sub_id))
7791         sub_id_set = 1;
7792       else if (unformat (i, "outer_vlan_id %d", &tmp))
7793         outer_vlan_id = tmp;
7794       else if (unformat (i, "inner_vlan_id %d", &tmp))
7795         inner_vlan_id = tmp;
7796
7797 #define _(a) else if (unformat (i, #a)) a = 1 ;
7798       foreach_create_subif_bit
7799 #undef _
7800         else
7801         {
7802           clib_warning ("parse error '%U'", format_unformat_error, i);
7803           return -99;
7804         }
7805     }
7806
7807   if (sw_if_index_set == 0)
7808     {
7809       errmsg ("missing interface name or sw_if_index");
7810       return -99;
7811     }
7812
7813   if (sub_id_set == 0)
7814     {
7815       errmsg ("missing sub_id");
7816       return -99;
7817     }
7818   M (CREATE_SUBIF, mp);
7819
7820   mp->sw_if_index = ntohl (sw_if_index);
7821   mp->sub_id = ntohl (sub_id);
7822
7823 #define _(a) mp->a = a;
7824   foreach_create_subif_bit;
7825 #undef _
7826
7827   mp->outer_vlan_id = ntohs (outer_vlan_id);
7828   mp->inner_vlan_id = ntohs (inner_vlan_id);
7829
7830   S (mp);
7831   W (ret);
7832   return ret;
7833 }
7834
7835 static int
7836 api_oam_add_del (vat_main_t * vam)
7837 {
7838   unformat_input_t *i = vam->input;
7839   vl_api_oam_add_del_t *mp;
7840   u32 vrf_id = 0;
7841   u8 is_add = 1;
7842   ip4_address_t src, dst;
7843   u8 src_set = 0;
7844   u8 dst_set = 0;
7845   int ret;
7846
7847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7848     {
7849       if (unformat (i, "vrf %d", &vrf_id))
7850         ;
7851       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7852         src_set = 1;
7853       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7854         dst_set = 1;
7855       else if (unformat (i, "del"))
7856         is_add = 0;
7857       else
7858         {
7859           clib_warning ("parse error '%U'", format_unformat_error, i);
7860           return -99;
7861         }
7862     }
7863
7864   if (src_set == 0)
7865     {
7866       errmsg ("missing src addr");
7867       return -99;
7868     }
7869
7870   if (dst_set == 0)
7871     {
7872       errmsg ("missing dst addr");
7873       return -99;
7874     }
7875
7876   M (OAM_ADD_DEL, mp);
7877
7878   mp->vrf_id = ntohl (vrf_id);
7879   mp->is_add = is_add;
7880   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7881   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7882
7883   S (mp);
7884   W (ret);
7885   return ret;
7886 }
7887
7888 static int
7889 api_reset_fib (vat_main_t * vam)
7890 {
7891   unformat_input_t *i = vam->input;
7892   vl_api_reset_fib_t *mp;
7893   u32 vrf_id = 0;
7894   u8 is_ipv6 = 0;
7895   u8 vrf_id_set = 0;
7896
7897   int ret;
7898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7899     {
7900       if (unformat (i, "vrf %d", &vrf_id))
7901         vrf_id_set = 1;
7902       else if (unformat (i, "ipv6"))
7903         is_ipv6 = 1;
7904       else
7905         {
7906           clib_warning ("parse error '%U'", format_unformat_error, i);
7907           return -99;
7908         }
7909     }
7910
7911   if (vrf_id_set == 0)
7912     {
7913       errmsg ("missing vrf id");
7914       return -99;
7915     }
7916
7917   M (RESET_FIB, mp);
7918
7919   mp->vrf_id = ntohl (vrf_id);
7920   mp->is_ipv6 = is_ipv6;
7921
7922   S (mp);
7923   W (ret);
7924   return ret;
7925 }
7926
7927 static int
7928 api_dhcp_proxy_config (vat_main_t * vam)
7929 {
7930   unformat_input_t *i = vam->input;
7931   vl_api_dhcp_proxy_config_t *mp;
7932   u32 rx_vrf_id = 0;
7933   u32 server_vrf_id = 0;
7934   u8 is_add = 1;
7935   u8 v4_address_set = 0;
7936   u8 v6_address_set = 0;
7937   ip4_address_t v4address;
7938   ip6_address_t v6address;
7939   u8 v4_src_address_set = 0;
7940   u8 v6_src_address_set = 0;
7941   ip4_address_t v4srcaddress;
7942   ip6_address_t v6srcaddress;
7943   int ret;
7944
7945   /* Parse args required to build the message */
7946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7947     {
7948       if (unformat (i, "del"))
7949         is_add = 0;
7950       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7951         ;
7952       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7953         ;
7954       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7955         v4_address_set = 1;
7956       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7957         v6_address_set = 1;
7958       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7959         v4_src_address_set = 1;
7960       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7961         v6_src_address_set = 1;
7962       else
7963         break;
7964     }
7965
7966   if (v4_address_set && v6_address_set)
7967     {
7968       errmsg ("both v4 and v6 server addresses set");
7969       return -99;
7970     }
7971   if (!v4_address_set && !v6_address_set)
7972     {
7973       errmsg ("no server addresses set");
7974       return -99;
7975     }
7976
7977   if (v4_src_address_set && v6_src_address_set)
7978     {
7979       errmsg ("both v4 and v6  src addresses set");
7980       return -99;
7981     }
7982   if (!v4_src_address_set && !v6_src_address_set)
7983     {
7984       errmsg ("no src addresses set");
7985       return -99;
7986     }
7987
7988   if (!(v4_src_address_set && v4_address_set) &&
7989       !(v6_src_address_set && v6_address_set))
7990     {
7991       errmsg ("no matching server and src addresses set");
7992       return -99;
7993     }
7994
7995   /* Construct the API message */
7996   M (DHCP_PROXY_CONFIG, mp);
7997
7998   mp->is_add = is_add;
7999   mp->rx_vrf_id = ntohl (rx_vrf_id);
8000   mp->server_vrf_id = ntohl (server_vrf_id);
8001   if (v6_address_set)
8002     {
8003       mp->is_ipv6 = 1;
8004       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8005       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8006     }
8007   else
8008     {
8009       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8010       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8011     }
8012
8013   /* send it... */
8014   S (mp);
8015
8016   /* Wait for a reply, return good/bad news  */
8017   W (ret);
8018   return ret;
8019 }
8020
8021 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8022 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8023
8024 static void
8025 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8026 {
8027   vat_main_t *vam = &vat_main;
8028   u32 i, count = mp->count;
8029   vl_api_dhcp_server_t *s;
8030
8031   if (mp->is_ipv6)
8032     print (vam->ofp,
8033            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8034            ntohl (mp->rx_vrf_id),
8035            format_ip6_address, mp->dhcp_src_address,
8036            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8037   else
8038     print (vam->ofp,
8039            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8040            ntohl (mp->rx_vrf_id),
8041            format_ip4_address, mp->dhcp_src_address,
8042            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8043
8044   for (i = 0; i < count; i++)
8045     {
8046       s = &mp->servers[i];
8047
8048       if (mp->is_ipv6)
8049         print (vam->ofp,
8050                " Server Table-ID %d, Server Address %U",
8051                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8052       else
8053         print (vam->ofp,
8054                " Server Table-ID %d, Server Address %U",
8055                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8056     }
8057 }
8058
8059 static void vl_api_dhcp_proxy_details_t_handler_json
8060   (vl_api_dhcp_proxy_details_t * mp)
8061 {
8062   vat_main_t *vam = &vat_main;
8063   vat_json_node_t *node = NULL;
8064   u32 i, count = mp->count;
8065   struct in_addr ip4;
8066   struct in6_addr ip6;
8067   vl_api_dhcp_server_t *s;
8068
8069   if (VAT_JSON_ARRAY != vam->json_tree.type)
8070     {
8071       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8072       vat_json_init_array (&vam->json_tree);
8073     }
8074   node = vat_json_array_add (&vam->json_tree);
8075
8076   vat_json_init_object (node);
8077   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8078   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8079   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8080
8081   if (mp->is_ipv6)
8082     {
8083       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8084       vat_json_object_add_ip6 (node, "src_address", ip6);
8085     }
8086   else
8087     {
8088       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8089       vat_json_object_add_ip4 (node, "src_address", ip4);
8090     }
8091
8092   for (i = 0; i < count; i++)
8093     {
8094       s = &mp->servers[i];
8095
8096       vat_json_object_add_uint (node, "server-table-id",
8097                                 ntohl (s->server_vrf_id));
8098
8099       if (mp->is_ipv6)
8100         {
8101           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8102           vat_json_object_add_ip4 (node, "src_address", ip4);
8103         }
8104       else
8105         {
8106           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8107           vat_json_object_add_ip6 (node, "server_address", ip6);
8108         }
8109     }
8110 }
8111
8112 static int
8113 api_dhcp_proxy_dump (vat_main_t * vam)
8114 {
8115   unformat_input_t *i = vam->input;
8116   vl_api_control_ping_t *mp_ping;
8117   vl_api_dhcp_proxy_dump_t *mp;
8118   u8 is_ipv6 = 0;
8119   int ret;
8120
8121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8122     {
8123       if (unformat (i, "ipv6"))
8124         is_ipv6 = 1;
8125       else
8126         {
8127           clib_warning ("parse error '%U'", format_unformat_error, i);
8128           return -99;
8129         }
8130     }
8131
8132   M (DHCP_PROXY_DUMP, mp);
8133
8134   mp->is_ip6 = is_ipv6;
8135   S (mp);
8136
8137   /* Use a control ping for synchronization */
8138   M (CONTROL_PING, mp_ping);
8139   S (mp_ping);
8140
8141   W (ret);
8142   return ret;
8143 }
8144
8145 static int
8146 api_dhcp_proxy_set_vss (vat_main_t * vam)
8147 {
8148   unformat_input_t *i = vam->input;
8149   vl_api_dhcp_proxy_set_vss_t *mp;
8150   u8 is_ipv6 = 0;
8151   u8 is_add = 1;
8152   u32 tbl_id;
8153   u8 tbl_id_set = 0;
8154   u32 oui;
8155   u8 oui_set = 0;
8156   u32 fib_id;
8157   u8 fib_id_set = 0;
8158   int ret;
8159
8160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8161     {
8162       if (unformat (i, "tbl_id %d", &tbl_id))
8163         tbl_id_set = 1;
8164       if (unformat (i, "fib_id %d", &fib_id))
8165         fib_id_set = 1;
8166       if (unformat (i, "oui %d", &oui))
8167         oui_set = 1;
8168       else if (unformat (i, "ipv6"))
8169         is_ipv6 = 1;
8170       else if (unformat (i, "del"))
8171         is_add = 0;
8172       else
8173         {
8174           clib_warning ("parse error '%U'", format_unformat_error, i);
8175           return -99;
8176         }
8177     }
8178
8179   if (tbl_id_set == 0)
8180     {
8181       errmsg ("missing tbl id");
8182       return -99;
8183     }
8184
8185   if (fib_id_set == 0)
8186     {
8187       errmsg ("missing fib id");
8188       return -99;
8189     }
8190   if (oui_set == 0)
8191     {
8192       errmsg ("missing oui");
8193       return -99;
8194     }
8195
8196   M (DHCP_PROXY_SET_VSS, mp);
8197   mp->tbl_id = ntohl (tbl_id);
8198   mp->fib_id = ntohl (fib_id);
8199   mp->oui = ntohl (oui);
8200   mp->is_ipv6 = is_ipv6;
8201   mp->is_add = is_add;
8202
8203   S (mp);
8204   W (ret);
8205   return ret;
8206 }
8207
8208 static int
8209 api_dhcp_client_config (vat_main_t * vam)
8210 {
8211   unformat_input_t *i = vam->input;
8212   vl_api_dhcp_client_config_t *mp;
8213   u32 sw_if_index;
8214   u8 sw_if_index_set = 0;
8215   u8 is_add = 1;
8216   u8 *hostname = 0;
8217   u8 disable_event = 0;
8218   int ret;
8219
8220   /* Parse args required to build the message */
8221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8222     {
8223       if (unformat (i, "del"))
8224         is_add = 0;
8225       else
8226         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8227         sw_if_index_set = 1;
8228       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8229         sw_if_index_set = 1;
8230       else if (unformat (i, "hostname %s", &hostname))
8231         ;
8232       else if (unformat (i, "disable_event"))
8233         disable_event = 1;
8234       else
8235         break;
8236     }
8237
8238   if (sw_if_index_set == 0)
8239     {
8240       errmsg ("missing interface name or sw_if_index");
8241       return -99;
8242     }
8243
8244   if (vec_len (hostname) > 63)
8245     {
8246       errmsg ("hostname too long");
8247     }
8248   vec_add1 (hostname, 0);
8249
8250   /* Construct the API message */
8251   M (DHCP_CLIENT_CONFIG, mp);
8252
8253   mp->sw_if_index = htonl (sw_if_index);
8254   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8255   vec_free (hostname);
8256   mp->is_add = is_add;
8257   mp->want_dhcp_event = disable_event ? 0 : 1;
8258   mp->pid = htonl (getpid ());
8259
8260   /* send it... */
8261   S (mp);
8262
8263   /* Wait for a reply, return good/bad news  */
8264   W (ret);
8265   return ret;
8266 }
8267
8268 static int
8269 api_set_ip_flow_hash (vat_main_t * vam)
8270 {
8271   unformat_input_t *i = vam->input;
8272   vl_api_set_ip_flow_hash_t *mp;
8273   u32 vrf_id = 0;
8274   u8 is_ipv6 = 0;
8275   u8 vrf_id_set = 0;
8276   u8 src = 0;
8277   u8 dst = 0;
8278   u8 sport = 0;
8279   u8 dport = 0;
8280   u8 proto = 0;
8281   u8 reverse = 0;
8282   int ret;
8283
8284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8285     {
8286       if (unformat (i, "vrf %d", &vrf_id))
8287         vrf_id_set = 1;
8288       else if (unformat (i, "ipv6"))
8289         is_ipv6 = 1;
8290       else if (unformat (i, "src"))
8291         src = 1;
8292       else if (unformat (i, "dst"))
8293         dst = 1;
8294       else if (unformat (i, "sport"))
8295         sport = 1;
8296       else if (unformat (i, "dport"))
8297         dport = 1;
8298       else if (unformat (i, "proto"))
8299         proto = 1;
8300       else if (unformat (i, "reverse"))
8301         reverse = 1;
8302
8303       else
8304         {
8305           clib_warning ("parse error '%U'", format_unformat_error, i);
8306           return -99;
8307         }
8308     }
8309
8310   if (vrf_id_set == 0)
8311     {
8312       errmsg ("missing vrf id");
8313       return -99;
8314     }
8315
8316   M (SET_IP_FLOW_HASH, mp);
8317   mp->src = src;
8318   mp->dst = dst;
8319   mp->sport = sport;
8320   mp->dport = dport;
8321   mp->proto = proto;
8322   mp->reverse = reverse;
8323   mp->vrf_id = ntohl (vrf_id);
8324   mp->is_ipv6 = is_ipv6;
8325
8326   S (mp);
8327   W (ret);
8328   return ret;
8329 }
8330
8331 static int
8332 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8333 {
8334   unformat_input_t *i = vam->input;
8335   vl_api_sw_interface_ip6_enable_disable_t *mp;
8336   u32 sw_if_index;
8337   u8 sw_if_index_set = 0;
8338   u8 enable = 0;
8339   int ret;
8340
8341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8342     {
8343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8344         sw_if_index_set = 1;
8345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8346         sw_if_index_set = 1;
8347       else if (unformat (i, "enable"))
8348         enable = 1;
8349       else if (unformat (i, "disable"))
8350         enable = 0;
8351       else
8352         {
8353           clib_warning ("parse error '%U'", format_unformat_error, i);
8354           return -99;
8355         }
8356     }
8357
8358   if (sw_if_index_set == 0)
8359     {
8360       errmsg ("missing interface name or sw_if_index");
8361       return -99;
8362     }
8363
8364   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8365
8366   mp->sw_if_index = ntohl (sw_if_index);
8367   mp->enable = enable;
8368
8369   S (mp);
8370   W (ret);
8371   return ret;
8372 }
8373
8374 static int
8375 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8376 {
8377   unformat_input_t *i = vam->input;
8378   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8379   u32 sw_if_index;
8380   u8 sw_if_index_set = 0;
8381   u8 v6_address_set = 0;
8382   ip6_address_t v6address;
8383   int ret;
8384
8385   /* Parse args required to build the message */
8386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8387     {
8388       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8389         sw_if_index_set = 1;
8390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8391         sw_if_index_set = 1;
8392       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8393         v6_address_set = 1;
8394       else
8395         break;
8396     }
8397
8398   if (sw_if_index_set == 0)
8399     {
8400       errmsg ("missing interface name or sw_if_index");
8401       return -99;
8402     }
8403   if (!v6_address_set)
8404     {
8405       errmsg ("no address set");
8406       return -99;
8407     }
8408
8409   /* Construct the API message */
8410   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8411
8412   mp->sw_if_index = ntohl (sw_if_index);
8413   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8414
8415   /* send it... */
8416   S (mp);
8417
8418   /* Wait for a reply, return good/bad news  */
8419   W (ret);
8420   return ret;
8421 }
8422
8423 static int
8424 api_ip6nd_proxy_add_del (vat_main_t * vam)
8425 {
8426   unformat_input_t *i = vam->input;
8427   vl_api_ip6nd_proxy_add_del_t *mp;
8428   u32 sw_if_index = ~0;
8429   u8 v6_address_set = 0;
8430   ip6_address_t v6address;
8431   u8 is_del = 0;
8432   int ret;
8433
8434   /* Parse args required to build the message */
8435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8436     {
8437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8438         ;
8439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8440         ;
8441       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8442         v6_address_set = 1;
8443       if (unformat (i, "del"))
8444         is_del = 1;
8445       else
8446         {
8447           clib_warning ("parse error '%U'", format_unformat_error, i);
8448           return -99;
8449         }
8450     }
8451
8452   if (sw_if_index == ~0)
8453     {
8454       errmsg ("missing interface name or sw_if_index");
8455       return -99;
8456     }
8457   if (!v6_address_set)
8458     {
8459       errmsg ("no address set");
8460       return -99;
8461     }
8462
8463   /* Construct the API message */
8464   M (IP6ND_PROXY_ADD_DEL, mp);
8465
8466   mp->is_del = is_del;
8467   mp->sw_if_index = ntohl (sw_if_index);
8468   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8469
8470   /* send it... */
8471   S (mp);
8472
8473   /* Wait for a reply, return good/bad news  */
8474   W (ret);
8475   return ret;
8476 }
8477
8478 static int
8479 api_ip6nd_proxy_dump (vat_main_t * vam)
8480 {
8481   vl_api_ip6nd_proxy_dump_t *mp;
8482   vl_api_control_ping_t *mp_ping;
8483   int ret;
8484
8485   M (IP6ND_PROXY_DUMP, mp);
8486
8487   S (mp);
8488
8489   /* Use a control ping for synchronization */
8490   M (CONTROL_PING, mp_ping);
8491   S (mp_ping);
8492
8493   W (ret);
8494   return ret;
8495 }
8496
8497 static void vl_api_ip6nd_proxy_details_t_handler
8498   (vl_api_ip6nd_proxy_details_t * mp)
8499 {
8500   vat_main_t *vam = &vat_main;
8501
8502   print (vam->ofp, "host %U sw_if_index %d",
8503          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8504 }
8505
8506 static void vl_api_ip6nd_proxy_details_t_handler_json
8507   (vl_api_ip6nd_proxy_details_t * mp)
8508 {
8509   vat_main_t *vam = &vat_main;
8510   struct in6_addr ip6;
8511   vat_json_node_t *node = NULL;
8512
8513   if (VAT_JSON_ARRAY != vam->json_tree.type)
8514     {
8515       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8516       vat_json_init_array (&vam->json_tree);
8517     }
8518   node = vat_json_array_add (&vam->json_tree);
8519
8520   vat_json_init_object (node);
8521   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8522
8523   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8524   vat_json_object_add_ip6 (node, "host", ip6);
8525 }
8526
8527 static int
8528 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8529 {
8530   unformat_input_t *i = vam->input;
8531   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8532   u32 sw_if_index;
8533   u8 sw_if_index_set = 0;
8534   u32 address_length = 0;
8535   u8 v6_address_set = 0;
8536   ip6_address_t v6address;
8537   u8 use_default = 0;
8538   u8 no_advertise = 0;
8539   u8 off_link = 0;
8540   u8 no_autoconfig = 0;
8541   u8 no_onlink = 0;
8542   u8 is_no = 0;
8543   u32 val_lifetime = 0;
8544   u32 pref_lifetime = 0;
8545   int ret;
8546
8547   /* Parse args required to build the message */
8548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8549     {
8550       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8551         sw_if_index_set = 1;
8552       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8553         sw_if_index_set = 1;
8554       else if (unformat (i, "%U/%d",
8555                          unformat_ip6_address, &v6address, &address_length))
8556         v6_address_set = 1;
8557       else if (unformat (i, "val_life %d", &val_lifetime))
8558         ;
8559       else if (unformat (i, "pref_life %d", &pref_lifetime))
8560         ;
8561       else if (unformat (i, "def"))
8562         use_default = 1;
8563       else if (unformat (i, "noadv"))
8564         no_advertise = 1;
8565       else if (unformat (i, "offl"))
8566         off_link = 1;
8567       else if (unformat (i, "noauto"))
8568         no_autoconfig = 1;
8569       else if (unformat (i, "nolink"))
8570         no_onlink = 1;
8571       else if (unformat (i, "isno"))
8572         is_no = 1;
8573       else
8574         {
8575           clib_warning ("parse error '%U'", format_unformat_error, i);
8576           return -99;
8577         }
8578     }
8579
8580   if (sw_if_index_set == 0)
8581     {
8582       errmsg ("missing interface name or sw_if_index");
8583       return -99;
8584     }
8585   if (!v6_address_set)
8586     {
8587       errmsg ("no address set");
8588       return -99;
8589     }
8590
8591   /* Construct the API message */
8592   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8593
8594   mp->sw_if_index = ntohl (sw_if_index);
8595   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8596   mp->address_length = address_length;
8597   mp->use_default = use_default;
8598   mp->no_advertise = no_advertise;
8599   mp->off_link = off_link;
8600   mp->no_autoconfig = no_autoconfig;
8601   mp->no_onlink = no_onlink;
8602   mp->is_no = is_no;
8603   mp->val_lifetime = ntohl (val_lifetime);
8604   mp->pref_lifetime = ntohl (pref_lifetime);
8605
8606   /* send it... */
8607   S (mp);
8608
8609   /* Wait for a reply, return good/bad news  */
8610   W (ret);
8611   return ret;
8612 }
8613
8614 static int
8615 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8616 {
8617   unformat_input_t *i = vam->input;
8618   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8619   u32 sw_if_index;
8620   u8 sw_if_index_set = 0;
8621   u8 suppress = 0;
8622   u8 managed = 0;
8623   u8 other = 0;
8624   u8 ll_option = 0;
8625   u8 send_unicast = 0;
8626   u8 cease = 0;
8627   u8 is_no = 0;
8628   u8 default_router = 0;
8629   u32 max_interval = 0;
8630   u32 min_interval = 0;
8631   u32 lifetime = 0;
8632   u32 initial_count = 0;
8633   u32 initial_interval = 0;
8634   int ret;
8635
8636
8637   /* Parse args required to build the message */
8638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8639     {
8640       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8641         sw_if_index_set = 1;
8642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8643         sw_if_index_set = 1;
8644       else if (unformat (i, "maxint %d", &max_interval))
8645         ;
8646       else if (unformat (i, "minint %d", &min_interval))
8647         ;
8648       else if (unformat (i, "life %d", &lifetime))
8649         ;
8650       else if (unformat (i, "count %d", &initial_count))
8651         ;
8652       else if (unformat (i, "interval %d", &initial_interval))
8653         ;
8654       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8655         suppress = 1;
8656       else if (unformat (i, "managed"))
8657         managed = 1;
8658       else if (unformat (i, "other"))
8659         other = 1;
8660       else if (unformat (i, "ll"))
8661         ll_option = 1;
8662       else if (unformat (i, "send"))
8663         send_unicast = 1;
8664       else if (unformat (i, "cease"))
8665         cease = 1;
8666       else if (unformat (i, "isno"))
8667         is_no = 1;
8668       else if (unformat (i, "def"))
8669         default_router = 1;
8670       else
8671         {
8672           clib_warning ("parse error '%U'", format_unformat_error, i);
8673           return -99;
8674         }
8675     }
8676
8677   if (sw_if_index_set == 0)
8678     {
8679       errmsg ("missing interface name or sw_if_index");
8680       return -99;
8681     }
8682
8683   /* Construct the API message */
8684   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8685
8686   mp->sw_if_index = ntohl (sw_if_index);
8687   mp->max_interval = ntohl (max_interval);
8688   mp->min_interval = ntohl (min_interval);
8689   mp->lifetime = ntohl (lifetime);
8690   mp->initial_count = ntohl (initial_count);
8691   mp->initial_interval = ntohl (initial_interval);
8692   mp->suppress = suppress;
8693   mp->managed = managed;
8694   mp->other = other;
8695   mp->ll_option = ll_option;
8696   mp->send_unicast = send_unicast;
8697   mp->cease = cease;
8698   mp->is_no = is_no;
8699   mp->default_router = default_router;
8700
8701   /* send it... */
8702   S (mp);
8703
8704   /* Wait for a reply, return good/bad news  */
8705   W (ret);
8706   return ret;
8707 }
8708
8709 static int
8710 api_set_arp_neighbor_limit (vat_main_t * vam)
8711 {
8712   unformat_input_t *i = vam->input;
8713   vl_api_set_arp_neighbor_limit_t *mp;
8714   u32 arp_nbr_limit;
8715   u8 limit_set = 0;
8716   u8 is_ipv6 = 0;
8717   int ret;
8718
8719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8720     {
8721       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8722         limit_set = 1;
8723       else if (unformat (i, "ipv6"))
8724         is_ipv6 = 1;
8725       else
8726         {
8727           clib_warning ("parse error '%U'", format_unformat_error, i);
8728           return -99;
8729         }
8730     }
8731
8732   if (limit_set == 0)
8733     {
8734       errmsg ("missing limit value");
8735       return -99;
8736     }
8737
8738   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8739
8740   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8741   mp->is_ipv6 = is_ipv6;
8742
8743   S (mp);
8744   W (ret);
8745   return ret;
8746 }
8747
8748 static int
8749 api_l2_patch_add_del (vat_main_t * vam)
8750 {
8751   unformat_input_t *i = vam->input;
8752   vl_api_l2_patch_add_del_t *mp;
8753   u32 rx_sw_if_index;
8754   u8 rx_sw_if_index_set = 0;
8755   u32 tx_sw_if_index;
8756   u8 tx_sw_if_index_set = 0;
8757   u8 is_add = 1;
8758   int ret;
8759
8760   /* Parse args required to build the message */
8761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8762     {
8763       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8764         rx_sw_if_index_set = 1;
8765       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8766         tx_sw_if_index_set = 1;
8767       else if (unformat (i, "rx"))
8768         {
8769           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8770             {
8771               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8772                             &rx_sw_if_index))
8773                 rx_sw_if_index_set = 1;
8774             }
8775           else
8776             break;
8777         }
8778       else if (unformat (i, "tx"))
8779         {
8780           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8781             {
8782               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8783                             &tx_sw_if_index))
8784                 tx_sw_if_index_set = 1;
8785             }
8786           else
8787             break;
8788         }
8789       else if (unformat (i, "del"))
8790         is_add = 0;
8791       else
8792         break;
8793     }
8794
8795   if (rx_sw_if_index_set == 0)
8796     {
8797       errmsg ("missing rx interface name or rx_sw_if_index");
8798       return -99;
8799     }
8800
8801   if (tx_sw_if_index_set == 0)
8802     {
8803       errmsg ("missing tx interface name or tx_sw_if_index");
8804       return -99;
8805     }
8806
8807   M (L2_PATCH_ADD_DEL, mp);
8808
8809   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8810   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8811   mp->is_add = is_add;
8812
8813   S (mp);
8814   W (ret);
8815   return ret;
8816 }
8817
8818 u8 is_del;
8819 u8 localsid_addr[16];
8820 u8 end_psp;
8821 u8 behavior;
8822 u32 sw_if_index;
8823 u32 vlan_index;
8824 u32 fib_table;
8825 u8 nh_addr[16];
8826
8827 static int
8828 api_sr_localsid_add_del (vat_main_t * vam)
8829 {
8830   unformat_input_t *i = vam->input;
8831   vl_api_sr_localsid_add_del_t *mp;
8832
8833   u8 is_del;
8834   ip6_address_t localsid;
8835   u8 end_psp = 0;
8836   u8 behavior = ~0;
8837   u32 sw_if_index;
8838   u32 fib_table = ~(u32) 0;
8839   ip6_address_t next_hop;
8840
8841   bool nexthop_set = 0;
8842
8843   int ret;
8844
8845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8846     {
8847       if (unformat (i, "del"))
8848         is_del = 1;
8849       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8850       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8851         nexthop_set = 1;
8852       else if (unformat (i, "behavior %u", &behavior));
8853       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8854       else if (unformat (i, "fib-table %u", &fib_table));
8855       else if (unformat (i, "end.psp %u", &behavior));
8856       else
8857         break;
8858     }
8859
8860   M (SR_LOCALSID_ADD_DEL, mp);
8861
8862   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8863   if (nexthop_set)
8864     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8865   mp->behavior = behavior;
8866   mp->sw_if_index = ntohl (sw_if_index);
8867   mp->fib_table = ntohl (fib_table);
8868   mp->end_psp = end_psp;
8869   mp->is_del = is_del;
8870
8871   S (mp);
8872   W (ret);
8873   return ret;
8874 }
8875
8876 static int
8877 api_ioam_enable (vat_main_t * vam)
8878 {
8879   unformat_input_t *input = vam->input;
8880   vl_api_ioam_enable_t *mp;
8881   u32 id = 0;
8882   int has_trace_option = 0;
8883   int has_pot_option = 0;
8884   int has_seqno_option = 0;
8885   int has_analyse_option = 0;
8886   int ret;
8887
8888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8889     {
8890       if (unformat (input, "trace"))
8891         has_trace_option = 1;
8892       else if (unformat (input, "pot"))
8893         has_pot_option = 1;
8894       else if (unformat (input, "seqno"))
8895         has_seqno_option = 1;
8896       else if (unformat (input, "analyse"))
8897         has_analyse_option = 1;
8898       else
8899         break;
8900     }
8901   M (IOAM_ENABLE, mp);
8902   mp->id = htons (id);
8903   mp->seqno = has_seqno_option;
8904   mp->analyse = has_analyse_option;
8905   mp->pot_enable = has_pot_option;
8906   mp->trace_enable = has_trace_option;
8907
8908   S (mp);
8909   W (ret);
8910   return ret;
8911 }
8912
8913
8914 static int
8915 api_ioam_disable (vat_main_t * vam)
8916 {
8917   vl_api_ioam_disable_t *mp;
8918   int ret;
8919
8920   M (IOAM_DISABLE, mp);
8921   S (mp);
8922   W (ret);
8923   return ret;
8924 }
8925
8926 #define foreach_tcp_proto_field                 \
8927 _(src_port)                                     \
8928 _(dst_port)
8929
8930 #define foreach_udp_proto_field                 \
8931 _(src_port)                                     \
8932 _(dst_port)
8933
8934 #define foreach_ip4_proto_field                 \
8935 _(src_address)                                  \
8936 _(dst_address)                                  \
8937 _(tos)                                          \
8938 _(length)                                       \
8939 _(fragment_id)                                  \
8940 _(ttl)                                          \
8941 _(protocol)                                     \
8942 _(checksum)
8943
8944 typedef struct
8945 {
8946   u16 src_port, dst_port;
8947 } tcpudp_header_t;
8948
8949 #if VPP_API_TEST_BUILTIN == 0
8950 uword
8951 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8952 {
8953   u8 **maskp = va_arg (*args, u8 **);
8954   u8 *mask = 0;
8955   u8 found_something = 0;
8956   tcp_header_t *tcp;
8957
8958 #define _(a) u8 a=0;
8959   foreach_tcp_proto_field;
8960 #undef _
8961
8962   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (0);
8965 #define _(a) else if (unformat (input, #a)) a=1;
8966       foreach_tcp_proto_field
8967 #undef _
8968         else
8969         break;
8970     }
8971
8972 #define _(a) found_something += a;
8973   foreach_tcp_proto_field;
8974 #undef _
8975
8976   if (found_something == 0)
8977     return 0;
8978
8979   vec_validate (mask, sizeof (*tcp) - 1);
8980
8981   tcp = (tcp_header_t *) mask;
8982
8983 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8984   foreach_tcp_proto_field;
8985 #undef _
8986
8987   *maskp = mask;
8988   return 1;
8989 }
8990
8991 uword
8992 unformat_udp_mask (unformat_input_t * input, va_list * args)
8993 {
8994   u8 **maskp = va_arg (*args, u8 **);
8995   u8 *mask = 0;
8996   u8 found_something = 0;
8997   udp_header_t *udp;
8998
8999 #define _(a) u8 a=0;
9000   foreach_udp_proto_field;
9001 #undef _
9002
9003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9004     {
9005       if (0);
9006 #define _(a) else if (unformat (input, #a)) a=1;
9007       foreach_udp_proto_field
9008 #undef _
9009         else
9010         break;
9011     }
9012
9013 #define _(a) found_something += a;
9014   foreach_udp_proto_field;
9015 #undef _
9016
9017   if (found_something == 0)
9018     return 0;
9019
9020   vec_validate (mask, sizeof (*udp) - 1);
9021
9022   udp = (udp_header_t *) mask;
9023
9024 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9025   foreach_udp_proto_field;
9026 #undef _
9027
9028   *maskp = mask;
9029   return 1;
9030 }
9031
9032 uword
9033 unformat_l4_mask (unformat_input_t * input, va_list * args)
9034 {
9035   u8 **maskp = va_arg (*args, u8 **);
9036   u16 src_port = 0, dst_port = 0;
9037   tcpudp_header_t *tcpudp;
9038
9039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9040     {
9041       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9042         return 1;
9043       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9044         return 1;
9045       else if (unformat (input, "src_port"))
9046         src_port = 0xFFFF;
9047       else if (unformat (input, "dst_port"))
9048         dst_port = 0xFFFF;
9049       else
9050         return 0;
9051     }
9052
9053   if (!src_port && !dst_port)
9054     return 0;
9055
9056   u8 *mask = 0;
9057   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9058
9059   tcpudp = (tcpudp_header_t *) mask;
9060   tcpudp->src_port = src_port;
9061   tcpudp->dst_port = dst_port;
9062
9063   *maskp = mask;
9064
9065   return 1;
9066 }
9067
9068 uword
9069 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9070 {
9071   u8 **maskp = va_arg (*args, u8 **);
9072   u8 *mask = 0;
9073   u8 found_something = 0;
9074   ip4_header_t *ip;
9075
9076 #define _(a) u8 a=0;
9077   foreach_ip4_proto_field;
9078 #undef _
9079   u8 version = 0;
9080   u8 hdr_length = 0;
9081
9082
9083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9084     {
9085       if (unformat (input, "version"))
9086         version = 1;
9087       else if (unformat (input, "hdr_length"))
9088         hdr_length = 1;
9089       else if (unformat (input, "src"))
9090         src_address = 1;
9091       else if (unformat (input, "dst"))
9092         dst_address = 1;
9093       else if (unformat (input, "proto"))
9094         protocol = 1;
9095
9096 #define _(a) else if (unformat (input, #a)) a=1;
9097       foreach_ip4_proto_field
9098 #undef _
9099         else
9100         break;
9101     }
9102
9103 #define _(a) found_something += a;
9104   foreach_ip4_proto_field;
9105 #undef _
9106
9107   if (found_something == 0)
9108     return 0;
9109
9110   vec_validate (mask, sizeof (*ip) - 1);
9111
9112   ip = (ip4_header_t *) mask;
9113
9114 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9115   foreach_ip4_proto_field;
9116 #undef _
9117
9118   ip->ip_version_and_header_length = 0;
9119
9120   if (version)
9121     ip->ip_version_and_header_length |= 0xF0;
9122
9123   if (hdr_length)
9124     ip->ip_version_and_header_length |= 0x0F;
9125
9126   *maskp = mask;
9127   return 1;
9128 }
9129
9130 #define foreach_ip6_proto_field                 \
9131 _(src_address)                                  \
9132 _(dst_address)                                  \
9133 _(payload_length)                               \
9134 _(hop_limit)                                    \
9135 _(protocol)
9136
9137 uword
9138 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9139 {
9140   u8 **maskp = va_arg (*args, u8 **);
9141   u8 *mask = 0;
9142   u8 found_something = 0;
9143   ip6_header_t *ip;
9144   u32 ip_version_traffic_class_and_flow_label;
9145
9146 #define _(a) u8 a=0;
9147   foreach_ip6_proto_field;
9148 #undef _
9149   u8 version = 0;
9150   u8 traffic_class = 0;
9151   u8 flow_label = 0;
9152
9153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9154     {
9155       if (unformat (input, "version"))
9156         version = 1;
9157       else if (unformat (input, "traffic-class"))
9158         traffic_class = 1;
9159       else if (unformat (input, "flow-label"))
9160         flow_label = 1;
9161       else if (unformat (input, "src"))
9162         src_address = 1;
9163       else if (unformat (input, "dst"))
9164         dst_address = 1;
9165       else if (unformat (input, "proto"))
9166         protocol = 1;
9167
9168 #define _(a) else if (unformat (input, #a)) a=1;
9169       foreach_ip6_proto_field
9170 #undef _
9171         else
9172         break;
9173     }
9174
9175 #define _(a) found_something += a;
9176   foreach_ip6_proto_field;
9177 #undef _
9178
9179   if (found_something == 0)
9180     return 0;
9181
9182   vec_validate (mask, sizeof (*ip) - 1);
9183
9184   ip = (ip6_header_t *) mask;
9185
9186 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9187   foreach_ip6_proto_field;
9188 #undef _
9189
9190   ip_version_traffic_class_and_flow_label = 0;
9191
9192   if (version)
9193     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9194
9195   if (traffic_class)
9196     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9197
9198   if (flow_label)
9199     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9200
9201   ip->ip_version_traffic_class_and_flow_label =
9202     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9203
9204   *maskp = mask;
9205   return 1;
9206 }
9207
9208 uword
9209 unformat_l3_mask (unformat_input_t * input, va_list * args)
9210 {
9211   u8 **maskp = va_arg (*args, u8 **);
9212
9213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9214     {
9215       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9216         return 1;
9217       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9218         return 1;
9219       else
9220         break;
9221     }
9222   return 0;
9223 }
9224
9225 uword
9226 unformat_l2_mask (unformat_input_t * input, va_list * args)
9227 {
9228   u8 **maskp = va_arg (*args, u8 **);
9229   u8 *mask = 0;
9230   u8 src = 0;
9231   u8 dst = 0;
9232   u8 proto = 0;
9233   u8 tag1 = 0;
9234   u8 tag2 = 0;
9235   u8 ignore_tag1 = 0;
9236   u8 ignore_tag2 = 0;
9237   u8 cos1 = 0;
9238   u8 cos2 = 0;
9239   u8 dot1q = 0;
9240   u8 dot1ad = 0;
9241   int len = 14;
9242
9243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9244     {
9245       if (unformat (input, "src"))
9246         src = 1;
9247       else if (unformat (input, "dst"))
9248         dst = 1;
9249       else if (unformat (input, "proto"))
9250         proto = 1;
9251       else if (unformat (input, "tag1"))
9252         tag1 = 1;
9253       else if (unformat (input, "tag2"))
9254         tag2 = 1;
9255       else if (unformat (input, "ignore-tag1"))
9256         ignore_tag1 = 1;
9257       else if (unformat (input, "ignore-tag2"))
9258         ignore_tag2 = 1;
9259       else if (unformat (input, "cos1"))
9260         cos1 = 1;
9261       else if (unformat (input, "cos2"))
9262         cos2 = 1;
9263       else if (unformat (input, "dot1q"))
9264         dot1q = 1;
9265       else if (unformat (input, "dot1ad"))
9266         dot1ad = 1;
9267       else
9268         break;
9269     }
9270   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9271        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9272     return 0;
9273
9274   if (tag1 || ignore_tag1 || cos1 || dot1q)
9275     len = 18;
9276   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9277     len = 22;
9278
9279   vec_validate (mask, len - 1);
9280
9281   if (dst)
9282     memset (mask, 0xff, 6);
9283
9284   if (src)
9285     memset (mask + 6, 0xff, 6);
9286
9287   if (tag2 || dot1ad)
9288     {
9289       /* inner vlan tag */
9290       if (tag2)
9291         {
9292           mask[19] = 0xff;
9293           mask[18] = 0x0f;
9294         }
9295       if (cos2)
9296         mask[18] |= 0xe0;
9297       if (proto)
9298         mask[21] = mask[20] = 0xff;
9299       if (tag1)
9300         {
9301           mask[15] = 0xff;
9302           mask[14] = 0x0f;
9303         }
9304       if (cos1)
9305         mask[14] |= 0xe0;
9306       *maskp = mask;
9307       return 1;
9308     }
9309   if (tag1 | dot1q)
9310     {
9311       if (tag1)
9312         {
9313           mask[15] = 0xff;
9314           mask[14] = 0x0f;
9315         }
9316       if (cos1)
9317         mask[14] |= 0xe0;
9318       if (proto)
9319         mask[16] = mask[17] = 0xff;
9320
9321       *maskp = mask;
9322       return 1;
9323     }
9324   if (cos2)
9325     mask[18] |= 0xe0;
9326   if (cos1)
9327     mask[14] |= 0xe0;
9328   if (proto)
9329     mask[12] = mask[13] = 0xff;
9330
9331   *maskp = mask;
9332   return 1;
9333 }
9334
9335 uword
9336 unformat_classify_mask (unformat_input_t * input, va_list * args)
9337 {
9338   u8 **maskp = va_arg (*args, u8 **);
9339   u32 *skipp = va_arg (*args, u32 *);
9340   u32 *matchp = va_arg (*args, u32 *);
9341   u32 match;
9342   u8 *mask = 0;
9343   u8 *l2 = 0;
9344   u8 *l3 = 0;
9345   u8 *l4 = 0;
9346   int i;
9347
9348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9349     {
9350       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9351         ;
9352       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9353         ;
9354       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9355         ;
9356       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9357         ;
9358       else
9359         break;
9360     }
9361
9362   if (l4 && !l3)
9363     {
9364       vec_free (mask);
9365       vec_free (l2);
9366       vec_free (l4);
9367       return 0;
9368     }
9369
9370   if (mask || l2 || l3 || l4)
9371     {
9372       if (l2 || l3 || l4)
9373         {
9374           /* "With a free Ethernet header in every package" */
9375           if (l2 == 0)
9376             vec_validate (l2, 13);
9377           mask = l2;
9378           if (vec_len (l3))
9379             {
9380               vec_append (mask, l3);
9381               vec_free (l3);
9382             }
9383           if (vec_len (l4))
9384             {
9385               vec_append (mask, l4);
9386               vec_free (l4);
9387             }
9388         }
9389
9390       /* Scan forward looking for the first significant mask octet */
9391       for (i = 0; i < vec_len (mask); i++)
9392         if (mask[i])
9393           break;
9394
9395       /* compute (skip, match) params */
9396       *skipp = i / sizeof (u32x4);
9397       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9398
9399       /* Pad mask to an even multiple of the vector size */
9400       while (vec_len (mask) % sizeof (u32x4))
9401         vec_add1 (mask, 0);
9402
9403       match = vec_len (mask) / sizeof (u32x4);
9404
9405       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9406         {
9407           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9408           if (*tmp || *(tmp + 1))
9409             break;
9410           match--;
9411         }
9412       if (match == 0)
9413         clib_warning ("BUG: match 0");
9414
9415       _vec_len (mask) = match * sizeof (u32x4);
9416
9417       *matchp = match;
9418       *maskp = mask;
9419
9420       return 1;
9421     }
9422
9423   return 0;
9424 }
9425 #endif /* VPP_API_TEST_BUILTIN */
9426
9427 #define foreach_l2_next                         \
9428 _(drop, DROP)                                   \
9429 _(ethernet, ETHERNET_INPUT)                     \
9430 _(ip4, IP4_INPUT)                               \
9431 _(ip6, IP6_INPUT)
9432
9433 uword
9434 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9435 {
9436   u32 *miss_next_indexp = va_arg (*args, u32 *);
9437   u32 next_index = 0;
9438   u32 tmp;
9439
9440 #define _(n,N) \
9441   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9442   foreach_l2_next;
9443 #undef _
9444
9445   if (unformat (input, "%d", &tmp))
9446     {
9447       next_index = tmp;
9448       goto out;
9449     }
9450
9451   return 0;
9452
9453 out:
9454   *miss_next_indexp = next_index;
9455   return 1;
9456 }
9457
9458 #define foreach_ip_next                         \
9459 _(drop, DROP)                                   \
9460 _(local, LOCAL)                                 \
9461 _(rewrite, REWRITE)
9462
9463 uword
9464 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9465 {
9466   u32 *miss_next_indexp = va_arg (*args, u32 *);
9467   u32 next_index = 0;
9468   u32 tmp;
9469
9470 #define _(n,N) \
9471   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9472   foreach_ip_next;
9473 #undef _
9474
9475   if (unformat (input, "%d", &tmp))
9476     {
9477       next_index = tmp;
9478       goto out;
9479     }
9480
9481   return 0;
9482
9483 out:
9484   *miss_next_indexp = next_index;
9485   return 1;
9486 }
9487
9488 #define foreach_acl_next                        \
9489 _(deny, DENY)
9490
9491 uword
9492 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9493 {
9494   u32 *miss_next_indexp = va_arg (*args, u32 *);
9495   u32 next_index = 0;
9496   u32 tmp;
9497
9498 #define _(n,N) \
9499   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9500   foreach_acl_next;
9501 #undef _
9502
9503   if (unformat (input, "permit"))
9504     {
9505       next_index = ~0;
9506       goto out;
9507     }
9508   else if (unformat (input, "%d", &tmp))
9509     {
9510       next_index = tmp;
9511       goto out;
9512     }
9513
9514   return 0;
9515
9516 out:
9517   *miss_next_indexp = next_index;
9518   return 1;
9519 }
9520
9521 uword
9522 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9523 {
9524   u32 *r = va_arg (*args, u32 *);
9525
9526   if (unformat (input, "conform-color"))
9527     *r = POLICE_CONFORM;
9528   else if (unformat (input, "exceed-color"))
9529     *r = POLICE_EXCEED;
9530   else
9531     return 0;
9532
9533   return 1;
9534 }
9535
9536 static int
9537 api_classify_add_del_table (vat_main_t * vam)
9538 {
9539   unformat_input_t *i = vam->input;
9540   vl_api_classify_add_del_table_t *mp;
9541
9542   u32 nbuckets = 2;
9543   u32 skip = ~0;
9544   u32 match = ~0;
9545   int is_add = 1;
9546   int del_chain = 0;
9547   u32 table_index = ~0;
9548   u32 next_table_index = ~0;
9549   u32 miss_next_index = ~0;
9550   u32 memory_size = 32 << 20;
9551   u8 *mask = 0;
9552   u32 current_data_flag = 0;
9553   int current_data_offset = 0;
9554   int ret;
9555
9556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9557     {
9558       if (unformat (i, "del"))
9559         is_add = 0;
9560       else if (unformat (i, "del-chain"))
9561         {
9562           is_add = 0;
9563           del_chain = 1;
9564         }
9565       else if (unformat (i, "buckets %d", &nbuckets))
9566         ;
9567       else if (unformat (i, "memory_size %d", &memory_size))
9568         ;
9569       else if (unformat (i, "skip %d", &skip))
9570         ;
9571       else if (unformat (i, "match %d", &match))
9572         ;
9573       else if (unformat (i, "table %d", &table_index))
9574         ;
9575       else if (unformat (i, "mask %U", unformat_classify_mask,
9576                          &mask, &skip, &match))
9577         ;
9578       else if (unformat (i, "next-table %d", &next_table_index))
9579         ;
9580       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9581                          &miss_next_index))
9582         ;
9583       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9584                          &miss_next_index))
9585         ;
9586       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9587                          &miss_next_index))
9588         ;
9589       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9590         ;
9591       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9592         ;
9593       else
9594         break;
9595     }
9596
9597   if (is_add && mask == 0)
9598     {
9599       errmsg ("Mask required");
9600       return -99;
9601     }
9602
9603   if (is_add && skip == ~0)
9604     {
9605       errmsg ("skip count required");
9606       return -99;
9607     }
9608
9609   if (is_add && match == ~0)
9610     {
9611       errmsg ("match count required");
9612       return -99;
9613     }
9614
9615   if (!is_add && table_index == ~0)
9616     {
9617       errmsg ("table index required for delete");
9618       return -99;
9619     }
9620
9621   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9622
9623   mp->is_add = is_add;
9624   mp->del_chain = del_chain;
9625   mp->table_index = ntohl (table_index);
9626   mp->nbuckets = ntohl (nbuckets);
9627   mp->memory_size = ntohl (memory_size);
9628   mp->skip_n_vectors = ntohl (skip);
9629   mp->match_n_vectors = ntohl (match);
9630   mp->next_table_index = ntohl (next_table_index);
9631   mp->miss_next_index = ntohl (miss_next_index);
9632   mp->current_data_flag = ntohl (current_data_flag);
9633   mp->current_data_offset = ntohl (current_data_offset);
9634   clib_memcpy (mp->mask, mask, vec_len (mask));
9635
9636   vec_free (mask);
9637
9638   S (mp);
9639   W (ret);
9640   return ret;
9641 }
9642
9643 #if VPP_API_TEST_BUILTIN == 0
9644 uword
9645 unformat_l4_match (unformat_input_t * input, va_list * args)
9646 {
9647   u8 **matchp = va_arg (*args, u8 **);
9648
9649   u8 *proto_header = 0;
9650   int src_port = 0;
9651   int dst_port = 0;
9652
9653   tcpudp_header_t h;
9654
9655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9656     {
9657       if (unformat (input, "src_port %d", &src_port))
9658         ;
9659       else if (unformat (input, "dst_port %d", &dst_port))
9660         ;
9661       else
9662         return 0;
9663     }
9664
9665   h.src_port = clib_host_to_net_u16 (src_port);
9666   h.dst_port = clib_host_to_net_u16 (dst_port);
9667   vec_validate (proto_header, sizeof (h) - 1);
9668   memcpy (proto_header, &h, sizeof (h));
9669
9670   *matchp = proto_header;
9671
9672   return 1;
9673 }
9674
9675 uword
9676 unformat_ip4_match (unformat_input_t * input, va_list * args)
9677 {
9678   u8 **matchp = va_arg (*args, u8 **);
9679   u8 *match = 0;
9680   ip4_header_t *ip;
9681   int version = 0;
9682   u32 version_val;
9683   int hdr_length = 0;
9684   u32 hdr_length_val;
9685   int src = 0, dst = 0;
9686   ip4_address_t src_val, dst_val;
9687   int proto = 0;
9688   u32 proto_val;
9689   int tos = 0;
9690   u32 tos_val;
9691   int length = 0;
9692   u32 length_val;
9693   int fragment_id = 0;
9694   u32 fragment_id_val;
9695   int ttl = 0;
9696   int ttl_val;
9697   int checksum = 0;
9698   u32 checksum_val;
9699
9700   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9701     {
9702       if (unformat (input, "version %d", &version_val))
9703         version = 1;
9704       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9705         hdr_length = 1;
9706       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9707         src = 1;
9708       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9709         dst = 1;
9710       else if (unformat (input, "proto %d", &proto_val))
9711         proto = 1;
9712       else if (unformat (input, "tos %d", &tos_val))
9713         tos = 1;
9714       else if (unformat (input, "length %d", &length_val))
9715         length = 1;
9716       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9717         fragment_id = 1;
9718       else if (unformat (input, "ttl %d", &ttl_val))
9719         ttl = 1;
9720       else if (unformat (input, "checksum %d", &checksum_val))
9721         checksum = 1;
9722       else
9723         break;
9724     }
9725
9726   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9727       + ttl + checksum == 0)
9728     return 0;
9729
9730   /*
9731    * Aligned because we use the real comparison functions
9732    */
9733   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9734
9735   ip = (ip4_header_t *) match;
9736
9737   /* These are realistically matched in practice */
9738   if (src)
9739     ip->src_address.as_u32 = src_val.as_u32;
9740
9741   if (dst)
9742     ip->dst_address.as_u32 = dst_val.as_u32;
9743
9744   if (proto)
9745     ip->protocol = proto_val;
9746
9747
9748   /* These are not, but they're included for completeness */
9749   if (version)
9750     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9751
9752   if (hdr_length)
9753     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9754
9755   if (tos)
9756     ip->tos = tos_val;
9757
9758   if (length)
9759     ip->length = clib_host_to_net_u16 (length_val);
9760
9761   if (ttl)
9762     ip->ttl = ttl_val;
9763
9764   if (checksum)
9765     ip->checksum = clib_host_to_net_u16 (checksum_val);
9766
9767   *matchp = match;
9768   return 1;
9769 }
9770
9771 uword
9772 unformat_ip6_match (unformat_input_t * input, va_list * args)
9773 {
9774   u8 **matchp = va_arg (*args, u8 **);
9775   u8 *match = 0;
9776   ip6_header_t *ip;
9777   int version = 0;
9778   u32 version_val;
9779   u8 traffic_class = 0;
9780   u32 traffic_class_val = 0;
9781   u8 flow_label = 0;
9782   u8 flow_label_val;
9783   int src = 0, dst = 0;
9784   ip6_address_t src_val, dst_val;
9785   int proto = 0;
9786   u32 proto_val;
9787   int payload_length = 0;
9788   u32 payload_length_val;
9789   int hop_limit = 0;
9790   int hop_limit_val;
9791   u32 ip_version_traffic_class_and_flow_label;
9792
9793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9794     {
9795       if (unformat (input, "version %d", &version_val))
9796         version = 1;
9797       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9798         traffic_class = 1;
9799       else if (unformat (input, "flow_label %d", &flow_label_val))
9800         flow_label = 1;
9801       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9802         src = 1;
9803       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9804         dst = 1;
9805       else if (unformat (input, "proto %d", &proto_val))
9806         proto = 1;
9807       else if (unformat (input, "payload_length %d", &payload_length_val))
9808         payload_length = 1;
9809       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9810         hop_limit = 1;
9811       else
9812         break;
9813     }
9814
9815   if (version + traffic_class + flow_label + src + dst + proto +
9816       payload_length + hop_limit == 0)
9817     return 0;
9818
9819   /*
9820    * Aligned because we use the real comparison functions
9821    */
9822   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9823
9824   ip = (ip6_header_t *) match;
9825
9826   if (src)
9827     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9828
9829   if (dst)
9830     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9831
9832   if (proto)
9833     ip->protocol = proto_val;
9834
9835   ip_version_traffic_class_and_flow_label = 0;
9836
9837   if (version)
9838     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9839
9840   if (traffic_class)
9841     ip_version_traffic_class_and_flow_label |=
9842       (traffic_class_val & 0xFF) << 20;
9843
9844   if (flow_label)
9845     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9846
9847   ip->ip_version_traffic_class_and_flow_label =
9848     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9849
9850   if (payload_length)
9851     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9852
9853   if (hop_limit)
9854     ip->hop_limit = hop_limit_val;
9855
9856   *matchp = match;
9857   return 1;
9858 }
9859
9860 uword
9861 unformat_l3_match (unformat_input_t * input, va_list * args)
9862 {
9863   u8 **matchp = va_arg (*args, u8 **);
9864
9865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9866     {
9867       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9868         return 1;
9869       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9870         return 1;
9871       else
9872         break;
9873     }
9874   return 0;
9875 }
9876
9877 uword
9878 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9879 {
9880   u8 *tagp = va_arg (*args, u8 *);
9881   u32 tag;
9882
9883   if (unformat (input, "%d", &tag))
9884     {
9885       tagp[0] = (tag >> 8) & 0x0F;
9886       tagp[1] = tag & 0xFF;
9887       return 1;
9888     }
9889
9890   return 0;
9891 }
9892
9893 uword
9894 unformat_l2_match (unformat_input_t * input, va_list * args)
9895 {
9896   u8 **matchp = va_arg (*args, u8 **);
9897   u8 *match = 0;
9898   u8 src = 0;
9899   u8 src_val[6];
9900   u8 dst = 0;
9901   u8 dst_val[6];
9902   u8 proto = 0;
9903   u16 proto_val;
9904   u8 tag1 = 0;
9905   u8 tag1_val[2];
9906   u8 tag2 = 0;
9907   u8 tag2_val[2];
9908   int len = 14;
9909   u8 ignore_tag1 = 0;
9910   u8 ignore_tag2 = 0;
9911   u8 cos1 = 0;
9912   u8 cos2 = 0;
9913   u32 cos1_val = 0;
9914   u32 cos2_val = 0;
9915
9916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9917     {
9918       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9919         src = 1;
9920       else
9921         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9922         dst = 1;
9923       else if (unformat (input, "proto %U",
9924                          unformat_ethernet_type_host_byte_order, &proto_val))
9925         proto = 1;
9926       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9927         tag1 = 1;
9928       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9929         tag2 = 1;
9930       else if (unformat (input, "ignore-tag1"))
9931         ignore_tag1 = 1;
9932       else if (unformat (input, "ignore-tag2"))
9933         ignore_tag2 = 1;
9934       else if (unformat (input, "cos1 %d", &cos1_val))
9935         cos1 = 1;
9936       else if (unformat (input, "cos2 %d", &cos2_val))
9937         cos2 = 1;
9938       else
9939         break;
9940     }
9941   if ((src + dst + proto + tag1 + tag2 +
9942        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9943     return 0;
9944
9945   if (tag1 || ignore_tag1 || cos1)
9946     len = 18;
9947   if (tag2 || ignore_tag2 || cos2)
9948     len = 22;
9949
9950   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9951
9952   if (dst)
9953     clib_memcpy (match, dst_val, 6);
9954
9955   if (src)
9956     clib_memcpy (match + 6, src_val, 6);
9957
9958   if (tag2)
9959     {
9960       /* inner vlan tag */
9961       match[19] = tag2_val[1];
9962       match[18] = tag2_val[0];
9963       if (cos2)
9964         match[18] |= (cos2_val & 0x7) << 5;
9965       if (proto)
9966         {
9967           match[21] = proto_val & 0xff;
9968           match[20] = proto_val >> 8;
9969         }
9970       if (tag1)
9971         {
9972           match[15] = tag1_val[1];
9973           match[14] = tag1_val[0];
9974         }
9975       if (cos1)
9976         match[14] |= (cos1_val & 0x7) << 5;
9977       *matchp = match;
9978       return 1;
9979     }
9980   if (tag1)
9981     {
9982       match[15] = tag1_val[1];
9983       match[14] = tag1_val[0];
9984       if (proto)
9985         {
9986           match[17] = proto_val & 0xff;
9987           match[16] = proto_val >> 8;
9988         }
9989       if (cos1)
9990         match[14] |= (cos1_val & 0x7) << 5;
9991
9992       *matchp = match;
9993       return 1;
9994     }
9995   if (cos2)
9996     match[18] |= (cos2_val & 0x7) << 5;
9997   if (cos1)
9998     match[14] |= (cos1_val & 0x7) << 5;
9999   if (proto)
10000     {
10001       match[13] = proto_val & 0xff;
10002       match[12] = proto_val >> 8;
10003     }
10004
10005   *matchp = match;
10006   return 1;
10007 }
10008 #endif
10009
10010 uword
10011 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10012 {
10013   u8 **matchp = va_arg (*args, u8 **);
10014   u32 skip_n_vectors = va_arg (*args, u32);
10015   u32 match_n_vectors = va_arg (*args, u32);
10016
10017   u8 *match = 0;
10018   u8 *l2 = 0;
10019   u8 *l3 = 0;
10020   u8 *l4 = 0;
10021
10022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10023     {
10024       if (unformat (input, "hex %U", unformat_hex_string, &match))
10025         ;
10026       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10027         ;
10028       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10029         ;
10030       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10031         ;
10032       else
10033         break;
10034     }
10035
10036   if (l4 && !l3)
10037     {
10038       vec_free (match);
10039       vec_free (l2);
10040       vec_free (l4);
10041       return 0;
10042     }
10043
10044   if (match || l2 || l3 || l4)
10045     {
10046       if (l2 || l3 || l4)
10047         {
10048           /* "Win a free Ethernet header in every packet" */
10049           if (l2 == 0)
10050             vec_validate_aligned (l2, 13, sizeof (u32x4));
10051           match = l2;
10052           if (vec_len (l3))
10053             {
10054               vec_append_aligned (match, l3, sizeof (u32x4));
10055               vec_free (l3);
10056             }
10057           if (vec_len (l4))
10058             {
10059               vec_append_aligned (match, l4, sizeof (u32x4));
10060               vec_free (l4);
10061             }
10062         }
10063
10064       /* Make sure the vector is big enough even if key is all 0's */
10065       vec_validate_aligned
10066         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10067          sizeof (u32x4));
10068
10069       /* Set size, include skipped vectors */
10070       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10071
10072       *matchp = match;
10073
10074       return 1;
10075     }
10076
10077   return 0;
10078 }
10079
10080 static int
10081 api_classify_add_del_session (vat_main_t * vam)
10082 {
10083   unformat_input_t *i = vam->input;
10084   vl_api_classify_add_del_session_t *mp;
10085   int is_add = 1;
10086   u32 table_index = ~0;
10087   u32 hit_next_index = ~0;
10088   u32 opaque_index = ~0;
10089   u8 *match = 0;
10090   i32 advance = 0;
10091   u32 skip_n_vectors = 0;
10092   u32 match_n_vectors = 0;
10093   u32 action = 0;
10094   u32 metadata = 0;
10095   int ret;
10096
10097   /*
10098    * Warning: you have to supply skip_n and match_n
10099    * because the API client cant simply look at the classify
10100    * table object.
10101    */
10102
10103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104     {
10105       if (unformat (i, "del"))
10106         is_add = 0;
10107       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10108                          &hit_next_index))
10109         ;
10110       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10111                          &hit_next_index))
10112         ;
10113       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10114                          &hit_next_index))
10115         ;
10116       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10117         ;
10118       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10119         ;
10120       else if (unformat (i, "opaque-index %d", &opaque_index))
10121         ;
10122       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10123         ;
10124       else if (unformat (i, "match_n %d", &match_n_vectors))
10125         ;
10126       else if (unformat (i, "match %U", api_unformat_classify_match,
10127                          &match, skip_n_vectors, match_n_vectors))
10128         ;
10129       else if (unformat (i, "advance %d", &advance))
10130         ;
10131       else if (unformat (i, "table-index %d", &table_index))
10132         ;
10133       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10134         action = 1;
10135       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10136         action = 2;
10137       else if (unformat (i, "action %d", &action))
10138         ;
10139       else if (unformat (i, "metadata %d", &metadata))
10140         ;
10141       else
10142         break;
10143     }
10144
10145   if (table_index == ~0)
10146     {
10147       errmsg ("Table index required");
10148       return -99;
10149     }
10150
10151   if (is_add && match == 0)
10152     {
10153       errmsg ("Match value required");
10154       return -99;
10155     }
10156
10157   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10158
10159   mp->is_add = is_add;
10160   mp->table_index = ntohl (table_index);
10161   mp->hit_next_index = ntohl (hit_next_index);
10162   mp->opaque_index = ntohl (opaque_index);
10163   mp->advance = ntohl (advance);
10164   mp->action = action;
10165   mp->metadata = ntohl (metadata);
10166   clib_memcpy (mp->match, match, vec_len (match));
10167   vec_free (match);
10168
10169   S (mp);
10170   W (ret);
10171   return ret;
10172 }
10173
10174 static int
10175 api_classify_set_interface_ip_table (vat_main_t * vam)
10176 {
10177   unformat_input_t *i = vam->input;
10178   vl_api_classify_set_interface_ip_table_t *mp;
10179   u32 sw_if_index;
10180   int sw_if_index_set;
10181   u32 table_index = ~0;
10182   u8 is_ipv6 = 0;
10183   int ret;
10184
10185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10186     {
10187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10188         sw_if_index_set = 1;
10189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10190         sw_if_index_set = 1;
10191       else if (unformat (i, "table %d", &table_index))
10192         ;
10193       else
10194         {
10195           clib_warning ("parse error '%U'", format_unformat_error, i);
10196           return -99;
10197         }
10198     }
10199
10200   if (sw_if_index_set == 0)
10201     {
10202       errmsg ("missing interface name or sw_if_index");
10203       return -99;
10204     }
10205
10206
10207   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10208
10209   mp->sw_if_index = ntohl (sw_if_index);
10210   mp->table_index = ntohl (table_index);
10211   mp->is_ipv6 = is_ipv6;
10212
10213   S (mp);
10214   W (ret);
10215   return ret;
10216 }
10217
10218 static int
10219 api_classify_set_interface_l2_tables (vat_main_t * vam)
10220 {
10221   unformat_input_t *i = vam->input;
10222   vl_api_classify_set_interface_l2_tables_t *mp;
10223   u32 sw_if_index;
10224   int sw_if_index_set;
10225   u32 ip4_table_index = ~0;
10226   u32 ip6_table_index = ~0;
10227   u32 other_table_index = ~0;
10228   u32 is_input = 1;
10229   int ret;
10230
10231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10232     {
10233       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10234         sw_if_index_set = 1;
10235       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10236         sw_if_index_set = 1;
10237       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10238         ;
10239       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10240         ;
10241       else if (unformat (i, "other-table %d", &other_table_index))
10242         ;
10243       else if (unformat (i, "is-input %d", &is_input))
10244         ;
10245       else
10246         {
10247           clib_warning ("parse error '%U'", format_unformat_error, i);
10248           return -99;
10249         }
10250     }
10251
10252   if (sw_if_index_set == 0)
10253     {
10254       errmsg ("missing interface name or sw_if_index");
10255       return -99;
10256     }
10257
10258
10259   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10260
10261   mp->sw_if_index = ntohl (sw_if_index);
10262   mp->ip4_table_index = ntohl (ip4_table_index);
10263   mp->ip6_table_index = ntohl (ip6_table_index);
10264   mp->other_table_index = ntohl (other_table_index);
10265   mp->is_input = (u8) is_input;
10266
10267   S (mp);
10268   W (ret);
10269   return ret;
10270 }
10271
10272 static int
10273 api_set_ipfix_exporter (vat_main_t * vam)
10274 {
10275   unformat_input_t *i = vam->input;
10276   vl_api_set_ipfix_exporter_t *mp;
10277   ip4_address_t collector_address;
10278   u8 collector_address_set = 0;
10279   u32 collector_port = ~0;
10280   ip4_address_t src_address;
10281   u8 src_address_set = 0;
10282   u32 vrf_id = ~0;
10283   u32 path_mtu = ~0;
10284   u32 template_interval = ~0;
10285   u8 udp_checksum = 0;
10286   int ret;
10287
10288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10289     {
10290       if (unformat (i, "collector_address %U", unformat_ip4_address,
10291                     &collector_address))
10292         collector_address_set = 1;
10293       else if (unformat (i, "collector_port %d", &collector_port))
10294         ;
10295       else if (unformat (i, "src_address %U", unformat_ip4_address,
10296                          &src_address))
10297         src_address_set = 1;
10298       else if (unformat (i, "vrf_id %d", &vrf_id))
10299         ;
10300       else if (unformat (i, "path_mtu %d", &path_mtu))
10301         ;
10302       else if (unformat (i, "template_interval %d", &template_interval))
10303         ;
10304       else if (unformat (i, "udp_checksum"))
10305         udp_checksum = 1;
10306       else
10307         break;
10308     }
10309
10310   if (collector_address_set == 0)
10311     {
10312       errmsg ("collector_address required");
10313       return -99;
10314     }
10315
10316   if (src_address_set == 0)
10317     {
10318       errmsg ("src_address required");
10319       return -99;
10320     }
10321
10322   M (SET_IPFIX_EXPORTER, mp);
10323
10324   memcpy (mp->collector_address, collector_address.data,
10325           sizeof (collector_address.data));
10326   mp->collector_port = htons ((u16) collector_port);
10327   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10328   mp->vrf_id = htonl (vrf_id);
10329   mp->path_mtu = htonl (path_mtu);
10330   mp->template_interval = htonl (template_interval);
10331   mp->udp_checksum = udp_checksum;
10332
10333   S (mp);
10334   W (ret);
10335   return ret;
10336 }
10337
10338 static int
10339 api_set_ipfix_classify_stream (vat_main_t * vam)
10340 {
10341   unformat_input_t *i = vam->input;
10342   vl_api_set_ipfix_classify_stream_t *mp;
10343   u32 domain_id = 0;
10344   u32 src_port = UDP_DST_PORT_ipfix;
10345   int ret;
10346
10347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10348     {
10349       if (unformat (i, "domain %d", &domain_id))
10350         ;
10351       else if (unformat (i, "src_port %d", &src_port))
10352         ;
10353       else
10354         {
10355           errmsg ("unknown input `%U'", format_unformat_error, i);
10356           return -99;
10357         }
10358     }
10359
10360   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10361
10362   mp->domain_id = htonl (domain_id);
10363   mp->src_port = htons ((u16) src_port);
10364
10365   S (mp);
10366   W (ret);
10367   return ret;
10368 }
10369
10370 static int
10371 api_ipfix_classify_table_add_del (vat_main_t * vam)
10372 {
10373   unformat_input_t *i = vam->input;
10374   vl_api_ipfix_classify_table_add_del_t *mp;
10375   int is_add = -1;
10376   u32 classify_table_index = ~0;
10377   u8 ip_version = 0;
10378   u8 transport_protocol = 255;
10379   int ret;
10380
10381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10382     {
10383       if (unformat (i, "add"))
10384         is_add = 1;
10385       else if (unformat (i, "del"))
10386         is_add = 0;
10387       else if (unformat (i, "table %d", &classify_table_index))
10388         ;
10389       else if (unformat (i, "ip4"))
10390         ip_version = 4;
10391       else if (unformat (i, "ip6"))
10392         ip_version = 6;
10393       else if (unformat (i, "tcp"))
10394         transport_protocol = 6;
10395       else if (unformat (i, "udp"))
10396         transport_protocol = 17;
10397       else
10398         {
10399           errmsg ("unknown input `%U'", format_unformat_error, i);
10400           return -99;
10401         }
10402     }
10403
10404   if (is_add == -1)
10405     {
10406       errmsg ("expecting: add|del");
10407       return -99;
10408     }
10409   if (classify_table_index == ~0)
10410     {
10411       errmsg ("classifier table not specified");
10412       return -99;
10413     }
10414   if (ip_version == 0)
10415     {
10416       errmsg ("IP version not specified");
10417       return -99;
10418     }
10419
10420   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10421
10422   mp->is_add = is_add;
10423   mp->table_id = htonl (classify_table_index);
10424   mp->ip_version = ip_version;
10425   mp->transport_protocol = transport_protocol;
10426
10427   S (mp);
10428   W (ret);
10429   return ret;
10430 }
10431
10432 static int
10433 api_get_node_index (vat_main_t * vam)
10434 {
10435   unformat_input_t *i = vam->input;
10436   vl_api_get_node_index_t *mp;
10437   u8 *name = 0;
10438   int ret;
10439
10440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10441     {
10442       if (unformat (i, "node %s", &name))
10443         ;
10444       else
10445         break;
10446     }
10447   if (name == 0)
10448     {
10449       errmsg ("node name required");
10450       return -99;
10451     }
10452   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10453     {
10454       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10455       return -99;
10456     }
10457
10458   M (GET_NODE_INDEX, mp);
10459   clib_memcpy (mp->node_name, name, vec_len (name));
10460   vec_free (name);
10461
10462   S (mp);
10463   W (ret);
10464   return ret;
10465 }
10466
10467 static int
10468 api_get_next_index (vat_main_t * vam)
10469 {
10470   unformat_input_t *i = vam->input;
10471   vl_api_get_next_index_t *mp;
10472   u8 *node_name = 0, *next_node_name = 0;
10473   int ret;
10474
10475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10476     {
10477       if (unformat (i, "node-name %s", &node_name))
10478         ;
10479       else if (unformat (i, "next-node-name %s", &next_node_name))
10480         break;
10481     }
10482
10483   if (node_name == 0)
10484     {
10485       errmsg ("node name required");
10486       return -99;
10487     }
10488   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10489     {
10490       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10491       return -99;
10492     }
10493
10494   if (next_node_name == 0)
10495     {
10496       errmsg ("next node name required");
10497       return -99;
10498     }
10499   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10500     {
10501       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10502       return -99;
10503     }
10504
10505   M (GET_NEXT_INDEX, mp);
10506   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10507   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10508   vec_free (node_name);
10509   vec_free (next_node_name);
10510
10511   S (mp);
10512   W (ret);
10513   return ret;
10514 }
10515
10516 static int
10517 api_add_node_next (vat_main_t * vam)
10518 {
10519   unformat_input_t *i = vam->input;
10520   vl_api_add_node_next_t *mp;
10521   u8 *name = 0;
10522   u8 *next = 0;
10523   int ret;
10524
10525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10526     {
10527       if (unformat (i, "node %s", &name))
10528         ;
10529       else if (unformat (i, "next %s", &next))
10530         ;
10531       else
10532         break;
10533     }
10534   if (name == 0)
10535     {
10536       errmsg ("node name required");
10537       return -99;
10538     }
10539   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10540     {
10541       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10542       return -99;
10543     }
10544   if (next == 0)
10545     {
10546       errmsg ("next node required");
10547       return -99;
10548     }
10549   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10550     {
10551       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10552       return -99;
10553     }
10554
10555   M (ADD_NODE_NEXT, mp);
10556   clib_memcpy (mp->node_name, name, vec_len (name));
10557   clib_memcpy (mp->next_name, next, vec_len (next));
10558   vec_free (name);
10559   vec_free (next);
10560
10561   S (mp);
10562   W (ret);
10563   return ret;
10564 }
10565
10566 static int
10567 api_l2tpv3_create_tunnel (vat_main_t * vam)
10568 {
10569   unformat_input_t *i = vam->input;
10570   ip6_address_t client_address, our_address;
10571   int client_address_set = 0;
10572   int our_address_set = 0;
10573   u32 local_session_id = 0;
10574   u32 remote_session_id = 0;
10575   u64 local_cookie = 0;
10576   u64 remote_cookie = 0;
10577   u8 l2_sublayer_present = 0;
10578   vl_api_l2tpv3_create_tunnel_t *mp;
10579   int ret;
10580
10581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10582     {
10583       if (unformat (i, "client_address %U", unformat_ip6_address,
10584                     &client_address))
10585         client_address_set = 1;
10586       else if (unformat (i, "our_address %U", unformat_ip6_address,
10587                          &our_address))
10588         our_address_set = 1;
10589       else if (unformat (i, "local_session_id %d", &local_session_id))
10590         ;
10591       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10592         ;
10593       else if (unformat (i, "local_cookie %lld", &local_cookie))
10594         ;
10595       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10596         ;
10597       else if (unformat (i, "l2-sublayer-present"))
10598         l2_sublayer_present = 1;
10599       else
10600         break;
10601     }
10602
10603   if (client_address_set == 0)
10604     {
10605       errmsg ("client_address required");
10606       return -99;
10607     }
10608
10609   if (our_address_set == 0)
10610     {
10611       errmsg ("our_address required");
10612       return -99;
10613     }
10614
10615   M (L2TPV3_CREATE_TUNNEL, mp);
10616
10617   clib_memcpy (mp->client_address, client_address.as_u8,
10618                sizeof (mp->client_address));
10619
10620   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10621
10622   mp->local_session_id = ntohl (local_session_id);
10623   mp->remote_session_id = ntohl (remote_session_id);
10624   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10625   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10626   mp->l2_sublayer_present = l2_sublayer_present;
10627   mp->is_ipv6 = 1;
10628
10629   S (mp);
10630   W (ret);
10631   return ret;
10632 }
10633
10634 static int
10635 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10636 {
10637   unformat_input_t *i = vam->input;
10638   u32 sw_if_index;
10639   u8 sw_if_index_set = 0;
10640   u64 new_local_cookie = 0;
10641   u64 new_remote_cookie = 0;
10642   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10643   int ret;
10644
10645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10646     {
10647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10648         sw_if_index_set = 1;
10649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10650         sw_if_index_set = 1;
10651       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10652         ;
10653       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10654         ;
10655       else
10656         break;
10657     }
10658
10659   if (sw_if_index_set == 0)
10660     {
10661       errmsg ("missing interface name or sw_if_index");
10662       return -99;
10663     }
10664
10665   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10666
10667   mp->sw_if_index = ntohl (sw_if_index);
10668   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10669   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10670
10671   S (mp);
10672   W (ret);
10673   return ret;
10674 }
10675
10676 static int
10677 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10678 {
10679   unformat_input_t *i = vam->input;
10680   vl_api_l2tpv3_interface_enable_disable_t *mp;
10681   u32 sw_if_index;
10682   u8 sw_if_index_set = 0;
10683   u8 enable_disable = 1;
10684   int ret;
10685
10686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10687     {
10688       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10689         sw_if_index_set = 1;
10690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10691         sw_if_index_set = 1;
10692       else if (unformat (i, "enable"))
10693         enable_disable = 1;
10694       else if (unformat (i, "disable"))
10695         enable_disable = 0;
10696       else
10697         break;
10698     }
10699
10700   if (sw_if_index_set == 0)
10701     {
10702       errmsg ("missing interface name or sw_if_index");
10703       return -99;
10704     }
10705
10706   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10707
10708   mp->sw_if_index = ntohl (sw_if_index);
10709   mp->enable_disable = enable_disable;
10710
10711   S (mp);
10712   W (ret);
10713   return ret;
10714 }
10715
10716 static int
10717 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10718 {
10719   unformat_input_t *i = vam->input;
10720   vl_api_l2tpv3_set_lookup_key_t *mp;
10721   u8 key = ~0;
10722   int ret;
10723
10724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10725     {
10726       if (unformat (i, "lookup_v6_src"))
10727         key = L2T_LOOKUP_SRC_ADDRESS;
10728       else if (unformat (i, "lookup_v6_dst"))
10729         key = L2T_LOOKUP_DST_ADDRESS;
10730       else if (unformat (i, "lookup_session_id"))
10731         key = L2T_LOOKUP_SESSION_ID;
10732       else
10733         break;
10734     }
10735
10736   if (key == (u8) ~ 0)
10737     {
10738       errmsg ("l2tp session lookup key unset");
10739       return -99;
10740     }
10741
10742   M (L2TPV3_SET_LOOKUP_KEY, mp);
10743
10744   mp->key = key;
10745
10746   S (mp);
10747   W (ret);
10748   return ret;
10749 }
10750
10751 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10752   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10753 {
10754   vat_main_t *vam = &vat_main;
10755
10756   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10757          format_ip6_address, mp->our_address,
10758          format_ip6_address, mp->client_address,
10759          clib_net_to_host_u32 (mp->sw_if_index));
10760
10761   print (vam->ofp,
10762          "   local cookies %016llx %016llx remote cookie %016llx",
10763          clib_net_to_host_u64 (mp->local_cookie[0]),
10764          clib_net_to_host_u64 (mp->local_cookie[1]),
10765          clib_net_to_host_u64 (mp->remote_cookie));
10766
10767   print (vam->ofp, "   local session-id %d remote session-id %d",
10768          clib_net_to_host_u32 (mp->local_session_id),
10769          clib_net_to_host_u32 (mp->remote_session_id));
10770
10771   print (vam->ofp, "   l2 specific sublayer %s\n",
10772          mp->l2_sublayer_present ? "preset" : "absent");
10773
10774 }
10775
10776 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10777   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10778 {
10779   vat_main_t *vam = &vat_main;
10780   vat_json_node_t *node = NULL;
10781   struct in6_addr addr;
10782
10783   if (VAT_JSON_ARRAY != vam->json_tree.type)
10784     {
10785       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10786       vat_json_init_array (&vam->json_tree);
10787     }
10788   node = vat_json_array_add (&vam->json_tree);
10789
10790   vat_json_init_object (node);
10791
10792   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10793   vat_json_object_add_ip6 (node, "our_address", addr);
10794   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10795   vat_json_object_add_ip6 (node, "client_address", addr);
10796
10797   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10798   vat_json_init_array (lc);
10799   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10800   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10801   vat_json_object_add_uint (node, "remote_cookie",
10802                             clib_net_to_host_u64 (mp->remote_cookie));
10803
10804   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10805   vat_json_object_add_uint (node, "local_session_id",
10806                             clib_net_to_host_u32 (mp->local_session_id));
10807   vat_json_object_add_uint (node, "remote_session_id",
10808                             clib_net_to_host_u32 (mp->remote_session_id));
10809   vat_json_object_add_string_copy (node, "l2_sublayer",
10810                                    mp->l2_sublayer_present ? (u8 *) "present"
10811                                    : (u8 *) "absent");
10812 }
10813
10814 static int
10815 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10816 {
10817   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10818   vl_api_control_ping_t *mp_ping;
10819   int ret;
10820
10821   /* Get list of l2tpv3-tunnel interfaces */
10822   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10823   S (mp);
10824
10825   /* Use a control ping for synchronization */
10826   M (CONTROL_PING, mp_ping);
10827   S (mp_ping);
10828
10829   W (ret);
10830   return ret;
10831 }
10832
10833
10834 static void vl_api_sw_interface_tap_details_t_handler
10835   (vl_api_sw_interface_tap_details_t * mp)
10836 {
10837   vat_main_t *vam = &vat_main;
10838
10839   print (vam->ofp, "%-16s %d",
10840          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10841 }
10842
10843 static void vl_api_sw_interface_tap_details_t_handler_json
10844   (vl_api_sw_interface_tap_details_t * mp)
10845 {
10846   vat_main_t *vam = &vat_main;
10847   vat_json_node_t *node = NULL;
10848
10849   if (VAT_JSON_ARRAY != vam->json_tree.type)
10850     {
10851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10852       vat_json_init_array (&vam->json_tree);
10853     }
10854   node = vat_json_array_add (&vam->json_tree);
10855
10856   vat_json_init_object (node);
10857   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10858   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10859 }
10860
10861 static int
10862 api_sw_interface_tap_dump (vat_main_t * vam)
10863 {
10864   vl_api_sw_interface_tap_dump_t *mp;
10865   vl_api_control_ping_t *mp_ping;
10866   int ret;
10867
10868   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10869   /* Get list of tap interfaces */
10870   M (SW_INTERFACE_TAP_DUMP, mp);
10871   S (mp);
10872
10873   /* Use a control ping for synchronization */
10874   M (CONTROL_PING, mp_ping);
10875   S (mp_ping);
10876
10877   W (ret);
10878   return ret;
10879 }
10880
10881 static uword unformat_vxlan_decap_next
10882   (unformat_input_t * input, va_list * args)
10883 {
10884   u32 *result = va_arg (*args, u32 *);
10885   u32 tmp;
10886
10887   if (unformat (input, "l2"))
10888     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10889   else if (unformat (input, "%d", &tmp))
10890     *result = tmp;
10891   else
10892     return 0;
10893   return 1;
10894 }
10895
10896 static int
10897 api_vxlan_add_del_tunnel (vat_main_t * vam)
10898 {
10899   unformat_input_t *line_input = vam->input;
10900   vl_api_vxlan_add_del_tunnel_t *mp;
10901   ip46_address_t src, dst;
10902   u8 is_add = 1;
10903   u8 ipv4_set = 0, ipv6_set = 0;
10904   u8 src_set = 0;
10905   u8 dst_set = 0;
10906   u8 grp_set = 0;
10907   u32 mcast_sw_if_index = ~0;
10908   u32 encap_vrf_id = 0;
10909   u32 decap_next_index = ~0;
10910   u32 vni = 0;
10911   int ret;
10912
10913   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10914   memset (&src, 0, sizeof src);
10915   memset (&dst, 0, sizeof dst);
10916
10917   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10918     {
10919       if (unformat (line_input, "del"))
10920         is_add = 0;
10921       else
10922         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10923         {
10924           ipv4_set = 1;
10925           src_set = 1;
10926         }
10927       else
10928         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10929         {
10930           ipv4_set = 1;
10931           dst_set = 1;
10932         }
10933       else
10934         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10935         {
10936           ipv6_set = 1;
10937           src_set = 1;
10938         }
10939       else
10940         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10941         {
10942           ipv6_set = 1;
10943           dst_set = 1;
10944         }
10945       else if (unformat (line_input, "group %U %U",
10946                          unformat_ip4_address, &dst.ip4,
10947                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10948         {
10949           grp_set = dst_set = 1;
10950           ipv4_set = 1;
10951         }
10952       else if (unformat (line_input, "group %U",
10953                          unformat_ip4_address, &dst.ip4))
10954         {
10955           grp_set = dst_set = 1;
10956           ipv4_set = 1;
10957         }
10958       else if (unformat (line_input, "group %U %U",
10959                          unformat_ip6_address, &dst.ip6,
10960                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10961         {
10962           grp_set = dst_set = 1;
10963           ipv6_set = 1;
10964         }
10965       else if (unformat (line_input, "group %U",
10966                          unformat_ip6_address, &dst.ip6))
10967         {
10968           grp_set = dst_set = 1;
10969           ipv6_set = 1;
10970         }
10971       else
10972         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10973         ;
10974       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10975         ;
10976       else if (unformat (line_input, "decap-next %U",
10977                          unformat_vxlan_decap_next, &decap_next_index))
10978         ;
10979       else if (unformat (line_input, "vni %d", &vni))
10980         ;
10981       else
10982         {
10983           errmsg ("parse error '%U'", format_unformat_error, line_input);
10984           return -99;
10985         }
10986     }
10987
10988   if (src_set == 0)
10989     {
10990       errmsg ("tunnel src address not specified");
10991       return -99;
10992     }
10993   if (dst_set == 0)
10994     {
10995       errmsg ("tunnel dst address not specified");
10996       return -99;
10997     }
10998
10999   if (grp_set && !ip46_address_is_multicast (&dst))
11000     {
11001       errmsg ("tunnel group address not multicast");
11002       return -99;
11003     }
11004   if (grp_set && mcast_sw_if_index == ~0)
11005     {
11006       errmsg ("tunnel nonexistent multicast device");
11007       return -99;
11008     }
11009   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11010     {
11011       errmsg ("tunnel dst address must be unicast");
11012       return -99;
11013     }
11014
11015
11016   if (ipv4_set && ipv6_set)
11017     {
11018       errmsg ("both IPv4 and IPv6 addresses specified");
11019       return -99;
11020     }
11021
11022   if ((vni == 0) || (vni >> 24))
11023     {
11024       errmsg ("vni not specified or out of range");
11025       return -99;
11026     }
11027
11028   M (VXLAN_ADD_DEL_TUNNEL, mp);
11029
11030   if (ipv6_set)
11031     {
11032       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11033       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11034     }
11035   else
11036     {
11037       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11038       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11039     }
11040   mp->encap_vrf_id = ntohl (encap_vrf_id);
11041   mp->decap_next_index = ntohl (decap_next_index);
11042   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11043   mp->vni = ntohl (vni);
11044   mp->is_add = is_add;
11045   mp->is_ipv6 = ipv6_set;
11046
11047   S (mp);
11048   W (ret);
11049   return ret;
11050 }
11051
11052 static void vl_api_vxlan_tunnel_details_t_handler
11053   (vl_api_vxlan_tunnel_details_t * mp)
11054 {
11055   vat_main_t *vam = &vat_main;
11056   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11057   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11058
11059   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11060          ntohl (mp->sw_if_index),
11061          format_ip46_address, &src, IP46_TYPE_ANY,
11062          format_ip46_address, &dst, IP46_TYPE_ANY,
11063          ntohl (mp->encap_vrf_id),
11064          ntohl (mp->decap_next_index), ntohl (mp->vni),
11065          ntohl (mp->mcast_sw_if_index));
11066 }
11067
11068 static void vl_api_vxlan_tunnel_details_t_handler_json
11069   (vl_api_vxlan_tunnel_details_t * mp)
11070 {
11071   vat_main_t *vam = &vat_main;
11072   vat_json_node_t *node = NULL;
11073
11074   if (VAT_JSON_ARRAY != vam->json_tree.type)
11075     {
11076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11077       vat_json_init_array (&vam->json_tree);
11078     }
11079   node = vat_json_array_add (&vam->json_tree);
11080
11081   vat_json_init_object (node);
11082   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11083   if (mp->is_ipv6)
11084     {
11085       struct in6_addr ip6;
11086
11087       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11088       vat_json_object_add_ip6 (node, "src_address", ip6);
11089       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11090       vat_json_object_add_ip6 (node, "dst_address", ip6);
11091     }
11092   else
11093     {
11094       struct in_addr ip4;
11095
11096       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11097       vat_json_object_add_ip4 (node, "src_address", ip4);
11098       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11099       vat_json_object_add_ip4 (node, "dst_address", ip4);
11100     }
11101   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11102   vat_json_object_add_uint (node, "decap_next_index",
11103                             ntohl (mp->decap_next_index));
11104   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11105   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11106   vat_json_object_add_uint (node, "mcast_sw_if_index",
11107                             ntohl (mp->mcast_sw_if_index));
11108 }
11109
11110 static int
11111 api_vxlan_tunnel_dump (vat_main_t * vam)
11112 {
11113   unformat_input_t *i = vam->input;
11114   vl_api_vxlan_tunnel_dump_t *mp;
11115   vl_api_control_ping_t *mp_ping;
11116   u32 sw_if_index;
11117   u8 sw_if_index_set = 0;
11118   int ret;
11119
11120   /* Parse args required to build the message */
11121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11122     {
11123       if (unformat (i, "sw_if_index %d", &sw_if_index))
11124         sw_if_index_set = 1;
11125       else
11126         break;
11127     }
11128
11129   if (sw_if_index_set == 0)
11130     {
11131       sw_if_index = ~0;
11132     }
11133
11134   if (!vam->json_output)
11135     {
11136       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11137              "sw_if_index", "src_address", "dst_address",
11138              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11139     }
11140
11141   /* Get list of vxlan-tunnel interfaces */
11142   M (VXLAN_TUNNEL_DUMP, mp);
11143
11144   mp->sw_if_index = htonl (sw_if_index);
11145
11146   S (mp);
11147
11148   /* Use a control ping for synchronization */
11149   M (CONTROL_PING, mp_ping);
11150   S (mp_ping);
11151
11152   W (ret);
11153   return ret;
11154 }
11155
11156 static int
11157 api_gre_add_del_tunnel (vat_main_t * vam)
11158 {
11159   unformat_input_t *line_input = vam->input;
11160   vl_api_gre_add_del_tunnel_t *mp;
11161   ip4_address_t src4, dst4;
11162   ip6_address_t src6, dst6;
11163   u8 is_add = 1;
11164   u8 ipv4_set = 0;
11165   u8 ipv6_set = 0;
11166   u8 teb = 0;
11167   u8 src_set = 0;
11168   u8 dst_set = 0;
11169   u32 outer_fib_id = 0;
11170   int ret;
11171
11172   memset (&src4, 0, sizeof src4);
11173   memset (&dst4, 0, sizeof dst4);
11174   memset (&src6, 0, sizeof src6);
11175   memset (&dst6, 0, sizeof dst6);
11176
11177   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11178     {
11179       if (unformat (line_input, "del"))
11180         is_add = 0;
11181       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11182         {
11183           src_set = 1;
11184           ipv4_set = 1;
11185         }
11186       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11187         {
11188           dst_set = 1;
11189           ipv4_set = 1;
11190         }
11191       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11192         {
11193           src_set = 1;
11194           ipv6_set = 1;
11195         }
11196       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11197         {
11198           dst_set = 1;
11199           ipv6_set = 1;
11200         }
11201       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11202         ;
11203       else if (unformat (line_input, "teb"))
11204         teb = 1;
11205       else
11206         {
11207           errmsg ("parse error '%U'", format_unformat_error, line_input);
11208           return -99;
11209         }
11210     }
11211
11212   if (src_set == 0)
11213     {
11214       errmsg ("tunnel src address not specified");
11215       return -99;
11216     }
11217   if (dst_set == 0)
11218     {
11219       errmsg ("tunnel dst address not specified");
11220       return -99;
11221     }
11222   if (ipv4_set && ipv6_set)
11223     {
11224       errmsg ("both IPv4 and IPv6 addresses specified");
11225       return -99;
11226     }
11227
11228
11229   M (GRE_ADD_DEL_TUNNEL, mp);
11230
11231   if (ipv4_set)
11232     {
11233       clib_memcpy (&mp->src_address, &src4, 4);
11234       clib_memcpy (&mp->dst_address, &dst4, 4);
11235     }
11236   else
11237     {
11238       clib_memcpy (&mp->src_address, &src6, 16);
11239       clib_memcpy (&mp->dst_address, &dst6, 16);
11240     }
11241   mp->outer_fib_id = ntohl (outer_fib_id);
11242   mp->is_add = is_add;
11243   mp->teb = teb;
11244   mp->is_ipv6 = ipv6_set;
11245
11246   S (mp);
11247   W (ret);
11248   return ret;
11249 }
11250
11251 static void vl_api_gre_tunnel_details_t_handler
11252   (vl_api_gre_tunnel_details_t * mp)
11253 {
11254   vat_main_t *vam = &vat_main;
11255   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11256   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11257
11258   print (vam->ofp, "%11d%24U%24U%6d%14d",
11259          ntohl (mp->sw_if_index),
11260          format_ip46_address, &src, IP46_TYPE_ANY,
11261          format_ip46_address, &dst, IP46_TYPE_ANY,
11262          mp->teb, ntohl (mp->outer_fib_id));
11263 }
11264
11265 static void vl_api_gre_tunnel_details_t_handler_json
11266   (vl_api_gre_tunnel_details_t * mp)
11267 {
11268   vat_main_t *vam = &vat_main;
11269   vat_json_node_t *node = NULL;
11270   struct in_addr ip4;
11271   struct in6_addr ip6;
11272
11273   if (VAT_JSON_ARRAY != vam->json_tree.type)
11274     {
11275       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11276       vat_json_init_array (&vam->json_tree);
11277     }
11278   node = vat_json_array_add (&vam->json_tree);
11279
11280   vat_json_init_object (node);
11281   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11282   if (!mp->is_ipv6)
11283     {
11284       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11285       vat_json_object_add_ip4 (node, "src_address", ip4);
11286       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11287       vat_json_object_add_ip4 (node, "dst_address", ip4);
11288     }
11289   else
11290     {
11291       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11292       vat_json_object_add_ip6 (node, "src_address", ip6);
11293       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11294       vat_json_object_add_ip6 (node, "dst_address", ip6);
11295     }
11296   vat_json_object_add_uint (node, "teb", mp->teb);
11297   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11298   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11299 }
11300
11301 static int
11302 api_gre_tunnel_dump (vat_main_t * vam)
11303 {
11304   unformat_input_t *i = vam->input;
11305   vl_api_gre_tunnel_dump_t *mp;
11306   vl_api_control_ping_t *mp_ping;
11307   u32 sw_if_index;
11308   u8 sw_if_index_set = 0;
11309   int ret;
11310
11311   /* Parse args required to build the message */
11312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11313     {
11314       if (unformat (i, "sw_if_index %d", &sw_if_index))
11315         sw_if_index_set = 1;
11316       else
11317         break;
11318     }
11319
11320   if (sw_if_index_set == 0)
11321     {
11322       sw_if_index = ~0;
11323     }
11324
11325   if (!vam->json_output)
11326     {
11327       print (vam->ofp, "%11s%24s%24s%6s%14s",
11328              "sw_if_index", "src_address", "dst_address", "teb",
11329              "outer_fib_id");
11330     }
11331
11332   /* Get list of gre-tunnel interfaces */
11333   M (GRE_TUNNEL_DUMP, mp);
11334
11335   mp->sw_if_index = htonl (sw_if_index);
11336
11337   S (mp);
11338
11339   /* Use a control ping for synchronization */
11340   M (CONTROL_PING, mp_ping);
11341   S (mp_ping);
11342
11343   W (ret);
11344   return ret;
11345 }
11346
11347 static int
11348 api_l2_fib_clear_table (vat_main_t * vam)
11349 {
11350 //  unformat_input_t * i = vam->input;
11351   vl_api_l2_fib_clear_table_t *mp;
11352   int ret;
11353
11354   M (L2_FIB_CLEAR_TABLE, mp);
11355
11356   S (mp);
11357   W (ret);
11358   return ret;
11359 }
11360
11361 static int
11362 api_l2_interface_efp_filter (vat_main_t * vam)
11363 {
11364   unformat_input_t *i = vam->input;
11365   vl_api_l2_interface_efp_filter_t *mp;
11366   u32 sw_if_index;
11367   u8 enable = 1;
11368   u8 sw_if_index_set = 0;
11369   int ret;
11370
11371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11372     {
11373       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11374         sw_if_index_set = 1;
11375       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11376         sw_if_index_set = 1;
11377       else if (unformat (i, "enable"))
11378         enable = 1;
11379       else if (unformat (i, "disable"))
11380         enable = 0;
11381       else
11382         {
11383           clib_warning ("parse error '%U'", format_unformat_error, i);
11384           return -99;
11385         }
11386     }
11387
11388   if (sw_if_index_set == 0)
11389     {
11390       errmsg ("missing sw_if_index");
11391       return -99;
11392     }
11393
11394   M (L2_INTERFACE_EFP_FILTER, mp);
11395
11396   mp->sw_if_index = ntohl (sw_if_index);
11397   mp->enable_disable = enable;
11398
11399   S (mp);
11400   W (ret);
11401   return ret;
11402 }
11403
11404 #define foreach_vtr_op                          \
11405 _("disable",  L2_VTR_DISABLED)                  \
11406 _("push-1",  L2_VTR_PUSH_1)                     \
11407 _("push-2",  L2_VTR_PUSH_2)                     \
11408 _("pop-1",  L2_VTR_POP_1)                       \
11409 _("pop-2",  L2_VTR_POP_2)                       \
11410 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11411 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11412 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11413 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11414
11415 static int
11416 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11417 {
11418   unformat_input_t *i = vam->input;
11419   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11420   u32 sw_if_index;
11421   u8 sw_if_index_set = 0;
11422   u8 vtr_op_set = 0;
11423   u32 vtr_op = 0;
11424   u32 push_dot1q = 1;
11425   u32 tag1 = ~0;
11426   u32 tag2 = ~0;
11427   int ret;
11428
11429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11430     {
11431       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11432         sw_if_index_set = 1;
11433       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11434         sw_if_index_set = 1;
11435       else if (unformat (i, "vtr_op %d", &vtr_op))
11436         vtr_op_set = 1;
11437 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11438       foreach_vtr_op
11439 #undef _
11440         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11441         ;
11442       else if (unformat (i, "tag1 %d", &tag1))
11443         ;
11444       else if (unformat (i, "tag2 %d", &tag2))
11445         ;
11446       else
11447         {
11448           clib_warning ("parse error '%U'", format_unformat_error, i);
11449           return -99;
11450         }
11451     }
11452
11453   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11454     {
11455       errmsg ("missing vtr operation or sw_if_index");
11456       return -99;
11457     }
11458
11459   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11460   mp->sw_if_index = ntohl (sw_if_index);
11461   mp->vtr_op = ntohl (vtr_op);
11462   mp->push_dot1q = ntohl (push_dot1q);
11463   mp->tag1 = ntohl (tag1);
11464   mp->tag2 = ntohl (tag2);
11465
11466   S (mp);
11467   W (ret);
11468   return ret;
11469 }
11470
11471 static int
11472 api_create_vhost_user_if (vat_main_t * vam)
11473 {
11474   unformat_input_t *i = vam->input;
11475   vl_api_create_vhost_user_if_t *mp;
11476   u8 *file_name;
11477   u8 is_server = 0;
11478   u8 file_name_set = 0;
11479   u32 custom_dev_instance = ~0;
11480   u8 hwaddr[6];
11481   u8 use_custom_mac = 0;
11482   u8 *tag = 0;
11483   int ret;
11484   u8 operation_mode = VHOST_USER_POLLING_MODE;
11485
11486   /* Shut up coverity */
11487   memset (hwaddr, 0, sizeof (hwaddr));
11488
11489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11490     {
11491       if (unformat (i, "socket %s", &file_name))
11492         {
11493           file_name_set = 1;
11494         }
11495       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11496         ;
11497       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11498         use_custom_mac = 1;
11499       else if (unformat (i, "server"))
11500         is_server = 1;
11501       else if (unformat (i, "tag %s", &tag))
11502         ;
11503       else if (unformat (i, "mode %U",
11504                          api_unformat_vhost_user_operation_mode,
11505                          &operation_mode))
11506         ;
11507       else
11508         break;
11509     }
11510
11511   if (file_name_set == 0)
11512     {
11513       errmsg ("missing socket file name");
11514       return -99;
11515     }
11516
11517   if (vec_len (file_name) > 255)
11518     {
11519       errmsg ("socket file name too long");
11520       return -99;
11521     }
11522   vec_add1 (file_name, 0);
11523
11524   M (CREATE_VHOST_USER_IF, mp);
11525
11526   mp->operation_mode = operation_mode;
11527   mp->is_server = is_server;
11528   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11529   vec_free (file_name);
11530   if (custom_dev_instance != ~0)
11531     {
11532       mp->renumber = 1;
11533       mp->custom_dev_instance = ntohl (custom_dev_instance);
11534     }
11535   mp->use_custom_mac = use_custom_mac;
11536   clib_memcpy (mp->mac_address, hwaddr, 6);
11537   if (tag)
11538     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11539   vec_free (tag);
11540
11541   S (mp);
11542   W (ret);
11543   return ret;
11544 }
11545
11546 static int
11547 api_modify_vhost_user_if (vat_main_t * vam)
11548 {
11549   unformat_input_t *i = vam->input;
11550   vl_api_modify_vhost_user_if_t *mp;
11551   u8 *file_name;
11552   u8 is_server = 0;
11553   u8 file_name_set = 0;
11554   u32 custom_dev_instance = ~0;
11555   u8 sw_if_index_set = 0;
11556   u32 sw_if_index = (u32) ~ 0;
11557   int ret;
11558   u8 operation_mode = VHOST_USER_POLLING_MODE;
11559
11560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11561     {
11562       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11563         sw_if_index_set = 1;
11564       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11565         sw_if_index_set = 1;
11566       else if (unformat (i, "socket %s", &file_name))
11567         {
11568           file_name_set = 1;
11569         }
11570       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11571         ;
11572       else if (unformat (i, "server"))
11573         is_server = 1;
11574       else if (unformat (i, "mode %U",
11575                          api_unformat_vhost_user_operation_mode,
11576                          &operation_mode))
11577         ;
11578       else
11579         break;
11580     }
11581
11582   if (sw_if_index_set == 0)
11583     {
11584       errmsg ("missing sw_if_index or interface name");
11585       return -99;
11586     }
11587
11588   if (file_name_set == 0)
11589     {
11590       errmsg ("missing socket file name");
11591       return -99;
11592     }
11593
11594   if (vec_len (file_name) > 255)
11595     {
11596       errmsg ("socket file name too long");
11597       return -99;
11598     }
11599   vec_add1 (file_name, 0);
11600
11601   M (MODIFY_VHOST_USER_IF, mp);
11602
11603   mp->operation_mode = operation_mode;
11604   mp->sw_if_index = ntohl (sw_if_index);
11605   mp->is_server = is_server;
11606   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11607   vec_free (file_name);
11608   if (custom_dev_instance != ~0)
11609     {
11610       mp->renumber = 1;
11611       mp->custom_dev_instance = ntohl (custom_dev_instance);
11612     }
11613
11614   S (mp);
11615   W (ret);
11616   return ret;
11617 }
11618
11619 static int
11620 api_delete_vhost_user_if (vat_main_t * vam)
11621 {
11622   unformat_input_t *i = vam->input;
11623   vl_api_delete_vhost_user_if_t *mp;
11624   u32 sw_if_index = ~0;
11625   u8 sw_if_index_set = 0;
11626   int ret;
11627
11628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11629     {
11630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11631         sw_if_index_set = 1;
11632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11633         sw_if_index_set = 1;
11634       else
11635         break;
11636     }
11637
11638   if (sw_if_index_set == 0)
11639     {
11640       errmsg ("missing sw_if_index or interface name");
11641       return -99;
11642     }
11643
11644
11645   M (DELETE_VHOST_USER_IF, mp);
11646
11647   mp->sw_if_index = ntohl (sw_if_index);
11648
11649   S (mp);
11650   W (ret);
11651   return ret;
11652 }
11653
11654 static void vl_api_sw_interface_vhost_user_details_t_handler
11655   (vl_api_sw_interface_vhost_user_details_t * mp)
11656 {
11657   vat_main_t *vam = &vat_main;
11658
11659   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
11660          (char *) mp->interface_name,
11661          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11662          clib_net_to_host_u64 (mp->features), mp->is_server,
11663          ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11664          mp->operation_mode, (char *) mp->sock_filename);
11665   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11666 }
11667
11668 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11669   (vl_api_sw_interface_vhost_user_details_t * mp)
11670 {
11671   vat_main_t *vam = &vat_main;
11672   vat_json_node_t *node = NULL;
11673
11674   if (VAT_JSON_ARRAY != vam->json_tree.type)
11675     {
11676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11677       vat_json_init_array (&vam->json_tree);
11678     }
11679   node = vat_json_array_add (&vam->json_tree);
11680
11681   vat_json_init_object (node);
11682   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11683   vat_json_object_add_string_copy (node, "interface_name",
11684                                    mp->interface_name);
11685   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11686                             ntohl (mp->virtio_net_hdr_sz));
11687   vat_json_object_add_uint (node, "features",
11688                             clib_net_to_host_u64 (mp->features));
11689   vat_json_object_add_uint (node, "is_server", mp->is_server);
11690   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11691   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11692   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11693   vat_json_object_add_uint (node, "mode", mp->operation_mode);
11694 }
11695
11696 static int
11697 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11698 {
11699   vl_api_sw_interface_vhost_user_dump_t *mp;
11700   vl_api_control_ping_t *mp_ping;
11701   int ret;
11702   print (vam->ofp,
11703          "Interface name            idx hdr_sz features server regions mode"
11704          "      filename");
11705
11706   /* Get list of vhost-user interfaces */
11707   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11708   S (mp);
11709
11710   /* Use a control ping for synchronization */
11711   M (CONTROL_PING, mp_ping);
11712   S (mp_ping);
11713
11714   W (ret);
11715   return ret;
11716 }
11717
11718 static int
11719 api_show_version (vat_main_t * vam)
11720 {
11721   vl_api_show_version_t *mp;
11722   int ret;
11723
11724   M (SHOW_VERSION, mp);
11725
11726   S (mp);
11727   W (ret);
11728   return ret;
11729 }
11730
11731
11732 static int
11733 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11734 {
11735   unformat_input_t *line_input = vam->input;
11736   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11737   ip4_address_t local4, remote4;
11738   ip6_address_t local6, remote6;
11739   u8 is_add = 1;
11740   u8 ipv4_set = 0, ipv6_set = 0;
11741   u8 local_set = 0;
11742   u8 remote_set = 0;
11743   u32 encap_vrf_id = 0;
11744   u32 decap_vrf_id = 0;
11745   u8 protocol = ~0;
11746   u32 vni;
11747   u8 vni_set = 0;
11748   int ret;
11749
11750   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11751     {
11752       if (unformat (line_input, "del"))
11753         is_add = 0;
11754       else if (unformat (line_input, "local %U",
11755                          unformat_ip4_address, &local4))
11756         {
11757           local_set = 1;
11758           ipv4_set = 1;
11759         }
11760       else if (unformat (line_input, "remote %U",
11761                          unformat_ip4_address, &remote4))
11762         {
11763           remote_set = 1;
11764           ipv4_set = 1;
11765         }
11766       else if (unformat (line_input, "local %U",
11767                          unformat_ip6_address, &local6))
11768         {
11769           local_set = 1;
11770           ipv6_set = 1;
11771         }
11772       else if (unformat (line_input, "remote %U",
11773                          unformat_ip6_address, &remote6))
11774         {
11775           remote_set = 1;
11776           ipv6_set = 1;
11777         }
11778       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11779         ;
11780       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11781         ;
11782       else if (unformat (line_input, "vni %d", &vni))
11783         vni_set = 1;
11784       else if (unformat (line_input, "next-ip4"))
11785         protocol = 1;
11786       else if (unformat (line_input, "next-ip6"))
11787         protocol = 2;
11788       else if (unformat (line_input, "next-ethernet"))
11789         protocol = 3;
11790       else if (unformat (line_input, "next-nsh"))
11791         protocol = 4;
11792       else
11793         {
11794           errmsg ("parse error '%U'", format_unformat_error, line_input);
11795           return -99;
11796         }
11797     }
11798
11799   if (local_set == 0)
11800     {
11801       errmsg ("tunnel local address not specified");
11802       return -99;
11803     }
11804   if (remote_set == 0)
11805     {
11806       errmsg ("tunnel remote address not specified");
11807       return -99;
11808     }
11809   if (ipv4_set && ipv6_set)
11810     {
11811       errmsg ("both IPv4 and IPv6 addresses specified");
11812       return -99;
11813     }
11814
11815   if (vni_set == 0)
11816     {
11817       errmsg ("vni not specified");
11818       return -99;
11819     }
11820
11821   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11822
11823
11824   if (ipv6_set)
11825     {
11826       clib_memcpy (&mp->local, &local6, sizeof (local6));
11827       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11828     }
11829   else
11830     {
11831       clib_memcpy (&mp->local, &local4, sizeof (local4));
11832       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11833     }
11834
11835   mp->encap_vrf_id = ntohl (encap_vrf_id);
11836   mp->decap_vrf_id = ntohl (decap_vrf_id);
11837   mp->protocol = protocol;
11838   mp->vni = ntohl (vni);
11839   mp->is_add = is_add;
11840   mp->is_ipv6 = ipv6_set;
11841
11842   S (mp);
11843   W (ret);
11844   return ret;
11845 }
11846
11847 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11848   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11849 {
11850   vat_main_t *vam = &vat_main;
11851
11852   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11853          ntohl (mp->sw_if_index),
11854          format_ip46_address, &(mp->local[0]),
11855          format_ip46_address, &(mp->remote[0]),
11856          ntohl (mp->vni),
11857          ntohl (mp->protocol),
11858          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11859 }
11860
11861 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11862   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11863 {
11864   vat_main_t *vam = &vat_main;
11865   vat_json_node_t *node = NULL;
11866   struct in_addr ip4;
11867   struct in6_addr ip6;
11868
11869   if (VAT_JSON_ARRAY != vam->json_tree.type)
11870     {
11871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11872       vat_json_init_array (&vam->json_tree);
11873     }
11874   node = vat_json_array_add (&vam->json_tree);
11875
11876   vat_json_init_object (node);
11877   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11878   if (mp->is_ipv6)
11879     {
11880       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11881       vat_json_object_add_ip6 (node, "local", ip6);
11882       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11883       vat_json_object_add_ip6 (node, "remote", ip6);
11884     }
11885   else
11886     {
11887       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11888       vat_json_object_add_ip4 (node, "local", ip4);
11889       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11890       vat_json_object_add_ip4 (node, "remote", ip4);
11891     }
11892   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11893   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11894   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11895   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11896   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11897 }
11898
11899 static int
11900 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11901 {
11902   unformat_input_t *i = vam->input;
11903   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11904   vl_api_control_ping_t *mp_ping;
11905   u32 sw_if_index;
11906   u8 sw_if_index_set = 0;
11907   int ret;
11908
11909   /* Parse args required to build the message */
11910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11911     {
11912       if (unformat (i, "sw_if_index %d", &sw_if_index))
11913         sw_if_index_set = 1;
11914       else
11915         break;
11916     }
11917
11918   if (sw_if_index_set == 0)
11919     {
11920       sw_if_index = ~0;
11921     }
11922
11923   if (!vam->json_output)
11924     {
11925       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11926              "sw_if_index", "local", "remote", "vni",
11927              "protocol", "encap_vrf_id", "decap_vrf_id");
11928     }
11929
11930   /* Get list of vxlan-tunnel interfaces */
11931   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11932
11933   mp->sw_if_index = htonl (sw_if_index);
11934
11935   S (mp);
11936
11937   /* Use a control ping for synchronization */
11938   M (CONTROL_PING, mp_ping);
11939   S (mp_ping);
11940
11941   W (ret);
11942   return ret;
11943 }
11944
11945 u8 *
11946 format_l2_fib_mac_address (u8 * s, va_list * args)
11947 {
11948   u8 *a = va_arg (*args, u8 *);
11949
11950   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11951                  a[2], a[3], a[4], a[5], a[6], a[7]);
11952 }
11953
11954 static void vl_api_l2_fib_table_details_t_handler
11955   (vl_api_l2_fib_table_details_t * mp)
11956 {
11957   vat_main_t *vam = &vat_main;
11958
11959   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11960          "       %d       %d     %d",
11961          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11962          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11963          mp->bvi_mac);
11964 }
11965
11966 static void vl_api_l2_fib_table_details_t_handler_json
11967   (vl_api_l2_fib_table_details_t * mp)
11968 {
11969   vat_main_t *vam = &vat_main;
11970   vat_json_node_t *node = NULL;
11971
11972   if (VAT_JSON_ARRAY != vam->json_tree.type)
11973     {
11974       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11975       vat_json_init_array (&vam->json_tree);
11976     }
11977   node = vat_json_array_add (&vam->json_tree);
11978
11979   vat_json_init_object (node);
11980   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11981   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11982   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11983   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11984   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11985   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11986 }
11987
11988 static int
11989 api_l2_fib_table_dump (vat_main_t * vam)
11990 {
11991   unformat_input_t *i = vam->input;
11992   vl_api_l2_fib_table_dump_t *mp;
11993   vl_api_control_ping_t *mp_ping;
11994   u32 bd_id;
11995   u8 bd_id_set = 0;
11996   int ret;
11997
11998   /* Parse args required to build the message */
11999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12000     {
12001       if (unformat (i, "bd_id %d", &bd_id))
12002         bd_id_set = 1;
12003       else
12004         break;
12005     }
12006
12007   if (bd_id_set == 0)
12008     {
12009       errmsg ("missing bridge domain");
12010       return -99;
12011     }
12012
12013   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12014
12015   /* Get list of l2 fib entries */
12016   M (L2_FIB_TABLE_DUMP, mp);
12017
12018   mp->bd_id = ntohl (bd_id);
12019   S (mp);
12020
12021   /* Use a control ping for synchronization */
12022   M (CONTROL_PING, mp_ping);
12023   S (mp_ping);
12024
12025   W (ret);
12026   return ret;
12027 }
12028
12029
12030 static int
12031 api_interface_name_renumber (vat_main_t * vam)
12032 {
12033   unformat_input_t *line_input = vam->input;
12034   vl_api_interface_name_renumber_t *mp;
12035   u32 sw_if_index = ~0;
12036   u32 new_show_dev_instance = ~0;
12037   int ret;
12038
12039   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12040     {
12041       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12042                     &sw_if_index))
12043         ;
12044       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12045         ;
12046       else if (unformat (line_input, "new_show_dev_instance %d",
12047                          &new_show_dev_instance))
12048         ;
12049       else
12050         break;
12051     }
12052
12053   if (sw_if_index == ~0)
12054     {
12055       errmsg ("missing interface name or sw_if_index");
12056       return -99;
12057     }
12058
12059   if (new_show_dev_instance == ~0)
12060     {
12061       errmsg ("missing new_show_dev_instance");
12062       return -99;
12063     }
12064
12065   M (INTERFACE_NAME_RENUMBER, mp);
12066
12067   mp->sw_if_index = ntohl (sw_if_index);
12068   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12069
12070   S (mp);
12071   W (ret);
12072   return ret;
12073 }
12074
12075 static int
12076 api_want_ip4_arp_events (vat_main_t * vam)
12077 {
12078   unformat_input_t *line_input = vam->input;
12079   vl_api_want_ip4_arp_events_t *mp;
12080   ip4_address_t address;
12081   int address_set = 0;
12082   u32 enable_disable = 1;
12083   int ret;
12084
12085   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12086     {
12087       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12088         address_set = 1;
12089       else if (unformat (line_input, "del"))
12090         enable_disable = 0;
12091       else
12092         break;
12093     }
12094
12095   if (address_set == 0)
12096     {
12097       errmsg ("missing addresses");
12098       return -99;
12099     }
12100
12101   M (WANT_IP4_ARP_EVENTS, mp);
12102   mp->enable_disable = enable_disable;
12103   mp->pid = htonl (getpid ());
12104   mp->address = address.as_u32;
12105
12106   S (mp);
12107   W (ret);
12108   return ret;
12109 }
12110
12111 static int
12112 api_want_ip6_nd_events (vat_main_t * vam)
12113 {
12114   unformat_input_t *line_input = vam->input;
12115   vl_api_want_ip6_nd_events_t *mp;
12116   ip6_address_t address;
12117   int address_set = 0;
12118   u32 enable_disable = 1;
12119   int ret;
12120
12121   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12122     {
12123       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12124         address_set = 1;
12125       else if (unformat (line_input, "del"))
12126         enable_disable = 0;
12127       else
12128         break;
12129     }
12130
12131   if (address_set == 0)
12132     {
12133       errmsg ("missing addresses");
12134       return -99;
12135     }
12136
12137   M (WANT_IP6_ND_EVENTS, mp);
12138   mp->enable_disable = enable_disable;
12139   mp->pid = htonl (getpid ());
12140   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12141
12142   S (mp);
12143   W (ret);
12144   return ret;
12145 }
12146
12147 static int
12148 api_input_acl_set_interface (vat_main_t * vam)
12149 {
12150   unformat_input_t *i = vam->input;
12151   vl_api_input_acl_set_interface_t *mp;
12152   u32 sw_if_index;
12153   int sw_if_index_set;
12154   u32 ip4_table_index = ~0;
12155   u32 ip6_table_index = ~0;
12156   u32 l2_table_index = ~0;
12157   u8 is_add = 1;
12158   int ret;
12159
12160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12161     {
12162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12163         sw_if_index_set = 1;
12164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12165         sw_if_index_set = 1;
12166       else if (unformat (i, "del"))
12167         is_add = 0;
12168       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12169         ;
12170       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12171         ;
12172       else if (unformat (i, "l2-table %d", &l2_table_index))
12173         ;
12174       else
12175         {
12176           clib_warning ("parse error '%U'", format_unformat_error, i);
12177           return -99;
12178         }
12179     }
12180
12181   if (sw_if_index_set == 0)
12182     {
12183       errmsg ("missing interface name or sw_if_index");
12184       return -99;
12185     }
12186
12187   M (INPUT_ACL_SET_INTERFACE, mp);
12188
12189   mp->sw_if_index = ntohl (sw_if_index);
12190   mp->ip4_table_index = ntohl (ip4_table_index);
12191   mp->ip6_table_index = ntohl (ip6_table_index);
12192   mp->l2_table_index = ntohl (l2_table_index);
12193   mp->is_add = is_add;
12194
12195   S (mp);
12196   W (ret);
12197   return ret;
12198 }
12199
12200 static int
12201 api_ip_address_dump (vat_main_t * vam)
12202 {
12203   unformat_input_t *i = vam->input;
12204   vl_api_ip_address_dump_t *mp;
12205   vl_api_control_ping_t *mp_ping;
12206   u32 sw_if_index = ~0;
12207   u8 sw_if_index_set = 0;
12208   u8 ipv4_set = 0;
12209   u8 ipv6_set = 0;
12210   int ret;
12211
12212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12213     {
12214       if (unformat (i, "sw_if_index %d", &sw_if_index))
12215         sw_if_index_set = 1;
12216       else
12217         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12218         sw_if_index_set = 1;
12219       else if (unformat (i, "ipv4"))
12220         ipv4_set = 1;
12221       else if (unformat (i, "ipv6"))
12222         ipv6_set = 1;
12223       else
12224         break;
12225     }
12226
12227   if (ipv4_set && ipv6_set)
12228     {
12229       errmsg ("ipv4 and ipv6 flags cannot be both set");
12230       return -99;
12231     }
12232
12233   if ((!ipv4_set) && (!ipv6_set))
12234     {
12235       errmsg ("no ipv4 nor ipv6 flag set");
12236       return -99;
12237     }
12238
12239   if (sw_if_index_set == 0)
12240     {
12241       errmsg ("missing interface name or sw_if_index");
12242       return -99;
12243     }
12244
12245   vam->current_sw_if_index = sw_if_index;
12246   vam->is_ipv6 = ipv6_set;
12247
12248   M (IP_ADDRESS_DUMP, mp);
12249   mp->sw_if_index = ntohl (sw_if_index);
12250   mp->is_ipv6 = ipv6_set;
12251   S (mp);
12252
12253   /* Use a control ping for synchronization */
12254   M (CONTROL_PING, mp_ping);
12255   S (mp_ping);
12256
12257   W (ret);
12258   return ret;
12259 }
12260
12261 static int
12262 api_ip_dump (vat_main_t * vam)
12263 {
12264   vl_api_ip_dump_t *mp;
12265   vl_api_control_ping_t *mp_ping;
12266   unformat_input_t *in = vam->input;
12267   int ipv4_set = 0;
12268   int ipv6_set = 0;
12269   int is_ipv6;
12270   int i;
12271   int ret;
12272
12273   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12274     {
12275       if (unformat (in, "ipv4"))
12276         ipv4_set = 1;
12277       else if (unformat (in, "ipv6"))
12278         ipv6_set = 1;
12279       else
12280         break;
12281     }
12282
12283   if (ipv4_set && ipv6_set)
12284     {
12285       errmsg ("ipv4 and ipv6 flags cannot be both set");
12286       return -99;
12287     }
12288
12289   if ((!ipv4_set) && (!ipv6_set))
12290     {
12291       errmsg ("no ipv4 nor ipv6 flag set");
12292       return -99;
12293     }
12294
12295   is_ipv6 = ipv6_set;
12296   vam->is_ipv6 = is_ipv6;
12297
12298   /* free old data */
12299   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12300     {
12301       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12302     }
12303   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12304
12305   M (IP_DUMP, mp);
12306   mp->is_ipv6 = ipv6_set;
12307   S (mp);
12308
12309   /* Use a control ping for synchronization */
12310   M (CONTROL_PING, mp_ping);
12311   S (mp_ping);
12312
12313   W (ret);
12314   return ret;
12315 }
12316
12317 static int
12318 api_ipsec_spd_add_del (vat_main_t * vam)
12319 {
12320   unformat_input_t *i = vam->input;
12321   vl_api_ipsec_spd_add_del_t *mp;
12322   u32 spd_id = ~0;
12323   u8 is_add = 1;
12324   int ret;
12325
12326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12327     {
12328       if (unformat (i, "spd_id %d", &spd_id))
12329         ;
12330       else if (unformat (i, "del"))
12331         is_add = 0;
12332       else
12333         {
12334           clib_warning ("parse error '%U'", format_unformat_error, i);
12335           return -99;
12336         }
12337     }
12338   if (spd_id == ~0)
12339     {
12340       errmsg ("spd_id must be set");
12341       return -99;
12342     }
12343
12344   M (IPSEC_SPD_ADD_DEL, mp);
12345
12346   mp->spd_id = ntohl (spd_id);
12347   mp->is_add = is_add;
12348
12349   S (mp);
12350   W (ret);
12351   return ret;
12352 }
12353
12354 static int
12355 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12356 {
12357   unformat_input_t *i = vam->input;
12358   vl_api_ipsec_interface_add_del_spd_t *mp;
12359   u32 sw_if_index;
12360   u8 sw_if_index_set = 0;
12361   u32 spd_id = (u32) ~ 0;
12362   u8 is_add = 1;
12363   int ret;
12364
12365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12366     {
12367       if (unformat (i, "del"))
12368         is_add = 0;
12369       else if (unformat (i, "spd_id %d", &spd_id))
12370         ;
12371       else
12372         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12373         sw_if_index_set = 1;
12374       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12375         sw_if_index_set = 1;
12376       else
12377         {
12378           clib_warning ("parse error '%U'", format_unformat_error, i);
12379           return -99;
12380         }
12381
12382     }
12383
12384   if (spd_id == (u32) ~ 0)
12385     {
12386       errmsg ("spd_id must be set");
12387       return -99;
12388     }
12389
12390   if (sw_if_index_set == 0)
12391     {
12392       errmsg ("missing interface name or sw_if_index");
12393       return -99;
12394     }
12395
12396   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12397
12398   mp->spd_id = ntohl (spd_id);
12399   mp->sw_if_index = ntohl (sw_if_index);
12400   mp->is_add = is_add;
12401
12402   S (mp);
12403   W (ret);
12404   return ret;
12405 }
12406
12407 static int
12408 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12409 {
12410   unformat_input_t *i = vam->input;
12411   vl_api_ipsec_spd_add_del_entry_t *mp;
12412   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12413   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12414   i32 priority = 0;
12415   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12416   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12417   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12418   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12419   int ret;
12420
12421   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12422   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12423   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12424   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12425   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12426   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12427
12428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12429     {
12430       if (unformat (i, "del"))
12431         is_add = 0;
12432       if (unformat (i, "outbound"))
12433         is_outbound = 1;
12434       if (unformat (i, "inbound"))
12435         is_outbound = 0;
12436       else if (unformat (i, "spd_id %d", &spd_id))
12437         ;
12438       else if (unformat (i, "sa_id %d", &sa_id))
12439         ;
12440       else if (unformat (i, "priority %d", &priority))
12441         ;
12442       else if (unformat (i, "protocol %d", &protocol))
12443         ;
12444       else if (unformat (i, "lport_start %d", &lport_start))
12445         ;
12446       else if (unformat (i, "lport_stop %d", &lport_stop))
12447         ;
12448       else if (unformat (i, "rport_start %d", &rport_start))
12449         ;
12450       else if (unformat (i, "rport_stop %d", &rport_stop))
12451         ;
12452       else
12453         if (unformat
12454             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12455         {
12456           is_ipv6 = 0;
12457           is_ip_any = 0;
12458         }
12459       else
12460         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12461         {
12462           is_ipv6 = 0;
12463           is_ip_any = 0;
12464         }
12465       else
12466         if (unformat
12467             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12468         {
12469           is_ipv6 = 0;
12470           is_ip_any = 0;
12471         }
12472       else
12473         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12474         {
12475           is_ipv6 = 0;
12476           is_ip_any = 0;
12477         }
12478       else
12479         if (unformat
12480             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12481         {
12482           is_ipv6 = 1;
12483           is_ip_any = 0;
12484         }
12485       else
12486         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12487         {
12488           is_ipv6 = 1;
12489           is_ip_any = 0;
12490         }
12491       else
12492         if (unformat
12493             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12494         {
12495           is_ipv6 = 1;
12496           is_ip_any = 0;
12497         }
12498       else
12499         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12500         {
12501           is_ipv6 = 1;
12502           is_ip_any = 0;
12503         }
12504       else
12505         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12506         {
12507           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12508             {
12509               clib_warning ("unsupported action: 'resolve'");
12510               return -99;
12511             }
12512         }
12513       else
12514         {
12515           clib_warning ("parse error '%U'", format_unformat_error, i);
12516           return -99;
12517         }
12518
12519     }
12520
12521   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12522
12523   mp->spd_id = ntohl (spd_id);
12524   mp->priority = ntohl (priority);
12525   mp->is_outbound = is_outbound;
12526
12527   mp->is_ipv6 = is_ipv6;
12528   if (is_ipv6 || is_ip_any)
12529     {
12530       clib_memcpy (mp->remote_address_start, &raddr6_start,
12531                    sizeof (ip6_address_t));
12532       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12533                    sizeof (ip6_address_t));
12534       clib_memcpy (mp->local_address_start, &laddr6_start,
12535                    sizeof (ip6_address_t));
12536       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12537                    sizeof (ip6_address_t));
12538     }
12539   else
12540     {
12541       clib_memcpy (mp->remote_address_start, &raddr4_start,
12542                    sizeof (ip4_address_t));
12543       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12544                    sizeof (ip4_address_t));
12545       clib_memcpy (mp->local_address_start, &laddr4_start,
12546                    sizeof (ip4_address_t));
12547       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12548                    sizeof (ip4_address_t));
12549     }
12550   mp->protocol = (u8) protocol;
12551   mp->local_port_start = ntohs ((u16) lport_start);
12552   mp->local_port_stop = ntohs ((u16) lport_stop);
12553   mp->remote_port_start = ntohs ((u16) rport_start);
12554   mp->remote_port_stop = ntohs ((u16) rport_stop);
12555   mp->policy = (u8) policy;
12556   mp->sa_id = ntohl (sa_id);
12557   mp->is_add = is_add;
12558   mp->is_ip_any = is_ip_any;
12559   S (mp);
12560   W (ret);
12561   return ret;
12562 }
12563
12564 static int
12565 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12566 {
12567   unformat_input_t *i = vam->input;
12568   vl_api_ipsec_sad_add_del_entry_t *mp;
12569   u32 sad_id = 0, spi = 0;
12570   u8 *ck = 0, *ik = 0;
12571   u8 is_add = 1;
12572
12573   u8 protocol = IPSEC_PROTOCOL_AH;
12574   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12575   u32 crypto_alg = 0, integ_alg = 0;
12576   ip4_address_t tun_src4;
12577   ip4_address_t tun_dst4;
12578   ip6_address_t tun_src6;
12579   ip6_address_t tun_dst6;
12580   int ret;
12581
12582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12583     {
12584       if (unformat (i, "del"))
12585         is_add = 0;
12586       else if (unformat (i, "sad_id %d", &sad_id))
12587         ;
12588       else if (unformat (i, "spi %d", &spi))
12589         ;
12590       else if (unformat (i, "esp"))
12591         protocol = IPSEC_PROTOCOL_ESP;
12592       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12593         {
12594           is_tunnel = 1;
12595           is_tunnel_ipv6 = 0;
12596         }
12597       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12598         {
12599           is_tunnel = 1;
12600           is_tunnel_ipv6 = 0;
12601         }
12602       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12603         {
12604           is_tunnel = 1;
12605           is_tunnel_ipv6 = 1;
12606         }
12607       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12608         {
12609           is_tunnel = 1;
12610           is_tunnel_ipv6 = 1;
12611         }
12612       else
12613         if (unformat
12614             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12615         {
12616           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12617               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12618             {
12619               clib_warning ("unsupported crypto-alg: '%U'",
12620                             format_ipsec_crypto_alg, crypto_alg);
12621               return -99;
12622             }
12623         }
12624       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12625         ;
12626       else
12627         if (unformat
12628             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12629         {
12630           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12631               integ_alg >= IPSEC_INTEG_N_ALG)
12632             {
12633               clib_warning ("unsupported integ-alg: '%U'",
12634                             format_ipsec_integ_alg, integ_alg);
12635               return -99;
12636             }
12637         }
12638       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12639         ;
12640       else
12641         {
12642           clib_warning ("parse error '%U'", format_unformat_error, i);
12643           return -99;
12644         }
12645
12646     }
12647
12648   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12649
12650   mp->sad_id = ntohl (sad_id);
12651   mp->is_add = is_add;
12652   mp->protocol = protocol;
12653   mp->spi = ntohl (spi);
12654   mp->is_tunnel = is_tunnel;
12655   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12656   mp->crypto_algorithm = crypto_alg;
12657   mp->integrity_algorithm = integ_alg;
12658   mp->crypto_key_length = vec_len (ck);
12659   mp->integrity_key_length = vec_len (ik);
12660
12661   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12662     mp->crypto_key_length = sizeof (mp->crypto_key);
12663
12664   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12665     mp->integrity_key_length = sizeof (mp->integrity_key);
12666
12667   if (ck)
12668     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12669   if (ik)
12670     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12671
12672   if (is_tunnel)
12673     {
12674       if (is_tunnel_ipv6)
12675         {
12676           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12677                        sizeof (ip6_address_t));
12678           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12679                        sizeof (ip6_address_t));
12680         }
12681       else
12682         {
12683           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12684                        sizeof (ip4_address_t));
12685           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12686                        sizeof (ip4_address_t));
12687         }
12688     }
12689
12690   S (mp);
12691   W (ret);
12692   return ret;
12693 }
12694
12695 static int
12696 api_ipsec_sa_set_key (vat_main_t * vam)
12697 {
12698   unformat_input_t *i = vam->input;
12699   vl_api_ipsec_sa_set_key_t *mp;
12700   u32 sa_id;
12701   u8 *ck = 0, *ik = 0;
12702   int ret;
12703
12704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12705     {
12706       if (unformat (i, "sa_id %d", &sa_id))
12707         ;
12708       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12709         ;
12710       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12711         ;
12712       else
12713         {
12714           clib_warning ("parse error '%U'", format_unformat_error, i);
12715           return -99;
12716         }
12717     }
12718
12719   M (IPSEC_SA_SET_KEY, mp);
12720
12721   mp->sa_id = ntohl (sa_id);
12722   mp->crypto_key_length = vec_len (ck);
12723   mp->integrity_key_length = vec_len (ik);
12724
12725   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12726     mp->crypto_key_length = sizeof (mp->crypto_key);
12727
12728   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12729     mp->integrity_key_length = sizeof (mp->integrity_key);
12730
12731   if (ck)
12732     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12733   if (ik)
12734     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12735
12736   S (mp);
12737   W (ret);
12738   return ret;
12739 }
12740
12741 static int
12742 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12743 {
12744   unformat_input_t *i = vam->input;
12745   vl_api_ipsec_tunnel_if_add_del_t *mp;
12746   u32 local_spi = 0, remote_spi = 0;
12747   u32 crypto_alg = 0, integ_alg = 0;
12748   u8 *lck = NULL, *rck = NULL;
12749   u8 *lik = NULL, *rik = NULL;
12750   ip4_address_t local_ip = { {0} };
12751   ip4_address_t remote_ip = { {0} };
12752   u8 is_add = 1;
12753   u8 esn = 0;
12754   u8 anti_replay = 0;
12755   int ret;
12756
12757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12758     {
12759       if (unformat (i, "del"))
12760         is_add = 0;
12761       else if (unformat (i, "esn"))
12762         esn = 1;
12763       else if (unformat (i, "anti_replay"))
12764         anti_replay = 1;
12765       else if (unformat (i, "local_spi %d", &local_spi))
12766         ;
12767       else if (unformat (i, "remote_spi %d", &remote_spi))
12768         ;
12769       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12770         ;
12771       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12772         ;
12773       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12774         ;
12775       else
12776         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12777         ;
12778       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12779         ;
12780       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12781         ;
12782       else
12783         if (unformat
12784             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12785         {
12786           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12787               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12788             {
12789               errmsg ("unsupported crypto-alg: '%U'\n",
12790                       format_ipsec_crypto_alg, crypto_alg);
12791               return -99;
12792             }
12793         }
12794       else
12795         if (unformat
12796             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12797         {
12798           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12799               integ_alg >= IPSEC_INTEG_N_ALG)
12800             {
12801               errmsg ("unsupported integ-alg: '%U'\n",
12802                       format_ipsec_integ_alg, integ_alg);
12803               return -99;
12804             }
12805         }
12806       else
12807         {
12808           errmsg ("parse error '%U'\n", format_unformat_error, i);
12809           return -99;
12810         }
12811     }
12812
12813   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12814
12815   mp->is_add = is_add;
12816   mp->esn = esn;
12817   mp->anti_replay = anti_replay;
12818
12819   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12820   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12821
12822   mp->local_spi = htonl (local_spi);
12823   mp->remote_spi = htonl (remote_spi);
12824   mp->crypto_alg = (u8) crypto_alg;
12825
12826   mp->local_crypto_key_len = 0;
12827   if (lck)
12828     {
12829       mp->local_crypto_key_len = vec_len (lck);
12830       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12831         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12832       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12833     }
12834
12835   mp->remote_crypto_key_len = 0;
12836   if (rck)
12837     {
12838       mp->remote_crypto_key_len = vec_len (rck);
12839       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12840         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12841       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12842     }
12843
12844   mp->integ_alg = (u8) integ_alg;
12845
12846   mp->local_integ_key_len = 0;
12847   if (lik)
12848     {
12849       mp->local_integ_key_len = vec_len (lik);
12850       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12851         mp->local_integ_key_len = sizeof (mp->local_integ_key);
12852       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12853     }
12854
12855   mp->remote_integ_key_len = 0;
12856   if (rik)
12857     {
12858       mp->remote_integ_key_len = vec_len (rik);
12859       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12860         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12861       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12862     }
12863
12864   S (mp);
12865   W (ret);
12866   return ret;
12867 }
12868
12869 static int
12870 api_ikev2_profile_add_del (vat_main_t * vam)
12871 {
12872   unformat_input_t *i = vam->input;
12873   vl_api_ikev2_profile_add_del_t *mp;
12874   u8 is_add = 1;
12875   u8 *name = 0;
12876   int ret;
12877
12878   const char *valid_chars = "a-zA-Z0-9_";
12879
12880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12881     {
12882       if (unformat (i, "del"))
12883         is_add = 0;
12884       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12885         vec_add1 (name, 0);
12886       else
12887         {
12888           errmsg ("parse error '%U'", format_unformat_error, i);
12889           return -99;
12890         }
12891     }
12892
12893   if (!vec_len (name))
12894     {
12895       errmsg ("profile name must be specified");
12896       return -99;
12897     }
12898
12899   if (vec_len (name) > 64)
12900     {
12901       errmsg ("profile name too long");
12902       return -99;
12903     }
12904
12905   M (IKEV2_PROFILE_ADD_DEL, mp);
12906
12907   clib_memcpy (mp->name, name, vec_len (name));
12908   mp->is_add = is_add;
12909   vec_free (name);
12910
12911   S (mp);
12912   W (ret);
12913   return ret;
12914 }
12915
12916 static int
12917 api_ikev2_profile_set_auth (vat_main_t * vam)
12918 {
12919   unformat_input_t *i = vam->input;
12920   vl_api_ikev2_profile_set_auth_t *mp;
12921   u8 *name = 0;
12922   u8 *data = 0;
12923   u32 auth_method = 0;
12924   u8 is_hex = 0;
12925   int ret;
12926
12927   const char *valid_chars = "a-zA-Z0-9_";
12928
12929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12930     {
12931       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12932         vec_add1 (name, 0);
12933       else if (unformat (i, "auth_method %U",
12934                          unformat_ikev2_auth_method, &auth_method))
12935         ;
12936       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12937         is_hex = 1;
12938       else if (unformat (i, "auth_data %v", &data))
12939         ;
12940       else
12941         {
12942           errmsg ("parse error '%U'", format_unformat_error, i);
12943           return -99;
12944         }
12945     }
12946
12947   if (!vec_len (name))
12948     {
12949       errmsg ("profile name must be specified");
12950       return -99;
12951     }
12952
12953   if (vec_len (name) > 64)
12954     {
12955       errmsg ("profile name too long");
12956       return -99;
12957     }
12958
12959   if (!vec_len (data))
12960     {
12961       errmsg ("auth_data must be specified");
12962       return -99;
12963     }
12964
12965   if (!auth_method)
12966     {
12967       errmsg ("auth_method must be specified");
12968       return -99;
12969     }
12970
12971   M (IKEV2_PROFILE_SET_AUTH, mp);
12972
12973   mp->is_hex = is_hex;
12974   mp->auth_method = (u8) auth_method;
12975   mp->data_len = vec_len (data);
12976   clib_memcpy (mp->name, name, vec_len (name));
12977   clib_memcpy (mp->data, data, vec_len (data));
12978   vec_free (name);
12979   vec_free (data);
12980
12981   S (mp);
12982   W (ret);
12983   return ret;
12984 }
12985
12986 static int
12987 api_ikev2_profile_set_id (vat_main_t * vam)
12988 {
12989   unformat_input_t *i = vam->input;
12990   vl_api_ikev2_profile_set_id_t *mp;
12991   u8 *name = 0;
12992   u8 *data = 0;
12993   u8 is_local = 0;
12994   u32 id_type = 0;
12995   ip4_address_t ip4;
12996   int ret;
12997
12998   const char *valid_chars = "a-zA-Z0-9_";
12999
13000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13001     {
13002       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13003         vec_add1 (name, 0);
13004       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13005         ;
13006       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13007         {
13008           data = vec_new (u8, 4);
13009           clib_memcpy (data, ip4.as_u8, 4);
13010         }
13011       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13012         ;
13013       else if (unformat (i, "id_data %v", &data))
13014         ;
13015       else if (unformat (i, "local"))
13016         is_local = 1;
13017       else if (unformat (i, "remote"))
13018         is_local = 0;
13019       else
13020         {
13021           errmsg ("parse error '%U'", format_unformat_error, i);
13022           return -99;
13023         }
13024     }
13025
13026   if (!vec_len (name))
13027     {
13028       errmsg ("profile name must be specified");
13029       return -99;
13030     }
13031
13032   if (vec_len (name) > 64)
13033     {
13034       errmsg ("profile name too long");
13035       return -99;
13036     }
13037
13038   if (!vec_len (data))
13039     {
13040       errmsg ("id_data must be specified");
13041       return -99;
13042     }
13043
13044   if (!id_type)
13045     {
13046       errmsg ("id_type must be specified");
13047       return -99;
13048     }
13049
13050   M (IKEV2_PROFILE_SET_ID, mp);
13051
13052   mp->is_local = is_local;
13053   mp->id_type = (u8) id_type;
13054   mp->data_len = vec_len (data);
13055   clib_memcpy (mp->name, name, vec_len (name));
13056   clib_memcpy (mp->data, data, vec_len (data));
13057   vec_free (name);
13058   vec_free (data);
13059
13060   S (mp);
13061   W (ret);
13062   return ret;
13063 }
13064
13065 static int
13066 api_ikev2_profile_set_ts (vat_main_t * vam)
13067 {
13068   unformat_input_t *i = vam->input;
13069   vl_api_ikev2_profile_set_ts_t *mp;
13070   u8 *name = 0;
13071   u8 is_local = 0;
13072   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13073   ip4_address_t start_addr, end_addr;
13074
13075   const char *valid_chars = "a-zA-Z0-9_";
13076   int ret;
13077
13078   start_addr.as_u32 = 0;
13079   end_addr.as_u32 = (u32) ~ 0;
13080
13081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13082     {
13083       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13084         vec_add1 (name, 0);
13085       else if (unformat (i, "protocol %d", &proto))
13086         ;
13087       else if (unformat (i, "start_port %d", &start_port))
13088         ;
13089       else if (unformat (i, "end_port %d", &end_port))
13090         ;
13091       else
13092         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13093         ;
13094       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13095         ;
13096       else if (unformat (i, "local"))
13097         is_local = 1;
13098       else if (unformat (i, "remote"))
13099         is_local = 0;
13100       else
13101         {
13102           errmsg ("parse error '%U'", format_unformat_error, i);
13103           return -99;
13104         }
13105     }
13106
13107   if (!vec_len (name))
13108     {
13109       errmsg ("profile name must be specified");
13110       return -99;
13111     }
13112
13113   if (vec_len (name) > 64)
13114     {
13115       errmsg ("profile name too long");
13116       return -99;
13117     }
13118
13119   M (IKEV2_PROFILE_SET_TS, mp);
13120
13121   mp->is_local = is_local;
13122   mp->proto = (u8) proto;
13123   mp->start_port = (u16) start_port;
13124   mp->end_port = (u16) end_port;
13125   mp->start_addr = start_addr.as_u32;
13126   mp->end_addr = end_addr.as_u32;
13127   clib_memcpy (mp->name, name, vec_len (name));
13128   vec_free (name);
13129
13130   S (mp);
13131   W (ret);
13132   return ret;
13133 }
13134
13135 static int
13136 api_ikev2_set_local_key (vat_main_t * vam)
13137 {
13138   unformat_input_t *i = vam->input;
13139   vl_api_ikev2_set_local_key_t *mp;
13140   u8 *file = 0;
13141   int ret;
13142
13143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13144     {
13145       if (unformat (i, "file %v", &file))
13146         vec_add1 (file, 0);
13147       else
13148         {
13149           errmsg ("parse error '%U'", format_unformat_error, i);
13150           return -99;
13151         }
13152     }
13153
13154   if (!vec_len (file))
13155     {
13156       errmsg ("RSA key file must be specified");
13157       return -99;
13158     }
13159
13160   if (vec_len (file) > 256)
13161     {
13162       errmsg ("file name too long");
13163       return -99;
13164     }
13165
13166   M (IKEV2_SET_LOCAL_KEY, mp);
13167
13168   clib_memcpy (mp->key_file, file, vec_len (file));
13169   vec_free (file);
13170
13171   S (mp);
13172   W (ret);
13173   return ret;
13174 }
13175
13176 static int
13177 api_ikev2_set_responder (vat_main_t * vam)
13178 {
13179   unformat_input_t *i = vam->input;
13180   vl_api_ikev2_set_responder_t *mp;
13181   int ret;
13182   u8 *name = 0;
13183   u32 sw_if_index = ~0;
13184   ip4_address_t address;
13185
13186   const char *valid_chars = "a-zA-Z0-9_";
13187
13188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13189     {
13190       if (unformat
13191           (i, "%U interface %d address %U", unformat_token, valid_chars,
13192            &name, &sw_if_index, unformat_ip4_address, &address))
13193         vec_add1 (name, 0);
13194       else
13195         {
13196           errmsg ("parse error '%U'", format_unformat_error, i);
13197           return -99;
13198         }
13199     }
13200
13201   if (!vec_len (name))
13202     {
13203       errmsg ("profile name must be specified");
13204       return -99;
13205     }
13206
13207   if (vec_len (name) > 64)
13208     {
13209       errmsg ("profile name too long");
13210       return -99;
13211     }
13212
13213   M (IKEV2_SET_RESPONDER, mp);
13214
13215   clib_memcpy (mp->name, name, vec_len (name));
13216   vec_free (name);
13217
13218   mp->sw_if_index = sw_if_index;
13219   clib_memcpy (mp->address, &address, sizeof (address));
13220
13221   S (mp);
13222   W (ret);
13223   return ret;
13224 }
13225
13226 static int
13227 api_ikev2_set_ike_transforms (vat_main_t * vam)
13228 {
13229   unformat_input_t *i = vam->input;
13230   vl_api_ikev2_set_ike_transforms_t *mp;
13231   int ret;
13232   u8 *name = 0;
13233   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13234
13235   const char *valid_chars = "a-zA-Z0-9_";
13236
13237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13238     {
13239       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13240                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13241         vec_add1 (name, 0);
13242       else
13243         {
13244           errmsg ("parse error '%U'", format_unformat_error, i);
13245           return -99;
13246         }
13247     }
13248
13249   if (!vec_len (name))
13250     {
13251       errmsg ("profile name must be specified");
13252       return -99;
13253     }
13254
13255   if (vec_len (name) > 64)
13256     {
13257       errmsg ("profile name too long");
13258       return -99;
13259     }
13260
13261   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13262
13263   clib_memcpy (mp->name, name, vec_len (name));
13264   vec_free (name);
13265   mp->crypto_alg = crypto_alg;
13266   mp->crypto_key_size = crypto_key_size;
13267   mp->integ_alg = integ_alg;
13268   mp->dh_group = dh_group;
13269
13270   S (mp);
13271   W (ret);
13272   return ret;
13273 }
13274
13275
13276 static int
13277 api_ikev2_set_esp_transforms (vat_main_t * vam)
13278 {
13279   unformat_input_t *i = vam->input;
13280   vl_api_ikev2_set_esp_transforms_t *mp;
13281   int ret;
13282   u8 *name = 0;
13283   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13284
13285   const char *valid_chars = "a-zA-Z0-9_";
13286
13287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13288     {
13289       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13290                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13291         vec_add1 (name, 0);
13292       else
13293         {
13294           errmsg ("parse error '%U'", format_unformat_error, i);
13295           return -99;
13296         }
13297     }
13298
13299   if (!vec_len (name))
13300     {
13301       errmsg ("profile name must be specified");
13302       return -99;
13303     }
13304
13305   if (vec_len (name) > 64)
13306     {
13307       errmsg ("profile name too long");
13308       return -99;
13309     }
13310
13311   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13312
13313   clib_memcpy (mp->name, name, vec_len (name));
13314   vec_free (name);
13315   mp->crypto_alg = crypto_alg;
13316   mp->crypto_key_size = crypto_key_size;
13317   mp->integ_alg = integ_alg;
13318   mp->dh_group = dh_group;
13319
13320   S (mp);
13321   W (ret);
13322   return ret;
13323 }
13324
13325 static int
13326 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13327 {
13328   unformat_input_t *i = vam->input;
13329   vl_api_ikev2_set_sa_lifetime_t *mp;
13330   int ret;
13331   u8 *name = 0;
13332   u64 lifetime, lifetime_maxdata;
13333   u32 lifetime_jitter, handover;
13334
13335   const char *valid_chars = "a-zA-Z0-9_";
13336
13337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13338     {
13339       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13340                     &lifetime, &lifetime_jitter, &handover,
13341                     &lifetime_maxdata))
13342         vec_add1 (name, 0);
13343       else
13344         {
13345           errmsg ("parse error '%U'", format_unformat_error, i);
13346           return -99;
13347         }
13348     }
13349
13350   if (!vec_len (name))
13351     {
13352       errmsg ("profile name must be specified");
13353       return -99;
13354     }
13355
13356   if (vec_len (name) > 64)
13357     {
13358       errmsg ("profile name too long");
13359       return -99;
13360     }
13361
13362   M (IKEV2_SET_SA_LIFETIME, mp);
13363
13364   clib_memcpy (mp->name, name, vec_len (name));
13365   vec_free (name);
13366   mp->lifetime = lifetime;
13367   mp->lifetime_jitter = lifetime_jitter;
13368   mp->handover = handover;
13369   mp->lifetime_maxdata = lifetime_maxdata;
13370
13371   S (mp);
13372   W (ret);
13373   return ret;
13374 }
13375
13376 static int
13377 api_ikev2_initiate_sa_init (vat_main_t * vam)
13378 {
13379   unformat_input_t *i = vam->input;
13380   vl_api_ikev2_initiate_sa_init_t *mp;
13381   int ret;
13382   u8 *name = 0;
13383
13384   const char *valid_chars = "a-zA-Z0-9_";
13385
13386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13387     {
13388       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13389         vec_add1 (name, 0);
13390       else
13391         {
13392           errmsg ("parse error '%U'", format_unformat_error, i);
13393           return -99;
13394         }
13395     }
13396
13397   if (!vec_len (name))
13398     {
13399       errmsg ("profile name must be specified");
13400       return -99;
13401     }
13402
13403   if (vec_len (name) > 64)
13404     {
13405       errmsg ("profile name too long");
13406       return -99;
13407     }
13408
13409   M (IKEV2_INITIATE_SA_INIT, mp);
13410
13411   clib_memcpy (mp->name, name, vec_len (name));
13412   vec_free (name);
13413
13414   S (mp);
13415   W (ret);
13416   return ret;
13417 }
13418
13419 static int
13420 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13421 {
13422   unformat_input_t *i = vam->input;
13423   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13424   int ret;
13425   u64 ispi;
13426
13427
13428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13429     {
13430       if (unformat (i, "%lx", &ispi))
13431         ;
13432       else
13433         {
13434           errmsg ("parse error '%U'", format_unformat_error, i);
13435           return -99;
13436         }
13437     }
13438
13439   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13440
13441   mp->ispi = ispi;
13442
13443   S (mp);
13444   W (ret);
13445   return ret;
13446 }
13447
13448 static int
13449 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13450 {
13451   unformat_input_t *i = vam->input;
13452   vl_api_ikev2_initiate_del_child_sa_t *mp;
13453   int ret;
13454   u32 ispi;
13455
13456
13457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13458     {
13459       if (unformat (i, "%x", &ispi))
13460         ;
13461       else
13462         {
13463           errmsg ("parse error '%U'", format_unformat_error, i);
13464           return -99;
13465         }
13466     }
13467
13468   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13469
13470   mp->ispi = ispi;
13471
13472   S (mp);
13473   W (ret);
13474   return ret;
13475 }
13476
13477 static int
13478 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13479 {
13480   unformat_input_t *i = vam->input;
13481   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13482   int ret;
13483   u32 ispi;
13484
13485
13486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13487     {
13488       if (unformat (i, "%x", &ispi))
13489         ;
13490       else
13491         {
13492           errmsg ("parse error '%U'", format_unformat_error, i);
13493           return -99;
13494         }
13495     }
13496
13497   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13498
13499   mp->ispi = ispi;
13500
13501   S (mp);
13502   W (ret);
13503   return ret;
13504 }
13505
13506 /*
13507  * MAP
13508  */
13509 static int
13510 api_map_add_domain (vat_main_t * vam)
13511 {
13512   unformat_input_t *i = vam->input;
13513   vl_api_map_add_domain_t *mp;
13514
13515   ip4_address_t ip4_prefix;
13516   ip6_address_t ip6_prefix;
13517   ip6_address_t ip6_src;
13518   u32 num_m_args = 0;
13519   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13520     0, psid_length = 0;
13521   u8 is_translation = 0;
13522   u32 mtu = 0;
13523   u32 ip6_src_len = 128;
13524   int ret;
13525
13526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13527     {
13528       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13529                     &ip4_prefix, &ip4_prefix_len))
13530         num_m_args++;
13531       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13532                          &ip6_prefix, &ip6_prefix_len))
13533         num_m_args++;
13534       else
13535         if (unformat
13536             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13537              &ip6_src_len))
13538         num_m_args++;
13539       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13540         num_m_args++;
13541       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13542         num_m_args++;
13543       else if (unformat (i, "psid-offset %d", &psid_offset))
13544         num_m_args++;
13545       else if (unformat (i, "psid-len %d", &psid_length))
13546         num_m_args++;
13547       else if (unformat (i, "mtu %d", &mtu))
13548         num_m_args++;
13549       else if (unformat (i, "map-t"))
13550         is_translation = 1;
13551       else
13552         {
13553           clib_warning ("parse error '%U'", format_unformat_error, i);
13554           return -99;
13555         }
13556     }
13557
13558   if (num_m_args < 3)
13559     {
13560       errmsg ("mandatory argument(s) missing");
13561       return -99;
13562     }
13563
13564   /* Construct the API message */
13565   M (MAP_ADD_DOMAIN, mp);
13566
13567   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13568   mp->ip4_prefix_len = ip4_prefix_len;
13569
13570   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13571   mp->ip6_prefix_len = ip6_prefix_len;
13572
13573   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13574   mp->ip6_src_prefix_len = ip6_src_len;
13575
13576   mp->ea_bits_len = ea_bits_len;
13577   mp->psid_offset = psid_offset;
13578   mp->psid_length = psid_length;
13579   mp->is_translation = is_translation;
13580   mp->mtu = htons (mtu);
13581
13582   /* send it... */
13583   S (mp);
13584
13585   /* Wait for a reply, return good/bad news  */
13586   W (ret);
13587   return ret;
13588 }
13589
13590 static int
13591 api_map_del_domain (vat_main_t * vam)
13592 {
13593   unformat_input_t *i = vam->input;
13594   vl_api_map_del_domain_t *mp;
13595
13596   u32 num_m_args = 0;
13597   u32 index;
13598   int ret;
13599
13600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13601     {
13602       if (unformat (i, "index %d", &index))
13603         num_m_args++;
13604       else
13605         {
13606           clib_warning ("parse error '%U'", format_unformat_error, i);
13607           return -99;
13608         }
13609     }
13610
13611   if (num_m_args != 1)
13612     {
13613       errmsg ("mandatory argument(s) missing");
13614       return -99;
13615     }
13616
13617   /* Construct the API message */
13618   M (MAP_DEL_DOMAIN, mp);
13619
13620   mp->index = ntohl (index);
13621
13622   /* send it... */
13623   S (mp);
13624
13625   /* Wait for a reply, return good/bad news  */
13626   W (ret);
13627   return ret;
13628 }
13629
13630 static int
13631 api_map_add_del_rule (vat_main_t * vam)
13632 {
13633   unformat_input_t *i = vam->input;
13634   vl_api_map_add_del_rule_t *mp;
13635   u8 is_add = 1;
13636   ip6_address_t ip6_dst;
13637   u32 num_m_args = 0, index, psid = 0;
13638   int ret;
13639
13640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13641     {
13642       if (unformat (i, "index %d", &index))
13643         num_m_args++;
13644       else if (unformat (i, "psid %d", &psid))
13645         num_m_args++;
13646       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13647         num_m_args++;
13648       else if (unformat (i, "del"))
13649         {
13650           is_add = 0;
13651         }
13652       else
13653         {
13654           clib_warning ("parse error '%U'", format_unformat_error, i);
13655           return -99;
13656         }
13657     }
13658
13659   /* Construct the API message */
13660   M (MAP_ADD_DEL_RULE, mp);
13661
13662   mp->index = ntohl (index);
13663   mp->is_add = is_add;
13664   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13665   mp->psid = ntohs (psid);
13666
13667   /* send it... */
13668   S (mp);
13669
13670   /* Wait for a reply, return good/bad news  */
13671   W (ret);
13672   return ret;
13673 }
13674
13675 static int
13676 api_map_domain_dump (vat_main_t * vam)
13677 {
13678   vl_api_map_domain_dump_t *mp;
13679   vl_api_control_ping_t *mp_ping;
13680   int ret;
13681
13682   /* Construct the API message */
13683   M (MAP_DOMAIN_DUMP, mp);
13684
13685   /* send it... */
13686   S (mp);
13687
13688   /* Use a control ping for synchronization */
13689   M (CONTROL_PING, mp_ping);
13690   S (mp_ping);
13691
13692   W (ret);
13693   return ret;
13694 }
13695
13696 static int
13697 api_map_rule_dump (vat_main_t * vam)
13698 {
13699   unformat_input_t *i = vam->input;
13700   vl_api_map_rule_dump_t *mp;
13701   vl_api_control_ping_t *mp_ping;
13702   u32 domain_index = ~0;
13703   int ret;
13704
13705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13706     {
13707       if (unformat (i, "index %u", &domain_index))
13708         ;
13709       else
13710         break;
13711     }
13712
13713   if (domain_index == ~0)
13714     {
13715       clib_warning ("parse error: domain index expected");
13716       return -99;
13717     }
13718
13719   /* Construct the API message */
13720   M (MAP_RULE_DUMP, mp);
13721
13722   mp->domain_index = htonl (domain_index);
13723
13724   /* send it... */
13725   S (mp);
13726
13727   /* Use a control ping for synchronization */
13728   M (CONTROL_PING, mp_ping);
13729   S (mp_ping);
13730
13731   W (ret);
13732   return ret;
13733 }
13734
13735 static void vl_api_map_add_domain_reply_t_handler
13736   (vl_api_map_add_domain_reply_t * mp)
13737 {
13738   vat_main_t *vam = &vat_main;
13739   i32 retval = ntohl (mp->retval);
13740
13741   if (vam->async_mode)
13742     {
13743       vam->async_errors += (retval < 0);
13744     }
13745   else
13746     {
13747       vam->retval = retval;
13748       vam->result_ready = 1;
13749     }
13750 }
13751
13752 static void vl_api_map_add_domain_reply_t_handler_json
13753   (vl_api_map_add_domain_reply_t * mp)
13754 {
13755   vat_main_t *vam = &vat_main;
13756   vat_json_node_t node;
13757
13758   vat_json_init_object (&node);
13759   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13760   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13761
13762   vat_json_print (vam->ofp, &node);
13763   vat_json_free (&node);
13764
13765   vam->retval = ntohl (mp->retval);
13766   vam->result_ready = 1;
13767 }
13768
13769 static int
13770 api_get_first_msg_id (vat_main_t * vam)
13771 {
13772   vl_api_get_first_msg_id_t *mp;
13773   unformat_input_t *i = vam->input;
13774   u8 *name;
13775   u8 name_set = 0;
13776   int ret;
13777
13778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13779     {
13780       if (unformat (i, "client %s", &name))
13781         name_set = 1;
13782       else
13783         break;
13784     }
13785
13786   if (name_set == 0)
13787     {
13788       errmsg ("missing client name");
13789       return -99;
13790     }
13791   vec_add1 (name, 0);
13792
13793   if (vec_len (name) > 63)
13794     {
13795       errmsg ("client name too long");
13796       return -99;
13797     }
13798
13799   M (GET_FIRST_MSG_ID, mp);
13800   clib_memcpy (mp->name, name, vec_len (name));
13801   S (mp);
13802   W (ret);
13803   return ret;
13804 }
13805
13806 static int
13807 api_cop_interface_enable_disable (vat_main_t * vam)
13808 {
13809   unformat_input_t *line_input = vam->input;
13810   vl_api_cop_interface_enable_disable_t *mp;
13811   u32 sw_if_index = ~0;
13812   u8 enable_disable = 1;
13813   int ret;
13814
13815   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13816     {
13817       if (unformat (line_input, "disable"))
13818         enable_disable = 0;
13819       if (unformat (line_input, "enable"))
13820         enable_disable = 1;
13821       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13822                          vam, &sw_if_index))
13823         ;
13824       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13825         ;
13826       else
13827         break;
13828     }
13829
13830   if (sw_if_index == ~0)
13831     {
13832       errmsg ("missing interface name or sw_if_index");
13833       return -99;
13834     }
13835
13836   /* Construct the API message */
13837   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13838   mp->sw_if_index = ntohl (sw_if_index);
13839   mp->enable_disable = enable_disable;
13840
13841   /* send it... */
13842   S (mp);
13843   /* Wait for the reply */
13844   W (ret);
13845   return ret;
13846 }
13847
13848 static int
13849 api_cop_whitelist_enable_disable (vat_main_t * vam)
13850 {
13851   unformat_input_t *line_input = vam->input;
13852   vl_api_cop_whitelist_enable_disable_t *mp;
13853   u32 sw_if_index = ~0;
13854   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13855   u32 fib_id = 0;
13856   int ret;
13857
13858   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13859     {
13860       if (unformat (line_input, "ip4"))
13861         ip4 = 1;
13862       else if (unformat (line_input, "ip6"))
13863         ip6 = 1;
13864       else if (unformat (line_input, "default"))
13865         default_cop = 1;
13866       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13867                          vam, &sw_if_index))
13868         ;
13869       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13870         ;
13871       else if (unformat (line_input, "fib-id %d", &fib_id))
13872         ;
13873       else
13874         break;
13875     }
13876
13877   if (sw_if_index == ~0)
13878     {
13879       errmsg ("missing interface name or sw_if_index");
13880       return -99;
13881     }
13882
13883   /* Construct the API message */
13884   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13885   mp->sw_if_index = ntohl (sw_if_index);
13886   mp->fib_id = ntohl (fib_id);
13887   mp->ip4 = ip4;
13888   mp->ip6 = ip6;
13889   mp->default_cop = default_cop;
13890
13891   /* send it... */
13892   S (mp);
13893   /* Wait for the reply */
13894   W (ret);
13895   return ret;
13896 }
13897
13898 static int
13899 api_get_node_graph (vat_main_t * vam)
13900 {
13901   vl_api_get_node_graph_t *mp;
13902   int ret;
13903
13904   M (GET_NODE_GRAPH, mp);
13905
13906   /* send it... */
13907   S (mp);
13908   /* Wait for the reply */
13909   W (ret);
13910   return ret;
13911 }
13912
13913 /* *INDENT-OFF* */
13914 /** Used for parsing LISP eids */
13915 typedef CLIB_PACKED(struct{
13916   u8 addr[16];   /**< eid address */
13917   u32 len;       /**< prefix length if IP */
13918   u8 type;      /**< type of eid */
13919 }) lisp_eid_vat_t;
13920 /* *INDENT-ON* */
13921
13922 static uword
13923 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13924 {
13925   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13926
13927   memset (a, 0, sizeof (a[0]));
13928
13929   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13930     {
13931       a->type = 0;              /* ipv4 type */
13932     }
13933   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13934     {
13935       a->type = 1;              /* ipv6 type */
13936     }
13937   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13938     {
13939       a->type = 2;              /* mac type */
13940     }
13941   else
13942     {
13943       return 0;
13944     }
13945
13946   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13947     {
13948       return 0;
13949     }
13950
13951   return 1;
13952 }
13953
13954 static int
13955 lisp_eid_size_vat (u8 type)
13956 {
13957   switch (type)
13958     {
13959     case 0:
13960       return 4;
13961     case 1:
13962       return 16;
13963     case 2:
13964       return 6;
13965     }
13966   return 0;
13967 }
13968
13969 static void
13970 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13971 {
13972   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13973 }
13974
13975 static int
13976 api_one_add_del_locator_set (vat_main_t * vam)
13977 {
13978   unformat_input_t *input = vam->input;
13979   vl_api_one_add_del_locator_set_t *mp;
13980   u8 is_add = 1;
13981   u8 *locator_set_name = NULL;
13982   u8 locator_set_name_set = 0;
13983   vl_api_local_locator_t locator, *locators = 0;
13984   u32 sw_if_index, priority, weight;
13985   u32 data_len = 0;
13986
13987   int ret;
13988   /* Parse args required to build the message */
13989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13990     {
13991       if (unformat (input, "del"))
13992         {
13993           is_add = 0;
13994         }
13995       else if (unformat (input, "locator-set %s", &locator_set_name))
13996         {
13997           locator_set_name_set = 1;
13998         }
13999       else if (unformat (input, "sw_if_index %u p %u w %u",
14000                          &sw_if_index, &priority, &weight))
14001         {
14002           locator.sw_if_index = htonl (sw_if_index);
14003           locator.priority = priority;
14004           locator.weight = weight;
14005           vec_add1 (locators, locator);
14006         }
14007       else
14008         if (unformat
14009             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14010              &sw_if_index, &priority, &weight))
14011         {
14012           locator.sw_if_index = htonl (sw_if_index);
14013           locator.priority = priority;
14014           locator.weight = weight;
14015           vec_add1 (locators, locator);
14016         }
14017       else
14018         break;
14019     }
14020
14021   if (locator_set_name_set == 0)
14022     {
14023       errmsg ("missing locator-set name");
14024       vec_free (locators);
14025       return -99;
14026     }
14027
14028   if (vec_len (locator_set_name) > 64)
14029     {
14030       errmsg ("locator-set name too long");
14031       vec_free (locator_set_name);
14032       vec_free (locators);
14033       return -99;
14034     }
14035   vec_add1 (locator_set_name, 0);
14036
14037   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14038
14039   /* Construct the API message */
14040   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14041
14042   mp->is_add = is_add;
14043   clib_memcpy (mp->locator_set_name, locator_set_name,
14044                vec_len (locator_set_name));
14045   vec_free (locator_set_name);
14046
14047   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14048   if (locators)
14049     clib_memcpy (mp->locators, locators, data_len);
14050   vec_free (locators);
14051
14052   /* send it... */
14053   S (mp);
14054
14055   /* Wait for a reply... */
14056   W (ret);
14057   return ret;
14058 }
14059
14060 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14061
14062 static int
14063 api_one_add_del_locator (vat_main_t * vam)
14064 {
14065   unformat_input_t *input = vam->input;
14066   vl_api_one_add_del_locator_t *mp;
14067   u32 tmp_if_index = ~0;
14068   u32 sw_if_index = ~0;
14069   u8 sw_if_index_set = 0;
14070   u8 sw_if_index_if_name_set = 0;
14071   u32 priority = ~0;
14072   u8 priority_set = 0;
14073   u32 weight = ~0;
14074   u8 weight_set = 0;
14075   u8 is_add = 1;
14076   u8 *locator_set_name = NULL;
14077   u8 locator_set_name_set = 0;
14078   int ret;
14079
14080   /* Parse args required to build the message */
14081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14082     {
14083       if (unformat (input, "del"))
14084         {
14085           is_add = 0;
14086         }
14087       else if (unformat (input, "locator-set %s", &locator_set_name))
14088         {
14089           locator_set_name_set = 1;
14090         }
14091       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14092                          &tmp_if_index))
14093         {
14094           sw_if_index_if_name_set = 1;
14095           sw_if_index = tmp_if_index;
14096         }
14097       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14098         {
14099           sw_if_index_set = 1;
14100           sw_if_index = tmp_if_index;
14101         }
14102       else if (unformat (input, "p %d", &priority))
14103         {
14104           priority_set = 1;
14105         }
14106       else if (unformat (input, "w %d", &weight))
14107         {
14108           weight_set = 1;
14109         }
14110       else
14111         break;
14112     }
14113
14114   if (locator_set_name_set == 0)
14115     {
14116       errmsg ("missing locator-set name");
14117       return -99;
14118     }
14119
14120   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14121     {
14122       errmsg ("missing sw_if_index");
14123       vec_free (locator_set_name);
14124       return -99;
14125     }
14126
14127   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14128     {
14129       errmsg ("cannot use both params interface name and sw_if_index");
14130       vec_free (locator_set_name);
14131       return -99;
14132     }
14133
14134   if (priority_set == 0)
14135     {
14136       errmsg ("missing locator-set priority");
14137       vec_free (locator_set_name);
14138       return -99;
14139     }
14140
14141   if (weight_set == 0)
14142     {
14143       errmsg ("missing locator-set weight");
14144       vec_free (locator_set_name);
14145       return -99;
14146     }
14147
14148   if (vec_len (locator_set_name) > 64)
14149     {
14150       errmsg ("locator-set name too long");
14151       vec_free (locator_set_name);
14152       return -99;
14153     }
14154   vec_add1 (locator_set_name, 0);
14155
14156   /* Construct the API message */
14157   M (ONE_ADD_DEL_LOCATOR, mp);
14158
14159   mp->is_add = is_add;
14160   mp->sw_if_index = ntohl (sw_if_index);
14161   mp->priority = priority;
14162   mp->weight = weight;
14163   clib_memcpy (mp->locator_set_name, locator_set_name,
14164                vec_len (locator_set_name));
14165   vec_free (locator_set_name);
14166
14167   /* send it... */
14168   S (mp);
14169
14170   /* Wait for a reply... */
14171   W (ret);
14172   return ret;
14173 }
14174
14175 #define api_lisp_add_del_locator api_one_add_del_locator
14176
14177 uword
14178 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14179 {
14180   u32 *key_id = va_arg (*args, u32 *);
14181   u8 *s = 0;
14182
14183   if (unformat (input, "%s", &s))
14184     {
14185       if (!strcmp ((char *) s, "sha1"))
14186         key_id[0] = HMAC_SHA_1_96;
14187       else if (!strcmp ((char *) s, "sha256"))
14188         key_id[0] = HMAC_SHA_256_128;
14189       else
14190         {
14191           clib_warning ("invalid key_id: '%s'", s);
14192           key_id[0] = HMAC_NO_KEY;
14193         }
14194     }
14195   else
14196     return 0;
14197
14198   vec_free (s);
14199   return 1;
14200 }
14201
14202 static int
14203 api_one_add_del_local_eid (vat_main_t * vam)
14204 {
14205   unformat_input_t *input = vam->input;
14206   vl_api_one_add_del_local_eid_t *mp;
14207   u8 is_add = 1;
14208   u8 eid_set = 0;
14209   lisp_eid_vat_t _eid, *eid = &_eid;
14210   u8 *locator_set_name = 0;
14211   u8 locator_set_name_set = 0;
14212   u32 vni = 0;
14213   u16 key_id = 0;
14214   u8 *key = 0;
14215   int ret;
14216
14217   /* Parse args required to build the message */
14218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14219     {
14220       if (unformat (input, "del"))
14221         {
14222           is_add = 0;
14223         }
14224       else if (unformat (input, "vni %d", &vni))
14225         {
14226           ;
14227         }
14228       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14229         {
14230           eid_set = 1;
14231         }
14232       else if (unformat (input, "locator-set %s", &locator_set_name))
14233         {
14234           locator_set_name_set = 1;
14235         }
14236       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14237         ;
14238       else if (unformat (input, "secret-key %_%v%_", &key))
14239         ;
14240       else
14241         break;
14242     }
14243
14244   if (locator_set_name_set == 0)
14245     {
14246       errmsg ("missing locator-set name");
14247       return -99;
14248     }
14249
14250   if (0 == eid_set)
14251     {
14252       errmsg ("EID address not set!");
14253       vec_free (locator_set_name);
14254       return -99;
14255     }
14256
14257   if (key && (0 == key_id))
14258     {
14259       errmsg ("invalid key_id!");
14260       return -99;
14261     }
14262
14263   if (vec_len (key) > 64)
14264     {
14265       errmsg ("key too long");
14266       vec_free (key);
14267       return -99;
14268     }
14269
14270   if (vec_len (locator_set_name) > 64)
14271     {
14272       errmsg ("locator-set name too long");
14273       vec_free (locator_set_name);
14274       return -99;
14275     }
14276   vec_add1 (locator_set_name, 0);
14277
14278   /* Construct the API message */
14279   M (ONE_ADD_DEL_LOCAL_EID, mp);
14280
14281   mp->is_add = is_add;
14282   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14283   mp->eid_type = eid->type;
14284   mp->prefix_len = eid->len;
14285   mp->vni = clib_host_to_net_u32 (vni);
14286   mp->key_id = clib_host_to_net_u16 (key_id);
14287   clib_memcpy (mp->locator_set_name, locator_set_name,
14288                vec_len (locator_set_name));
14289   clib_memcpy (mp->key, key, vec_len (key));
14290
14291   vec_free (locator_set_name);
14292   vec_free (key);
14293
14294   /* send it... */
14295   S (mp);
14296
14297   /* Wait for a reply... */
14298   W (ret);
14299   return ret;
14300 }
14301
14302 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14303
14304 static int
14305 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14306 {
14307   u32 dp_table = 0, vni = 0;;
14308   unformat_input_t *input = vam->input;
14309   vl_api_gpe_add_del_fwd_entry_t *mp;
14310   u8 is_add = 1;
14311   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14312   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14313   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14314   u32 action = ~0, w;
14315   ip4_address_t rmt_rloc4, lcl_rloc4;
14316   ip6_address_t rmt_rloc6, lcl_rloc6;
14317   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14318   int ret;
14319
14320   memset (&rloc, 0, sizeof (rloc));
14321
14322   /* Parse args required to build the message */
14323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14324     {
14325       if (unformat (input, "del"))
14326         is_add = 0;
14327       else if (unformat (input, "add"))
14328         is_add = 1;
14329       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14330         {
14331           rmt_eid_set = 1;
14332         }
14333       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14334         {
14335           lcl_eid_set = 1;
14336         }
14337       else if (unformat (input, "vrf %d", &dp_table))
14338         ;
14339       else if (unformat (input, "bd %d", &dp_table))
14340         ;
14341       else if (unformat (input, "vni %d", &vni))
14342         ;
14343       else if (unformat (input, "w %d", &w))
14344         {
14345           if (!curr_rloc)
14346             {
14347               errmsg ("No RLOC configured for setting priority/weight!");
14348               return -99;
14349             }
14350           curr_rloc->weight = w;
14351         }
14352       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14353                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14354         {
14355           rloc.is_ip4 = 1;
14356
14357           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14358           rloc.weight = 0;
14359           vec_add1 (lcl_locs, rloc);
14360
14361           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14362           vec_add1 (rmt_locs, rloc);
14363           /* weight saved in rmt loc */
14364           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14365         }
14366       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14367                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14368         {
14369           rloc.is_ip4 = 0;
14370           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14371           rloc.weight = 0;
14372           vec_add1 (lcl_locs, rloc);
14373
14374           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14375           vec_add1 (rmt_locs, rloc);
14376           /* weight saved in rmt loc */
14377           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14378         }
14379       else if (unformat (input, "action %d", &action))
14380         {
14381           ;
14382         }
14383       else
14384         {
14385           clib_warning ("parse error '%U'", format_unformat_error, input);
14386           return -99;
14387         }
14388     }
14389
14390   if (!rmt_eid_set)
14391     {
14392       errmsg ("remote eid addresses not set");
14393       return -99;
14394     }
14395
14396   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14397     {
14398       errmsg ("eid types don't match");
14399       return -99;
14400     }
14401
14402   if (0 == rmt_locs && (u32) ~ 0 == action)
14403     {
14404       errmsg ("action not set for negative mapping");
14405       return -99;
14406     }
14407
14408   /* Construct the API message */
14409   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14410       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14411
14412   mp->is_add = is_add;
14413   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14414   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14415   mp->eid_type = rmt_eid->type;
14416   mp->dp_table = clib_host_to_net_u32 (dp_table);
14417   mp->vni = clib_host_to_net_u32 (vni);
14418   mp->rmt_len = rmt_eid->len;
14419   mp->lcl_len = lcl_eid->len;
14420   mp->action = action;
14421
14422   if (0 != rmt_locs && 0 != lcl_locs)
14423     {
14424       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14425       clib_memcpy (mp->locs, lcl_locs,
14426                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14427
14428       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14429       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14430                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14431     }
14432   vec_free (lcl_locs);
14433   vec_free (rmt_locs);
14434
14435   /* send it... */
14436   S (mp);
14437
14438   /* Wait for a reply... */
14439   W (ret);
14440   return ret;
14441 }
14442
14443 static int
14444 api_one_add_del_map_server (vat_main_t * vam)
14445 {
14446   unformat_input_t *input = vam->input;
14447   vl_api_one_add_del_map_server_t *mp;
14448   u8 is_add = 1;
14449   u8 ipv4_set = 0;
14450   u8 ipv6_set = 0;
14451   ip4_address_t ipv4;
14452   ip6_address_t ipv6;
14453   int ret;
14454
14455   /* Parse args required to build the message */
14456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14457     {
14458       if (unformat (input, "del"))
14459         {
14460           is_add = 0;
14461         }
14462       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14463         {
14464           ipv4_set = 1;
14465         }
14466       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14467         {
14468           ipv6_set = 1;
14469         }
14470       else
14471         break;
14472     }
14473
14474   if (ipv4_set && ipv6_set)
14475     {
14476       errmsg ("both eid v4 and v6 addresses set");
14477       return -99;
14478     }
14479
14480   if (!ipv4_set && !ipv6_set)
14481     {
14482       errmsg ("eid addresses not set");
14483       return -99;
14484     }
14485
14486   /* Construct the API message */
14487   M (ONE_ADD_DEL_MAP_SERVER, mp);
14488
14489   mp->is_add = is_add;
14490   if (ipv6_set)
14491     {
14492       mp->is_ipv6 = 1;
14493       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14494     }
14495   else
14496     {
14497       mp->is_ipv6 = 0;
14498       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14499     }
14500
14501   /* send it... */
14502   S (mp);
14503
14504   /* Wait for a reply... */
14505   W (ret);
14506   return ret;
14507 }
14508
14509 #define api_lisp_add_del_map_server api_one_add_del_map_server
14510
14511 static int
14512 api_one_add_del_map_resolver (vat_main_t * vam)
14513 {
14514   unformat_input_t *input = vam->input;
14515   vl_api_one_add_del_map_resolver_t *mp;
14516   u8 is_add = 1;
14517   u8 ipv4_set = 0;
14518   u8 ipv6_set = 0;
14519   ip4_address_t ipv4;
14520   ip6_address_t ipv6;
14521   int ret;
14522
14523   /* Parse args required to build the message */
14524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14525     {
14526       if (unformat (input, "del"))
14527         {
14528           is_add = 0;
14529         }
14530       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14531         {
14532           ipv4_set = 1;
14533         }
14534       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14535         {
14536           ipv6_set = 1;
14537         }
14538       else
14539         break;
14540     }
14541
14542   if (ipv4_set && ipv6_set)
14543     {
14544       errmsg ("both eid v4 and v6 addresses set");
14545       return -99;
14546     }
14547
14548   if (!ipv4_set && !ipv6_set)
14549     {
14550       errmsg ("eid addresses not set");
14551       return -99;
14552     }
14553
14554   /* Construct the API message */
14555   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14556
14557   mp->is_add = is_add;
14558   if (ipv6_set)
14559     {
14560       mp->is_ipv6 = 1;
14561       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14562     }
14563   else
14564     {
14565       mp->is_ipv6 = 0;
14566       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14567     }
14568
14569   /* send it... */
14570   S (mp);
14571
14572   /* Wait for a reply... */
14573   W (ret);
14574   return ret;
14575 }
14576
14577 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14578
14579 static int
14580 api_lisp_gpe_enable_disable (vat_main_t * vam)
14581 {
14582   unformat_input_t *input = vam->input;
14583   vl_api_gpe_enable_disable_t *mp;
14584   u8 is_set = 0;
14585   u8 is_en = 1;
14586   int ret;
14587
14588   /* Parse args required to build the message */
14589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14590     {
14591       if (unformat (input, "enable"))
14592         {
14593           is_set = 1;
14594           is_en = 1;
14595         }
14596       else if (unformat (input, "disable"))
14597         {
14598           is_set = 1;
14599           is_en = 0;
14600         }
14601       else
14602         break;
14603     }
14604
14605   if (is_set == 0)
14606     {
14607       errmsg ("Value not set");
14608       return -99;
14609     }
14610
14611   /* Construct the API message */
14612   M (GPE_ENABLE_DISABLE, mp);
14613
14614   mp->is_en = is_en;
14615
14616   /* send it... */
14617   S (mp);
14618
14619   /* Wait for a reply... */
14620   W (ret);
14621   return ret;
14622 }
14623
14624 static int
14625 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14626 {
14627   unformat_input_t *input = vam->input;
14628   vl_api_one_rloc_probe_enable_disable_t *mp;
14629   u8 is_set = 0;
14630   u8 is_en = 0;
14631   int ret;
14632
14633   /* Parse args required to build the message */
14634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14635     {
14636       if (unformat (input, "enable"))
14637         {
14638           is_set = 1;
14639           is_en = 1;
14640         }
14641       else if (unformat (input, "disable"))
14642         is_set = 1;
14643       else
14644         break;
14645     }
14646
14647   if (!is_set)
14648     {
14649       errmsg ("Value not set");
14650       return -99;
14651     }
14652
14653   /* Construct the API message */
14654   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14655
14656   mp->is_enabled = is_en;
14657
14658   /* send it... */
14659   S (mp);
14660
14661   /* Wait for a reply... */
14662   W (ret);
14663   return ret;
14664 }
14665
14666 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14667
14668 static int
14669 api_one_map_register_enable_disable (vat_main_t * vam)
14670 {
14671   unformat_input_t *input = vam->input;
14672   vl_api_one_map_register_enable_disable_t *mp;
14673   u8 is_set = 0;
14674   u8 is_en = 0;
14675   int ret;
14676
14677   /* Parse args required to build the message */
14678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (input, "enable"))
14681         {
14682           is_set = 1;
14683           is_en = 1;
14684         }
14685       else if (unformat (input, "disable"))
14686         is_set = 1;
14687       else
14688         break;
14689     }
14690
14691   if (!is_set)
14692     {
14693       errmsg ("Value not set");
14694       return -99;
14695     }
14696
14697   /* Construct the API message */
14698   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14699
14700   mp->is_enabled = is_en;
14701
14702   /* send it... */
14703   S (mp);
14704
14705   /* Wait for a reply... */
14706   W (ret);
14707   return ret;
14708 }
14709
14710 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14711
14712 static int
14713 api_one_enable_disable (vat_main_t * vam)
14714 {
14715   unformat_input_t *input = vam->input;
14716   vl_api_one_enable_disable_t *mp;
14717   u8 is_set = 0;
14718   u8 is_en = 0;
14719   int ret;
14720
14721   /* Parse args required to build the message */
14722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14723     {
14724       if (unformat (input, "enable"))
14725         {
14726           is_set = 1;
14727           is_en = 1;
14728         }
14729       else if (unformat (input, "disable"))
14730         {
14731           is_set = 1;
14732         }
14733       else
14734         break;
14735     }
14736
14737   if (!is_set)
14738     {
14739       errmsg ("Value not set");
14740       return -99;
14741     }
14742
14743   /* Construct the API message */
14744   M (ONE_ENABLE_DISABLE, mp);
14745
14746   mp->is_en = is_en;
14747
14748   /* send it... */
14749   S (mp);
14750
14751   /* Wait for a reply... */
14752   W (ret);
14753   return ret;
14754 }
14755
14756 #define api_lisp_enable_disable api_one_enable_disable
14757
14758 static int
14759 api_show_one_map_register_state (vat_main_t * vam)
14760 {
14761   vl_api_show_one_map_register_state_t *mp;
14762   int ret;
14763
14764   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14765
14766   /* send */
14767   S (mp);
14768
14769   /* wait for reply */
14770   W (ret);
14771   return ret;
14772 }
14773
14774 #define api_show_lisp_map_register_state api_show_one_map_register_state
14775
14776 static int
14777 api_show_one_rloc_probe_state (vat_main_t * vam)
14778 {
14779   vl_api_show_one_rloc_probe_state_t *mp;
14780   int ret;
14781
14782   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14783
14784   /* send */
14785   S (mp);
14786
14787   /* wait for reply */
14788   W (ret);
14789   return ret;
14790 }
14791
14792 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14793
14794 static int
14795 api_one_stats_enable_disable (vat_main_t * vam)
14796 {
14797   vl_api_one_stats_enable_disable_t *mp;
14798   unformat_input_t *input = vam->input;
14799   u8 is_set = 0;
14800   u8 is_en = 0;
14801   int ret;
14802
14803   /* Parse args required to build the message */
14804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14805     {
14806       if (unformat (input, "enable"))
14807         {
14808           is_set = 1;
14809           is_en = 1;
14810         }
14811       else if (unformat (input, "disable"))
14812         {
14813           is_set = 1;
14814         }
14815       else
14816         break;
14817     }
14818
14819   if (!is_set)
14820     {
14821       errmsg ("Value not set");
14822       return -99;
14823     }
14824
14825   M (ONE_STATS_ENABLE_DISABLE, mp);
14826   mp->is_en = is_en;
14827
14828   /* send */
14829   S (mp);
14830
14831   /* wait for reply */
14832   W (ret);
14833   return ret;
14834 }
14835
14836 static int
14837 api_show_one_stats_enable_disable (vat_main_t * vam)
14838 {
14839   vl_api_show_one_stats_enable_disable_t *mp;
14840   int ret;
14841
14842   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14843
14844   /* send */
14845   S (mp);
14846
14847   /* wait for reply */
14848   W (ret);
14849   return ret;
14850 }
14851
14852 static int
14853 api_show_one_map_request_mode (vat_main_t * vam)
14854 {
14855   vl_api_show_one_map_request_mode_t *mp;
14856   int ret;
14857
14858   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14859
14860   /* send */
14861   S (mp);
14862
14863   /* wait for reply */
14864   W (ret);
14865   return ret;
14866 }
14867
14868 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14869
14870 static int
14871 api_one_map_request_mode (vat_main_t * vam)
14872 {
14873   unformat_input_t *input = vam->input;
14874   vl_api_one_map_request_mode_t *mp;
14875   u8 mode = 0;
14876   int ret;
14877
14878   /* Parse args required to build the message */
14879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14880     {
14881       if (unformat (input, "dst-only"))
14882         mode = 0;
14883       else if (unformat (input, "src-dst"))
14884         mode = 1;
14885       else
14886         {
14887           errmsg ("parse error '%U'", format_unformat_error, input);
14888           return -99;
14889         }
14890     }
14891
14892   M (ONE_MAP_REQUEST_MODE, mp);
14893
14894   mp->mode = mode;
14895
14896   /* send */
14897   S (mp);
14898
14899   /* wait for reply */
14900   W (ret);
14901   return ret;
14902 }
14903
14904 #define api_lisp_map_request_mode api_one_map_request_mode
14905
14906 /**
14907  * Enable/disable ONE proxy ITR.
14908  *
14909  * @param vam vpp API test context
14910  * @return return code
14911  */
14912 static int
14913 api_one_pitr_set_locator_set (vat_main_t * vam)
14914 {
14915   u8 ls_name_set = 0;
14916   unformat_input_t *input = vam->input;
14917   vl_api_one_pitr_set_locator_set_t *mp;
14918   u8 is_add = 1;
14919   u8 *ls_name = 0;
14920   int ret;
14921
14922   /* Parse args required to build the message */
14923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (input, "del"))
14926         is_add = 0;
14927       else if (unformat (input, "locator-set %s", &ls_name))
14928         ls_name_set = 1;
14929       else
14930         {
14931           errmsg ("parse error '%U'", format_unformat_error, input);
14932           return -99;
14933         }
14934     }
14935
14936   if (!ls_name_set)
14937     {
14938       errmsg ("locator-set name not set!");
14939       return -99;
14940     }
14941
14942   M (ONE_PITR_SET_LOCATOR_SET, mp);
14943
14944   mp->is_add = is_add;
14945   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14946   vec_free (ls_name);
14947
14948   /* send */
14949   S (mp);
14950
14951   /* wait for reply */
14952   W (ret);
14953   return ret;
14954 }
14955
14956 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14957
14958 static int
14959 api_show_one_pitr (vat_main_t * vam)
14960 {
14961   vl_api_show_one_pitr_t *mp;
14962   int ret;
14963
14964   if (!vam->json_output)
14965     {
14966       print (vam->ofp, "%=20s", "lisp status:");
14967     }
14968
14969   M (SHOW_ONE_PITR, mp);
14970   /* send it... */
14971   S (mp);
14972
14973   /* Wait for a reply... */
14974   W (ret);
14975   return ret;
14976 }
14977
14978 #define api_show_lisp_pitr api_show_one_pitr
14979
14980 static int
14981 api_one_use_petr (vat_main_t * vam)
14982 {
14983   unformat_input_t *input = vam->input;
14984   vl_api_one_use_petr_t *mp;
14985   u8 is_add = 0;
14986   ip_address_t ip;
14987   int ret;
14988
14989   memset (&ip, 0, sizeof (ip));
14990
14991   /* Parse args required to build the message */
14992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14993     {
14994       if (unformat (input, "disable"))
14995         is_add = 0;
14996       else
14997         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14998         {
14999           is_add = 1;
15000           ip_addr_version (&ip) = IP4;
15001         }
15002       else
15003         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15004         {
15005           is_add = 1;
15006           ip_addr_version (&ip) = IP6;
15007         }
15008       else
15009         {
15010           errmsg ("parse error '%U'", format_unformat_error, input);
15011           return -99;
15012         }
15013     }
15014
15015   M (ONE_USE_PETR, mp);
15016
15017   mp->is_add = is_add;
15018   if (is_add)
15019     {
15020       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15021       if (mp->is_ip4)
15022         clib_memcpy (mp->address, &ip, 4);
15023       else
15024         clib_memcpy (mp->address, &ip, 16);
15025     }
15026
15027   /* send */
15028   S (mp);
15029
15030   /* wait for reply */
15031   W (ret);
15032   return ret;
15033 }
15034
15035 #define api_lisp_use_petr api_one_use_petr
15036
15037 static int
15038 api_show_one_use_petr (vat_main_t * vam)
15039 {
15040   vl_api_show_one_use_petr_t *mp;
15041   int ret;
15042
15043   if (!vam->json_output)
15044     {
15045       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15046     }
15047
15048   M (SHOW_ONE_USE_PETR, mp);
15049   /* send it... */
15050   S (mp);
15051
15052   /* Wait for a reply... */
15053   W (ret);
15054   return ret;
15055 }
15056
15057 #define api_show_lisp_use_petr api_show_one_use_petr
15058
15059 /**
15060  * Add/delete mapping between vni and vrf
15061  */
15062 static int
15063 api_one_eid_table_add_del_map (vat_main_t * vam)
15064 {
15065   unformat_input_t *input = vam->input;
15066   vl_api_one_eid_table_add_del_map_t *mp;
15067   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15068   u32 vni, vrf, bd_index;
15069   int ret;
15070
15071   /* Parse args required to build the message */
15072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15073     {
15074       if (unformat (input, "del"))
15075         is_add = 0;
15076       else if (unformat (input, "vrf %d", &vrf))
15077         vrf_set = 1;
15078       else if (unformat (input, "bd_index %d", &bd_index))
15079         bd_index_set = 1;
15080       else if (unformat (input, "vni %d", &vni))
15081         vni_set = 1;
15082       else
15083         break;
15084     }
15085
15086   if (!vni_set || (!vrf_set && !bd_index_set))
15087     {
15088       errmsg ("missing arguments!");
15089       return -99;
15090     }
15091
15092   if (vrf_set && bd_index_set)
15093     {
15094       errmsg ("error: both vrf and bd entered!");
15095       return -99;
15096     }
15097
15098   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15099
15100   mp->is_add = is_add;
15101   mp->vni = htonl (vni);
15102   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15103   mp->is_l2 = bd_index_set;
15104
15105   /* send */
15106   S (mp);
15107
15108   /* wait for reply */
15109   W (ret);
15110   return ret;
15111 }
15112
15113 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15114
15115 uword
15116 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15117 {
15118   u32 *action = va_arg (*args, u32 *);
15119   u8 *s = 0;
15120
15121   if (unformat (input, "%s", &s))
15122     {
15123       if (!strcmp ((char *) s, "no-action"))
15124         action[0] = 0;
15125       else if (!strcmp ((char *) s, "natively-forward"))
15126         action[0] = 1;
15127       else if (!strcmp ((char *) s, "send-map-request"))
15128         action[0] = 2;
15129       else if (!strcmp ((char *) s, "drop"))
15130         action[0] = 3;
15131       else
15132         {
15133           clib_warning ("invalid action: '%s'", s);
15134           action[0] = 3;
15135         }
15136     }
15137   else
15138     return 0;
15139
15140   vec_free (s);
15141   return 1;
15142 }
15143
15144 /**
15145  * Add/del remote mapping to/from ONE control plane
15146  *
15147  * @param vam vpp API test context
15148  * @return return code
15149  */
15150 static int
15151 api_one_add_del_remote_mapping (vat_main_t * vam)
15152 {
15153   unformat_input_t *input = vam->input;
15154   vl_api_one_add_del_remote_mapping_t *mp;
15155   u32 vni = 0;
15156   lisp_eid_vat_t _eid, *eid = &_eid;
15157   lisp_eid_vat_t _seid, *seid = &_seid;
15158   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15159   u32 action = ~0, p, w, data_len;
15160   ip4_address_t rloc4;
15161   ip6_address_t rloc6;
15162   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15163   int ret;
15164
15165   memset (&rloc, 0, sizeof (rloc));
15166
15167   /* Parse args required to build the message */
15168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15169     {
15170       if (unformat (input, "del-all"))
15171         {
15172           del_all = 1;
15173         }
15174       else if (unformat (input, "del"))
15175         {
15176           is_add = 0;
15177         }
15178       else if (unformat (input, "add"))
15179         {
15180           is_add = 1;
15181         }
15182       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15183         {
15184           eid_set = 1;
15185         }
15186       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15187         {
15188           seid_set = 1;
15189         }
15190       else if (unformat (input, "vni %d", &vni))
15191         {
15192           ;
15193         }
15194       else if (unformat (input, "p %d w %d", &p, &w))
15195         {
15196           if (!curr_rloc)
15197             {
15198               errmsg ("No RLOC configured for setting priority/weight!");
15199               return -99;
15200             }
15201           curr_rloc->priority = p;
15202           curr_rloc->weight = w;
15203         }
15204       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15205         {
15206           rloc.is_ip4 = 1;
15207           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15208           vec_add1 (rlocs, rloc);
15209           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15210         }
15211       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15212         {
15213           rloc.is_ip4 = 0;
15214           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15215           vec_add1 (rlocs, rloc);
15216           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15217         }
15218       else if (unformat (input, "action %U",
15219                          unformat_negative_mapping_action, &action))
15220         {
15221           ;
15222         }
15223       else
15224         {
15225           clib_warning ("parse error '%U'", format_unformat_error, input);
15226           return -99;
15227         }
15228     }
15229
15230   if (0 == eid_set)
15231     {
15232       errmsg ("missing params!");
15233       return -99;
15234     }
15235
15236   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15237     {
15238       errmsg ("no action set for negative map-reply!");
15239       return -99;
15240     }
15241
15242   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15243
15244   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15245   mp->is_add = is_add;
15246   mp->vni = htonl (vni);
15247   mp->action = (u8) action;
15248   mp->is_src_dst = seid_set;
15249   mp->eid_len = eid->len;
15250   mp->seid_len = seid->len;
15251   mp->del_all = del_all;
15252   mp->eid_type = eid->type;
15253   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15254   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15255
15256   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15257   clib_memcpy (mp->rlocs, rlocs, data_len);
15258   vec_free (rlocs);
15259
15260   /* send it... */
15261   S (mp);
15262
15263   /* Wait for a reply... */
15264   W (ret);
15265   return ret;
15266 }
15267
15268 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15269
15270 /**
15271  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15272  * forwarding entries in data-plane accordingly.
15273  *
15274  * @param vam vpp API test context
15275  * @return return code
15276  */
15277 static int
15278 api_one_add_del_adjacency (vat_main_t * vam)
15279 {
15280   unformat_input_t *input = vam->input;
15281   vl_api_one_add_del_adjacency_t *mp;
15282   u32 vni = 0;
15283   ip4_address_t leid4, reid4;
15284   ip6_address_t leid6, reid6;
15285   u8 reid_mac[6] = { 0 };
15286   u8 leid_mac[6] = { 0 };
15287   u8 reid_type, leid_type;
15288   u32 leid_len = 0, reid_len = 0, len;
15289   u8 is_add = 1;
15290   int ret;
15291
15292   leid_type = reid_type = (u8) ~ 0;
15293
15294   /* Parse args required to build the message */
15295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15296     {
15297       if (unformat (input, "del"))
15298         {
15299           is_add = 0;
15300         }
15301       else if (unformat (input, "add"))
15302         {
15303           is_add = 1;
15304         }
15305       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15306                          &reid4, &len))
15307         {
15308           reid_type = 0;        /* ipv4 */
15309           reid_len = len;
15310         }
15311       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15312                          &reid6, &len))
15313         {
15314           reid_type = 1;        /* ipv6 */
15315           reid_len = len;
15316         }
15317       else if (unformat (input, "reid %U", unformat_ethernet_address,
15318                          reid_mac))
15319         {
15320           reid_type = 2;        /* mac */
15321         }
15322       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15323                          &leid4, &len))
15324         {
15325           leid_type = 0;        /* ipv4 */
15326           leid_len = len;
15327         }
15328       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15329                          &leid6, &len))
15330         {
15331           leid_type = 1;        /* ipv6 */
15332           leid_len = len;
15333         }
15334       else if (unformat (input, "leid %U", unformat_ethernet_address,
15335                          leid_mac))
15336         {
15337           leid_type = 2;        /* mac */
15338         }
15339       else if (unformat (input, "vni %d", &vni))
15340         {
15341           ;
15342         }
15343       else
15344         {
15345           errmsg ("parse error '%U'", format_unformat_error, input);
15346           return -99;
15347         }
15348     }
15349
15350   if ((u8) ~ 0 == reid_type)
15351     {
15352       errmsg ("missing params!");
15353       return -99;
15354     }
15355
15356   if (leid_type != reid_type)
15357     {
15358       errmsg ("remote and local EIDs are of different types!");
15359       return -99;
15360     }
15361
15362   M (ONE_ADD_DEL_ADJACENCY, mp);
15363   mp->is_add = is_add;
15364   mp->vni = htonl (vni);
15365   mp->leid_len = leid_len;
15366   mp->reid_len = reid_len;
15367   mp->eid_type = reid_type;
15368
15369   switch (mp->eid_type)
15370     {
15371     case 0:
15372       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15373       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15374       break;
15375     case 1:
15376       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15377       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15378       break;
15379     case 2:
15380       clib_memcpy (mp->leid, leid_mac, 6);
15381       clib_memcpy (mp->reid, reid_mac, 6);
15382       break;
15383     default:
15384       errmsg ("unknown EID type %d!", mp->eid_type);
15385       return 0;
15386     }
15387
15388   /* send it... */
15389   S (mp);
15390
15391   /* Wait for a reply... */
15392   W (ret);
15393   return ret;
15394 }
15395
15396 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15397
15398 uword
15399 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15400 {
15401   u32 *mode = va_arg (*args, u32 *);
15402
15403   if (unformat (input, "lisp"))
15404     *mode = 0;
15405   else if (unformat (input, "vxlan"))
15406     *mode = 1;
15407   else
15408     return 0;
15409
15410   return 1;
15411 }
15412
15413 static int
15414 api_gpe_get_encap_mode (vat_main_t * vam)
15415 {
15416   vl_api_gpe_get_encap_mode_t *mp;
15417   int ret;
15418
15419   /* Construct the API message */
15420   M (GPE_GET_ENCAP_MODE, mp);
15421
15422   /* send it... */
15423   S (mp);
15424
15425   /* Wait for a reply... */
15426   W (ret);
15427   return ret;
15428 }
15429
15430 static int
15431 api_gpe_set_encap_mode (vat_main_t * vam)
15432 {
15433   unformat_input_t *input = vam->input;
15434   vl_api_gpe_set_encap_mode_t *mp;
15435   int ret;
15436   u32 mode = 0;
15437
15438   /* Parse args required to build the message */
15439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15440     {
15441       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15442         ;
15443       else
15444         break;
15445     }
15446
15447   /* Construct the API message */
15448   M (GPE_SET_ENCAP_MODE, mp);
15449
15450   mp->mode = mode;
15451
15452   /* send it... */
15453   S (mp);
15454
15455   /* Wait for a reply... */
15456   W (ret);
15457   return ret;
15458 }
15459
15460 static int
15461 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15462 {
15463   unformat_input_t *input = vam->input;
15464   vl_api_gpe_add_del_iface_t *mp;
15465   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15466   u32 dp_table = 0, vni = 0;
15467   int ret;
15468
15469   /* Parse args required to build the message */
15470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15471     {
15472       if (unformat (input, "up"))
15473         {
15474           action_set = 1;
15475           is_add = 1;
15476         }
15477       else if (unformat (input, "down"))
15478         {
15479           action_set = 1;
15480           is_add = 0;
15481         }
15482       else if (unformat (input, "table_id %d", &dp_table))
15483         {
15484           dp_table_set = 1;
15485         }
15486       else if (unformat (input, "bd_id %d", &dp_table))
15487         {
15488           dp_table_set = 1;
15489           is_l2 = 1;
15490         }
15491       else if (unformat (input, "vni %d", &vni))
15492         {
15493           vni_set = 1;
15494         }
15495       else
15496         break;
15497     }
15498
15499   if (action_set == 0)
15500     {
15501       errmsg ("Action not set");
15502       return -99;
15503     }
15504   if (dp_table_set == 0 || vni_set == 0)
15505     {
15506       errmsg ("vni and dp_table must be set");
15507       return -99;
15508     }
15509
15510   /* Construct the API message */
15511   M (GPE_ADD_DEL_IFACE, mp);
15512
15513   mp->is_add = is_add;
15514   mp->dp_table = dp_table;
15515   mp->is_l2 = is_l2;
15516   mp->vni = vni;
15517
15518   /* send it... */
15519   S (mp);
15520
15521   /* Wait for a reply... */
15522   W (ret);
15523   return ret;
15524 }
15525
15526 /**
15527  * Add/del map request itr rlocs from ONE control plane and updates
15528  *
15529  * @param vam vpp API test context
15530  * @return return code
15531  */
15532 static int
15533 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15534 {
15535   unformat_input_t *input = vam->input;
15536   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15537   u8 *locator_set_name = 0;
15538   u8 locator_set_name_set = 0;
15539   u8 is_add = 1;
15540   int ret;
15541
15542   /* Parse args required to build the message */
15543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15544     {
15545       if (unformat (input, "del"))
15546         {
15547           is_add = 0;
15548         }
15549       else if (unformat (input, "%_%v%_", &locator_set_name))
15550         {
15551           locator_set_name_set = 1;
15552         }
15553       else
15554         {
15555           clib_warning ("parse error '%U'", format_unformat_error, input);
15556           return -99;
15557         }
15558     }
15559
15560   if (is_add && !locator_set_name_set)
15561     {
15562       errmsg ("itr-rloc is not set!");
15563       return -99;
15564     }
15565
15566   if (is_add && vec_len (locator_set_name) > 64)
15567     {
15568       errmsg ("itr-rloc locator-set name too long");
15569       vec_free (locator_set_name);
15570       return -99;
15571     }
15572
15573   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15574   mp->is_add = is_add;
15575   if (is_add)
15576     {
15577       clib_memcpy (mp->locator_set_name, locator_set_name,
15578                    vec_len (locator_set_name));
15579     }
15580   else
15581     {
15582       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15583     }
15584   vec_free (locator_set_name);
15585
15586   /* send it... */
15587   S (mp);
15588
15589   /* Wait for a reply... */
15590   W (ret);
15591   return ret;
15592 }
15593
15594 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15595
15596 static int
15597 api_one_locator_dump (vat_main_t * vam)
15598 {
15599   unformat_input_t *input = vam->input;
15600   vl_api_one_locator_dump_t *mp;
15601   vl_api_control_ping_t *mp_ping;
15602   u8 is_index_set = 0, is_name_set = 0;
15603   u8 *ls_name = 0;
15604   u32 ls_index = ~0;
15605   int ret;
15606
15607   /* Parse args required to build the message */
15608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15609     {
15610       if (unformat (input, "ls_name %_%v%_", &ls_name))
15611         {
15612           is_name_set = 1;
15613         }
15614       else if (unformat (input, "ls_index %d", &ls_index))
15615         {
15616           is_index_set = 1;
15617         }
15618       else
15619         {
15620           errmsg ("parse error '%U'", format_unformat_error, input);
15621           return -99;
15622         }
15623     }
15624
15625   if (!is_index_set && !is_name_set)
15626     {
15627       errmsg ("error: expected one of index or name!");
15628       return -99;
15629     }
15630
15631   if (is_index_set && is_name_set)
15632     {
15633       errmsg ("error: only one param expected!");
15634       return -99;
15635     }
15636
15637   if (vec_len (ls_name) > 62)
15638     {
15639       errmsg ("error: locator set name too long!");
15640       return -99;
15641     }
15642
15643   if (!vam->json_output)
15644     {
15645       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15646     }
15647
15648   M (ONE_LOCATOR_DUMP, mp);
15649   mp->is_index_set = is_index_set;
15650
15651   if (is_index_set)
15652     mp->ls_index = clib_host_to_net_u32 (ls_index);
15653   else
15654     {
15655       vec_add1 (ls_name, 0);
15656       strncpy ((char *) mp->ls_name, (char *) ls_name,
15657                sizeof (mp->ls_name) - 1);
15658     }
15659
15660   /* send it... */
15661   S (mp);
15662
15663   /* Use a control ping for synchronization */
15664   M (CONTROL_PING, mp_ping);
15665   S (mp_ping);
15666
15667   /* Wait for a reply... */
15668   W (ret);
15669   return ret;
15670 }
15671
15672 #define api_lisp_locator_dump api_one_locator_dump
15673
15674 static int
15675 api_one_locator_set_dump (vat_main_t * vam)
15676 {
15677   vl_api_one_locator_set_dump_t *mp;
15678   vl_api_control_ping_t *mp_ping;
15679   unformat_input_t *input = vam->input;
15680   u8 filter = 0;
15681   int ret;
15682
15683   /* Parse args required to build the message */
15684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15685     {
15686       if (unformat (input, "local"))
15687         {
15688           filter = 1;
15689         }
15690       else if (unformat (input, "remote"))
15691         {
15692           filter = 2;
15693         }
15694       else
15695         {
15696           errmsg ("parse error '%U'", format_unformat_error, input);
15697           return -99;
15698         }
15699     }
15700
15701   if (!vam->json_output)
15702     {
15703       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15704     }
15705
15706   M (ONE_LOCATOR_SET_DUMP, mp);
15707
15708   mp->filter = filter;
15709
15710   /* send it... */
15711   S (mp);
15712
15713   /* Use a control ping for synchronization */
15714   M (CONTROL_PING, mp_ping);
15715   S (mp_ping);
15716
15717   /* Wait for a reply... */
15718   W (ret);
15719   return ret;
15720 }
15721
15722 #define api_lisp_locator_set_dump api_one_locator_set_dump
15723
15724 static int
15725 api_one_eid_table_map_dump (vat_main_t * vam)
15726 {
15727   u8 is_l2 = 0;
15728   u8 mode_set = 0;
15729   unformat_input_t *input = vam->input;
15730   vl_api_one_eid_table_map_dump_t *mp;
15731   vl_api_control_ping_t *mp_ping;
15732   int ret;
15733
15734   /* Parse args required to build the message */
15735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15736     {
15737       if (unformat (input, "l2"))
15738         {
15739           is_l2 = 1;
15740           mode_set = 1;
15741         }
15742       else if (unformat (input, "l3"))
15743         {
15744           is_l2 = 0;
15745           mode_set = 1;
15746         }
15747       else
15748         {
15749           errmsg ("parse error '%U'", format_unformat_error, input);
15750           return -99;
15751         }
15752     }
15753
15754   if (!mode_set)
15755     {
15756       errmsg ("expected one of 'l2' or 'l3' parameter!");
15757       return -99;
15758     }
15759
15760   if (!vam->json_output)
15761     {
15762       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15763     }
15764
15765   M (ONE_EID_TABLE_MAP_DUMP, mp);
15766   mp->is_l2 = is_l2;
15767
15768   /* send it... */
15769   S (mp);
15770
15771   /* Use a control ping for synchronization */
15772   M (CONTROL_PING, mp_ping);
15773   S (mp_ping);
15774
15775   /* Wait for a reply... */
15776   W (ret);
15777   return ret;
15778 }
15779
15780 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15781
15782 static int
15783 api_one_eid_table_vni_dump (vat_main_t * vam)
15784 {
15785   vl_api_one_eid_table_vni_dump_t *mp;
15786   vl_api_control_ping_t *mp_ping;
15787   int ret;
15788
15789   if (!vam->json_output)
15790     {
15791       print (vam->ofp, "VNI");
15792     }
15793
15794   M (ONE_EID_TABLE_VNI_DUMP, mp);
15795
15796   /* send it... */
15797   S (mp);
15798
15799   /* Use a control ping for synchronization */
15800   M (CONTROL_PING, mp_ping);
15801   S (mp_ping);
15802
15803   /* Wait for a reply... */
15804   W (ret);
15805   return ret;
15806 }
15807
15808 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15809
15810 static int
15811 api_one_eid_table_dump (vat_main_t * vam)
15812 {
15813   unformat_input_t *i = vam->input;
15814   vl_api_one_eid_table_dump_t *mp;
15815   vl_api_control_ping_t *mp_ping;
15816   struct in_addr ip4;
15817   struct in6_addr ip6;
15818   u8 mac[6];
15819   u8 eid_type = ~0, eid_set = 0;
15820   u32 prefix_length = ~0, t, vni = 0;
15821   u8 filter = 0;
15822   int ret;
15823
15824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15825     {
15826       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15827         {
15828           eid_set = 1;
15829           eid_type = 0;
15830           prefix_length = t;
15831         }
15832       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15833         {
15834           eid_set = 1;
15835           eid_type = 1;
15836           prefix_length = t;
15837         }
15838       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15839         {
15840           eid_set = 1;
15841           eid_type = 2;
15842         }
15843       else if (unformat (i, "vni %d", &t))
15844         {
15845           vni = t;
15846         }
15847       else if (unformat (i, "local"))
15848         {
15849           filter = 1;
15850         }
15851       else if (unformat (i, "remote"))
15852         {
15853           filter = 2;
15854         }
15855       else
15856         {
15857           errmsg ("parse error '%U'", format_unformat_error, i);
15858           return -99;
15859         }
15860     }
15861
15862   if (!vam->json_output)
15863     {
15864       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15865              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15866     }
15867
15868   M (ONE_EID_TABLE_DUMP, mp);
15869
15870   mp->filter = filter;
15871   if (eid_set)
15872     {
15873       mp->eid_set = 1;
15874       mp->vni = htonl (vni);
15875       mp->eid_type = eid_type;
15876       switch (eid_type)
15877         {
15878         case 0:
15879           mp->prefix_length = prefix_length;
15880           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15881           break;
15882         case 1:
15883           mp->prefix_length = prefix_length;
15884           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15885           break;
15886         case 2:
15887           clib_memcpy (mp->eid, mac, sizeof (mac));
15888           break;
15889         default:
15890           errmsg ("unknown EID type %d!", eid_type);
15891           return -99;
15892         }
15893     }
15894
15895   /* send it... */
15896   S (mp);
15897
15898   /* Use a control ping for synchronization */
15899   M (CONTROL_PING, mp_ping);
15900   S (mp_ping);
15901
15902   /* Wait for a reply... */
15903   W (ret);
15904   return ret;
15905 }
15906
15907 #define api_lisp_eid_table_dump api_one_eid_table_dump
15908
15909 static int
15910 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15911 {
15912   unformat_input_t *i = vam->input;
15913   vl_api_gpe_fwd_entries_get_t *mp;
15914   u8 vni_set = 0;
15915   u32 vni = ~0;
15916   int ret;
15917
15918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15919     {
15920       if (unformat (i, "vni %d", &vni))
15921         {
15922           vni_set = 1;
15923         }
15924       else
15925         {
15926           errmsg ("parse error '%U'", format_unformat_error, i);
15927           return -99;
15928         }
15929     }
15930
15931   if (!vni_set)
15932     {
15933       errmsg ("vni not set!");
15934       return -99;
15935     }
15936
15937   if (!vam->json_output)
15938     {
15939       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15940              "leid", "reid");
15941     }
15942
15943   M (GPE_FWD_ENTRIES_GET, mp);
15944   mp->vni = clib_host_to_net_u32 (vni);
15945
15946   /* send it... */
15947   S (mp);
15948
15949   /* Wait for a reply... */
15950   W (ret);
15951   return ret;
15952 }
15953
15954 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
15955 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
15956 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15957 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15958 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15959 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15960
15961 static int
15962 api_one_adjacencies_get (vat_main_t * vam)
15963 {
15964   unformat_input_t *i = vam->input;
15965   vl_api_one_adjacencies_get_t *mp;
15966   u8 vni_set = 0;
15967   u32 vni = ~0;
15968   int ret;
15969
15970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15971     {
15972       if (unformat (i, "vni %d", &vni))
15973         {
15974           vni_set = 1;
15975         }
15976       else
15977         {
15978           errmsg ("parse error '%U'", format_unformat_error, i);
15979           return -99;
15980         }
15981     }
15982
15983   if (!vni_set)
15984     {
15985       errmsg ("vni not set!");
15986       return -99;
15987     }
15988
15989   if (!vam->json_output)
15990     {
15991       print (vam->ofp, "%s %40s", "leid", "reid");
15992     }
15993
15994   M (ONE_ADJACENCIES_GET, mp);
15995   mp->vni = clib_host_to_net_u32 (vni);
15996
15997   /* send it... */
15998   S (mp);
15999
16000   /* Wait for a reply... */
16001   W (ret);
16002   return ret;
16003 }
16004
16005 #define api_lisp_adjacencies_get api_one_adjacencies_get
16006
16007 static int
16008 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16009 {
16010   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16011   int ret;
16012
16013   if (!vam->json_output)
16014     {
16015       print (vam->ofp, "VNIs");
16016     }
16017
16018   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16019
16020   /* send it... */
16021   S (mp);
16022
16023   /* Wait for a reply... */
16024   W (ret);
16025   return ret;
16026 }
16027
16028 static int
16029 api_one_map_server_dump (vat_main_t * vam)
16030 {
16031   vl_api_one_map_server_dump_t *mp;
16032   vl_api_control_ping_t *mp_ping;
16033   int ret;
16034
16035   if (!vam->json_output)
16036     {
16037       print (vam->ofp, "%=20s", "Map server");
16038     }
16039
16040   M (ONE_MAP_SERVER_DUMP, mp);
16041   /* send it... */
16042   S (mp);
16043
16044   /* Use a control ping for synchronization */
16045   M (CONTROL_PING, mp_ping);
16046   S (mp_ping);
16047
16048   /* Wait for a reply... */
16049   W (ret);
16050   return ret;
16051 }
16052
16053 #define api_lisp_map_server_dump api_one_map_server_dump
16054
16055 static int
16056 api_one_map_resolver_dump (vat_main_t * vam)
16057 {
16058   vl_api_one_map_resolver_dump_t *mp;
16059   vl_api_control_ping_t *mp_ping;
16060   int ret;
16061
16062   if (!vam->json_output)
16063     {
16064       print (vam->ofp, "%=20s", "Map resolver");
16065     }
16066
16067   M (ONE_MAP_RESOLVER_DUMP, mp);
16068   /* send it... */
16069   S (mp);
16070
16071   /* Use a control ping for synchronization */
16072   M (CONTROL_PING, mp_ping);
16073   S (mp_ping);
16074
16075   /* Wait for a reply... */
16076   W (ret);
16077   return ret;
16078 }
16079
16080 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16081
16082 static int
16083 api_one_stats_flush (vat_main_t * vam)
16084 {
16085   vl_api_one_stats_flush_t *mp;
16086   int ret = 0;
16087
16088   M (ONE_STATS_FLUSH, mp);
16089   S (mp);
16090   W (ret);
16091   return ret;
16092 }
16093
16094 static int
16095 api_one_stats_dump (vat_main_t * vam)
16096 {
16097   vl_api_one_stats_dump_t *mp;
16098   vl_api_control_ping_t *mp_ping;
16099   int ret;
16100
16101   M (ONE_STATS_DUMP, mp);
16102   /* send it... */
16103   S (mp);
16104
16105   /* Use a control ping for synchronization */
16106   M (CONTROL_PING, mp_ping);
16107   S (mp_ping);
16108
16109   /* Wait for a reply... */
16110   W (ret);
16111   return ret;
16112 }
16113
16114 static int
16115 api_show_one_status (vat_main_t * vam)
16116 {
16117   vl_api_show_one_status_t *mp;
16118   int ret;
16119
16120   if (!vam->json_output)
16121     {
16122       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16123     }
16124
16125   M (SHOW_ONE_STATUS, mp);
16126   /* send it... */
16127   S (mp);
16128   /* Wait for a reply... */
16129   W (ret);
16130   return ret;
16131 }
16132
16133 #define api_show_lisp_status api_show_one_status
16134
16135 static int
16136 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16137 {
16138   vl_api_gpe_fwd_entry_path_dump_t *mp;
16139   vl_api_control_ping_t *mp_ping;
16140   unformat_input_t *i = vam->input;
16141   u32 fwd_entry_index = ~0;
16142   int ret;
16143
16144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (i, "index %d", &fwd_entry_index))
16147         ;
16148       else
16149         break;
16150     }
16151
16152   if (~0 == fwd_entry_index)
16153     {
16154       errmsg ("no index specified!");
16155       return -99;
16156     }
16157
16158   if (!vam->json_output)
16159     {
16160       print (vam->ofp, "first line");
16161     }
16162
16163   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16164
16165   /* send it... */
16166   S (mp);
16167   /* Use a control ping for synchronization */
16168   M (CONTROL_PING, mp_ping);
16169   S (mp_ping);
16170
16171   /* Wait for a reply... */
16172   W (ret);
16173   return ret;
16174 }
16175
16176 static int
16177 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16178 {
16179   vl_api_one_get_map_request_itr_rlocs_t *mp;
16180   int ret;
16181
16182   if (!vam->json_output)
16183     {
16184       print (vam->ofp, "%=20s", "itr-rlocs:");
16185     }
16186
16187   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16188   /* send it... */
16189   S (mp);
16190   /* Wait for a reply... */
16191   W (ret);
16192   return ret;
16193 }
16194
16195 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16196
16197 static int
16198 api_af_packet_create (vat_main_t * vam)
16199 {
16200   unformat_input_t *i = vam->input;
16201   vl_api_af_packet_create_t *mp;
16202   u8 *host_if_name = 0;
16203   u8 hw_addr[6];
16204   u8 random_hw_addr = 1;
16205   int ret;
16206
16207   memset (hw_addr, 0, sizeof (hw_addr));
16208
16209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16210     {
16211       if (unformat (i, "name %s", &host_if_name))
16212         vec_add1 (host_if_name, 0);
16213       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16214         random_hw_addr = 0;
16215       else
16216         break;
16217     }
16218
16219   if (!vec_len (host_if_name))
16220     {
16221       errmsg ("host-interface name must be specified");
16222       return -99;
16223     }
16224
16225   if (vec_len (host_if_name) > 64)
16226     {
16227       errmsg ("host-interface name too long");
16228       return -99;
16229     }
16230
16231   M (AF_PACKET_CREATE, mp);
16232
16233   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16234   clib_memcpy (mp->hw_addr, hw_addr, 6);
16235   mp->use_random_hw_addr = random_hw_addr;
16236   vec_free (host_if_name);
16237
16238   S (mp);
16239
16240   /* *INDENT-OFF* */
16241   W2 (ret,
16242       ({
16243         if (ret == 0)
16244           fprintf (vam->ofp ? vam->ofp : stderr,
16245                    " new sw_if_index = %d\n", vam->sw_if_index);
16246       }));
16247   /* *INDENT-ON* */
16248   return ret;
16249 }
16250
16251 static int
16252 api_af_packet_delete (vat_main_t * vam)
16253 {
16254   unformat_input_t *i = vam->input;
16255   vl_api_af_packet_delete_t *mp;
16256   u8 *host_if_name = 0;
16257   int ret;
16258
16259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16260     {
16261       if (unformat (i, "name %s", &host_if_name))
16262         vec_add1 (host_if_name, 0);
16263       else
16264         break;
16265     }
16266
16267   if (!vec_len (host_if_name))
16268     {
16269       errmsg ("host-interface name must be specified");
16270       return -99;
16271     }
16272
16273   if (vec_len (host_if_name) > 64)
16274     {
16275       errmsg ("host-interface name too long");
16276       return -99;
16277     }
16278
16279   M (AF_PACKET_DELETE, mp);
16280
16281   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16282   vec_free (host_if_name);
16283
16284   S (mp);
16285   W (ret);
16286   return ret;
16287 }
16288
16289 static int
16290 api_policer_add_del (vat_main_t * vam)
16291 {
16292   unformat_input_t *i = vam->input;
16293   vl_api_policer_add_del_t *mp;
16294   u8 is_add = 1;
16295   u8 *name = 0;
16296   u32 cir = 0;
16297   u32 eir = 0;
16298   u64 cb = 0;
16299   u64 eb = 0;
16300   u8 rate_type = 0;
16301   u8 round_type = 0;
16302   u8 type = 0;
16303   u8 color_aware = 0;
16304   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16305   int ret;
16306
16307   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16308   conform_action.dscp = 0;
16309   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16310   exceed_action.dscp = 0;
16311   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16312   violate_action.dscp = 0;
16313
16314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16315     {
16316       if (unformat (i, "del"))
16317         is_add = 0;
16318       else if (unformat (i, "name %s", &name))
16319         vec_add1 (name, 0);
16320       else if (unformat (i, "cir %u", &cir))
16321         ;
16322       else if (unformat (i, "eir %u", &eir))
16323         ;
16324       else if (unformat (i, "cb %u", &cb))
16325         ;
16326       else if (unformat (i, "eb %u", &eb))
16327         ;
16328       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16329                          &rate_type))
16330         ;
16331       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16332                          &round_type))
16333         ;
16334       else if (unformat (i, "type %U", unformat_policer_type, &type))
16335         ;
16336       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16337                          &conform_action))
16338         ;
16339       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16340                          &exceed_action))
16341         ;
16342       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16343                          &violate_action))
16344         ;
16345       else if (unformat (i, "color-aware"))
16346         color_aware = 1;
16347       else
16348         break;
16349     }
16350
16351   if (!vec_len (name))
16352     {
16353       errmsg ("policer name must be specified");
16354       return -99;
16355     }
16356
16357   if (vec_len (name) > 64)
16358     {
16359       errmsg ("policer name too long");
16360       return -99;
16361     }
16362
16363   M (POLICER_ADD_DEL, mp);
16364
16365   clib_memcpy (mp->name, name, vec_len (name));
16366   vec_free (name);
16367   mp->is_add = is_add;
16368   mp->cir = cir;
16369   mp->eir = eir;
16370   mp->cb = cb;
16371   mp->eb = eb;
16372   mp->rate_type = rate_type;
16373   mp->round_type = round_type;
16374   mp->type = type;
16375   mp->conform_action_type = conform_action.action_type;
16376   mp->conform_dscp = conform_action.dscp;
16377   mp->exceed_action_type = exceed_action.action_type;
16378   mp->exceed_dscp = exceed_action.dscp;
16379   mp->violate_action_type = violate_action.action_type;
16380   mp->violate_dscp = violate_action.dscp;
16381   mp->color_aware = color_aware;
16382
16383   S (mp);
16384   W (ret);
16385   return ret;
16386 }
16387
16388 static int
16389 api_policer_dump (vat_main_t * vam)
16390 {
16391   unformat_input_t *i = vam->input;
16392   vl_api_policer_dump_t *mp;
16393   vl_api_control_ping_t *mp_ping;
16394   u8 *match_name = 0;
16395   u8 match_name_valid = 0;
16396   int ret;
16397
16398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16399     {
16400       if (unformat (i, "name %s", &match_name))
16401         {
16402           vec_add1 (match_name, 0);
16403           match_name_valid = 1;
16404         }
16405       else
16406         break;
16407     }
16408
16409   M (POLICER_DUMP, mp);
16410   mp->match_name_valid = match_name_valid;
16411   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16412   vec_free (match_name);
16413   /* send it... */
16414   S (mp);
16415
16416   /* Use a control ping for synchronization */
16417   M (CONTROL_PING, mp_ping);
16418   S (mp_ping);
16419
16420   /* Wait for a reply... */
16421   W (ret);
16422   return ret;
16423 }
16424
16425 static int
16426 api_policer_classify_set_interface (vat_main_t * vam)
16427 {
16428   unformat_input_t *i = vam->input;
16429   vl_api_policer_classify_set_interface_t *mp;
16430   u32 sw_if_index;
16431   int sw_if_index_set;
16432   u32 ip4_table_index = ~0;
16433   u32 ip6_table_index = ~0;
16434   u32 l2_table_index = ~0;
16435   u8 is_add = 1;
16436   int ret;
16437
16438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16439     {
16440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16441         sw_if_index_set = 1;
16442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16443         sw_if_index_set = 1;
16444       else if (unformat (i, "del"))
16445         is_add = 0;
16446       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16447         ;
16448       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16449         ;
16450       else if (unformat (i, "l2-table %d", &l2_table_index))
16451         ;
16452       else
16453         {
16454           clib_warning ("parse error '%U'", format_unformat_error, i);
16455           return -99;
16456         }
16457     }
16458
16459   if (sw_if_index_set == 0)
16460     {
16461       errmsg ("missing interface name or sw_if_index");
16462       return -99;
16463     }
16464
16465   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16466
16467   mp->sw_if_index = ntohl (sw_if_index);
16468   mp->ip4_table_index = ntohl (ip4_table_index);
16469   mp->ip6_table_index = ntohl (ip6_table_index);
16470   mp->l2_table_index = ntohl (l2_table_index);
16471   mp->is_add = is_add;
16472
16473   S (mp);
16474   W (ret);
16475   return ret;
16476 }
16477
16478 static int
16479 api_policer_classify_dump (vat_main_t * vam)
16480 {
16481   unformat_input_t *i = vam->input;
16482   vl_api_policer_classify_dump_t *mp;
16483   vl_api_control_ping_t *mp_ping;
16484   u8 type = POLICER_CLASSIFY_N_TABLES;
16485   int ret;
16486
16487   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16488     ;
16489   else
16490     {
16491       errmsg ("classify table type must be specified");
16492       return -99;
16493     }
16494
16495   if (!vam->json_output)
16496     {
16497       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16498     }
16499
16500   M (POLICER_CLASSIFY_DUMP, mp);
16501   mp->type = type;
16502   /* send it... */
16503   S (mp);
16504
16505   /* Use a control ping for synchronization */
16506   M (CONTROL_PING, mp_ping);
16507   S (mp_ping);
16508
16509   /* Wait for a reply... */
16510   W (ret);
16511   return ret;
16512 }
16513
16514 static int
16515 api_netmap_create (vat_main_t * vam)
16516 {
16517   unformat_input_t *i = vam->input;
16518   vl_api_netmap_create_t *mp;
16519   u8 *if_name = 0;
16520   u8 hw_addr[6];
16521   u8 random_hw_addr = 1;
16522   u8 is_pipe = 0;
16523   u8 is_master = 0;
16524   int ret;
16525
16526   memset (hw_addr, 0, sizeof (hw_addr));
16527
16528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16529     {
16530       if (unformat (i, "name %s", &if_name))
16531         vec_add1 (if_name, 0);
16532       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16533         random_hw_addr = 0;
16534       else if (unformat (i, "pipe"))
16535         is_pipe = 1;
16536       else if (unformat (i, "master"))
16537         is_master = 1;
16538       else if (unformat (i, "slave"))
16539         is_master = 0;
16540       else
16541         break;
16542     }
16543
16544   if (!vec_len (if_name))
16545     {
16546       errmsg ("interface name must be specified");
16547       return -99;
16548     }
16549
16550   if (vec_len (if_name) > 64)
16551     {
16552       errmsg ("interface name too long");
16553       return -99;
16554     }
16555
16556   M (NETMAP_CREATE, mp);
16557
16558   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16559   clib_memcpy (mp->hw_addr, hw_addr, 6);
16560   mp->use_random_hw_addr = random_hw_addr;
16561   mp->is_pipe = is_pipe;
16562   mp->is_master = is_master;
16563   vec_free (if_name);
16564
16565   S (mp);
16566   W (ret);
16567   return ret;
16568 }
16569
16570 static int
16571 api_netmap_delete (vat_main_t * vam)
16572 {
16573   unformat_input_t *i = vam->input;
16574   vl_api_netmap_delete_t *mp;
16575   u8 *if_name = 0;
16576   int ret;
16577
16578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16579     {
16580       if (unformat (i, "name %s", &if_name))
16581         vec_add1 (if_name, 0);
16582       else
16583         break;
16584     }
16585
16586   if (!vec_len (if_name))
16587     {
16588       errmsg ("interface name must be specified");
16589       return -99;
16590     }
16591
16592   if (vec_len (if_name) > 64)
16593     {
16594       errmsg ("interface name too long");
16595       return -99;
16596     }
16597
16598   M (NETMAP_DELETE, mp);
16599
16600   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16601   vec_free (if_name);
16602
16603   S (mp);
16604   W (ret);
16605   return ret;
16606 }
16607
16608 static void
16609 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16610 {
16611   if (fp->afi == IP46_TYPE_IP6)
16612     print (vam->ofp,
16613            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16614            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16615            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16616            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16617            format_ip6_address, fp->next_hop);
16618   else if (fp->afi == IP46_TYPE_IP4)
16619     print (vam->ofp,
16620            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16621            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16622            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16623            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16624            format_ip4_address, fp->next_hop);
16625 }
16626
16627 static void
16628 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16629                                  vl_api_fib_path2_t * fp)
16630 {
16631   struct in_addr ip4;
16632   struct in6_addr ip6;
16633
16634   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16635   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16636   vat_json_object_add_uint (node, "is_local", fp->is_local);
16637   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16638   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16639   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16640   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16641   if (fp->afi == IP46_TYPE_IP4)
16642     {
16643       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16644       vat_json_object_add_ip4 (node, "next_hop", ip4);
16645     }
16646   else if (fp->afi == IP46_TYPE_IP6)
16647     {
16648       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16649       vat_json_object_add_ip6 (node, "next_hop", ip6);
16650     }
16651 }
16652
16653 static void
16654 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16655 {
16656   vat_main_t *vam = &vat_main;
16657   int count = ntohl (mp->mt_count);
16658   vl_api_fib_path2_t *fp;
16659   i32 i;
16660
16661   print (vam->ofp, "[%d]: sw_if_index %d via:",
16662          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16663   fp = mp->mt_paths;
16664   for (i = 0; i < count; i++)
16665     {
16666       vl_api_mpls_fib_path_print (vam, fp);
16667       fp++;
16668     }
16669
16670   print (vam->ofp, "");
16671 }
16672
16673 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16674 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16675
16676 static void
16677 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16678 {
16679   vat_main_t *vam = &vat_main;
16680   vat_json_node_t *node = NULL;
16681   int count = ntohl (mp->mt_count);
16682   vl_api_fib_path2_t *fp;
16683   i32 i;
16684
16685   if (VAT_JSON_ARRAY != vam->json_tree.type)
16686     {
16687       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16688       vat_json_init_array (&vam->json_tree);
16689     }
16690   node = vat_json_array_add (&vam->json_tree);
16691
16692   vat_json_init_object (node);
16693   vat_json_object_add_uint (node, "tunnel_index",
16694                             ntohl (mp->mt_tunnel_index));
16695   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16696
16697   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16698
16699   fp = mp->mt_paths;
16700   for (i = 0; i < count; i++)
16701     {
16702       vl_api_mpls_fib_path_json_print (node, fp);
16703       fp++;
16704     }
16705 }
16706
16707 static int
16708 api_mpls_tunnel_dump (vat_main_t * vam)
16709 {
16710   vl_api_mpls_tunnel_dump_t *mp;
16711   vl_api_control_ping_t *mp_ping;
16712   i32 index = -1;
16713   int ret;
16714
16715   /* Parse args required to build the message */
16716   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16717     {
16718       if (!unformat (vam->input, "tunnel_index %d", &index))
16719         {
16720           index = -1;
16721           break;
16722         }
16723     }
16724
16725   print (vam->ofp, "  tunnel_index %d", index);
16726
16727   M (MPLS_TUNNEL_DUMP, mp);
16728   mp->tunnel_index = htonl (index);
16729   S (mp);
16730
16731   /* Use a control ping for synchronization */
16732   M (CONTROL_PING, mp_ping);
16733   S (mp_ping);
16734
16735   W (ret);
16736   return ret;
16737 }
16738
16739 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16740 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16741
16742
16743 static void
16744 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16745 {
16746   vat_main_t *vam = &vat_main;
16747   int count = ntohl (mp->count);
16748   vl_api_fib_path2_t *fp;
16749   int i;
16750
16751   print (vam->ofp,
16752          "table-id %d, label %u, ess_bit %u",
16753          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16754   fp = mp->path;
16755   for (i = 0; i < count; i++)
16756     {
16757       vl_api_mpls_fib_path_print (vam, fp);
16758       fp++;
16759     }
16760 }
16761
16762 static void vl_api_mpls_fib_details_t_handler_json
16763   (vl_api_mpls_fib_details_t * mp)
16764 {
16765   vat_main_t *vam = &vat_main;
16766   int count = ntohl (mp->count);
16767   vat_json_node_t *node = NULL;
16768   vl_api_fib_path2_t *fp;
16769   int i;
16770
16771   if (VAT_JSON_ARRAY != vam->json_tree.type)
16772     {
16773       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16774       vat_json_init_array (&vam->json_tree);
16775     }
16776   node = vat_json_array_add (&vam->json_tree);
16777
16778   vat_json_init_object (node);
16779   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16780   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16781   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16782   vat_json_object_add_uint (node, "path_count", count);
16783   fp = mp->path;
16784   for (i = 0; i < count; i++)
16785     {
16786       vl_api_mpls_fib_path_json_print (node, fp);
16787       fp++;
16788     }
16789 }
16790
16791 static int
16792 api_mpls_fib_dump (vat_main_t * vam)
16793 {
16794   vl_api_mpls_fib_dump_t *mp;
16795   vl_api_control_ping_t *mp_ping;
16796   int ret;
16797
16798   M (MPLS_FIB_DUMP, mp);
16799   S (mp);
16800
16801   /* Use a control ping for synchronization */
16802   M (CONTROL_PING, mp_ping);
16803   S (mp_ping);
16804
16805   W (ret);
16806   return ret;
16807 }
16808
16809 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16810 #define vl_api_ip_fib_details_t_print vl_noop_handler
16811
16812 static void
16813 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16814 {
16815   vat_main_t *vam = &vat_main;
16816   int count = ntohl (mp->count);
16817   vl_api_fib_path_t *fp;
16818   int i;
16819
16820   print (vam->ofp,
16821          "table-id %d, prefix %U/%d",
16822          ntohl (mp->table_id), format_ip4_address, mp->address,
16823          mp->address_length);
16824   fp = mp->path;
16825   for (i = 0; i < count; i++)
16826     {
16827       if (fp->afi == IP46_TYPE_IP6)
16828         print (vam->ofp,
16829                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16830                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16831                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16832                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16833                format_ip6_address, fp->next_hop);
16834       else if (fp->afi == IP46_TYPE_IP4)
16835         print (vam->ofp,
16836                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16837                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16838                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16839                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16840                format_ip4_address, fp->next_hop);
16841       fp++;
16842     }
16843 }
16844
16845 static void vl_api_ip_fib_details_t_handler_json
16846   (vl_api_ip_fib_details_t * mp)
16847 {
16848   vat_main_t *vam = &vat_main;
16849   int count = ntohl (mp->count);
16850   vat_json_node_t *node = NULL;
16851   struct in_addr ip4;
16852   struct in6_addr ip6;
16853   vl_api_fib_path_t *fp;
16854   int i;
16855
16856   if (VAT_JSON_ARRAY != vam->json_tree.type)
16857     {
16858       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16859       vat_json_init_array (&vam->json_tree);
16860     }
16861   node = vat_json_array_add (&vam->json_tree);
16862
16863   vat_json_init_object (node);
16864   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16865   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16866   vat_json_object_add_ip4 (node, "prefix", ip4);
16867   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16868   vat_json_object_add_uint (node, "path_count", count);
16869   fp = mp->path;
16870   for (i = 0; i < count; i++)
16871     {
16872       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16873       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16874       vat_json_object_add_uint (node, "is_local", fp->is_local);
16875       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16876       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16877       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16878       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16879       if (fp->afi == IP46_TYPE_IP4)
16880         {
16881           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16882           vat_json_object_add_ip4 (node, "next_hop", ip4);
16883         }
16884       else if (fp->afi == IP46_TYPE_IP6)
16885         {
16886           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16887           vat_json_object_add_ip6 (node, "next_hop", ip6);
16888         }
16889     }
16890 }
16891
16892 static int
16893 api_ip_fib_dump (vat_main_t * vam)
16894 {
16895   vl_api_ip_fib_dump_t *mp;
16896   vl_api_control_ping_t *mp_ping;
16897   int ret;
16898
16899   M (IP_FIB_DUMP, mp);
16900   S (mp);
16901
16902   /* Use a control ping for synchronization */
16903   M (CONTROL_PING, mp_ping);
16904   S (mp_ping);
16905
16906   W (ret);
16907   return ret;
16908 }
16909
16910 static int
16911 api_ip_mfib_dump (vat_main_t * vam)
16912 {
16913   vl_api_ip_mfib_dump_t *mp;
16914   vl_api_control_ping_t *mp_ping;
16915   int ret;
16916
16917   M (IP_MFIB_DUMP, mp);
16918   S (mp);
16919
16920   /* Use a control ping for synchronization */
16921   M (CONTROL_PING, mp_ping);
16922   S (mp_ping);
16923
16924   W (ret);
16925   return ret;
16926 }
16927
16928 static void vl_api_ip_neighbor_details_t_handler
16929   (vl_api_ip_neighbor_details_t * mp)
16930 {
16931   vat_main_t *vam = &vat_main;
16932
16933   print (vam->ofp, "%c %U %U",
16934          (mp->is_static) ? 'S' : 'D',
16935          format_ethernet_address, &mp->mac_address,
16936          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16937          &mp->ip_address);
16938 }
16939
16940 static void vl_api_ip_neighbor_details_t_handler_json
16941   (vl_api_ip_neighbor_details_t * mp)
16942 {
16943
16944   vat_main_t *vam = &vat_main;
16945   vat_json_node_t *node;
16946   struct in_addr ip4;
16947   struct in6_addr ip6;
16948
16949   if (VAT_JSON_ARRAY != vam->json_tree.type)
16950     {
16951       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16952       vat_json_init_array (&vam->json_tree);
16953     }
16954   node = vat_json_array_add (&vam->json_tree);
16955
16956   vat_json_init_object (node);
16957   vat_json_object_add_string_copy (node, "flag",
16958                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16959                                    "dynamic");
16960
16961   vat_json_object_add_string_copy (node, "link_layer",
16962                                    format (0, "%U", format_ethernet_address,
16963                                            &mp->mac_address));
16964
16965   if (mp->is_ipv6)
16966     {
16967       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16968       vat_json_object_add_ip6 (node, "ip_address", ip6);
16969     }
16970   else
16971     {
16972       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16973       vat_json_object_add_ip4 (node, "ip_address", ip4);
16974     }
16975 }
16976
16977 static int
16978 api_ip_neighbor_dump (vat_main_t * vam)
16979 {
16980   unformat_input_t *i = vam->input;
16981   vl_api_ip_neighbor_dump_t *mp;
16982   vl_api_control_ping_t *mp_ping;
16983   u8 is_ipv6 = 0;
16984   u32 sw_if_index = ~0;
16985   int ret;
16986
16987   /* Parse args required to build the message */
16988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16989     {
16990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16991         ;
16992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16993         ;
16994       else if (unformat (i, "ip6"))
16995         is_ipv6 = 1;
16996       else
16997         break;
16998     }
16999
17000   if (sw_if_index == ~0)
17001     {
17002       errmsg ("missing interface name or sw_if_index");
17003       return -99;
17004     }
17005
17006   M (IP_NEIGHBOR_DUMP, mp);
17007   mp->is_ipv6 = (u8) is_ipv6;
17008   mp->sw_if_index = ntohl (sw_if_index);
17009   S (mp);
17010
17011   /* Use a control ping for synchronization */
17012   M (CONTROL_PING, mp_ping);
17013   S (mp_ping);
17014
17015   W (ret);
17016   return ret;
17017 }
17018
17019 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17020 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17021
17022 static void
17023 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17024 {
17025   vat_main_t *vam = &vat_main;
17026   int count = ntohl (mp->count);
17027   vl_api_fib_path_t *fp;
17028   int i;
17029
17030   print (vam->ofp,
17031          "table-id %d, prefix %U/%d",
17032          ntohl (mp->table_id), format_ip6_address, mp->address,
17033          mp->address_length);
17034   fp = mp->path;
17035   for (i = 0; i < count; i++)
17036     {
17037       if (fp->afi == IP46_TYPE_IP6)
17038         print (vam->ofp,
17039                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17040                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17041                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17042                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17043                format_ip6_address, fp->next_hop);
17044       else if (fp->afi == IP46_TYPE_IP4)
17045         print (vam->ofp,
17046                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17047                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17048                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17049                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17050                format_ip4_address, fp->next_hop);
17051       fp++;
17052     }
17053 }
17054
17055 static void vl_api_ip6_fib_details_t_handler_json
17056   (vl_api_ip6_fib_details_t * mp)
17057 {
17058   vat_main_t *vam = &vat_main;
17059   int count = ntohl (mp->count);
17060   vat_json_node_t *node = NULL;
17061   struct in_addr ip4;
17062   struct in6_addr ip6;
17063   vl_api_fib_path_t *fp;
17064   int i;
17065
17066   if (VAT_JSON_ARRAY != vam->json_tree.type)
17067     {
17068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17069       vat_json_init_array (&vam->json_tree);
17070     }
17071   node = vat_json_array_add (&vam->json_tree);
17072
17073   vat_json_init_object (node);
17074   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17075   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17076   vat_json_object_add_ip6 (node, "prefix", ip6);
17077   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17078   vat_json_object_add_uint (node, "path_count", count);
17079   fp = mp->path;
17080   for (i = 0; i < count; i++)
17081     {
17082       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17083       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17084       vat_json_object_add_uint (node, "is_local", fp->is_local);
17085       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17086       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17087       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17088       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17089       if (fp->afi == IP46_TYPE_IP4)
17090         {
17091           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17092           vat_json_object_add_ip4 (node, "next_hop", ip4);
17093         }
17094       else if (fp->afi == IP46_TYPE_IP6)
17095         {
17096           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17097           vat_json_object_add_ip6 (node, "next_hop", ip6);
17098         }
17099     }
17100 }
17101
17102 static int
17103 api_ip6_fib_dump (vat_main_t * vam)
17104 {
17105   vl_api_ip6_fib_dump_t *mp;
17106   vl_api_control_ping_t *mp_ping;
17107   int ret;
17108
17109   M (IP6_FIB_DUMP, mp);
17110   S (mp);
17111
17112   /* Use a control ping for synchronization */
17113   M (CONTROL_PING, mp_ping);
17114   S (mp_ping);
17115
17116   W (ret);
17117   return ret;
17118 }
17119
17120 static int
17121 api_ip6_mfib_dump (vat_main_t * vam)
17122 {
17123   vl_api_ip6_mfib_dump_t *mp;
17124   vl_api_control_ping_t *mp_ping;
17125   int ret;
17126
17127   M (IP6_MFIB_DUMP, mp);
17128   S (mp);
17129
17130   /* Use a control ping for synchronization */
17131   M (CONTROL_PING, mp_ping);
17132   S (mp_ping);
17133
17134   W (ret);
17135   return ret;
17136 }
17137
17138 int
17139 api_classify_table_ids (vat_main_t * vam)
17140 {
17141   vl_api_classify_table_ids_t *mp;
17142   int ret;
17143
17144   /* Construct the API message */
17145   M (CLASSIFY_TABLE_IDS, mp);
17146   mp->context = 0;
17147
17148   S (mp);
17149   W (ret);
17150   return ret;
17151 }
17152
17153 int
17154 api_classify_table_by_interface (vat_main_t * vam)
17155 {
17156   unformat_input_t *input = vam->input;
17157   vl_api_classify_table_by_interface_t *mp;
17158
17159   u32 sw_if_index = ~0;
17160   int ret;
17161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17162     {
17163       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17164         ;
17165       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17166         ;
17167       else
17168         break;
17169     }
17170   if (sw_if_index == ~0)
17171     {
17172       errmsg ("missing interface name or sw_if_index");
17173       return -99;
17174     }
17175
17176   /* Construct the API message */
17177   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17178   mp->context = 0;
17179   mp->sw_if_index = ntohl (sw_if_index);
17180
17181   S (mp);
17182   W (ret);
17183   return ret;
17184 }
17185
17186 int
17187 api_classify_table_info (vat_main_t * vam)
17188 {
17189   unformat_input_t *input = vam->input;
17190   vl_api_classify_table_info_t *mp;
17191
17192   u32 table_id = ~0;
17193   int ret;
17194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17195     {
17196       if (unformat (input, "table_id %d", &table_id))
17197         ;
17198       else
17199         break;
17200     }
17201   if (table_id == ~0)
17202     {
17203       errmsg ("missing table id");
17204       return -99;
17205     }
17206
17207   /* Construct the API message */
17208   M (CLASSIFY_TABLE_INFO, mp);
17209   mp->context = 0;
17210   mp->table_id = ntohl (table_id);
17211
17212   S (mp);
17213   W (ret);
17214   return ret;
17215 }
17216
17217 int
17218 api_classify_session_dump (vat_main_t * vam)
17219 {
17220   unformat_input_t *input = vam->input;
17221   vl_api_classify_session_dump_t *mp;
17222   vl_api_control_ping_t *mp_ping;
17223
17224   u32 table_id = ~0;
17225   int ret;
17226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17227     {
17228       if (unformat (input, "table_id %d", &table_id))
17229         ;
17230       else
17231         break;
17232     }
17233   if (table_id == ~0)
17234     {
17235       errmsg ("missing table id");
17236       return -99;
17237     }
17238
17239   /* Construct the API message */
17240   M (CLASSIFY_SESSION_DUMP, mp);
17241   mp->context = 0;
17242   mp->table_id = ntohl (table_id);
17243   S (mp);
17244
17245   /* Use a control ping for synchronization */
17246   M (CONTROL_PING, mp_ping);
17247   S (mp_ping);
17248
17249   W (ret);
17250   return ret;
17251 }
17252
17253 static void
17254 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17255 {
17256   vat_main_t *vam = &vat_main;
17257
17258   print (vam->ofp, "collector_address %U, collector_port %d, "
17259          "src_address %U, vrf_id %d, path_mtu %u, "
17260          "template_interval %u, udp_checksum %d",
17261          format_ip4_address, mp->collector_address,
17262          ntohs (mp->collector_port),
17263          format_ip4_address, mp->src_address,
17264          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17265          ntohl (mp->template_interval), mp->udp_checksum);
17266
17267   vam->retval = 0;
17268   vam->result_ready = 1;
17269 }
17270
17271 static void
17272   vl_api_ipfix_exporter_details_t_handler_json
17273   (vl_api_ipfix_exporter_details_t * mp)
17274 {
17275   vat_main_t *vam = &vat_main;
17276   vat_json_node_t node;
17277   struct in_addr collector_address;
17278   struct in_addr src_address;
17279
17280   vat_json_init_object (&node);
17281   clib_memcpy (&collector_address, &mp->collector_address,
17282                sizeof (collector_address));
17283   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17284   vat_json_object_add_uint (&node, "collector_port",
17285                             ntohs (mp->collector_port));
17286   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17287   vat_json_object_add_ip4 (&node, "src_address", src_address);
17288   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17289   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17290   vat_json_object_add_uint (&node, "template_interval",
17291                             ntohl (mp->template_interval));
17292   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17293
17294   vat_json_print (vam->ofp, &node);
17295   vat_json_free (&node);
17296   vam->retval = 0;
17297   vam->result_ready = 1;
17298 }
17299
17300 int
17301 api_ipfix_exporter_dump (vat_main_t * vam)
17302 {
17303   vl_api_ipfix_exporter_dump_t *mp;
17304   int ret;
17305
17306   /* Construct the API message */
17307   M (IPFIX_EXPORTER_DUMP, mp);
17308   mp->context = 0;
17309
17310   S (mp);
17311   W (ret);
17312   return ret;
17313 }
17314
17315 static int
17316 api_ipfix_classify_stream_dump (vat_main_t * vam)
17317 {
17318   vl_api_ipfix_classify_stream_dump_t *mp;
17319   int ret;
17320
17321   /* Construct the API message */
17322   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17323   mp->context = 0;
17324
17325   S (mp);
17326   W (ret);
17327   return ret;
17328   /* NOTREACHED */
17329   return 0;
17330 }
17331
17332 static void
17333   vl_api_ipfix_classify_stream_details_t_handler
17334   (vl_api_ipfix_classify_stream_details_t * mp)
17335 {
17336   vat_main_t *vam = &vat_main;
17337   print (vam->ofp, "domain_id %d, src_port %d",
17338          ntohl (mp->domain_id), ntohs (mp->src_port));
17339   vam->retval = 0;
17340   vam->result_ready = 1;
17341 }
17342
17343 static void
17344   vl_api_ipfix_classify_stream_details_t_handler_json
17345   (vl_api_ipfix_classify_stream_details_t * mp)
17346 {
17347   vat_main_t *vam = &vat_main;
17348   vat_json_node_t node;
17349
17350   vat_json_init_object (&node);
17351   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17352   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17353
17354   vat_json_print (vam->ofp, &node);
17355   vat_json_free (&node);
17356   vam->retval = 0;
17357   vam->result_ready = 1;
17358 }
17359
17360 static int
17361 api_ipfix_classify_table_dump (vat_main_t * vam)
17362 {
17363   vl_api_ipfix_classify_table_dump_t *mp;
17364   vl_api_control_ping_t *mp_ping;
17365   int ret;
17366
17367   if (!vam->json_output)
17368     {
17369       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17370              "transport_protocol");
17371     }
17372
17373   /* Construct the API message */
17374   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17375
17376   /* send it... */
17377   S (mp);
17378
17379   /* Use a control ping for synchronization */
17380   M (CONTROL_PING, mp_ping);
17381   S (mp_ping);
17382
17383   W (ret);
17384   return ret;
17385 }
17386
17387 static void
17388   vl_api_ipfix_classify_table_details_t_handler
17389   (vl_api_ipfix_classify_table_details_t * mp)
17390 {
17391   vat_main_t *vam = &vat_main;
17392   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17393          mp->transport_protocol);
17394 }
17395
17396 static void
17397   vl_api_ipfix_classify_table_details_t_handler_json
17398   (vl_api_ipfix_classify_table_details_t * mp)
17399 {
17400   vat_json_node_t *node = NULL;
17401   vat_main_t *vam = &vat_main;
17402
17403   if (VAT_JSON_ARRAY != vam->json_tree.type)
17404     {
17405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17406       vat_json_init_array (&vam->json_tree);
17407     }
17408
17409   node = vat_json_array_add (&vam->json_tree);
17410   vat_json_init_object (node);
17411
17412   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17413   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17414   vat_json_object_add_uint (node, "transport_protocol",
17415                             mp->transport_protocol);
17416 }
17417
17418 static int
17419 api_sw_interface_span_enable_disable (vat_main_t * vam)
17420 {
17421   unformat_input_t *i = vam->input;
17422   vl_api_sw_interface_span_enable_disable_t *mp;
17423   u32 src_sw_if_index = ~0;
17424   u32 dst_sw_if_index = ~0;
17425   u8 state = 3;
17426   int ret;
17427
17428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17429     {
17430       if (unformat
17431           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17432         ;
17433       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17434         ;
17435       else
17436         if (unformat
17437             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17438         ;
17439       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17440         ;
17441       else if (unformat (i, "disable"))
17442         state = 0;
17443       else if (unformat (i, "rx"))
17444         state = 1;
17445       else if (unformat (i, "tx"))
17446         state = 2;
17447       else if (unformat (i, "both"))
17448         state = 3;
17449       else
17450         break;
17451     }
17452
17453   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17454
17455   mp->sw_if_index_from = htonl (src_sw_if_index);
17456   mp->sw_if_index_to = htonl (dst_sw_if_index);
17457   mp->state = state;
17458
17459   S (mp);
17460   W (ret);
17461   return ret;
17462 }
17463
17464 static void
17465 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17466                                             * mp)
17467 {
17468   vat_main_t *vam = &vat_main;
17469   u8 *sw_if_from_name = 0;
17470   u8 *sw_if_to_name = 0;
17471   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17472   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17473   char *states[] = { "none", "rx", "tx", "both" };
17474   hash_pair_t *p;
17475
17476   /* *INDENT-OFF* */
17477   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17478   ({
17479     if ((u32) p->value[0] == sw_if_index_from)
17480       {
17481         sw_if_from_name = (u8 *)(p->key);
17482         if (sw_if_to_name)
17483           break;
17484       }
17485     if ((u32) p->value[0] == sw_if_index_to)
17486       {
17487         sw_if_to_name = (u8 *)(p->key);
17488         if (sw_if_from_name)
17489           break;
17490       }
17491   }));
17492   /* *INDENT-ON* */
17493   print (vam->ofp, "%20s => %20s (%s)",
17494          sw_if_from_name, sw_if_to_name, states[mp->state]);
17495 }
17496
17497 static void
17498   vl_api_sw_interface_span_details_t_handler_json
17499   (vl_api_sw_interface_span_details_t * mp)
17500 {
17501   vat_main_t *vam = &vat_main;
17502   vat_json_node_t *node = NULL;
17503   u8 *sw_if_from_name = 0;
17504   u8 *sw_if_to_name = 0;
17505   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17506   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17507   hash_pair_t *p;
17508
17509   /* *INDENT-OFF* */
17510   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17511   ({
17512     if ((u32) p->value[0] == sw_if_index_from)
17513       {
17514         sw_if_from_name = (u8 *)(p->key);
17515         if (sw_if_to_name)
17516           break;
17517       }
17518     if ((u32) p->value[0] == sw_if_index_to)
17519       {
17520         sw_if_to_name = (u8 *)(p->key);
17521         if (sw_if_from_name)
17522           break;
17523       }
17524   }));
17525   /* *INDENT-ON* */
17526
17527   if (VAT_JSON_ARRAY != vam->json_tree.type)
17528     {
17529       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17530       vat_json_init_array (&vam->json_tree);
17531     }
17532   node = vat_json_array_add (&vam->json_tree);
17533
17534   vat_json_init_object (node);
17535   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17536   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17537   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17538   if (0 != sw_if_to_name)
17539     {
17540       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17541     }
17542   vat_json_object_add_uint (node, "state", mp->state);
17543 }
17544
17545 static int
17546 api_sw_interface_span_dump (vat_main_t * vam)
17547 {
17548   vl_api_sw_interface_span_dump_t *mp;
17549   vl_api_control_ping_t *mp_ping;
17550   int ret;
17551
17552   M (SW_INTERFACE_SPAN_DUMP, mp);
17553   S (mp);
17554
17555   /* Use a control ping for synchronization */
17556   M (CONTROL_PING, mp_ping);
17557   S (mp_ping);
17558
17559   W (ret);
17560   return ret;
17561 }
17562
17563 int
17564 api_pg_create_interface (vat_main_t * vam)
17565 {
17566   unformat_input_t *input = vam->input;
17567   vl_api_pg_create_interface_t *mp;
17568
17569   u32 if_id = ~0;
17570   int ret;
17571   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17572     {
17573       if (unformat (input, "if_id %d", &if_id))
17574         ;
17575       else
17576         break;
17577     }
17578   if (if_id == ~0)
17579     {
17580       errmsg ("missing pg interface index");
17581       return -99;
17582     }
17583
17584   /* Construct the API message */
17585   M (PG_CREATE_INTERFACE, mp);
17586   mp->context = 0;
17587   mp->interface_id = ntohl (if_id);
17588
17589   S (mp);
17590   W (ret);
17591   return ret;
17592 }
17593
17594 int
17595 api_pg_capture (vat_main_t * vam)
17596 {
17597   unformat_input_t *input = vam->input;
17598   vl_api_pg_capture_t *mp;
17599
17600   u32 if_id = ~0;
17601   u8 enable = 1;
17602   u32 count = 1;
17603   u8 pcap_file_set = 0;
17604   u8 *pcap_file = 0;
17605   int ret;
17606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17607     {
17608       if (unformat (input, "if_id %d", &if_id))
17609         ;
17610       else if (unformat (input, "pcap %s", &pcap_file))
17611         pcap_file_set = 1;
17612       else if (unformat (input, "count %d", &count))
17613         ;
17614       else if (unformat (input, "disable"))
17615         enable = 0;
17616       else
17617         break;
17618     }
17619   if (if_id == ~0)
17620     {
17621       errmsg ("missing pg interface index");
17622       return -99;
17623     }
17624   if (pcap_file_set > 0)
17625     {
17626       if (vec_len (pcap_file) > 255)
17627         {
17628           errmsg ("pcap file name is too long");
17629           return -99;
17630         }
17631     }
17632
17633   u32 name_len = vec_len (pcap_file);
17634   /* Construct the API message */
17635   M (PG_CAPTURE, mp);
17636   mp->context = 0;
17637   mp->interface_id = ntohl (if_id);
17638   mp->is_enabled = enable;
17639   mp->count = ntohl (count);
17640   mp->pcap_name_length = ntohl (name_len);
17641   if (pcap_file_set != 0)
17642     {
17643       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17644     }
17645   vec_free (pcap_file);
17646
17647   S (mp);
17648   W (ret);
17649   return ret;
17650 }
17651
17652 int
17653 api_pg_enable_disable (vat_main_t * vam)
17654 {
17655   unformat_input_t *input = vam->input;
17656   vl_api_pg_enable_disable_t *mp;
17657
17658   u8 enable = 1;
17659   u8 stream_name_set = 0;
17660   u8 *stream_name = 0;
17661   int ret;
17662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17663     {
17664       if (unformat (input, "stream %s", &stream_name))
17665         stream_name_set = 1;
17666       else if (unformat (input, "disable"))
17667         enable = 0;
17668       else
17669         break;
17670     }
17671
17672   if (stream_name_set > 0)
17673     {
17674       if (vec_len (stream_name) > 255)
17675         {
17676           errmsg ("stream name too long");
17677           return -99;
17678         }
17679     }
17680
17681   u32 name_len = vec_len (stream_name);
17682   /* Construct the API message */
17683   M (PG_ENABLE_DISABLE, mp);
17684   mp->context = 0;
17685   mp->is_enabled = enable;
17686   if (stream_name_set != 0)
17687     {
17688       mp->stream_name_length = ntohl (name_len);
17689       clib_memcpy (mp->stream_name, stream_name, name_len);
17690     }
17691   vec_free (stream_name);
17692
17693   S (mp);
17694   W (ret);
17695   return ret;
17696 }
17697
17698 int
17699 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17700 {
17701   unformat_input_t *input = vam->input;
17702   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17703
17704   u16 *low_ports = 0;
17705   u16 *high_ports = 0;
17706   u16 this_low;
17707   u16 this_hi;
17708   ip4_address_t ip4_addr;
17709   ip6_address_t ip6_addr;
17710   u32 length;
17711   u32 tmp, tmp2;
17712   u8 prefix_set = 0;
17713   u32 vrf_id = ~0;
17714   u8 is_add = 1;
17715   u8 is_ipv6 = 0;
17716   int ret;
17717
17718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17719     {
17720       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17721         {
17722           prefix_set = 1;
17723         }
17724       else
17725         if (unformat
17726             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17727         {
17728           prefix_set = 1;
17729           is_ipv6 = 1;
17730         }
17731       else if (unformat (input, "vrf %d", &vrf_id))
17732         ;
17733       else if (unformat (input, "del"))
17734         is_add = 0;
17735       else if (unformat (input, "port %d", &tmp))
17736         {
17737           if (tmp == 0 || tmp > 65535)
17738             {
17739               errmsg ("port %d out of range", tmp);
17740               return -99;
17741             }
17742           this_low = tmp;
17743           this_hi = this_low + 1;
17744           vec_add1 (low_ports, this_low);
17745           vec_add1 (high_ports, this_hi);
17746         }
17747       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17748         {
17749           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17750             {
17751               errmsg ("incorrect range parameters");
17752               return -99;
17753             }
17754           this_low = tmp;
17755           /* Note: in debug CLI +1 is added to high before
17756              passing to real fn that does "the work"
17757              (ip_source_and_port_range_check_add_del).
17758              This fn is a wrapper around the binary API fn a
17759              control plane will call, which expects this increment
17760              to have occurred. Hence letting the binary API control
17761              plane fn do the increment for consistency between VAT
17762              and other control planes.
17763            */
17764           this_hi = tmp2;
17765           vec_add1 (low_ports, this_low);
17766           vec_add1 (high_ports, this_hi);
17767         }
17768       else
17769         break;
17770     }
17771
17772   if (prefix_set == 0)
17773     {
17774       errmsg ("<address>/<mask> not specified");
17775       return -99;
17776     }
17777
17778   if (vrf_id == ~0)
17779     {
17780       errmsg ("VRF ID required, not specified");
17781       return -99;
17782     }
17783
17784   if (vrf_id == 0)
17785     {
17786       errmsg
17787         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17788       return -99;
17789     }
17790
17791   if (vec_len (low_ports) == 0)
17792     {
17793       errmsg ("At least one port or port range required");
17794       return -99;
17795     }
17796
17797   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17798
17799   mp->is_add = is_add;
17800
17801   if (is_ipv6)
17802     {
17803       mp->is_ipv6 = 1;
17804       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17805     }
17806   else
17807     {
17808       mp->is_ipv6 = 0;
17809       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17810     }
17811
17812   mp->mask_length = length;
17813   mp->number_of_ranges = vec_len (low_ports);
17814
17815   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17816   vec_free (low_ports);
17817
17818   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17819   vec_free (high_ports);
17820
17821   mp->vrf_id = ntohl (vrf_id);
17822
17823   S (mp);
17824   W (ret);
17825   return ret;
17826 }
17827
17828 int
17829 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17830 {
17831   unformat_input_t *input = vam->input;
17832   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17833   u32 sw_if_index = ~0;
17834   int vrf_set = 0;
17835   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17836   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17837   u8 is_add = 1;
17838   int ret;
17839
17840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17841     {
17842       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17843         ;
17844       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17845         ;
17846       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17847         vrf_set = 1;
17848       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17849         vrf_set = 1;
17850       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17851         vrf_set = 1;
17852       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17853         vrf_set = 1;
17854       else if (unformat (input, "del"))
17855         is_add = 0;
17856       else
17857         break;
17858     }
17859
17860   if (sw_if_index == ~0)
17861     {
17862       errmsg ("Interface required but not specified");
17863       return -99;
17864     }
17865
17866   if (vrf_set == 0)
17867     {
17868       errmsg ("VRF ID required but not specified");
17869       return -99;
17870     }
17871
17872   if (tcp_out_vrf_id == 0
17873       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17874     {
17875       errmsg
17876         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17877       return -99;
17878     }
17879
17880   /* Construct the API message */
17881   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17882
17883   mp->sw_if_index = ntohl (sw_if_index);
17884   mp->is_add = is_add;
17885   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17886   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17887   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17888   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17889
17890   /* send it... */
17891   S (mp);
17892
17893   /* Wait for a reply... */
17894   W (ret);
17895   return ret;
17896 }
17897
17898 static int
17899 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17900 {
17901   unformat_input_t *i = vam->input;
17902   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17903   u32 local_sa_id = 0;
17904   u32 remote_sa_id = 0;
17905   ip4_address_t src_address;
17906   ip4_address_t dst_address;
17907   u8 is_add = 1;
17908   int ret;
17909
17910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17911     {
17912       if (unformat (i, "local_sa %d", &local_sa_id))
17913         ;
17914       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17915         ;
17916       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17917         ;
17918       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17919         ;
17920       else if (unformat (i, "del"))
17921         is_add = 0;
17922       else
17923         {
17924           clib_warning ("parse error '%U'", format_unformat_error, i);
17925           return -99;
17926         }
17927     }
17928
17929   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17930
17931   mp->local_sa_id = ntohl (local_sa_id);
17932   mp->remote_sa_id = ntohl (remote_sa_id);
17933   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17934   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17935   mp->is_add = is_add;
17936
17937   S (mp);
17938   W (ret);
17939   return ret;
17940 }
17941
17942 static int
17943 api_punt (vat_main_t * vam)
17944 {
17945   unformat_input_t *i = vam->input;
17946   vl_api_punt_t *mp;
17947   u32 ipv = ~0;
17948   u32 protocol = ~0;
17949   u32 port = ~0;
17950   int is_add = 1;
17951   int ret;
17952
17953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17954     {
17955       if (unformat (i, "ip %d", &ipv))
17956         ;
17957       else if (unformat (i, "protocol %d", &protocol))
17958         ;
17959       else if (unformat (i, "port %d", &port))
17960         ;
17961       else if (unformat (i, "del"))
17962         is_add = 0;
17963       else
17964         {
17965           clib_warning ("parse error '%U'", format_unformat_error, i);
17966           return -99;
17967         }
17968     }
17969
17970   M (PUNT, mp);
17971
17972   mp->is_add = (u8) is_add;
17973   mp->ipv = (u8) ipv;
17974   mp->l4_protocol = (u8) protocol;
17975   mp->l4_port = htons ((u16) port);
17976
17977   S (mp);
17978   W (ret);
17979   return ret;
17980 }
17981
17982 static void vl_api_ipsec_gre_tunnel_details_t_handler
17983   (vl_api_ipsec_gre_tunnel_details_t * mp)
17984 {
17985   vat_main_t *vam = &vat_main;
17986
17987   print (vam->ofp, "%11d%15U%15U%14d%14d",
17988          ntohl (mp->sw_if_index),
17989          format_ip4_address, &mp->src_address,
17990          format_ip4_address, &mp->dst_address,
17991          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17992 }
17993
17994 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17995   (vl_api_ipsec_gre_tunnel_details_t * mp)
17996 {
17997   vat_main_t *vam = &vat_main;
17998   vat_json_node_t *node = NULL;
17999   struct in_addr ip4;
18000
18001   if (VAT_JSON_ARRAY != vam->json_tree.type)
18002     {
18003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18004       vat_json_init_array (&vam->json_tree);
18005     }
18006   node = vat_json_array_add (&vam->json_tree);
18007
18008   vat_json_init_object (node);
18009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18010   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18011   vat_json_object_add_ip4 (node, "src_address", ip4);
18012   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18013   vat_json_object_add_ip4 (node, "dst_address", ip4);
18014   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18015   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18016 }
18017
18018 static int
18019 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18020 {
18021   unformat_input_t *i = vam->input;
18022   vl_api_ipsec_gre_tunnel_dump_t *mp;
18023   vl_api_control_ping_t *mp_ping;
18024   u32 sw_if_index;
18025   u8 sw_if_index_set = 0;
18026   int ret;
18027
18028   /* Parse args required to build the message */
18029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18030     {
18031       if (unformat (i, "sw_if_index %d", &sw_if_index))
18032         sw_if_index_set = 1;
18033       else
18034         break;
18035     }
18036
18037   if (sw_if_index_set == 0)
18038     {
18039       sw_if_index = ~0;
18040     }
18041
18042   if (!vam->json_output)
18043     {
18044       print (vam->ofp, "%11s%15s%15s%14s%14s",
18045              "sw_if_index", "src_address", "dst_address",
18046              "local_sa_id", "remote_sa_id");
18047     }
18048
18049   /* Get list of gre-tunnel interfaces */
18050   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18051
18052   mp->sw_if_index = htonl (sw_if_index);
18053
18054   S (mp);
18055
18056   /* Use a control ping for synchronization */
18057   M (CONTROL_PING, mp_ping);
18058   S (mp_ping);
18059
18060   W (ret);
18061   return ret;
18062 }
18063
18064 static int
18065 api_delete_subif (vat_main_t * vam)
18066 {
18067   unformat_input_t *i = vam->input;
18068   vl_api_delete_subif_t *mp;
18069   u32 sw_if_index = ~0;
18070   int ret;
18071
18072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18073     {
18074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18075         ;
18076       if (unformat (i, "sw_if_index %d", &sw_if_index))
18077         ;
18078       else
18079         break;
18080     }
18081
18082   if (sw_if_index == ~0)
18083     {
18084       errmsg ("missing sw_if_index");
18085       return -99;
18086     }
18087
18088   /* Construct the API message */
18089   M (DELETE_SUBIF, mp);
18090   mp->sw_if_index = ntohl (sw_if_index);
18091
18092   S (mp);
18093   W (ret);
18094   return ret;
18095 }
18096
18097 #define foreach_pbb_vtr_op      \
18098 _("disable",  L2_VTR_DISABLED)  \
18099 _("pop",  L2_VTR_POP_2)         \
18100 _("push",  L2_VTR_PUSH_2)
18101
18102 static int
18103 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18104 {
18105   unformat_input_t *i = vam->input;
18106   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18107   u32 sw_if_index = ~0, vtr_op = ~0;
18108   u16 outer_tag = ~0;
18109   u8 dmac[6], smac[6];
18110   u8 dmac_set = 0, smac_set = 0;
18111   u16 vlanid = 0;
18112   u32 sid = ~0;
18113   u32 tmp;
18114   int ret;
18115
18116   /* Shut up coverity */
18117   memset (dmac, 0, sizeof (dmac));
18118   memset (smac, 0, sizeof (smac));
18119
18120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18121     {
18122       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18123         ;
18124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18125         ;
18126       else if (unformat (i, "vtr_op %d", &vtr_op))
18127         ;
18128 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18129       foreach_pbb_vtr_op
18130 #undef _
18131         else if (unformat (i, "translate_pbb_stag"))
18132         {
18133           if (unformat (i, "%d", &tmp))
18134             {
18135               vtr_op = L2_VTR_TRANSLATE_2_1;
18136               outer_tag = tmp;
18137             }
18138           else
18139             {
18140               errmsg
18141                 ("translate_pbb_stag operation requires outer tag definition");
18142               return -99;
18143             }
18144         }
18145       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18146         dmac_set++;
18147       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18148         smac_set++;
18149       else if (unformat (i, "sid %d", &sid))
18150         ;
18151       else if (unformat (i, "vlanid %d", &tmp))
18152         vlanid = tmp;
18153       else
18154         {
18155           clib_warning ("parse error '%U'", format_unformat_error, i);
18156           return -99;
18157         }
18158     }
18159
18160   if ((sw_if_index == ~0) || (vtr_op == ~0))
18161     {
18162       errmsg ("missing sw_if_index or vtr operation");
18163       return -99;
18164     }
18165   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18166       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18167     {
18168       errmsg
18169         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18170       return -99;
18171     }
18172
18173   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18174   mp->sw_if_index = ntohl (sw_if_index);
18175   mp->vtr_op = ntohl (vtr_op);
18176   mp->outer_tag = ntohs (outer_tag);
18177   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18178   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18179   mp->b_vlanid = ntohs (vlanid);
18180   mp->i_sid = ntohl (sid);
18181
18182   S (mp);
18183   W (ret);
18184   return ret;
18185 }
18186
18187 static int
18188 api_flow_classify_set_interface (vat_main_t * vam)
18189 {
18190   unformat_input_t *i = vam->input;
18191   vl_api_flow_classify_set_interface_t *mp;
18192   u32 sw_if_index;
18193   int sw_if_index_set;
18194   u32 ip4_table_index = ~0;
18195   u32 ip6_table_index = ~0;
18196   u8 is_add = 1;
18197   int ret;
18198
18199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18200     {
18201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18202         sw_if_index_set = 1;
18203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18204         sw_if_index_set = 1;
18205       else if (unformat (i, "del"))
18206         is_add = 0;
18207       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18208         ;
18209       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18210         ;
18211       else
18212         {
18213           clib_warning ("parse error '%U'", format_unformat_error, i);
18214           return -99;
18215         }
18216     }
18217
18218   if (sw_if_index_set == 0)
18219     {
18220       errmsg ("missing interface name or sw_if_index");
18221       return -99;
18222     }
18223
18224   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18225
18226   mp->sw_if_index = ntohl (sw_if_index);
18227   mp->ip4_table_index = ntohl (ip4_table_index);
18228   mp->ip6_table_index = ntohl (ip6_table_index);
18229   mp->is_add = is_add;
18230
18231   S (mp);
18232   W (ret);
18233   return ret;
18234 }
18235
18236 static int
18237 api_flow_classify_dump (vat_main_t * vam)
18238 {
18239   unformat_input_t *i = vam->input;
18240   vl_api_flow_classify_dump_t *mp;
18241   vl_api_control_ping_t *mp_ping;
18242   u8 type = FLOW_CLASSIFY_N_TABLES;
18243   int ret;
18244
18245   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18246     ;
18247   else
18248     {
18249       errmsg ("classify table type must be specified");
18250       return -99;
18251     }
18252
18253   if (!vam->json_output)
18254     {
18255       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18256     }
18257
18258   M (FLOW_CLASSIFY_DUMP, mp);
18259   mp->type = type;
18260   /* send it... */
18261   S (mp);
18262
18263   /* Use a control ping for synchronization */
18264   M (CONTROL_PING, mp_ping);
18265   S (mp_ping);
18266
18267   /* Wait for a reply... */
18268   W (ret);
18269   return ret;
18270 }
18271
18272 static int
18273 api_feature_enable_disable (vat_main_t * vam)
18274 {
18275   unformat_input_t *i = vam->input;
18276   vl_api_feature_enable_disable_t *mp;
18277   u8 *arc_name = 0;
18278   u8 *feature_name = 0;
18279   u32 sw_if_index = ~0;
18280   u8 enable = 1;
18281   int ret;
18282
18283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18284     {
18285       if (unformat (i, "arc_name %s", &arc_name))
18286         ;
18287       else if (unformat (i, "feature_name %s", &feature_name))
18288         ;
18289       else
18290         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18291         ;
18292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18293         ;
18294       else if (unformat (i, "disable"))
18295         enable = 0;
18296       else
18297         break;
18298     }
18299
18300   if (arc_name == 0)
18301     {
18302       errmsg ("missing arc name");
18303       return -99;
18304     }
18305   if (vec_len (arc_name) > 63)
18306     {
18307       errmsg ("arc name too long");
18308     }
18309
18310   if (feature_name == 0)
18311     {
18312       errmsg ("missing feature name");
18313       return -99;
18314     }
18315   if (vec_len (feature_name) > 63)
18316     {
18317       errmsg ("feature name too long");
18318     }
18319
18320   if (sw_if_index == ~0)
18321     {
18322       errmsg ("missing interface name or sw_if_index");
18323       return -99;
18324     }
18325
18326   /* Construct the API message */
18327   M (FEATURE_ENABLE_DISABLE, mp);
18328   mp->sw_if_index = ntohl (sw_if_index);
18329   mp->enable = enable;
18330   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18331   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18332   vec_free (arc_name);
18333   vec_free (feature_name);
18334
18335   S (mp);
18336   W (ret);
18337   return ret;
18338 }
18339
18340 static int
18341 api_sw_interface_tag_add_del (vat_main_t * vam)
18342 {
18343   unformat_input_t *i = vam->input;
18344   vl_api_sw_interface_tag_add_del_t *mp;
18345   u32 sw_if_index = ~0;
18346   u8 *tag = 0;
18347   u8 enable = 1;
18348   int ret;
18349
18350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18351     {
18352       if (unformat (i, "tag %s", &tag))
18353         ;
18354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18355         ;
18356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18357         ;
18358       else if (unformat (i, "del"))
18359         enable = 0;
18360       else
18361         break;
18362     }
18363
18364   if (sw_if_index == ~0)
18365     {
18366       errmsg ("missing interface name or sw_if_index");
18367       return -99;
18368     }
18369
18370   if (enable && (tag == 0))
18371     {
18372       errmsg ("no tag specified");
18373       return -99;
18374     }
18375
18376   /* Construct the API message */
18377   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18378   mp->sw_if_index = ntohl (sw_if_index);
18379   mp->is_add = enable;
18380   if (enable)
18381     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18382   vec_free (tag);
18383
18384   S (mp);
18385   W (ret);
18386   return ret;
18387 }
18388
18389 static void vl_api_l2_xconnect_details_t_handler
18390   (vl_api_l2_xconnect_details_t * mp)
18391 {
18392   vat_main_t *vam = &vat_main;
18393
18394   print (vam->ofp, "%15d%15d",
18395          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18396 }
18397
18398 static void vl_api_l2_xconnect_details_t_handler_json
18399   (vl_api_l2_xconnect_details_t * mp)
18400 {
18401   vat_main_t *vam = &vat_main;
18402   vat_json_node_t *node = NULL;
18403
18404   if (VAT_JSON_ARRAY != vam->json_tree.type)
18405     {
18406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18407       vat_json_init_array (&vam->json_tree);
18408     }
18409   node = vat_json_array_add (&vam->json_tree);
18410
18411   vat_json_init_object (node);
18412   vat_json_object_add_uint (node, "rx_sw_if_index",
18413                             ntohl (mp->rx_sw_if_index));
18414   vat_json_object_add_uint (node, "tx_sw_if_index",
18415                             ntohl (mp->tx_sw_if_index));
18416 }
18417
18418 static int
18419 api_l2_xconnect_dump (vat_main_t * vam)
18420 {
18421   vl_api_l2_xconnect_dump_t *mp;
18422   vl_api_control_ping_t *mp_ping;
18423   int ret;
18424
18425   if (!vam->json_output)
18426     {
18427       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18428     }
18429
18430   M (L2_XCONNECT_DUMP, mp);
18431
18432   S (mp);
18433
18434   /* Use a control ping for synchronization */
18435   M (CONTROL_PING, mp_ping);
18436   S (mp_ping);
18437
18438   W (ret);
18439   return ret;
18440 }
18441
18442 static int
18443 api_sw_interface_set_mtu (vat_main_t * vam)
18444 {
18445   unformat_input_t *i = vam->input;
18446   vl_api_sw_interface_set_mtu_t *mp;
18447   u32 sw_if_index = ~0;
18448   u32 mtu = 0;
18449   int ret;
18450
18451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18452     {
18453       if (unformat (i, "mtu %d", &mtu))
18454         ;
18455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18456         ;
18457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18458         ;
18459       else
18460         break;
18461     }
18462
18463   if (sw_if_index == ~0)
18464     {
18465       errmsg ("missing interface name or sw_if_index");
18466       return -99;
18467     }
18468
18469   if (mtu == 0)
18470     {
18471       errmsg ("no mtu specified");
18472       return -99;
18473     }
18474
18475   /* Construct the API message */
18476   M (SW_INTERFACE_SET_MTU, mp);
18477   mp->sw_if_index = ntohl (sw_if_index);
18478   mp->mtu = ntohs ((u16) mtu);
18479
18480   S (mp);
18481   W (ret);
18482   return ret;
18483 }
18484
18485
18486 static int
18487 q_or_quit (vat_main_t * vam)
18488 {
18489 #if VPP_API_TEST_BUILTIN == 0
18490   longjmp (vam->jump_buf, 1);
18491 #endif
18492   return 0;                     /* not so much */
18493 }
18494
18495 static int
18496 q (vat_main_t * vam)
18497 {
18498   return q_or_quit (vam);
18499 }
18500
18501 static int
18502 quit (vat_main_t * vam)
18503 {
18504   return q_or_quit (vam);
18505 }
18506
18507 static int
18508 comment (vat_main_t * vam)
18509 {
18510   return 0;
18511 }
18512
18513 static int
18514 cmd_cmp (void *a1, void *a2)
18515 {
18516   u8 **c1 = a1;
18517   u8 **c2 = a2;
18518
18519   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18520 }
18521
18522 static int
18523 help (vat_main_t * vam)
18524 {
18525   u8 **cmds = 0;
18526   u8 *name = 0;
18527   hash_pair_t *p;
18528   unformat_input_t *i = vam->input;
18529   int j;
18530
18531   if (unformat (i, "%s", &name))
18532     {
18533       uword *hs;
18534
18535       vec_add1 (name, 0);
18536
18537       hs = hash_get_mem (vam->help_by_name, name);
18538       if (hs)
18539         print (vam->ofp, "usage: %s %s", name, hs[0]);
18540       else
18541         print (vam->ofp, "No such msg / command '%s'", name);
18542       vec_free (name);
18543       return 0;
18544     }
18545
18546   print (vam->ofp, "Help is available for the following:");
18547
18548     /* *INDENT-OFF* */
18549     hash_foreach_pair (p, vam->function_by_name,
18550     ({
18551       vec_add1 (cmds, (u8 *)(p->key));
18552     }));
18553     /* *INDENT-ON* */
18554
18555   vec_sort_with_function (cmds, cmd_cmp);
18556
18557   for (j = 0; j < vec_len (cmds); j++)
18558     print (vam->ofp, "%s", cmds[j]);
18559
18560   vec_free (cmds);
18561   return 0;
18562 }
18563
18564 static int
18565 set (vat_main_t * vam)
18566 {
18567   u8 *name = 0, *value = 0;
18568   unformat_input_t *i = vam->input;
18569
18570   if (unformat (i, "%s", &name))
18571     {
18572       /* The input buffer is a vector, not a string. */
18573       value = vec_dup (i->buffer);
18574       vec_delete (value, i->index, 0);
18575       /* Almost certainly has a trailing newline */
18576       if (value[vec_len (value) - 1] == '\n')
18577         value[vec_len (value) - 1] = 0;
18578       /* Make sure it's a proper string, one way or the other */
18579       vec_add1 (value, 0);
18580       (void) clib_macro_set_value (&vam->macro_main,
18581                                    (char *) name, (char *) value);
18582     }
18583   else
18584     errmsg ("usage: set <name> <value>");
18585
18586   vec_free (name);
18587   vec_free (value);
18588   return 0;
18589 }
18590
18591 static int
18592 unset (vat_main_t * vam)
18593 {
18594   u8 *name = 0;
18595
18596   if (unformat (vam->input, "%s", &name))
18597     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18598       errmsg ("unset: %s wasn't set", name);
18599   vec_free (name);
18600   return 0;
18601 }
18602
18603 typedef struct
18604 {
18605   u8 *name;
18606   u8 *value;
18607 } macro_sort_t;
18608
18609
18610 static int
18611 macro_sort_cmp (void *a1, void *a2)
18612 {
18613   macro_sort_t *s1 = a1;
18614   macro_sort_t *s2 = a2;
18615
18616   return strcmp ((char *) (s1->name), (char *) (s2->name));
18617 }
18618
18619 static int
18620 dump_macro_table (vat_main_t * vam)
18621 {
18622   macro_sort_t *sort_me = 0, *sm;
18623   int i;
18624   hash_pair_t *p;
18625
18626     /* *INDENT-OFF* */
18627     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18628     ({
18629       vec_add2 (sort_me, sm, 1);
18630       sm->name = (u8 *)(p->key);
18631       sm->value = (u8 *) (p->value[0]);
18632     }));
18633     /* *INDENT-ON* */
18634
18635   vec_sort_with_function (sort_me, macro_sort_cmp);
18636
18637   if (vec_len (sort_me))
18638     print (vam->ofp, "%-15s%s", "Name", "Value");
18639   else
18640     print (vam->ofp, "The macro table is empty...");
18641
18642   for (i = 0; i < vec_len (sort_me); i++)
18643     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18644   return 0;
18645 }
18646
18647 static int
18648 dump_node_table (vat_main_t * vam)
18649 {
18650   int i, j;
18651   vlib_node_t *node, *next_node;
18652
18653   if (vec_len (vam->graph_nodes) == 0)
18654     {
18655       print (vam->ofp, "Node table empty, issue get_node_graph...");
18656       return 0;
18657     }
18658
18659   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18660     {
18661       node = vam->graph_nodes[i];
18662       print (vam->ofp, "[%d] %s", i, node->name);
18663       for (j = 0; j < vec_len (node->next_nodes); j++)
18664         {
18665           if (node->next_nodes[j] != ~0)
18666             {
18667               next_node = vam->graph_nodes[node->next_nodes[j]];
18668               print (vam->ofp, "  [%d] %s", j, next_node->name);
18669             }
18670         }
18671     }
18672   return 0;
18673 }
18674
18675 static int
18676 value_sort_cmp (void *a1, void *a2)
18677 {
18678   name_sort_t *n1 = a1;
18679   name_sort_t *n2 = a2;
18680
18681   if (n1->value < n2->value)
18682     return -1;
18683   if (n1->value > n2->value)
18684     return 1;
18685   return 0;
18686 }
18687
18688
18689 static int
18690 dump_msg_api_table (vat_main_t * vam)
18691 {
18692   api_main_t *am = &api_main;
18693   name_sort_t *nses = 0, *ns;
18694   hash_pair_t *hp;
18695   int i;
18696
18697   /* *INDENT-OFF* */
18698   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18699   ({
18700     vec_add2 (nses, ns, 1);
18701     ns->name = (u8 *)(hp->key);
18702     ns->value = (u32) hp->value[0];
18703   }));
18704   /* *INDENT-ON* */
18705
18706   vec_sort_with_function (nses, value_sort_cmp);
18707
18708   for (i = 0; i < vec_len (nses); i++)
18709     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18710   vec_free (nses);
18711   return 0;
18712 }
18713
18714 static int
18715 get_msg_id (vat_main_t * vam)
18716 {
18717   u8 *name_and_crc;
18718   u32 message_index;
18719
18720   if (unformat (vam->input, "%s", &name_and_crc))
18721     {
18722       message_index = vl_api_get_msg_index (name_and_crc);
18723       if (message_index == ~0)
18724         {
18725           print (vam->ofp, " '%s' not found", name_and_crc);
18726           return 0;
18727         }
18728       print (vam->ofp, " '%s' has message index %d",
18729              name_and_crc, message_index);
18730       return 0;
18731     }
18732   errmsg ("name_and_crc required...");
18733   return 0;
18734 }
18735
18736 static int
18737 search_node_table (vat_main_t * vam)
18738 {
18739   unformat_input_t *line_input = vam->input;
18740   u8 *node_to_find;
18741   int j;
18742   vlib_node_t *node, *next_node;
18743   uword *p;
18744
18745   if (vam->graph_node_index_by_name == 0)
18746     {
18747       print (vam->ofp, "Node table empty, issue get_node_graph...");
18748       return 0;
18749     }
18750
18751   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18752     {
18753       if (unformat (line_input, "%s", &node_to_find))
18754         {
18755           vec_add1 (node_to_find, 0);
18756           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18757           if (p == 0)
18758             {
18759               print (vam->ofp, "%s not found...", node_to_find);
18760               goto out;
18761             }
18762           node = vam->graph_nodes[p[0]];
18763           print (vam->ofp, "[%d] %s", p[0], node->name);
18764           for (j = 0; j < vec_len (node->next_nodes); j++)
18765             {
18766               if (node->next_nodes[j] != ~0)
18767                 {
18768                   next_node = vam->graph_nodes[node->next_nodes[j]];
18769                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18770                 }
18771             }
18772         }
18773
18774       else
18775         {
18776           clib_warning ("parse error '%U'", format_unformat_error,
18777                         line_input);
18778           return -99;
18779         }
18780
18781     out:
18782       vec_free (node_to_find);
18783
18784     }
18785
18786   return 0;
18787 }
18788
18789
18790 static int
18791 script (vat_main_t * vam)
18792 {
18793 #if (VPP_API_TEST_BUILTIN==0)
18794   u8 *s = 0;
18795   char *save_current_file;
18796   unformat_input_t save_input;
18797   jmp_buf save_jump_buf;
18798   u32 save_line_number;
18799
18800   FILE *new_fp, *save_ifp;
18801
18802   if (unformat (vam->input, "%s", &s))
18803     {
18804       new_fp = fopen ((char *) s, "r");
18805       if (new_fp == 0)
18806         {
18807           errmsg ("Couldn't open script file %s", s);
18808           vec_free (s);
18809           return -99;
18810         }
18811     }
18812   else
18813     {
18814       errmsg ("Missing script name");
18815       return -99;
18816     }
18817
18818   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18819   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18820   save_ifp = vam->ifp;
18821   save_line_number = vam->input_line_number;
18822   save_current_file = (char *) vam->current_file;
18823
18824   vam->input_line_number = 0;
18825   vam->ifp = new_fp;
18826   vam->current_file = s;
18827   do_one_file (vam);
18828
18829   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18830   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18831   vam->ifp = save_ifp;
18832   vam->input_line_number = save_line_number;
18833   vam->current_file = (u8 *) save_current_file;
18834   vec_free (s);
18835
18836   return 0;
18837 #else
18838   clib_warning ("use the exec command...");
18839   return -99;
18840 #endif
18841 }
18842
18843 static int
18844 echo (vat_main_t * vam)
18845 {
18846   print (vam->ofp, "%v", vam->input->buffer);
18847   return 0;
18848 }
18849
18850 /* List of API message constructors, CLI names map to api_xxx */
18851 #define foreach_vpe_api_msg                                             \
18852 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18853 _(sw_interface_dump,"")                                                 \
18854 _(sw_interface_set_flags,                                               \
18855   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18856 _(sw_interface_add_del_address,                                         \
18857   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18858 _(sw_interface_set_table,                                               \
18859   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18860 _(sw_interface_set_mpls_enable,                                         \
18861   "<intfc> | sw_if_index [disable | dis]")                              \
18862 _(sw_interface_set_vpath,                                               \
18863   "<intfc> | sw_if_index <id> enable | disable")                        \
18864 _(sw_interface_set_vxlan_bypass,                                        \
18865   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18866 _(sw_interface_set_l2_xconnect,                                         \
18867   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18868   "enable | disable")                                                   \
18869 _(sw_interface_set_l2_bridge,                                           \
18870   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
18871   "[shg <split-horizon-group>] [bvi]\n"                                 \
18872   "enable | disable")                                                   \
18873 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
18874 _(bridge_domain_add_del,                                                \
18875   "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") \
18876 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18877 _(l2fib_add_del,                                                        \
18878   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18879 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
18880 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
18881 _(l2_flags,                                                             \
18882   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18883 _(bridge_flags,                                                         \
18884   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18885 _(tap_connect,                                                          \
18886   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18887 _(tap_modify,                                                           \
18888   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18889 _(tap_delete,                                                           \
18890   "<vpp-if-name> | sw_if_index <id>")                                   \
18891 _(sw_interface_tap_dump, "")                                            \
18892 _(ip_add_del_route,                                                     \
18893   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18894   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18895   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18896   "[multipath] [count <n>]")                                            \
18897 _(ip_mroute_add_del,                                                    \
18898   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18899   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18900 _(mpls_route_add_del,                                                   \
18901   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18902   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18903   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18904   "[multipath] [count <n>]")                                            \
18905 _(mpls_ip_bind_unbind,                                                  \
18906   "<label> <addr/len>")                                                 \
18907 _(mpls_tunnel_add_del,                                                  \
18908   " via <addr> [table-id <n>]\n"                                        \
18909   "sw_if_index <id>] [l2]  [del]")                                      \
18910 _(proxy_arp_add_del,                                                    \
18911   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18912 _(proxy_arp_intfc_enable_disable,                                       \
18913   "<intfc> | sw_if_index <id> enable | disable")                        \
18914 _(sw_interface_set_unnumbered,                                          \
18915   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18916 _(ip_neighbor_add_del,                                                  \
18917   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18918   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18919 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18920 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18921 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18922   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18923   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18924   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18925 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18926 _(reset_fib, "vrf <n> [ipv6]")                                          \
18927 _(dhcp_proxy_config,                                                    \
18928   "svr <v46-address> src <v46-address>\n"                               \
18929    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18930 _(dhcp_proxy_set_vss,                                                   \
18931   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18932 _(dhcp_proxy_dump, "ip6")                                               \
18933 _(dhcp_client_config,                                                   \
18934   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18935 _(set_ip_flow_hash,                                                     \
18936   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18937 _(sw_interface_ip6_enable_disable,                                      \
18938   "<intfc> | sw_if_index <id> enable | disable")                        \
18939 _(sw_interface_ip6_set_link_local_address,                              \
18940   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18941 _(ip6nd_proxy_add_del,                                                  \
18942   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18943 _(ip6nd_proxy_dump, "")                                                 \
18944 _(sw_interface_ip6nd_ra_prefix,                                         \
18945   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18946   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18947   "[nolink] [isno]")                                                    \
18948 _(sw_interface_ip6nd_ra_config,                                         \
18949   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18950   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18951   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18952 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18953 _(l2_patch_add_del,                                                     \
18954   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18955   "enable | disable")                                                   \
18956 _(sr_localsid_add_del,                                                  \
18957   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18958   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18959 _(classify_add_del_table,                                               \
18960   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18961   " [del] [del-chain] mask <mask-value>\n"                              \
18962   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18963   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18964 _(classify_add_del_session,                                             \
18965   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18966   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18967   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18968   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18969 _(classify_set_interface_ip_table,                                      \
18970   "<intfc> | sw_if_index <nn> table <nn>")                              \
18971 _(classify_set_interface_l2_tables,                                     \
18972   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18973   "  [other-table <nn>]")                                               \
18974 _(get_node_index, "node <node-name")                                    \
18975 _(add_node_next, "node <node-name> next <next-node-name>")              \
18976 _(l2tpv3_create_tunnel,                                                 \
18977   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18978   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18979   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18980 _(l2tpv3_set_tunnel_cookies,                                            \
18981   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18982   "[new_remote_cookie <nn>]\n")                                         \
18983 _(l2tpv3_interface_enable_disable,                                      \
18984   "<intfc> | sw_if_index <nn> enable | disable")                        \
18985 _(l2tpv3_set_lookup_key,                                                \
18986   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18987 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18988 _(vxlan_add_del_tunnel,                                                 \
18989   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18990   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18991   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18992 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18993 _(gre_add_del_tunnel,                                                   \
18994   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18995 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18996 _(l2_fib_clear_table, "")                                               \
18997 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18998 _(l2_interface_vlan_tag_rewrite,                                        \
18999   "<intfc> | sw_if_index <nn> \n"                                       \
19000   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
19001   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
19002 _(create_vhost_user_if,                                                 \
19003         "socket <filename> [server] [renumber <dev_instance>] "         \
19004         "[mac <mac_address>] "                                          \
19005         "[mode <interrupt | polling>]")                                 \
19006 _(modify_vhost_user_if,                                                 \
19007         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
19008         "[server] [renumber <dev_instance>] "                           \
19009         "[mode <interrupt | polling>]")                                 \
19010 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
19011 _(sw_interface_vhost_user_dump, "")                                     \
19012 _(show_version, "")                                                     \
19013 _(vxlan_gpe_add_del_tunnel,                                             \
19014   "local <addr> remote <addr> vni <nn>\n"                               \
19015     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
19016   "[next-ethernet] [next-nsh]\n")                                       \
19017 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
19018 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
19019 _(interface_name_renumber,                                              \
19020   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
19021 _(input_acl_set_interface,                                              \
19022   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19023   "  [l2-table <nn>] [del]")                                            \
19024 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
19025 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
19026 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
19027 _(ip_dump, "ipv4 | ipv6")                                               \
19028 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
19029 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
19030   "  spid_id <n> ")                                                     \
19031 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
19032   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
19033   "  integ_alg <alg> integ_key <hex>")                                  \
19034 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
19035   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
19036   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19037   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19038 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
19039 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
19040   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19041   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
19042   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
19043 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
19044 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
19045   "(auth_data 0x<data> | auth_data <data>)")                            \
19046 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
19047   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
19048 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
19049   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
19050   "(local|remote)")                                                     \
19051 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
19052 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
19053 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19054 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19055 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
19056 _(ikev2_initiate_sa_init, "<profile_name>")                             \
19057 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
19058 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
19059 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
19060 _(delete_loopback,"sw_if_index <nn>")                                   \
19061 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19062 _(map_add_domain,                                                       \
19063   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
19064   "ip6-src <ip6addr> "                                                  \
19065   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
19066 _(map_del_domain, "index <n>")                                          \
19067 _(map_add_del_rule,                                                     \
19068   "index <n> psid <n> dst <ip6addr> [del]")                             \
19069 _(map_domain_dump, "")                                                  \
19070 _(map_rule_dump, "index <map-domain>")                                  \
19071 _(want_interface_events,  "enable|disable")                             \
19072 _(want_stats,"enable|disable")                                          \
19073 _(get_first_msg_id, "client <name>")                                    \
19074 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19075 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19076   "fib-id <nn> [ip4][ip6][default]")                                    \
19077 _(get_node_graph, " ")                                                  \
19078 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19079 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19080 _(ioam_disable, "")                                                     \
19081 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19082                             " sw_if_index <sw_if_index> p <priority> "  \
19083                             "w <weight>] [del]")                        \
19084 _(one_add_del_locator, "locator-set <locator_name> "                    \
19085                         "iface <intf> | sw_if_index <sw_if_index> "     \
19086                         "p <priority> w <weight> [del]")                \
19087 _(one_add_del_local_eid,"vni <vni> eid "                                \
19088                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19089                          "locator-set <locator_name> [del]"             \
19090                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19091 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19092 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19093 _(one_enable_disable, "enable|disable")                                 \
19094 _(one_map_register_enable_disable, "enable|disable")                    \
19095 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19096 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19097                                "[seid <seid>] "                         \
19098                                "rloc <locator> p <prio> "               \
19099                                "w <weight> [rloc <loc> ... ] "          \
19100                                "action <action> [del-all]")             \
19101 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19102                           "<local-eid>")                                \
19103 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19104 _(one_use_petr, "ip-address> | disable")                                \
19105 _(one_map_request_mode, "src-dst|dst-only")                             \
19106 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19107 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19108 _(one_locator_set_dump, "[local | remote]")                             \
19109 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19110 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19111                        "[local] | [remote]")                            \
19112 _(one_stats_enable_disable, "enable|disalbe")                           \
19113 _(show_one_stats_enable_disable, "")                                    \
19114 _(one_eid_table_vni_dump, "")                                           \
19115 _(one_eid_table_map_dump, "l2|l3")                                      \
19116 _(one_map_resolver_dump, "")                                            \
19117 _(one_map_server_dump, "")                                              \
19118 _(one_adjacencies_get, "vni <vni>")                                     \
19119 _(show_one_rloc_probe_state, "")                                        \
19120 _(show_one_map_register_state, "")                                      \
19121 _(show_one_status, "")                                                  \
19122 _(one_stats_dump, "")                                                   \
19123 _(one_stats_flush, "")                                                  \
19124 _(one_get_map_request_itr_rlocs, "")                                    \
19125 _(show_one_pitr, "")                                                    \
19126 _(show_one_use_petr, "")                                                \
19127 _(show_one_map_request_mode, "")                                        \
19128 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19129                             " sw_if_index <sw_if_index> p <priority> "  \
19130                             "w <weight>] [del]")                        \
19131 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19132                         "iface <intf> | sw_if_index <sw_if_index> "     \
19133                         "p <priority> w <weight> [del]")                \
19134 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19135                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19136                          "locator-set <locator_name> [del]"             \
19137                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19138 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19139 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19140 _(lisp_enable_disable, "enable|disable")                                \
19141 _(lisp_map_register_enable_disable, "enable|disable")                   \
19142 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19143 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19144                                "[seid <seid>] "                         \
19145                                "rloc <locator> p <prio> "               \
19146                                "w <weight> [rloc <loc> ... ] "          \
19147                                "action <action> [del-all]")             \
19148 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19149                           "<local-eid>")                                \
19150 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19151 _(lisp_use_petr, "<ip-address> | disable")                              \
19152 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19153 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19154 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19155 _(lisp_locator_set_dump, "[local | remote]")                            \
19156 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19157 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19158                        "[local] | [remote]")                            \
19159 _(lisp_eid_table_vni_dump, "")                                          \
19160 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19161 _(lisp_map_resolver_dump, "")                                           \
19162 _(lisp_map_server_dump, "")                                             \
19163 _(lisp_adjacencies_get, "vni <vni>")                                    \
19164 _(gpe_fwd_entry_vnis_get, "")                                           \
19165 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19166 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19167 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19168 _(gpe_get_encap_mode, "")                                               \
19169 _(lisp_gpe_add_del_iface, "up|down")                                    \
19170 _(lisp_gpe_enable_disable, "enable|disable")                            \
19171 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19172   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19173 _(show_lisp_rloc_probe_state, "")                                       \
19174 _(show_lisp_map_register_state, "")                                     \
19175 _(show_lisp_status, "")                                                 \
19176 _(lisp_get_map_request_itr_rlocs, "")                                   \
19177 _(show_lisp_pitr, "")                                                   \
19178 _(show_lisp_use_petr, "")                                               \
19179 _(show_lisp_map_request_mode, "")                                       \
19180 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19181 _(af_packet_delete, "name <host interface name>")                       \
19182 _(policer_add_del, "name <policer name> <params> [del]")                \
19183 _(policer_dump, "[name <policer name>]")                                \
19184 _(policer_classify_set_interface,                                       \
19185   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19186   "  [l2-table <nn>] [del]")                                            \
19187 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19188 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19189     "[master|slave]")                                                   \
19190 _(netmap_delete, "name <interface name>")                               \
19191 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19192 _(mpls_fib_dump, "")                                                    \
19193 _(classify_table_ids, "")                                               \
19194 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19195 _(classify_table_info, "table_id <nn>")                                 \
19196 _(classify_session_dump, "table_id <nn>")                               \
19197 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19198     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19199     "[template_interval <nn>] [udp_checksum]")                          \
19200 _(ipfix_exporter_dump, "")                                              \
19201 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19202 _(ipfix_classify_stream_dump, "")                                       \
19203 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19204 _(ipfix_classify_table_dump, "")                                        \
19205 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19206 _(sw_interface_span_dump, "")                                           \
19207 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19208 _(pg_create_interface, "if_id <nn>")                                    \
19209 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19210 _(pg_enable_disable, "[stream <id>] disable")                           \
19211 _(ip_source_and_port_range_check_add_del,                               \
19212   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19213 _(ip_source_and_port_range_check_interface_add_del,                     \
19214   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19215   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19216 _(ipsec_gre_add_del_tunnel,                                             \
19217   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19218 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19219 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19220 _(l2_interface_pbb_tag_rewrite,                                         \
19221   "<intfc> | sw_if_index <nn> \n"                                       \
19222   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19223   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19224 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19225 _(flow_classify_set_interface,                                          \
19226   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19227 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19228 _(ip_fib_dump, "")                                                      \
19229 _(ip_mfib_dump, "")                                                     \
19230 _(ip6_fib_dump, "")                                                     \
19231 _(ip6_mfib_dump, "")                                                    \
19232 _(feature_enable_disable, "arc_name <arc_name> "                        \
19233   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19234 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19235 "[disable]")                                                            \
19236 _(l2_xconnect_dump, "")                                                 \
19237 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19238 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19239 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19240
19241 /* List of command functions, CLI names map directly to functions */
19242 #define foreach_cli_function                                    \
19243 _(comment, "usage: comment <ignore-rest-of-line>")              \
19244 _(dump_interface_table, "usage: dump_interface_table")          \
19245 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19246 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19247 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19248 _(dump_stats_table, "usage: dump_stats_table")                  \
19249 _(dump_macro_table, "usage: dump_macro_table ")                 \
19250 _(dump_node_table, "usage: dump_node_table")                    \
19251 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19252 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19253 _(echo, "usage: echo <message>")                                \
19254 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19255 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19256 _(help, "usage: help")                                          \
19257 _(q, "usage: quit")                                             \
19258 _(quit, "usage: quit")                                          \
19259 _(search_node_table, "usage: search_node_table <name>...")      \
19260 _(set, "usage: set <variable-name> <value>")                    \
19261 _(script, "usage: script <file-name>")                          \
19262 _(unset, "usage: unset <variable-name>")
19263
19264 #define _(N,n)                                  \
19265     static void vl_api_##n##_t_handler_uni      \
19266     (vl_api_##n##_t * mp)                       \
19267     {                                           \
19268         vat_main_t * vam = &vat_main;           \
19269         if (vam->json_output) {                 \
19270             vl_api_##n##_t_handler_json(mp);    \
19271         } else {                                \
19272             vl_api_##n##_t_handler(mp);         \
19273         }                                       \
19274     }
19275 foreach_vpe_api_reply_msg;
19276 #if VPP_API_TEST_BUILTIN == 0
19277 foreach_standalone_reply_msg;
19278 #endif
19279 #undef _
19280
19281 void
19282 vat_api_hookup (vat_main_t * vam)
19283 {
19284 #define _(N,n)                                                  \
19285     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19286                            vl_api_##n##_t_handler_uni,          \
19287                            vl_noop_handler,                     \
19288                            vl_api_##n##_t_endian,               \
19289                            vl_api_##n##_t_print,                \
19290                            sizeof(vl_api_##n##_t), 1);
19291   foreach_vpe_api_reply_msg;
19292 #if VPP_API_TEST_BUILTIN == 0
19293   foreach_standalone_reply_msg;
19294 #endif
19295 #undef _
19296
19297 #if (VPP_API_TEST_BUILTIN==0)
19298   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19299
19300   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19301
19302   vam->function_by_name = hash_create_string (0, sizeof (uword));
19303
19304   vam->help_by_name = hash_create_string (0, sizeof (uword));
19305 #endif
19306
19307   /* API messages we can send */
19308 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19309   foreach_vpe_api_msg;
19310 #undef _
19311
19312   /* Help strings */
19313 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19314   foreach_vpe_api_msg;
19315 #undef _
19316
19317   /* CLI functions */
19318 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19319   foreach_cli_function;
19320 #undef _
19321
19322   /* Help strings */
19323 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19324   foreach_cli_function;
19325 #undef _
19326 }
19327
19328 #if VPP_API_TEST_BUILTIN
19329 static clib_error_t *
19330 vat_api_hookup_shim (vlib_main_t * vm)
19331 {
19332   vat_api_hookup (&vat_main);
19333   return 0;
19334 }
19335
19336 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19337 #endif
19338
19339 /*
19340  * fd.io coding-style-patch-verification: ON
19341  *
19342  * Local Variables:
19343  * eval: (c-set-style "gnu")
19344  * End:
19345  */