Repair plugin binary API message numbering
[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/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.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 static uword
115 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
116 {
117   vat_main_t *vam = va_arg (*args, vat_main_t *);
118   u32 *result = va_arg (*args, u32 *);
119   u8 *if_name;
120   uword *p;
121
122   if (!unformat (input, "%s", &if_name))
123     return 0;
124
125   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
126   if (p == 0)
127     return 0;
128   *result = p[0];
129   return 1;
130 }
131
132 #if VPP_API_TEST_BUILTIN == 0
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 #endif /* VPP_API_TEST_BUILTIN */
390
391 static uword
392 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "kbps"))
397     *r = SSE2_QOS_RATE_KBPS;
398   else if (unformat (input, "pps"))
399     *r = SSE2_QOS_RATE_PPS;
400   else
401     return 0;
402   return 1;
403 }
404
405 static uword
406 unformat_policer_round_type (unformat_input_t * input, va_list * args)
407 {
408   u8 *r = va_arg (*args, u8 *);
409
410   if (unformat (input, "closest"))
411     *r = SSE2_QOS_ROUND_TO_CLOSEST;
412   else if (unformat (input, "up"))
413     *r = SSE2_QOS_ROUND_TO_UP;
414   else if (unformat (input, "down"))
415     *r = SSE2_QOS_ROUND_TO_DOWN;
416   else
417     return 0;
418   return 1;
419 }
420
421 static uword
422 unformat_policer_type (unformat_input_t * input, va_list * args)
423 {
424   u8 *r = va_arg (*args, u8 *);
425
426   if (unformat (input, "1r2c"))
427     *r = SSE2_QOS_POLICER_TYPE_1R2C;
428   else if (unformat (input, "1r3c"))
429     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
430   else if (unformat (input, "2r3c-2698"))
431     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
432   else if (unformat (input, "2r3c-4115"))
433     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
434   else if (unformat (input, "2r3c-mef5cf1"))
435     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
436   else
437     return 0;
438   return 1;
439 }
440
441 static uword
442 unformat_dscp (unformat_input_t * input, va_list * va)
443 {
444   u8 *r = va_arg (*va, u8 *);
445
446   if (0);
447 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
448   foreach_vnet_dscp
449 #undef _
450     else
451     return 0;
452   return 1;
453 }
454
455 static uword
456 unformat_policer_action_type (unformat_input_t * input, va_list * va)
457 {
458   sse2_qos_pol_action_params_st *a
459     = va_arg (*va, sse2_qos_pol_action_params_st *);
460
461   if (unformat (input, "drop"))
462     a->action_type = SSE2_QOS_ACTION_DROP;
463   else if (unformat (input, "transmit"))
464     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
465   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
466     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
467   else
468     return 0;
469   return 1;
470 }
471
472 static uword
473 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
474 {
475   u32 *r = va_arg (*va, u32 *);
476   u32 tid;
477
478   if (unformat (input, "ip4"))
479     tid = POLICER_CLASSIFY_TABLE_IP4;
480   else if (unformat (input, "ip6"))
481     tid = POLICER_CLASSIFY_TABLE_IP6;
482   else if (unformat (input, "l2"))
483     tid = POLICER_CLASSIFY_TABLE_L2;
484   else
485     return 0;
486
487   *r = tid;
488   return 1;
489 }
490
491 static uword
492 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
493 {
494   u32 *r = va_arg (*va, u32 *);
495   u32 tid;
496
497   if (unformat (input, "ip4"))
498     tid = FLOW_CLASSIFY_TABLE_IP4;
499   else if (unformat (input, "ip6"))
500     tid = FLOW_CLASSIFY_TABLE_IP6;
501   else
502     return 0;
503
504   *r = tid;
505   return 1;
506 }
507
508 #if (VPP_API_TEST_BUILTIN==0)
509 u8 *
510 format_ip4_address (u8 * s, va_list * args)
511 {
512   u8 *a = va_arg (*args, u8 *);
513   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
514 }
515
516 u8 *
517 format_ip6_address (u8 * s, va_list * args)
518 {
519   ip6_address_t *a = va_arg (*args, ip6_address_t *);
520   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
521
522   i_max_n_zero = ARRAY_LEN (a->as_u16);
523   max_n_zeros = 0;
524   i_first_zero = i_max_n_zero;
525   n_zeros = 0;
526   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
527     {
528       u32 is_zero = a->as_u16[i] == 0;
529       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
530         {
531           i_first_zero = i;
532           n_zeros = 0;
533         }
534       n_zeros += is_zero;
535       if ((!is_zero && n_zeros > max_n_zeros)
536           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
537         {
538           i_max_n_zero = i_first_zero;
539           max_n_zeros = n_zeros;
540           i_first_zero = ARRAY_LEN (a->as_u16);
541           n_zeros = 0;
542         }
543     }
544
545   last_double_colon = 0;
546   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
547     {
548       if (i == i_max_n_zero && max_n_zeros > 1)
549         {
550           s = format (s, "::");
551           i += max_n_zeros - 1;
552           last_double_colon = 1;
553         }
554       else
555         {
556           s = format (s, "%s%x",
557                       (last_double_colon || i == 0) ? "" : ":",
558                       clib_net_to_host_u16 (a->as_u16[i]));
559           last_double_colon = 0;
560         }
561     }
562
563   return s;
564 }
565
566 /* Format an IP46 address. */
567 u8 *
568 format_ip46_address (u8 * s, va_list * args)
569 {
570   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
571   ip46_type_t type = va_arg (*args, ip46_type_t);
572   int is_ip4 = 1;
573
574   switch (type)
575     {
576     case IP46_TYPE_ANY:
577       is_ip4 = ip46_address_is_ip4 (ip46);
578       break;
579     case IP46_TYPE_IP4:
580       is_ip4 = 1;
581       break;
582     case IP46_TYPE_IP6:
583       is_ip4 = 0;
584       break;
585     }
586
587   return is_ip4 ?
588     format (s, "%U", format_ip4_address, &ip46->ip4) :
589     format (s, "%U", format_ip6_address, &ip46->ip6);
590 }
591
592 u8 *
593 format_ethernet_address (u8 * s, va_list * args)
594 {
595   u8 *a = va_arg (*args, u8 *);
596
597   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
598                  a[0], a[1], a[2], a[3], a[4], a[5]);
599 }
600 #endif
601
602 static void
603 increment_v4_address (ip4_address_t * a)
604 {
605   u32 v;
606
607   v = ntohl (a->as_u32) + 1;
608   a->as_u32 = ntohl (v);
609 }
610
611 static void
612 increment_v6_address (ip6_address_t * a)
613 {
614   u64 v0, v1;
615
616   v0 = clib_net_to_host_u64 (a->as_u64[0]);
617   v1 = clib_net_to_host_u64 (a->as_u64[1]);
618
619   v1 += 1;
620   if (v1 == 0)
621     v0 += 1;
622   a->as_u64[0] = clib_net_to_host_u64 (v0);
623   a->as_u64[1] = clib_net_to_host_u64 (v1);
624 }
625
626 static void
627 increment_mac_address (u64 * mac)
628 {
629   u64 tmp = *mac;
630
631   tmp = clib_net_to_host_u64 (tmp);
632   tmp += 1 << 16;               /* skip unused (least significant) octets */
633   tmp = clib_host_to_net_u64 (tmp);
634   *mac = tmp;
635 }
636
637 static void vl_api_create_loopback_reply_t_handler
638   (vl_api_create_loopback_reply_t * mp)
639 {
640   vat_main_t *vam = &vat_main;
641   i32 retval = ntohl (mp->retval);
642
643   vam->retval = retval;
644   vam->regenerate_interface_table = 1;
645   vam->sw_if_index = ntohl (mp->sw_if_index);
646   vam->result_ready = 1;
647 }
648
649 static void vl_api_create_loopback_reply_t_handler_json
650   (vl_api_create_loopback_reply_t * mp)
651 {
652   vat_main_t *vam = &vat_main;
653   vat_json_node_t node;
654
655   vat_json_init_object (&node);
656   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
657   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
658
659   vat_json_print (vam->ofp, &node);
660   vat_json_free (&node);
661   vam->retval = ntohl (mp->retval);
662   vam->result_ready = 1;
663 }
664
665 static void vl_api_af_packet_create_reply_t_handler
666   (vl_api_af_packet_create_reply_t * mp)
667 {
668   vat_main_t *vam = &vat_main;
669   i32 retval = ntohl (mp->retval);
670
671   vam->retval = retval;
672   vam->regenerate_interface_table = 1;
673   vam->sw_if_index = ntohl (mp->sw_if_index);
674   vam->result_ready = 1;
675 }
676
677 static void vl_api_af_packet_create_reply_t_handler_json
678   (vl_api_af_packet_create_reply_t * mp)
679 {
680   vat_main_t *vam = &vat_main;
681   vat_json_node_t node;
682
683   vat_json_init_object (&node);
684   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
685   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
686
687   vat_json_print (vam->ofp, &node);
688   vat_json_free (&node);
689
690   vam->retval = ntohl (mp->retval);
691   vam->result_ready = 1;
692 }
693
694 static void vl_api_create_vlan_subif_reply_t_handler
695   (vl_api_create_vlan_subif_reply_t * mp)
696 {
697   vat_main_t *vam = &vat_main;
698   i32 retval = ntohl (mp->retval);
699
700   vam->retval = retval;
701   vam->regenerate_interface_table = 1;
702   vam->sw_if_index = ntohl (mp->sw_if_index);
703   vam->result_ready = 1;
704 }
705
706 static void vl_api_create_vlan_subif_reply_t_handler_json
707   (vl_api_create_vlan_subif_reply_t * mp)
708 {
709   vat_main_t *vam = &vat_main;
710   vat_json_node_t node;
711
712   vat_json_init_object (&node);
713   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
714   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
715
716   vat_json_print (vam->ofp, &node);
717   vat_json_free (&node);
718
719   vam->retval = ntohl (mp->retval);
720   vam->result_ready = 1;
721 }
722
723 static void vl_api_create_subif_reply_t_handler
724   (vl_api_create_subif_reply_t * mp)
725 {
726   vat_main_t *vam = &vat_main;
727   i32 retval = ntohl (mp->retval);
728
729   vam->retval = retval;
730   vam->regenerate_interface_table = 1;
731   vam->sw_if_index = ntohl (mp->sw_if_index);
732   vam->result_ready = 1;
733 }
734
735 static void vl_api_create_subif_reply_t_handler_json
736   (vl_api_create_subif_reply_t * mp)
737 {
738   vat_main_t *vam = &vat_main;
739   vat_json_node_t node;
740
741   vat_json_init_object (&node);
742   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
743   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
744
745   vat_json_print (vam->ofp, &node);
746   vat_json_free (&node);
747
748   vam->retval = ntohl (mp->retval);
749   vam->result_ready = 1;
750 }
751
752 static void vl_api_interface_name_renumber_reply_t_handler
753   (vl_api_interface_name_renumber_reply_t * mp)
754 {
755   vat_main_t *vam = &vat_main;
756   i32 retval = ntohl (mp->retval);
757
758   vam->retval = retval;
759   vam->regenerate_interface_table = 1;
760   vam->result_ready = 1;
761 }
762
763 static void vl_api_interface_name_renumber_reply_t_handler_json
764   (vl_api_interface_name_renumber_reply_t * mp)
765 {
766   vat_main_t *vam = &vat_main;
767   vat_json_node_t node;
768
769   vat_json_init_object (&node);
770   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
771
772   vat_json_print (vam->ofp, &node);
773   vat_json_free (&node);
774
775   vam->retval = ntohl (mp->retval);
776   vam->result_ready = 1;
777 }
778
779 /*
780  * Special-case: build the interface table, maintain
781  * the next loopback sw_if_index vbl.
782  */
783 static void vl_api_sw_interface_details_t_handler
784   (vl_api_sw_interface_details_t * mp)
785 {
786   vat_main_t *vam = &vat_main;
787   u8 *s = format (0, "%s%c", mp->interface_name, 0);
788
789   hash_set_mem (vam->sw_if_index_by_interface_name, s,
790                 ntohl (mp->sw_if_index));
791
792   /* In sub interface case, fill the sub interface table entry */
793   if (mp->sw_if_index != mp->sup_sw_if_index)
794     {
795       sw_interface_subif_t *sub = NULL;
796
797       vec_add2 (vam->sw_if_subif_table, sub, 1);
798
799       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
800       strncpy ((char *) sub->interface_name, (char *) s,
801                vec_len (sub->interface_name));
802       sub->sw_if_index = ntohl (mp->sw_if_index);
803       sub->sub_id = ntohl (mp->sub_id);
804
805       sub->sub_dot1ad = mp->sub_dot1ad;
806       sub->sub_number_of_tags = mp->sub_number_of_tags;
807       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
808       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
809       sub->sub_exact_match = mp->sub_exact_match;
810       sub->sub_default = mp->sub_default;
811       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
812       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
813
814       /* vlan tag rewrite */
815       sub->vtr_op = ntohl (mp->vtr_op);
816       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
817       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
818       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
819     }
820 }
821
822 static void vl_api_sw_interface_details_t_handler_json
823   (vl_api_sw_interface_details_t * mp)
824 {
825   vat_main_t *vam = &vat_main;
826   vat_json_node_t *node = NULL;
827
828   if (VAT_JSON_ARRAY != vam->json_tree.type)
829     {
830       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
831       vat_json_init_array (&vam->json_tree);
832     }
833   node = vat_json_array_add (&vam->json_tree);
834
835   vat_json_init_object (node);
836   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
837   vat_json_object_add_uint (node, "sup_sw_if_index",
838                             ntohl (mp->sup_sw_if_index));
839   vat_json_object_add_uint (node, "l2_address_length",
840                             ntohl (mp->l2_address_length));
841   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
842                              sizeof (mp->l2_address));
843   vat_json_object_add_string_copy (node, "interface_name",
844                                    mp->interface_name);
845   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
846   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
847   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
848   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
849   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
850   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
851   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
852   vat_json_object_add_uint (node, "sub_number_of_tags",
853                             mp->sub_number_of_tags);
854   vat_json_object_add_uint (node, "sub_outer_vlan_id",
855                             ntohs (mp->sub_outer_vlan_id));
856   vat_json_object_add_uint (node, "sub_inner_vlan_id",
857                             ntohs (mp->sub_inner_vlan_id));
858   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
859   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
860   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
861                             mp->sub_outer_vlan_id_any);
862   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
863                             mp->sub_inner_vlan_id_any);
864   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
865   vat_json_object_add_uint (node, "vtr_push_dot1q",
866                             ntohl (mp->vtr_push_dot1q));
867   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
868   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
869 }
870
871 static void vl_api_sw_interface_set_flags_t_handler
872   (vl_api_sw_interface_set_flags_t * mp)
873 {
874   vat_main_t *vam = &vat_main;
875   if (vam->interface_event_display)
876     errmsg ("interface flags: sw_if_index %d %s %s",
877             ntohl (mp->sw_if_index),
878             mp->admin_up_down ? "admin-up" : "admin-down",
879             mp->link_up_down ? "link-up" : "link-down");
880 }
881
882 static void vl_api_sw_interface_set_flags_t_handler_json
883   (vl_api_sw_interface_set_flags_t * mp)
884 {
885   /* JSON output not supported */
886 }
887
888 static void
889 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
890 {
891   vat_main_t *vam = &vat_main;
892   i32 retval = ntohl (mp->retval);
893
894   vam->retval = retval;
895   vam->shmem_result = (u8 *) mp->reply_in_shmem;
896   vam->result_ready = 1;
897 }
898
899 static void
900 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
901 {
902   vat_main_t *vam = &vat_main;
903   vat_json_node_t node;
904   api_main_t *am = &api_main;
905   void *oldheap;
906   u8 *reply;
907
908   vat_json_init_object (&node);
909   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
910   vat_json_object_add_uint (&node, "reply_in_shmem",
911                             ntohl (mp->reply_in_shmem));
912   /* Toss the shared-memory original... */
913   pthread_mutex_lock (&am->vlib_rp->mutex);
914   oldheap = svm_push_data_heap (am->vlib_rp);
915
916   reply = (u8 *) (mp->reply_in_shmem);
917   vec_free (reply);
918
919   svm_pop_heap (oldheap);
920   pthread_mutex_unlock (&am->vlib_rp->mutex);
921
922   vat_json_print (vam->ofp, &node);
923   vat_json_free (&node);
924
925   vam->retval = ntohl (mp->retval);
926   vam->result_ready = 1;
927 }
928
929 static void
930 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
931 {
932   vat_main_t *vam = &vat_main;
933   i32 retval = ntohl (mp->retval);
934
935   vam->retval = retval;
936   vam->cmd_reply = mp->reply;
937   vam->result_ready = 1;
938 }
939
940 static void
941 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_string_copy (&node, "reply", mp->reply);
949
950   vat_json_print (vam->ofp, &node);
951   vat_json_free (&node);
952
953   vam->retval = ntohl (mp->retval);
954   vam->result_ready = 1;
955 }
956
957 static void vl_api_classify_add_del_table_reply_t_handler
958   (vl_api_classify_add_del_table_reply_t * mp)
959 {
960   vat_main_t *vam = &vat_main;
961   i32 retval = ntohl (mp->retval);
962   if (vam->async_mode)
963     {
964       vam->async_errors += (retval < 0);
965     }
966   else
967     {
968       vam->retval = retval;
969       if (retval == 0 &&
970           ((mp->new_table_index != 0xFFFFFFFF) ||
971            (mp->skip_n_vectors != 0xFFFFFFFF) ||
972            (mp->match_n_vectors != 0xFFFFFFFF)))
973         /*
974          * Note: this is just barely thread-safe, depends on
975          * the main thread spinning waiting for an answer...
976          */
977         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
978                 ntohl (mp->new_table_index),
979                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
980       vam->result_ready = 1;
981     }
982 }
983
984 static void vl_api_classify_add_del_table_reply_t_handler_json
985   (vl_api_classify_add_del_table_reply_t * mp)
986 {
987   vat_main_t *vam = &vat_main;
988   vat_json_node_t node;
989
990   vat_json_init_object (&node);
991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
992   vat_json_object_add_uint (&node, "new_table_index",
993                             ntohl (mp->new_table_index));
994   vat_json_object_add_uint (&node, "skip_n_vectors",
995                             ntohl (mp->skip_n_vectors));
996   vat_json_object_add_uint (&node, "match_n_vectors",
997                             ntohl (mp->match_n_vectors));
998
999   vat_json_print (vam->ofp, &node);
1000   vat_json_free (&node);
1001
1002   vam->retval = ntohl (mp->retval);
1003   vam->result_ready = 1;
1004 }
1005
1006 static void vl_api_get_node_index_reply_t_handler
1007   (vl_api_get_node_index_reply_t * mp)
1008 {
1009   vat_main_t *vam = &vat_main;
1010   i32 retval = ntohl (mp->retval);
1011   if (vam->async_mode)
1012     {
1013       vam->async_errors += (retval < 0);
1014     }
1015   else
1016     {
1017       vam->retval = retval;
1018       if (retval == 0)
1019         errmsg ("node index %d", ntohl (mp->node_index));
1020       vam->result_ready = 1;
1021     }
1022 }
1023
1024 static void vl_api_get_node_index_reply_t_handler_json
1025   (vl_api_get_node_index_reply_t * mp)
1026 {
1027   vat_main_t *vam = &vat_main;
1028   vat_json_node_t node;
1029
1030   vat_json_init_object (&node);
1031   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1032   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1033
1034   vat_json_print (vam->ofp, &node);
1035   vat_json_free (&node);
1036
1037   vam->retval = ntohl (mp->retval);
1038   vam->result_ready = 1;
1039 }
1040
1041 static void vl_api_get_next_index_reply_t_handler
1042   (vl_api_get_next_index_reply_t * mp)
1043 {
1044   vat_main_t *vam = &vat_main;
1045   i32 retval = ntohl (mp->retval);
1046   if (vam->async_mode)
1047     {
1048       vam->async_errors += (retval < 0);
1049     }
1050   else
1051     {
1052       vam->retval = retval;
1053       if (retval == 0)
1054         errmsg ("next node index %d", ntohl (mp->next_index));
1055       vam->result_ready = 1;
1056     }
1057 }
1058
1059 static void vl_api_get_next_index_reply_t_handler_json
1060   (vl_api_get_next_index_reply_t * mp)
1061 {
1062   vat_main_t *vam = &vat_main;
1063   vat_json_node_t node;
1064
1065   vat_json_init_object (&node);
1066   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1067   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1068
1069   vat_json_print (vam->ofp, &node);
1070   vat_json_free (&node);
1071
1072   vam->retval = ntohl (mp->retval);
1073   vam->result_ready = 1;
1074 }
1075
1076 static void vl_api_add_node_next_reply_t_handler
1077   (vl_api_add_node_next_reply_t * mp)
1078 {
1079   vat_main_t *vam = &vat_main;
1080   i32 retval = ntohl (mp->retval);
1081   if (vam->async_mode)
1082     {
1083       vam->async_errors += (retval < 0);
1084     }
1085   else
1086     {
1087       vam->retval = retval;
1088       if (retval == 0)
1089         errmsg ("next index %d", ntohl (mp->next_index));
1090       vam->result_ready = 1;
1091     }
1092 }
1093
1094 static void vl_api_add_node_next_reply_t_handler_json
1095   (vl_api_add_node_next_reply_t * mp)
1096 {
1097   vat_main_t *vam = &vat_main;
1098   vat_json_node_t node;
1099
1100   vat_json_init_object (&node);
1101   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1102   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_show_version_reply_t_handler
1112   (vl_api_show_version_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116
1117   if (retval >= 0)
1118     {
1119       errmsg ("        program: %s", mp->program);
1120       errmsg ("        version: %s", mp->version);
1121       errmsg ("     build date: %s", mp->build_date);
1122       errmsg ("build directory: %s", mp->build_directory);
1123     }
1124   vam->retval = retval;
1125   vam->result_ready = 1;
1126 }
1127
1128 static void vl_api_show_version_reply_t_handler_json
1129   (vl_api_show_version_reply_t * mp)
1130 {
1131   vat_main_t *vam = &vat_main;
1132   vat_json_node_t node;
1133
1134   vat_json_init_object (&node);
1135   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1136   vat_json_object_add_string_copy (&node, "program", mp->program);
1137   vat_json_object_add_string_copy (&node, "version", mp->version);
1138   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1139   vat_json_object_add_string_copy (&node, "build_directory",
1140                                    mp->build_directory);
1141
1142   vat_json_print (vam->ofp, &node);
1143   vat_json_free (&node);
1144
1145   vam->retval = ntohl (mp->retval);
1146   vam->result_ready = 1;
1147 }
1148
1149 static void
1150 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1151 {
1152   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1153           mp->mac_ip ? "mac/ip binding" : "address resolution",
1154           format_ip4_address, &mp->address,
1155           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1156 }
1157
1158 static void
1159 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1160 {
1161   /* JSON output not supported */
1162 }
1163
1164 static void
1165 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1166 {
1167   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1168           mp->mac_ip ? "mac/ip binding" : "address resolution",
1169           format_ip6_address, mp->address,
1170           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1171 }
1172
1173 static void
1174 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1175 {
1176   /* JSON output not supported */
1177 }
1178
1179 /*
1180  * Special-case: build the bridge domain table, maintain
1181  * the next bd id vbl.
1182  */
1183 static void vl_api_bridge_domain_details_t_handler
1184   (vl_api_bridge_domain_details_t * mp)
1185 {
1186   vat_main_t *vam = &vat_main;
1187   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1188
1189   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1190          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1191
1192   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1193          ntohl (mp->bd_id), mp->learn, mp->forward,
1194          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1195
1196   if (n_sw_ifs)
1197     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1198 }
1199
1200 static void vl_api_bridge_domain_details_t_handler_json
1201   (vl_api_bridge_domain_details_t * mp)
1202 {
1203   vat_main_t *vam = &vat_main;
1204   vat_json_node_t *node, *array = NULL;
1205
1206   if (VAT_JSON_ARRAY != vam->json_tree.type)
1207     {
1208       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1209       vat_json_init_array (&vam->json_tree);
1210     }
1211   node = vat_json_array_add (&vam->json_tree);
1212
1213   vat_json_init_object (node);
1214   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1215   vat_json_object_add_uint (node, "flood", mp->flood);
1216   vat_json_object_add_uint (node, "forward", mp->forward);
1217   vat_json_object_add_uint (node, "learn", mp->learn);
1218   vat_json_object_add_uint (node, "bvi_sw_if_index",
1219                             ntohl (mp->bvi_sw_if_index));
1220   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1221   array = vat_json_object_add (node, "sw_if");
1222   vat_json_init_array (array);
1223 }
1224
1225 /*
1226  * Special-case: build the bridge domain sw if table.
1227  */
1228 static void vl_api_bridge_domain_sw_if_details_t_handler
1229   (vl_api_bridge_domain_sw_if_details_t * mp)
1230 {
1231   vat_main_t *vam = &vat_main;
1232   hash_pair_t *p;
1233   u8 *sw_if_name = 0;
1234   u32 sw_if_index;
1235
1236   sw_if_index = ntohl (mp->sw_if_index);
1237   /* *INDENT-OFF* */
1238   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1239   ({
1240     if ((u32) p->value[0] == sw_if_index)
1241       {
1242         sw_if_name = (u8 *)(p->key);
1243         break;
1244       }
1245   }));
1246   /* *INDENT-ON* */
1247
1248   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1249          mp->shg, sw_if_name ? (char *) sw_if_name :
1250          "sw_if_index not found!");
1251 }
1252
1253 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1254   (vl_api_bridge_domain_sw_if_details_t * mp)
1255 {
1256   vat_main_t *vam = &vat_main;
1257   vat_json_node_t *node = NULL;
1258   uword last_index = 0;
1259
1260   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1261   ASSERT (vec_len (vam->json_tree.array) >= 1);
1262   last_index = vec_len (vam->json_tree.array) - 1;
1263   node = &vam->json_tree.array[last_index];
1264   node = vat_json_object_get_element (node, "sw_if");
1265   ASSERT (NULL != node);
1266   node = vat_json_array_add (node);
1267
1268   vat_json_init_object (node);
1269   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1270   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1271   vat_json_object_add_uint (node, "shg", mp->shg);
1272 }
1273
1274 static void vl_api_control_ping_reply_t_handler
1275   (vl_api_control_ping_reply_t * mp)
1276 {
1277   vat_main_t *vam = &vat_main;
1278   i32 retval = ntohl (mp->retval);
1279   if (vam->async_mode)
1280     {
1281       vam->async_errors += (retval < 0);
1282     }
1283   else
1284     {
1285       vam->retval = retval;
1286       vam->result_ready = 1;
1287     }
1288 }
1289
1290 static void vl_api_control_ping_reply_t_handler_json
1291   (vl_api_control_ping_reply_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   i32 retval = ntohl (mp->retval);
1295
1296   if (VAT_JSON_NONE != vam->json_tree.type)
1297     {
1298       vat_json_print (vam->ofp, &vam->json_tree);
1299       vat_json_free (&vam->json_tree);
1300       vam->json_tree.type = VAT_JSON_NONE;
1301     }
1302   else
1303     {
1304       /* just print [] */
1305       vat_json_init_array (&vam->json_tree);
1306       vat_json_print (vam->ofp, &vam->json_tree);
1307       vam->json_tree.type = VAT_JSON_NONE;
1308     }
1309
1310   vam->retval = retval;
1311   vam->result_ready = 1;
1312 }
1313
1314 static void
1315 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1316 {
1317   vat_main_t *vam = &vat_main;
1318   i32 retval = ntohl (mp->retval);
1319   if (vam->async_mode)
1320     {
1321       vam->async_errors += (retval < 0);
1322     }
1323   else
1324     {
1325       vam->retval = retval;
1326       vam->result_ready = 1;
1327     }
1328 }
1329
1330 static void vl_api_l2_flags_reply_t_handler_json
1331   (vl_api_l2_flags_reply_t * mp)
1332 {
1333   vat_main_t *vam = &vat_main;
1334   vat_json_node_t node;
1335
1336   vat_json_init_object (&node);
1337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1338   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1339                             ntohl (mp->resulting_feature_bitmap));
1340
1341   vat_json_print (vam->ofp, &node);
1342   vat_json_free (&node);
1343
1344   vam->retval = ntohl (mp->retval);
1345   vam->result_ready = 1;
1346 }
1347
1348 static void vl_api_bridge_flags_reply_t_handler
1349   (vl_api_bridge_flags_reply_t * mp)
1350 {
1351   vat_main_t *vam = &vat_main;
1352   i32 retval = ntohl (mp->retval);
1353   if (vam->async_mode)
1354     {
1355       vam->async_errors += (retval < 0);
1356     }
1357   else
1358     {
1359       vam->retval = retval;
1360       vam->result_ready = 1;
1361     }
1362 }
1363
1364 static void vl_api_bridge_flags_reply_t_handler_json
1365   (vl_api_bridge_flags_reply_t * mp)
1366 {
1367   vat_main_t *vam = &vat_main;
1368   vat_json_node_t node;
1369
1370   vat_json_init_object (&node);
1371   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1372   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1373                             ntohl (mp->resulting_feature_bitmap));
1374
1375   vat_json_print (vam->ofp, &node);
1376   vat_json_free (&node);
1377
1378   vam->retval = ntohl (mp->retval);
1379   vam->result_ready = 1;
1380 }
1381
1382 static void vl_api_tap_connect_reply_t_handler
1383   (vl_api_tap_connect_reply_t * mp)
1384 {
1385   vat_main_t *vam = &vat_main;
1386   i32 retval = ntohl (mp->retval);
1387   if (vam->async_mode)
1388     {
1389       vam->async_errors += (retval < 0);
1390     }
1391   else
1392     {
1393       vam->retval = retval;
1394       vam->sw_if_index = ntohl (mp->sw_if_index);
1395       vam->result_ready = 1;
1396     }
1397
1398 }
1399
1400 static void vl_api_tap_connect_reply_t_handler_json
1401   (vl_api_tap_connect_reply_t * mp)
1402 {
1403   vat_main_t *vam = &vat_main;
1404   vat_json_node_t node;
1405
1406   vat_json_init_object (&node);
1407   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1408   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1409
1410   vat_json_print (vam->ofp, &node);
1411   vat_json_free (&node);
1412
1413   vam->retval = ntohl (mp->retval);
1414   vam->result_ready = 1;
1415
1416 }
1417
1418 static void
1419 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1420 {
1421   vat_main_t *vam = &vat_main;
1422   i32 retval = ntohl (mp->retval);
1423   if (vam->async_mode)
1424     {
1425       vam->async_errors += (retval < 0);
1426     }
1427   else
1428     {
1429       vam->retval = retval;
1430       vam->sw_if_index = ntohl (mp->sw_if_index);
1431       vam->result_ready = 1;
1432     }
1433 }
1434
1435 static void vl_api_tap_modify_reply_t_handler_json
1436   (vl_api_tap_modify_reply_t * mp)
1437 {
1438   vat_main_t *vam = &vat_main;
1439   vat_json_node_t node;
1440
1441   vat_json_init_object (&node);
1442   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1443   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1444
1445   vat_json_print (vam->ofp, &node);
1446   vat_json_free (&node);
1447
1448   vam->retval = ntohl (mp->retval);
1449   vam->result_ready = 1;
1450 }
1451
1452 static void
1453 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1454 {
1455   vat_main_t *vam = &vat_main;
1456   i32 retval = ntohl (mp->retval);
1457   if (vam->async_mode)
1458     {
1459       vam->async_errors += (retval < 0);
1460     }
1461   else
1462     {
1463       vam->retval = retval;
1464       vam->result_ready = 1;
1465     }
1466 }
1467
1468 static void vl_api_tap_delete_reply_t_handler_json
1469   (vl_api_tap_delete_reply_t * mp)
1470 {
1471   vat_main_t *vam = &vat_main;
1472   vat_json_node_t node;
1473
1474   vat_json_init_object (&node);
1475   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1476
1477   vat_json_print (vam->ofp, &node);
1478   vat_json_free (&node);
1479
1480   vam->retval = ntohl (mp->retval);
1481   vam->result_ready = 1;
1482 }
1483
1484 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1485   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1486 {
1487   vat_main_t *vam = &vat_main;
1488   i32 retval = ntohl (mp->retval);
1489   if (vam->async_mode)
1490     {
1491       vam->async_errors += (retval < 0);
1492     }
1493   else
1494     {
1495       vam->retval = retval;
1496       vam->result_ready = 1;
1497     }
1498 }
1499
1500 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1501   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1502 {
1503   vat_main_t *vam = &vat_main;
1504   vat_json_node_t node;
1505
1506   vat_json_init_object (&node);
1507   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1508   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1509                             ntohl (mp->sw_if_index));
1510
1511   vat_json_print (vam->ofp, &node);
1512   vat_json_free (&node);
1513
1514   vam->retval = ntohl (mp->retval);
1515   vam->result_ready = 1;
1516 }
1517
1518 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1519   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1520 {
1521   vat_main_t *vam = &vat_main;
1522   i32 retval = ntohl (mp->retval);
1523   if (vam->async_mode)
1524     {
1525       vam->async_errors += (retval < 0);
1526     }
1527   else
1528     {
1529       vam->retval = retval;
1530       vam->sw_if_index = ntohl (mp->sw_if_index);
1531       vam->result_ready = 1;
1532     }
1533 }
1534
1535 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1536   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1537 {
1538   vat_main_t *vam = &vat_main;
1539   vat_json_node_t node;
1540
1541   vat_json_init_object (&node);
1542   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1543   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1544
1545   vat_json_print (vam->ofp, &node);
1546   vat_json_free (&node);
1547
1548   vam->retval = ntohl (mp->retval);
1549   vam->result_ready = 1;
1550 }
1551
1552
1553 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1554   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1555 {
1556   vat_main_t *vam = &vat_main;
1557   i32 retval = ntohl (mp->retval);
1558   if (vam->async_mode)
1559     {
1560       vam->async_errors += (retval < 0);
1561     }
1562   else
1563     {
1564       vam->retval = retval;
1565       vam->result_ready = 1;
1566     }
1567 }
1568
1569 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1570   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1578
1579   vat_json_print (vam->ofp, &node);
1580   vat_json_free (&node);
1581
1582   vam->retval = ntohl (mp->retval);
1583   vam->result_ready = 1;
1584 }
1585
1586 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1587   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1588 {
1589   vat_main_t *vam = &vat_main;
1590   i32 retval = ntohl (mp->retval);
1591   if (vam->async_mode)
1592     {
1593       vam->async_errors += (retval < 0);
1594     }
1595   else
1596     {
1597       vam->retval = retval;
1598       vam->sw_if_index = ntohl (mp->sw_if_index);
1599       vam->result_ready = 1;
1600     }
1601 }
1602
1603 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1604   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   vat_json_node_t node;
1608
1609   vat_json_init_object (&node);
1610   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1611   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1612
1613   vat_json_print (vam->ofp, &node);
1614   vat_json_free (&node);
1615
1616   vam->retval = ntohl (mp->retval);
1617   vam->result_ready = 1;
1618 }
1619
1620 static void vl_api_gre_add_del_tunnel_reply_t_handler
1621   (vl_api_gre_add_del_tunnel_reply_t * mp)
1622 {
1623   vat_main_t *vam = &vat_main;
1624   i32 retval = ntohl (mp->retval);
1625   if (vam->async_mode)
1626     {
1627       vam->async_errors += (retval < 0);
1628     }
1629   else
1630     {
1631       vam->retval = retval;
1632       vam->sw_if_index = ntohl (mp->sw_if_index);
1633       vam->result_ready = 1;
1634     }
1635 }
1636
1637 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1638   (vl_api_gre_add_del_tunnel_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   vat_json_node_t node;
1642
1643   vat_json_init_object (&node);
1644   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1645   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1646
1647   vat_json_print (vam->ofp, &node);
1648   vat_json_free (&node);
1649
1650   vam->retval = ntohl (mp->retval);
1651   vam->result_ready = 1;
1652 }
1653
1654 static void vl_api_create_vhost_user_if_reply_t_handler
1655   (vl_api_create_vhost_user_if_reply_t * mp)
1656 {
1657   vat_main_t *vam = &vat_main;
1658   i32 retval = ntohl (mp->retval);
1659   if (vam->async_mode)
1660     {
1661       vam->async_errors += (retval < 0);
1662     }
1663   else
1664     {
1665       vam->retval = retval;
1666       vam->sw_if_index = ntohl (mp->sw_if_index);
1667       vam->result_ready = 1;
1668     }
1669 }
1670
1671 static void vl_api_create_vhost_user_if_reply_t_handler_json
1672   (vl_api_create_vhost_user_if_reply_t * mp)
1673 {
1674   vat_main_t *vam = &vat_main;
1675   vat_json_node_t node;
1676
1677   vat_json_init_object (&node);
1678   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1679   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1680
1681   vat_json_print (vam->ofp, &node);
1682   vat_json_free (&node);
1683
1684   vam->retval = ntohl (mp->retval);
1685   vam->result_ready = 1;
1686 }
1687
1688 static void vl_api_ip_address_details_t_handler
1689   (vl_api_ip_address_details_t * mp)
1690 {
1691   vat_main_t *vam = &vat_main;
1692   static ip_address_details_t empty_ip_address_details = { {0} };
1693   ip_address_details_t *address = NULL;
1694   ip_details_t *current_ip_details = NULL;
1695   ip_details_t *details = NULL;
1696
1697   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1698
1699   if (!details || vam->current_sw_if_index >= vec_len (details)
1700       || !details[vam->current_sw_if_index].present)
1701     {
1702       errmsg ("ip address details arrived but not stored");
1703       errmsg ("ip_dump should be called first");
1704       return;
1705     }
1706
1707   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1708
1709 #define addresses (current_ip_details->addr)
1710
1711   vec_validate_init_empty (addresses, vec_len (addresses),
1712                            empty_ip_address_details);
1713
1714   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1715
1716   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1717   address->prefix_length = mp->prefix_length;
1718 #undef addresses
1719 }
1720
1721 static void vl_api_ip_address_details_t_handler_json
1722   (vl_api_ip_address_details_t * mp)
1723 {
1724   vat_main_t *vam = &vat_main;
1725   vat_json_node_t *node = NULL;
1726   struct in6_addr ip6;
1727   struct in_addr ip4;
1728
1729   if (VAT_JSON_ARRAY != vam->json_tree.type)
1730     {
1731       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1732       vat_json_init_array (&vam->json_tree);
1733     }
1734   node = vat_json_array_add (&vam->json_tree);
1735
1736   vat_json_init_object (node);
1737   if (vam->is_ipv6)
1738     {
1739       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1740       vat_json_object_add_ip6 (node, "ip", ip6);
1741     }
1742   else
1743     {
1744       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1745       vat_json_object_add_ip4 (node, "ip", ip4);
1746     }
1747   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1748 }
1749
1750 static void
1751 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1752 {
1753   vat_main_t *vam = &vat_main;
1754   static ip_details_t empty_ip_details = { 0 };
1755   ip_details_t *ip = NULL;
1756   u32 sw_if_index = ~0;
1757
1758   sw_if_index = ntohl (mp->sw_if_index);
1759
1760   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1761                            sw_if_index, empty_ip_details);
1762
1763   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1764                          sw_if_index);
1765
1766   ip->present = 1;
1767 }
1768
1769 static void
1770 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1771 {
1772   vat_main_t *vam = &vat_main;
1773
1774   if (VAT_JSON_ARRAY != vam->json_tree.type)
1775     {
1776       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1777       vat_json_init_array (&vam->json_tree);
1778     }
1779   vat_json_array_add_uint (&vam->json_tree,
1780                            clib_net_to_host_u32 (mp->sw_if_index));
1781 }
1782
1783 static void vl_api_map_domain_details_t_handler_json
1784   (vl_api_map_domain_details_t * mp)
1785 {
1786   vat_json_node_t *node = NULL;
1787   vat_main_t *vam = &vat_main;
1788   struct in6_addr ip6;
1789   struct in_addr ip4;
1790
1791   if (VAT_JSON_ARRAY != vam->json_tree.type)
1792     {
1793       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1794       vat_json_init_array (&vam->json_tree);
1795     }
1796
1797   node = vat_json_array_add (&vam->json_tree);
1798   vat_json_init_object (node);
1799
1800   vat_json_object_add_uint (node, "domain_index",
1801                             clib_net_to_host_u32 (mp->domain_index));
1802   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1803   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1804   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1805   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1806   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1807   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1808   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1809   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1810   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1811   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1812   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1813   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1814   vat_json_object_add_uint (node, "flags", mp->flags);
1815   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1816   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1817 }
1818
1819 static void vl_api_map_domain_details_t_handler
1820   (vl_api_map_domain_details_t * mp)
1821 {
1822   vat_main_t *vam = &vat_main;
1823
1824   if (mp->is_translation)
1825     {
1826       print (vam->ofp,
1827              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1828              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1829              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1830              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1831              clib_net_to_host_u32 (mp->domain_index));
1832     }
1833   else
1834     {
1835       print (vam->ofp,
1836              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1837              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1838              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1839              format_ip6_address, mp->ip6_src,
1840              clib_net_to_host_u32 (mp->domain_index));
1841     }
1842   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1843          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1844          mp->is_translation ? "map-t" : "");
1845 }
1846
1847 static void vl_api_map_rule_details_t_handler_json
1848   (vl_api_map_rule_details_t * mp)
1849 {
1850   struct in6_addr ip6;
1851   vat_json_node_t *node = NULL;
1852   vat_main_t *vam = &vat_main;
1853
1854   if (VAT_JSON_ARRAY != vam->json_tree.type)
1855     {
1856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1857       vat_json_init_array (&vam->json_tree);
1858     }
1859
1860   node = vat_json_array_add (&vam->json_tree);
1861   vat_json_init_object (node);
1862
1863   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1864   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1865   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1866 }
1867
1868 static void
1869 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1873          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1874 }
1875
1876 static void
1877 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1878 {
1879   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1880           "router_addr %U host_mac %U",
1881           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1882           format_ip4_address, &mp->host_address,
1883           format_ip4_address, &mp->router_address,
1884           format_ethernet_address, mp->host_mac);
1885 }
1886
1887 static void vl_api_dhcp_compl_event_t_handler_json
1888   (vl_api_dhcp_compl_event_t * mp)
1889 {
1890   /* JSON output not supported */
1891 }
1892
1893 static void
1894 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1895                               u32 counter)
1896 {
1897   vat_main_t *vam = &vat_main;
1898   static u64 default_counter = 0;
1899
1900   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1901                            NULL);
1902   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1903                            sw_if_index, default_counter);
1904   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1905 }
1906
1907 static void
1908 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1909                                 interface_counter_t counter)
1910 {
1911   vat_main_t *vam = &vat_main;
1912   static interface_counter_t default_counter = { 0, };
1913
1914   vec_validate_init_empty (vam->combined_interface_counters,
1915                            vnet_counter_type, NULL);
1916   vec_validate_init_empty (vam->combined_interface_counters
1917                            [vnet_counter_type], sw_if_index, default_counter);
1918   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1919 }
1920
1921 static void vl_api_vnet_interface_counters_t_handler
1922   (vl_api_vnet_interface_counters_t * mp)
1923 {
1924   /* not supported */
1925 }
1926
1927 static void vl_api_vnet_interface_counters_t_handler_json
1928   (vl_api_vnet_interface_counters_t * mp)
1929 {
1930   interface_counter_t counter;
1931   vlib_counter_t *v;
1932   u64 *v_packets;
1933   u64 packets;
1934   u32 count;
1935   u32 first_sw_if_index;
1936   int i;
1937
1938   count = ntohl (mp->count);
1939   first_sw_if_index = ntohl (mp->first_sw_if_index);
1940
1941   if (!mp->is_combined)
1942     {
1943       v_packets = (u64 *) & mp->data;
1944       for (i = 0; i < count; i++)
1945         {
1946           packets =
1947             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1948           set_simple_interface_counter (mp->vnet_counter_type,
1949                                         first_sw_if_index + i, packets);
1950           v_packets++;
1951         }
1952     }
1953   else
1954     {
1955       v = (vlib_counter_t *) & mp->data;
1956       for (i = 0; i < count; i++)
1957         {
1958           counter.packets =
1959             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1960           counter.bytes =
1961             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1962           set_combined_interface_counter (mp->vnet_counter_type,
1963                                           first_sw_if_index + i, counter);
1964           v++;
1965         }
1966     }
1967 }
1968
1969 static u32
1970 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1971 {
1972   vat_main_t *vam = &vat_main;
1973   u32 i;
1974
1975   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1976     {
1977       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1978         {
1979           return i;
1980         }
1981     }
1982   return ~0;
1983 }
1984
1985 static u32
1986 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1987 {
1988   vat_main_t *vam = &vat_main;
1989   u32 i;
1990
1991   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1992     {
1993       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1994         {
1995           return i;
1996         }
1997     }
1998   return ~0;
1999 }
2000
2001 static void vl_api_vnet_ip4_fib_counters_t_handler
2002   (vl_api_vnet_ip4_fib_counters_t * mp)
2003 {
2004   /* not supported */
2005 }
2006
2007 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2008   (vl_api_vnet_ip4_fib_counters_t * mp)
2009 {
2010   vat_main_t *vam = &vat_main;
2011   vl_api_ip4_fib_counter_t *v;
2012   ip4_fib_counter_t *counter;
2013   struct in_addr ip4;
2014   u32 vrf_id;
2015   u32 vrf_index;
2016   u32 count;
2017   int i;
2018
2019   vrf_id = ntohl (mp->vrf_id);
2020   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2021   if (~0 == vrf_index)
2022     {
2023       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2024       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2025       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2026       vec_validate (vam->ip4_fib_counters, vrf_index);
2027       vam->ip4_fib_counters[vrf_index] = NULL;
2028     }
2029
2030   vec_free (vam->ip4_fib_counters[vrf_index]);
2031   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2032   count = ntohl (mp->count);
2033   for (i = 0; i < count; i++)
2034     {
2035       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2036       counter = &vam->ip4_fib_counters[vrf_index][i];
2037       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2038       counter->address = ip4;
2039       counter->address_length = v->address_length;
2040       counter->packets = clib_net_to_host_u64 (v->packets);
2041       counter->bytes = clib_net_to_host_u64 (v->bytes);
2042       v++;
2043     }
2044 }
2045
2046 static void vl_api_vnet_ip4_nbr_counters_t_handler
2047   (vl_api_vnet_ip4_nbr_counters_t * mp)
2048 {
2049   /* not supported */
2050 }
2051
2052 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2053   (vl_api_vnet_ip4_nbr_counters_t * mp)
2054 {
2055   vat_main_t *vam = &vat_main;
2056   vl_api_ip4_nbr_counter_t *v;
2057   ip4_nbr_counter_t *counter;
2058   u32 sw_if_index;
2059   u32 count;
2060   int i;
2061
2062   sw_if_index = ntohl (mp->sw_if_index);
2063   count = ntohl (mp->count);
2064   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2065
2066   if (mp->begin)
2067     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2068
2069   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2070   for (i = 0; i < count; i++)
2071     {
2072       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2073       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2074       counter->address.s_addr = v->address;
2075       counter->packets = clib_net_to_host_u64 (v->packets);
2076       counter->bytes = clib_net_to_host_u64 (v->bytes);
2077       counter->linkt = v->link_type;
2078       v++;
2079     }
2080 }
2081
2082 static void vl_api_vnet_ip6_fib_counters_t_handler
2083   (vl_api_vnet_ip6_fib_counters_t * mp)
2084 {
2085   /* not supported */
2086 }
2087
2088 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2089   (vl_api_vnet_ip6_fib_counters_t * mp)
2090 {
2091   vat_main_t *vam = &vat_main;
2092   vl_api_ip6_fib_counter_t *v;
2093   ip6_fib_counter_t *counter;
2094   struct in6_addr ip6;
2095   u32 vrf_id;
2096   u32 vrf_index;
2097   u32 count;
2098   int i;
2099
2100   vrf_id = ntohl (mp->vrf_id);
2101   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2102   if (~0 == vrf_index)
2103     {
2104       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2105       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2106       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2107       vec_validate (vam->ip6_fib_counters, vrf_index);
2108       vam->ip6_fib_counters[vrf_index] = NULL;
2109     }
2110
2111   vec_free (vam->ip6_fib_counters[vrf_index]);
2112   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2113   count = ntohl (mp->count);
2114   for (i = 0; i < count; i++)
2115     {
2116       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2117       counter = &vam->ip6_fib_counters[vrf_index][i];
2118       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2119       counter->address = ip6;
2120       counter->address_length = v->address_length;
2121       counter->packets = clib_net_to_host_u64 (v->packets);
2122       counter->bytes = clib_net_to_host_u64 (v->bytes);
2123       v++;
2124     }
2125 }
2126
2127 static void vl_api_vnet_ip6_nbr_counters_t_handler
2128   (vl_api_vnet_ip6_nbr_counters_t * mp)
2129 {
2130   /* not supported */
2131 }
2132
2133 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2134   (vl_api_vnet_ip6_nbr_counters_t * mp)
2135 {
2136   vat_main_t *vam = &vat_main;
2137   vl_api_ip6_nbr_counter_t *v;
2138   ip6_nbr_counter_t *counter;
2139   struct in6_addr ip6;
2140   u32 sw_if_index;
2141   u32 count;
2142   int i;
2143
2144   sw_if_index = ntohl (mp->sw_if_index);
2145   count = ntohl (mp->count);
2146   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2147
2148   if (mp->begin)
2149     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2150
2151   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2152   for (i = 0; i < count; i++)
2153     {
2154       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2155       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2156       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2157       counter->address = ip6;
2158       counter->packets = clib_net_to_host_u64 (v->packets);
2159       counter->bytes = clib_net_to_host_u64 (v->bytes);
2160       v++;
2161     }
2162 }
2163
2164 static void vl_api_get_first_msg_id_reply_t_handler
2165   (vl_api_get_first_msg_id_reply_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   i32 retval = ntohl (mp->retval);
2169
2170   if (vam->async_mode)
2171     {
2172       vam->async_errors += (retval < 0);
2173     }
2174   else
2175     {
2176       vam->retval = retval;
2177       vam->result_ready = 1;
2178     }
2179   if (retval >= 0)
2180     {
2181       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2182     }
2183 }
2184
2185 static void vl_api_get_first_msg_id_reply_t_handler_json
2186   (vl_api_get_first_msg_id_reply_t * mp)
2187 {
2188   vat_main_t *vam = &vat_main;
2189   vat_json_node_t node;
2190
2191   vat_json_init_object (&node);
2192   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2193   vat_json_object_add_uint (&node, "first_msg_id",
2194                             (uint) ntohs (mp->first_msg_id));
2195
2196   vat_json_print (vam->ofp, &node);
2197   vat_json_free (&node);
2198
2199   vam->retval = ntohl (mp->retval);
2200   vam->result_ready = 1;
2201 }
2202
2203 static void vl_api_get_node_graph_reply_t_handler
2204   (vl_api_get_node_graph_reply_t * mp)
2205 {
2206   vat_main_t *vam = &vat_main;
2207   api_main_t *am = &api_main;
2208   i32 retval = ntohl (mp->retval);
2209   u8 *pvt_copy, *reply;
2210   void *oldheap;
2211   vlib_node_t *node;
2212   int i;
2213
2214   if (vam->async_mode)
2215     {
2216       vam->async_errors += (retval < 0);
2217     }
2218   else
2219     {
2220       vam->retval = retval;
2221       vam->result_ready = 1;
2222     }
2223
2224   /* "Should never happen..." */
2225   if (retval != 0)
2226     return;
2227
2228   reply = (u8 *) (mp->reply_in_shmem);
2229   pvt_copy = vec_dup (reply);
2230
2231   /* Toss the shared-memory original... */
2232   pthread_mutex_lock (&am->vlib_rp->mutex);
2233   oldheap = svm_push_data_heap (am->vlib_rp);
2234
2235   vec_free (reply);
2236
2237   svm_pop_heap (oldheap);
2238   pthread_mutex_unlock (&am->vlib_rp->mutex);
2239
2240   if (vam->graph_nodes)
2241     {
2242       hash_free (vam->graph_node_index_by_name);
2243
2244       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2245         {
2246           node = vam->graph_nodes[i];
2247           vec_free (node->name);
2248           vec_free (node->next_nodes);
2249           vec_free (node);
2250         }
2251       vec_free (vam->graph_nodes);
2252     }
2253
2254   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2255   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2256   vec_free (pvt_copy);
2257
2258   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2259     {
2260       node = vam->graph_nodes[i];
2261       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2262     }
2263 }
2264
2265 static void vl_api_get_node_graph_reply_t_handler_json
2266   (vl_api_get_node_graph_reply_t * mp)
2267 {
2268   vat_main_t *vam = &vat_main;
2269   api_main_t *am = &api_main;
2270   void *oldheap;
2271   vat_json_node_t node;
2272   u8 *reply;
2273
2274   /* $$$$ make this real? */
2275   vat_json_init_object (&node);
2276   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2277   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2278
2279   reply = (u8 *) (mp->reply_in_shmem);
2280
2281   /* Toss the shared-memory original... */
2282   pthread_mutex_lock (&am->vlib_rp->mutex);
2283   oldheap = svm_push_data_heap (am->vlib_rp);
2284
2285   vec_free (reply);
2286
2287   svm_pop_heap (oldheap);
2288   pthread_mutex_unlock (&am->vlib_rp->mutex);
2289
2290   vat_json_print (vam->ofp, &node);
2291   vat_json_free (&node);
2292
2293   vam->retval = ntohl (mp->retval);
2294   vam->result_ready = 1;
2295 }
2296
2297 static void
2298 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2299 {
2300   vat_main_t *vam = &vat_main;
2301   u8 *s = 0;
2302
2303   if (mp->local)
2304     {
2305       s = format (s, "%=16d%=16d%=16d",
2306                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2307     }
2308   else
2309     {
2310       s = format (s, "%=16U%=16d%=16d",
2311                   mp->is_ipv6 ? format_ip6_address :
2312                   format_ip4_address,
2313                   mp->ip_address, mp->priority, mp->weight);
2314     }
2315
2316   print (vam->ofp, "%v", s);
2317   vec_free (s);
2318 }
2319
2320 static void
2321 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2322                                             mp)
2323 {
2324   vat_main_t *vam = &vat_main;
2325   vat_json_node_t *node = NULL;
2326   struct in6_addr ip6;
2327   struct in_addr ip4;
2328
2329   if (VAT_JSON_ARRAY != vam->json_tree.type)
2330     {
2331       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2332       vat_json_init_array (&vam->json_tree);
2333     }
2334   node = vat_json_array_add (&vam->json_tree);
2335   vat_json_init_object (node);
2336
2337   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2338   vat_json_object_add_uint (node, "priority", mp->priority);
2339   vat_json_object_add_uint (node, "weight", mp->weight);
2340
2341   if (mp->local)
2342     vat_json_object_add_uint (node, "sw_if_index",
2343                               clib_net_to_host_u32 (mp->sw_if_index));
2344   else
2345     {
2346       if (mp->is_ipv6)
2347         {
2348           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2349           vat_json_object_add_ip6 (node, "address", ip6);
2350         }
2351       else
2352         {
2353           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2354           vat_json_object_add_ip4 (node, "address", ip4);
2355         }
2356     }
2357 }
2358
2359 static void
2360 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2361                                            mp)
2362 {
2363   vat_main_t *vam = &vat_main;
2364   u8 *ls_name = 0;
2365
2366   ls_name = format (0, "%s", mp->ls_name);
2367
2368   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2369          ls_name);
2370   vec_free (ls_name);
2371 }
2372
2373 static void
2374   vl_api_lisp_locator_set_details_t_handler_json
2375   (vl_api_lisp_locator_set_details_t * mp)
2376 {
2377   vat_main_t *vam = &vat_main;
2378   vat_json_node_t *node = 0;
2379   u8 *ls_name = 0;
2380
2381   ls_name = format (0, "%s", mp->ls_name);
2382   vec_add1 (ls_name, 0);
2383
2384   if (VAT_JSON_ARRAY != vam->json_tree.type)
2385     {
2386       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2387       vat_json_init_array (&vam->json_tree);
2388     }
2389   node = vat_json_array_add (&vam->json_tree);
2390
2391   vat_json_init_object (node);
2392   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2393   vat_json_object_add_uint (node, "ls_index",
2394                             clib_net_to_host_u32 (mp->ls_index));
2395   vec_free (ls_name);
2396 }
2397
2398 static u8 *
2399 format_lisp_flat_eid (u8 * s, va_list * args)
2400 {
2401   u32 type = va_arg (*args, u32);
2402   u8 *eid = va_arg (*args, u8 *);
2403   u32 eid_len = va_arg (*args, u32);
2404
2405   switch (type)
2406     {
2407     case 0:
2408       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2409     case 1:
2410       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2411     case 2:
2412       return format (s, "%U", format_ethernet_address, eid);
2413     }
2414   return 0;
2415 }
2416
2417 static u8 *
2418 format_lisp_eid_vat (u8 * s, va_list * args)
2419 {
2420   u32 type = va_arg (*args, u32);
2421   u8 *eid = va_arg (*args, u8 *);
2422   u32 eid_len = va_arg (*args, u32);
2423   u8 *seid = va_arg (*args, u8 *);
2424   u32 seid_len = va_arg (*args, u32);
2425   u32 is_src_dst = va_arg (*args, u32);
2426
2427   if (is_src_dst)
2428     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2429
2430   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2431
2432   return s;
2433 }
2434
2435 static void
2436 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   u8 *s = 0, *eid = 0;
2440
2441   if (~0 == mp->locator_set_index)
2442     s = format (0, "action: %d", mp->action);
2443   else
2444     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2445
2446   eid = format (0, "%U", format_lisp_eid_vat,
2447                 mp->eid_type,
2448                 mp->eid,
2449                 mp->eid_prefix_len,
2450                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2451   vec_add1 (eid, 0);
2452
2453   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2454          clib_net_to_host_u32 (mp->vni),
2455          eid,
2456          mp->is_local ? "local" : "remote",
2457          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2458          clib_net_to_host_u16 (mp->key_id), mp->key);
2459
2460   vec_free (s);
2461   vec_free (eid);
2462 }
2463
2464 static void
2465 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2466                                               * mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   vat_json_node_t *node = 0;
2470   u8 *eid = 0;
2471
2472   if (VAT_JSON_ARRAY != vam->json_tree.type)
2473     {
2474       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2475       vat_json_init_array (&vam->json_tree);
2476     }
2477   node = vat_json_array_add (&vam->json_tree);
2478
2479   vat_json_init_object (node);
2480   if (~0 == mp->locator_set_index)
2481     vat_json_object_add_uint (node, "action", mp->action);
2482   else
2483     vat_json_object_add_uint (node, "locator_set_index",
2484                               clib_net_to_host_u32 (mp->locator_set_index));
2485
2486   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2487   eid = format (0, "%U", format_lisp_eid_vat,
2488                 mp->eid_type,
2489                 mp->eid,
2490                 mp->eid_prefix_len,
2491                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2492   vec_add1 (eid, 0);
2493   vat_json_object_add_string_copy (node, "eid", eid);
2494   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2495   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2496   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2497
2498   if (mp->key_id)
2499     {
2500       vat_json_object_add_uint (node, "key_id",
2501                                 clib_net_to_host_u16 (mp->key_id));
2502       vat_json_object_add_string_copy (node, "key", mp->key);
2503     }
2504   vec_free (eid);
2505 }
2506
2507 static void
2508   vl_api_lisp_eid_table_map_details_t_handler
2509   (vl_api_lisp_eid_table_map_details_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512
2513   u8 *line = format (0, "%=10d%=10d",
2514                      clib_net_to_host_u32 (mp->vni),
2515                      clib_net_to_host_u32 (mp->dp_table));
2516   print (vam->ofp, "%v", line);
2517   vec_free (line);
2518 }
2519
2520 static void
2521   vl_api_lisp_eid_table_map_details_t_handler_json
2522   (vl_api_lisp_eid_table_map_details_t * mp)
2523 {
2524   vat_main_t *vam = &vat_main;
2525   vat_json_node_t *node = NULL;
2526
2527   if (VAT_JSON_ARRAY != vam->json_tree.type)
2528     {
2529       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2530       vat_json_init_array (&vam->json_tree);
2531     }
2532   node = vat_json_array_add (&vam->json_tree);
2533   vat_json_init_object (node);
2534   vat_json_object_add_uint (node, "dp_table",
2535                             clib_net_to_host_u32 (mp->dp_table));
2536   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2537 }
2538
2539 static void
2540   vl_api_lisp_eid_table_vni_details_t_handler
2541   (vl_api_lisp_eid_table_vni_details_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544
2545   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2546   print (vam->ofp, "%v", line);
2547   vec_free (line);
2548 }
2549
2550 static void
2551   vl_api_lisp_eid_table_vni_details_t_handler_json
2552   (vl_api_lisp_eid_table_vni_details_t * mp)
2553 {
2554   vat_main_t *vam = &vat_main;
2555   vat_json_node_t *node = NULL;
2556
2557   if (VAT_JSON_ARRAY != vam->json_tree.type)
2558     {
2559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2560       vat_json_init_array (&vam->json_tree);
2561     }
2562   node = vat_json_array_add (&vam->json_tree);
2563   vat_json_init_object (node);
2564   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2565 }
2566
2567 static void
2568   vl_api_show_lisp_map_register_state_reply_t_handler
2569   (vl_api_show_lisp_map_register_state_reply_t * mp)
2570 {
2571   vat_main_t *vam = &vat_main;
2572   int retval = clib_net_to_host_u32 (mp->retval);
2573
2574   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2575
2576   vam->retval = retval;
2577   vam->result_ready = 1;
2578 }
2579
2580 static void
2581   vl_api_show_lisp_map_register_state_reply_t_handler_json
2582   (vl_api_show_lisp_map_register_state_reply_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   vat_json_node_t _node, *node = &_node;
2586   int retval = clib_net_to_host_u32 (mp->retval);
2587
2588   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2589
2590   vat_json_init_object (node);
2591   vat_json_object_add_string_copy (node, "state", s);
2592
2593   vat_json_print (vam->ofp, node);
2594   vat_json_free (node);
2595
2596   vam->retval = retval;
2597   vam->result_ready = 1;
2598   vec_free (s);
2599 }
2600
2601 static void
2602   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2603   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   int retval = clib_net_to_host_u32 (mp->retval);
2607
2608   if (retval)
2609     goto end;
2610
2611   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2612 end:
2613   vam->retval = retval;
2614   vam->result_ready = 1;
2615 }
2616
2617 static void
2618   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2619   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2620 {
2621   vat_main_t *vam = &vat_main;
2622   vat_json_node_t _node, *node = &_node;
2623   int retval = clib_net_to_host_u32 (mp->retval);
2624
2625   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2626   vat_json_init_object (node);
2627   vat_json_object_add_string_copy (node, "state", s);
2628
2629   vat_json_print (vam->ofp, node);
2630   vat_json_free (node);
2631
2632   vam->retval = retval;
2633   vam->result_ready = 1;
2634   vec_free (s);
2635 }
2636
2637 static void
2638   vl_api_lisp_adjacencies_get_reply_t_handler
2639   (vl_api_lisp_adjacencies_get_reply_t * mp)
2640 {
2641   vat_main_t *vam = &vat_main;
2642   u32 i, n;
2643   int retval = clib_net_to_host_u32 (mp->retval);
2644   vl_api_lisp_adjacency_t *a;
2645
2646   if (retval)
2647     goto end;
2648
2649   n = clib_net_to_host_u32 (mp->count);
2650
2651   for (i = 0; i < n; i++)
2652     {
2653       a = &mp->adjacencies[i];
2654       print (vam->ofp, "%U %40U",
2655              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2656              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2657     }
2658
2659 end:
2660   vam->retval = retval;
2661   vam->result_ready = 1;
2662 }
2663
2664 static void
2665   vl_api_lisp_adjacencies_get_reply_t_handler_json
2666   (vl_api_lisp_adjacencies_get_reply_t * mp)
2667 {
2668   u8 *s = 0;
2669   vat_main_t *vam = &vat_main;
2670   vat_json_node_t *e = 0, root;
2671   u32 i, n;
2672   int retval = clib_net_to_host_u32 (mp->retval);
2673   vl_api_lisp_adjacency_t *a;
2674
2675   if (retval)
2676     goto end;
2677
2678   n = clib_net_to_host_u32 (mp->count);
2679   vat_json_init_array (&root);
2680
2681   for (i = 0; i < n; i++)
2682     {
2683       e = vat_json_array_add (&root);
2684       a = &mp->adjacencies[i];
2685
2686       vat_json_init_object (e);
2687       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2688                   a->leid_prefix_len);
2689       vec_add1 (s, 0);
2690       vat_json_object_add_string_copy (e, "leid", s);
2691       vec_free (s);
2692
2693       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2694                   a->reid_prefix_len);
2695       vec_add1 (s, 0);
2696       vat_json_object_add_string_copy (e, "reid", s);
2697       vec_free (s);
2698     }
2699
2700   vat_json_print (vam->ofp, &root);
2701   vat_json_free (&root);
2702
2703 end:
2704   vam->retval = retval;
2705   vam->result_ready = 1;
2706 }
2707
2708 static void
2709 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2710                                           * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713
2714   print (vam->ofp, "%=20U",
2715          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2716          mp->ip_address);
2717 }
2718
2719 static void
2720   vl_api_lisp_map_server_details_t_handler_json
2721   (vl_api_lisp_map_server_details_t * mp)
2722 {
2723   vat_main_t *vam = &vat_main;
2724   vat_json_node_t *node = NULL;
2725   struct in6_addr ip6;
2726   struct in_addr ip4;
2727
2728   if (VAT_JSON_ARRAY != vam->json_tree.type)
2729     {
2730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2731       vat_json_init_array (&vam->json_tree);
2732     }
2733   node = vat_json_array_add (&vam->json_tree);
2734
2735   vat_json_init_object (node);
2736   if (mp->is_ipv6)
2737     {
2738       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2739       vat_json_object_add_ip6 (node, "map-server", ip6);
2740     }
2741   else
2742     {
2743       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2744       vat_json_object_add_ip4 (node, "map-server", ip4);
2745     }
2746 }
2747
2748 static void
2749 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2750                                             * mp)
2751 {
2752   vat_main_t *vam = &vat_main;
2753
2754   print (vam->ofp, "%=20U",
2755          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2756          mp->ip_address);
2757 }
2758
2759 static void
2760   vl_api_lisp_map_resolver_details_t_handler_json
2761   (vl_api_lisp_map_resolver_details_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   vat_json_node_t *node = NULL;
2765   struct in6_addr ip6;
2766   struct in_addr ip4;
2767
2768   if (VAT_JSON_ARRAY != vam->json_tree.type)
2769     {
2770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2771       vat_json_init_array (&vam->json_tree);
2772     }
2773   node = vat_json_array_add (&vam->json_tree);
2774
2775   vat_json_init_object (node);
2776   if (mp->is_ipv6)
2777     {
2778       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2779       vat_json_object_add_ip6 (node, "map resolver", ip6);
2780     }
2781   else
2782     {
2783       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2784       vat_json_object_add_ip4 (node, "map resolver", ip4);
2785     }
2786 }
2787
2788 static void
2789   vl_api_show_lisp_status_reply_t_handler
2790   (vl_api_show_lisp_status_reply_t * mp)
2791 {
2792   vat_main_t *vam = &vat_main;
2793   i32 retval = ntohl (mp->retval);
2794
2795   if (0 <= retval)
2796     {
2797       print (vam->ofp, "feature: %s\ngpe: %s",
2798              mp->feature_status ? "enabled" : "disabled",
2799              mp->gpe_status ? "enabled" : "disabled");
2800     }
2801
2802   vam->retval = retval;
2803   vam->result_ready = 1;
2804 }
2805
2806 static void
2807   vl_api_show_lisp_status_reply_t_handler_json
2808   (vl_api_show_lisp_status_reply_t * mp)
2809 {
2810   vat_main_t *vam = &vat_main;
2811   vat_json_node_t node;
2812   u8 *gpe_status = NULL;
2813   u8 *feature_status = NULL;
2814
2815   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2816   feature_status = format (0, "%s",
2817                            mp->feature_status ? "enabled" : "disabled");
2818   vec_add1 (gpe_status, 0);
2819   vec_add1 (feature_status, 0);
2820
2821   vat_json_init_object (&node);
2822   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2823   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2824
2825   vec_free (gpe_status);
2826   vec_free (feature_status);
2827
2828   vat_json_print (vam->ofp, &node);
2829   vat_json_free (&node);
2830
2831   vam->retval = ntohl (mp->retval);
2832   vam->result_ready = 1;
2833 }
2834
2835 static void
2836   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2837   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2838 {
2839   vat_main_t *vam = &vat_main;
2840   i32 retval = ntohl (mp->retval);
2841
2842   if (retval >= 0)
2843     {
2844       print (vam->ofp, "%=20s", mp->locator_set_name);
2845     }
2846
2847   vam->retval = retval;
2848   vam->result_ready = 1;
2849 }
2850
2851 static void
2852   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2853   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2854 {
2855   vat_main_t *vam = &vat_main;
2856   vat_json_node_t *node = NULL;
2857
2858   if (VAT_JSON_ARRAY != vam->json_tree.type)
2859     {
2860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2861       vat_json_init_array (&vam->json_tree);
2862     }
2863   node = vat_json_array_add (&vam->json_tree);
2864
2865   vat_json_init_object (node);
2866   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2867
2868   vat_json_print (vam->ofp, node);
2869   vat_json_free (node);
2870
2871   vam->retval = ntohl (mp->retval);
2872   vam->result_ready = 1;
2873 }
2874
2875 static u8 *
2876 format_lisp_map_request_mode (u8 * s, va_list * args)
2877 {
2878   u32 mode = va_arg (*args, u32);
2879
2880   switch (mode)
2881     {
2882     case 0:
2883       return format (0, "dst-only");
2884     case 1:
2885       return format (0, "src-dst");
2886     }
2887   return 0;
2888 }
2889
2890 static void
2891   vl_api_show_lisp_map_request_mode_reply_t_handler
2892   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2893 {
2894   vat_main_t *vam = &vat_main;
2895   i32 retval = ntohl (mp->retval);
2896
2897   if (0 <= retval)
2898     {
2899       u32 mode = mp->mode;
2900       print (vam->ofp, "map_request_mode: %U",
2901              format_lisp_map_request_mode, mode);
2902     }
2903
2904   vam->retval = retval;
2905   vam->result_ready = 1;
2906 }
2907
2908 static void
2909   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2910   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2911 {
2912   vat_main_t *vam = &vat_main;
2913   vat_json_node_t node;
2914   u8 *s = 0;
2915   u32 mode;
2916
2917   mode = mp->mode;
2918   s = format (0, "%U", format_lisp_map_request_mode, mode);
2919   vec_add1 (s, 0);
2920
2921   vat_json_init_object (&node);
2922   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2923   vat_json_print (vam->ofp, &node);
2924   vat_json_free (&node);
2925
2926   vec_free (s);
2927   vam->retval = ntohl (mp->retval);
2928   vam->result_ready = 1;
2929 }
2930
2931 static void
2932 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2933 {
2934   vat_main_t *vam = &vat_main;
2935   i32 retval = ntohl (mp->retval);
2936
2937   if (0 <= retval)
2938     {
2939       print (vam->ofp, "%-20s%-16s",
2940              mp->status ? "enabled" : "disabled",
2941              mp->status ? (char *) mp->locator_set_name : "");
2942     }
2943
2944   vam->retval = retval;
2945   vam->result_ready = 1;
2946 }
2947
2948 static void
2949 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2950                                             mp)
2951 {
2952   vat_main_t *vam = &vat_main;
2953   vat_json_node_t node;
2954   u8 *status = 0;
2955
2956   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2957   vec_add1 (status, 0);
2958
2959   vat_json_init_object (&node);
2960   vat_json_object_add_string_copy (&node, "status", status);
2961   if (mp->status)
2962     {
2963       vat_json_object_add_string_copy (&node, "locator_set",
2964                                        mp->locator_set_name);
2965     }
2966
2967   vec_free (status);
2968
2969   vat_json_print (vam->ofp, &node);
2970   vat_json_free (&node);
2971
2972   vam->retval = ntohl (mp->retval);
2973   vam->result_ready = 1;
2974 }
2975
2976 static u8 *
2977 format_policer_type (u8 * s, va_list * va)
2978 {
2979   u32 i = va_arg (*va, u32);
2980
2981   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2982     s = format (s, "1r2c");
2983   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2984     s = format (s, "1r3c");
2985   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2986     s = format (s, "2r3c-2698");
2987   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2988     s = format (s, "2r3c-4115");
2989   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2990     s = format (s, "2r3c-mef5cf1");
2991   else
2992     s = format (s, "ILLEGAL");
2993   return s;
2994 }
2995
2996 static u8 *
2997 format_policer_rate_type (u8 * s, va_list * va)
2998 {
2999   u32 i = va_arg (*va, u32);
3000
3001   if (i == SSE2_QOS_RATE_KBPS)
3002     s = format (s, "kbps");
3003   else if (i == SSE2_QOS_RATE_PPS)
3004     s = format (s, "pps");
3005   else
3006     s = format (s, "ILLEGAL");
3007   return s;
3008 }
3009
3010 static u8 *
3011 format_policer_round_type (u8 * s, va_list * va)
3012 {
3013   u32 i = va_arg (*va, u32);
3014
3015   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3016     s = format (s, "closest");
3017   else if (i == SSE2_QOS_ROUND_TO_UP)
3018     s = format (s, "up");
3019   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3020     s = format (s, "down");
3021   else
3022     s = format (s, "ILLEGAL");
3023   return s;
3024 }
3025
3026 static u8 *
3027 format_policer_action_type (u8 * s, va_list * va)
3028 {
3029   u32 i = va_arg (*va, u32);
3030
3031   if (i == SSE2_QOS_ACTION_DROP)
3032     s = format (s, "drop");
3033   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3034     s = format (s, "transmit");
3035   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3036     s = format (s, "mark-and-transmit");
3037   else
3038     s = format (s, "ILLEGAL");
3039   return s;
3040 }
3041
3042 static u8 *
3043 format_dscp (u8 * s, va_list * va)
3044 {
3045   u32 i = va_arg (*va, u32);
3046   char *t = 0;
3047
3048   switch (i)
3049     {
3050 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3051       foreach_vnet_dscp
3052 #undef _
3053     default:
3054       return format (s, "ILLEGAL");
3055     }
3056   s = format (s, "%s", t);
3057   return s;
3058 }
3059
3060 static void
3061 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3062 {
3063   vat_main_t *vam = &vat_main;
3064   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3065
3066   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3067     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3068   else
3069     conform_dscp_str = format (0, "");
3070
3071   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3072     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3073   else
3074     exceed_dscp_str = format (0, "");
3075
3076   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3077     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3078   else
3079     violate_dscp_str = format (0, "");
3080
3081   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3082          "rate type %U, round type %U, %s rate, %s color-aware, "
3083          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3084          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3085          "conform action %U%s, exceed action %U%s, violate action %U%s",
3086          mp->name,
3087          format_policer_type, mp->type,
3088          ntohl (mp->cir),
3089          ntohl (mp->eir),
3090          clib_net_to_host_u64 (mp->cb),
3091          clib_net_to_host_u64 (mp->eb),
3092          format_policer_rate_type, mp->rate_type,
3093          format_policer_round_type, mp->round_type,
3094          mp->single_rate ? "single" : "dual",
3095          mp->color_aware ? "is" : "not",
3096          ntohl (mp->cir_tokens_per_period),
3097          ntohl (mp->pir_tokens_per_period),
3098          ntohl (mp->scale),
3099          ntohl (mp->current_limit),
3100          ntohl (mp->current_bucket),
3101          ntohl (mp->extended_limit),
3102          ntohl (mp->extended_bucket),
3103          clib_net_to_host_u64 (mp->last_update_time),
3104          format_policer_action_type, mp->conform_action_type,
3105          conform_dscp_str,
3106          format_policer_action_type, mp->exceed_action_type,
3107          exceed_dscp_str,
3108          format_policer_action_type, mp->violate_action_type,
3109          violate_dscp_str);
3110
3111   vec_free (conform_dscp_str);
3112   vec_free (exceed_dscp_str);
3113   vec_free (violate_dscp_str);
3114 }
3115
3116 static void vl_api_policer_details_t_handler_json
3117   (vl_api_policer_details_t * mp)
3118 {
3119   vat_main_t *vam = &vat_main;
3120   vat_json_node_t *node;
3121   u8 *rate_type_str, *round_type_str, *type_str;
3122   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3123
3124   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3125   round_type_str =
3126     format (0, "%U", format_policer_round_type, mp->round_type);
3127   type_str = format (0, "%U", format_policer_type, mp->type);
3128   conform_action_str = format (0, "%U", format_policer_action_type,
3129                                mp->conform_action_type);
3130   exceed_action_str = format (0, "%U", format_policer_action_type,
3131                               mp->exceed_action_type);
3132   violate_action_str = format (0, "%U", format_policer_action_type,
3133                                mp->violate_action_type);
3134
3135   if (VAT_JSON_ARRAY != vam->json_tree.type)
3136     {
3137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3138       vat_json_init_array (&vam->json_tree);
3139     }
3140   node = vat_json_array_add (&vam->json_tree);
3141
3142   vat_json_init_object (node);
3143   vat_json_object_add_string_copy (node, "name", mp->name);
3144   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3145   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3146   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3147   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3148   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3149   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3150   vat_json_object_add_string_copy (node, "type", type_str);
3151   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3152   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3153   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3154   vat_json_object_add_uint (node, "cir_tokens_per_period",
3155                             ntohl (mp->cir_tokens_per_period));
3156   vat_json_object_add_uint (node, "eir_tokens_per_period",
3157                             ntohl (mp->pir_tokens_per_period));
3158   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3159   vat_json_object_add_uint (node, "current_bucket",
3160                             ntohl (mp->current_bucket));
3161   vat_json_object_add_uint (node, "extended_limit",
3162                             ntohl (mp->extended_limit));
3163   vat_json_object_add_uint (node, "extended_bucket",
3164                             ntohl (mp->extended_bucket));
3165   vat_json_object_add_uint (node, "last_update_time",
3166                             ntohl (mp->last_update_time));
3167   vat_json_object_add_string_copy (node, "conform_action",
3168                                    conform_action_str);
3169   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3170     {
3171       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3172       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3173       vec_free (dscp_str);
3174     }
3175   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3176   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3177     {
3178       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3179       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3180       vec_free (dscp_str);
3181     }
3182   vat_json_object_add_string_copy (node, "violate_action",
3183                                    violate_action_str);
3184   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3185     {
3186       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3187       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3188       vec_free (dscp_str);
3189     }
3190
3191   vec_free (rate_type_str);
3192   vec_free (round_type_str);
3193   vec_free (type_str);
3194   vec_free (conform_action_str);
3195   vec_free (exceed_action_str);
3196   vec_free (violate_action_str);
3197 }
3198
3199 static void
3200 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3201                                            mp)
3202 {
3203   vat_main_t *vam = &vat_main;
3204   int i, count = ntohl (mp->count);
3205
3206   if (count > 0)
3207     print (vam->ofp, "classify table ids (%d) : ", count);
3208   for (i = 0; i < count; i++)
3209     {
3210       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3211       print (vam->ofp, (i < count - 1) ? "," : "");
3212     }
3213   vam->retval = ntohl (mp->retval);
3214   vam->result_ready = 1;
3215 }
3216
3217 static void
3218   vl_api_classify_table_ids_reply_t_handler_json
3219   (vl_api_classify_table_ids_reply_t * mp)
3220 {
3221   vat_main_t *vam = &vat_main;
3222   int i, count = ntohl (mp->count);
3223
3224   if (count > 0)
3225     {
3226       vat_json_node_t node;
3227
3228       vat_json_init_object (&node);
3229       for (i = 0; i < count; i++)
3230         {
3231           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3232         }
3233       vat_json_print (vam->ofp, &node);
3234       vat_json_free (&node);
3235     }
3236   vam->retval = ntohl (mp->retval);
3237   vam->result_ready = 1;
3238 }
3239
3240 static void
3241   vl_api_classify_table_by_interface_reply_t_handler
3242   (vl_api_classify_table_by_interface_reply_t * mp)
3243 {
3244   vat_main_t *vam = &vat_main;
3245   u32 table_id;
3246
3247   table_id = ntohl (mp->l2_table_id);
3248   if (table_id != ~0)
3249     print (vam->ofp, "l2 table id : %d", table_id);
3250   else
3251     print (vam->ofp, "l2 table id : No input ACL tables configured");
3252   table_id = ntohl (mp->ip4_table_id);
3253   if (table_id != ~0)
3254     print (vam->ofp, "ip4 table id : %d", table_id);
3255   else
3256     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3257   table_id = ntohl (mp->ip6_table_id);
3258   if (table_id != ~0)
3259     print (vam->ofp, "ip6 table id : %d", table_id);
3260   else
3261     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3262   vam->retval = ntohl (mp->retval);
3263   vam->result_ready = 1;
3264 }
3265
3266 static void
3267   vl_api_classify_table_by_interface_reply_t_handler_json
3268   (vl_api_classify_table_by_interface_reply_t * mp)
3269 {
3270   vat_main_t *vam = &vat_main;
3271   vat_json_node_t node;
3272
3273   vat_json_init_object (&node);
3274
3275   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3276   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3277   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3278
3279   vat_json_print (vam->ofp, &node);
3280   vat_json_free (&node);
3281
3282   vam->retval = ntohl (mp->retval);
3283   vam->result_ready = 1;
3284 }
3285
3286 static void vl_api_policer_add_del_reply_t_handler
3287   (vl_api_policer_add_del_reply_t * mp)
3288 {
3289   vat_main_t *vam = &vat_main;
3290   i32 retval = ntohl (mp->retval);
3291   if (vam->async_mode)
3292     {
3293       vam->async_errors += (retval < 0);
3294     }
3295   else
3296     {
3297       vam->retval = retval;
3298       vam->result_ready = 1;
3299       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3300         /*
3301          * Note: this is just barely thread-safe, depends on
3302          * the main thread spinning waiting for an answer...
3303          */
3304         errmsg ("policer index %d", ntohl (mp->policer_index));
3305     }
3306 }
3307
3308 static void vl_api_policer_add_del_reply_t_handler_json
3309   (vl_api_policer_add_del_reply_t * mp)
3310 {
3311   vat_main_t *vam = &vat_main;
3312   vat_json_node_t node;
3313
3314   vat_json_init_object (&node);
3315   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3316   vat_json_object_add_uint (&node, "policer_index",
3317                             ntohl (mp->policer_index));
3318
3319   vat_json_print (vam->ofp, &node);
3320   vat_json_free (&node);
3321
3322   vam->retval = ntohl (mp->retval);
3323   vam->result_ready = 1;
3324 }
3325
3326 /* Format hex dump. */
3327 u8 *
3328 format_hex_bytes (u8 * s, va_list * va)
3329 {
3330   u8 *bytes = va_arg (*va, u8 *);
3331   int n_bytes = va_arg (*va, int);
3332   uword i;
3333
3334   /* Print short or long form depending on byte count. */
3335   uword short_form = n_bytes <= 32;
3336   uword indent = format_get_indent (s);
3337
3338   if (n_bytes == 0)
3339     return s;
3340
3341   for (i = 0; i < n_bytes; i++)
3342     {
3343       if (!short_form && (i % 32) == 0)
3344         s = format (s, "%08x: ", i);
3345       s = format (s, "%02x", bytes[i]);
3346       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3347         s = format (s, "\n%U", format_white_space, indent);
3348     }
3349
3350   return s;
3351 }
3352
3353 static void
3354 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3355                                             * mp)
3356 {
3357   vat_main_t *vam = &vat_main;
3358   i32 retval = ntohl (mp->retval);
3359   if (retval == 0)
3360     {
3361       print (vam->ofp, "classify table info :");
3362       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3363              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3364              ntohl (mp->miss_next_index));
3365       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3366              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3367              ntohl (mp->match_n_vectors));
3368       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3369              ntohl (mp->mask_length));
3370     }
3371   vam->retval = retval;
3372   vam->result_ready = 1;
3373 }
3374
3375 static void
3376   vl_api_classify_table_info_reply_t_handler_json
3377   (vl_api_classify_table_info_reply_t * mp)
3378 {
3379   vat_main_t *vam = &vat_main;
3380   vat_json_node_t node;
3381
3382   i32 retval = ntohl (mp->retval);
3383   if (retval == 0)
3384     {
3385       vat_json_init_object (&node);
3386
3387       vat_json_object_add_int (&node, "sessions",
3388                                ntohl (mp->active_sessions));
3389       vat_json_object_add_int (&node, "nexttbl",
3390                                ntohl (mp->next_table_index));
3391       vat_json_object_add_int (&node, "nextnode",
3392                                ntohl (mp->miss_next_index));
3393       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3394       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3395       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3396       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3397                       ntohl (mp->mask_length), 0);
3398       vat_json_object_add_string_copy (&node, "mask", s);
3399
3400       vat_json_print (vam->ofp, &node);
3401       vat_json_free (&node);
3402     }
3403   vam->retval = ntohl (mp->retval);
3404   vam->result_ready = 1;
3405 }
3406
3407 static void
3408 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3409                                            mp)
3410 {
3411   vat_main_t *vam = &vat_main;
3412
3413   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3414          ntohl (mp->hit_next_index), ntohl (mp->advance),
3415          ntohl (mp->opaque_index));
3416   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3417          ntohl (mp->match_length));
3418 }
3419
3420 static void
3421   vl_api_classify_session_details_t_handler_json
3422   (vl_api_classify_session_details_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   vat_json_node_t *node = NULL;
3426
3427   if (VAT_JSON_ARRAY != vam->json_tree.type)
3428     {
3429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3430       vat_json_init_array (&vam->json_tree);
3431     }
3432   node = vat_json_array_add (&vam->json_tree);
3433
3434   vat_json_init_object (node);
3435   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3436   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3437   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3438   u8 *s =
3439     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3440             0);
3441   vat_json_object_add_string_copy (node, "match", s);
3442 }
3443
3444 static void vl_api_pg_create_interface_reply_t_handler
3445   (vl_api_pg_create_interface_reply_t * mp)
3446 {
3447   vat_main_t *vam = &vat_main;
3448
3449   vam->retval = ntohl (mp->retval);
3450   vam->result_ready = 1;
3451 }
3452
3453 static void vl_api_pg_create_interface_reply_t_handler_json
3454   (vl_api_pg_create_interface_reply_t * mp)
3455 {
3456   vat_main_t *vam = &vat_main;
3457   vat_json_node_t node;
3458
3459   i32 retval = ntohl (mp->retval);
3460   if (retval == 0)
3461     {
3462       vat_json_init_object (&node);
3463
3464       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3465
3466       vat_json_print (vam->ofp, &node);
3467       vat_json_free (&node);
3468     }
3469   vam->retval = ntohl (mp->retval);
3470   vam->result_ready = 1;
3471 }
3472
3473 static void vl_api_policer_classify_details_t_handler
3474   (vl_api_policer_classify_details_t * mp)
3475 {
3476   vat_main_t *vam = &vat_main;
3477
3478   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3479          ntohl (mp->table_index));
3480 }
3481
3482 static void vl_api_policer_classify_details_t_handler_json
3483   (vl_api_policer_classify_details_t * mp)
3484 {
3485   vat_main_t *vam = &vat_main;
3486   vat_json_node_t *node;
3487
3488   if (VAT_JSON_ARRAY != vam->json_tree.type)
3489     {
3490       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3491       vat_json_init_array (&vam->json_tree);
3492     }
3493   node = vat_json_array_add (&vam->json_tree);
3494
3495   vat_json_init_object (node);
3496   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3497   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3498 }
3499
3500 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3501   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3502 {
3503   vat_main_t *vam = &vat_main;
3504   i32 retval = ntohl (mp->retval);
3505   if (vam->async_mode)
3506     {
3507       vam->async_errors += (retval < 0);
3508     }
3509   else
3510     {
3511       vam->retval = retval;
3512       vam->sw_if_index = ntohl (mp->sw_if_index);
3513       vam->result_ready = 1;
3514     }
3515 }
3516
3517 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3518   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3519 {
3520   vat_main_t *vam = &vat_main;
3521   vat_json_node_t node;
3522
3523   vat_json_init_object (&node);
3524   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3525   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3526
3527   vat_json_print (vam->ofp, &node);
3528   vat_json_free (&node);
3529
3530   vam->retval = ntohl (mp->retval);
3531   vam->result_ready = 1;
3532 }
3533
3534 static void vl_api_flow_classify_details_t_handler
3535   (vl_api_flow_classify_details_t * mp)
3536 {
3537   vat_main_t *vam = &vat_main;
3538
3539   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3540          ntohl (mp->table_index));
3541 }
3542
3543 static void vl_api_flow_classify_details_t_handler_json
3544   (vl_api_flow_classify_details_t * mp)
3545 {
3546   vat_main_t *vam = &vat_main;
3547   vat_json_node_t *node;
3548
3549   if (VAT_JSON_ARRAY != vam->json_tree.type)
3550     {
3551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3552       vat_json_init_array (&vam->json_tree);
3553     }
3554   node = vat_json_array_add (&vam->json_tree);
3555
3556   vat_json_init_object (node);
3557   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3558   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3559 }
3560
3561
3562
3563 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3564 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3565 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3566 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3567 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3568 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3569 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3570 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3571 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3572 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3573
3574 /*
3575  * Generate boilerplate reply handlers, which
3576  * dig the return value out of the xxx_reply_t API message,
3577  * stick it into vam->retval, and set vam->result_ready
3578  *
3579  * Could also do this by pointing N message decode slots at
3580  * a single function, but that could break in subtle ways.
3581  */
3582
3583 #define foreach_standard_reply_retval_handler           \
3584 _(sw_interface_set_flags_reply)                         \
3585 _(sw_interface_add_del_address_reply)                   \
3586 _(sw_interface_set_table_reply)                         \
3587 _(sw_interface_set_mpls_enable_reply)                   \
3588 _(sw_interface_set_vpath_reply)                         \
3589 _(sw_interface_set_vxlan_bypass_reply)                  \
3590 _(sw_interface_set_l2_bridge_reply)                     \
3591 _(bridge_domain_add_del_reply)                          \
3592 _(sw_interface_set_l2_xconnect_reply)                   \
3593 _(l2fib_add_del_reply)                                  \
3594 _(ip_add_del_route_reply)                               \
3595 _(mpls_route_add_del_reply)                             \
3596 _(mpls_ip_bind_unbind_reply)                            \
3597 _(proxy_arp_add_del_reply)                              \
3598 _(proxy_arp_intfc_enable_disable_reply)                 \
3599 _(sw_interface_set_unnumbered_reply)                    \
3600 _(ip_neighbor_add_del_reply)                            \
3601 _(reset_vrf_reply)                                      \
3602 _(oam_add_del_reply)                                    \
3603 _(reset_fib_reply)                                      \
3604 _(dhcp_proxy_config_reply)                              \
3605 _(dhcp_proxy_config_2_reply)                            \
3606 _(dhcp_proxy_set_vss_reply)                             \
3607 _(dhcp_client_config_reply)                             \
3608 _(set_ip_flow_hash_reply)                               \
3609 _(sw_interface_ip6_enable_disable_reply)                \
3610 _(sw_interface_ip6_set_link_local_address_reply)        \
3611 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3612 _(sw_interface_ip6nd_ra_config_reply)                   \
3613 _(set_arp_neighbor_limit_reply)                         \
3614 _(l2_patch_add_del_reply)                               \
3615 _(sr_tunnel_add_del_reply)                              \
3616 _(sr_policy_add_del_reply)                              \
3617 _(sr_multicast_map_add_del_reply)                       \
3618 _(classify_add_del_session_reply)                       \
3619 _(classify_set_interface_ip_table_reply)                \
3620 _(classify_set_interface_l2_tables_reply)               \
3621 _(l2tpv3_set_tunnel_cookies_reply)                      \
3622 _(l2tpv3_interface_enable_disable_reply)                \
3623 _(l2tpv3_set_lookup_key_reply)                          \
3624 _(l2_fib_clear_table_reply)                             \
3625 _(l2_interface_efp_filter_reply)                        \
3626 _(l2_interface_vlan_tag_rewrite_reply)                  \
3627 _(modify_vhost_user_if_reply)                           \
3628 _(delete_vhost_user_if_reply)                           \
3629 _(want_ip4_arp_events_reply)                            \
3630 _(want_ip6_nd_events_reply)                             \
3631 _(input_acl_set_interface_reply)                        \
3632 _(ipsec_spd_add_del_reply)                              \
3633 _(ipsec_interface_add_del_spd_reply)                    \
3634 _(ipsec_spd_add_del_entry_reply)                        \
3635 _(ipsec_sad_add_del_entry_reply)                        \
3636 _(ipsec_sa_set_key_reply)                               \
3637 _(ikev2_profile_add_del_reply)                          \
3638 _(ikev2_profile_set_auth_reply)                         \
3639 _(ikev2_profile_set_id_reply)                           \
3640 _(ikev2_profile_set_ts_reply)                           \
3641 _(ikev2_set_local_key_reply)                            \
3642 _(delete_loopback_reply)                                \
3643 _(bd_ip_mac_add_del_reply)                              \
3644 _(map_del_domain_reply)                                 \
3645 _(map_add_del_rule_reply)                               \
3646 _(want_interface_events_reply)                          \
3647 _(want_stats_reply)                                     \
3648 _(cop_interface_enable_disable_reply)                   \
3649 _(cop_whitelist_enable_disable_reply)                   \
3650 _(sw_interface_clear_stats_reply)                       \
3651 _(ioam_enable_reply)                              \
3652 _(ioam_disable_reply)                              \
3653 _(lisp_add_del_locator_reply)                           \
3654 _(lisp_add_del_local_eid_reply)                         \
3655 _(lisp_add_del_remote_mapping_reply)                    \
3656 _(lisp_add_del_adjacency_reply)                         \
3657 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3658 _(lisp_add_del_map_resolver_reply)                      \
3659 _(lisp_add_del_map_server_reply)                        \
3660 _(lisp_gpe_enable_disable_reply)                        \
3661 _(lisp_gpe_add_del_iface_reply)                         \
3662 _(lisp_enable_disable_reply)                            \
3663 _(lisp_rloc_probe_enable_disable_reply)                 \
3664 _(lisp_map_register_enable_disable_reply)               \
3665 _(lisp_pitr_set_locator_set_reply)                      \
3666 _(lisp_map_request_mode_reply)                          \
3667 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3668 _(lisp_eid_table_add_del_map_reply)                     \
3669 _(vxlan_gpe_add_del_tunnel_reply)                       \
3670 _(af_packet_delete_reply)                               \
3671 _(policer_classify_set_interface_reply)                 \
3672 _(netmap_create_reply)                                  \
3673 _(netmap_delete_reply)                                  \
3674 _(set_ipfix_exporter_reply)                             \
3675 _(set_ipfix_classify_stream_reply)                      \
3676 _(ipfix_classify_table_add_del_reply)                   \
3677 _(flow_classify_set_interface_reply)                    \
3678 _(sw_interface_span_enable_disable_reply)               \
3679 _(pg_capture_reply)                                     \
3680 _(pg_enable_disable_reply)                              \
3681 _(ip_source_and_port_range_check_add_del_reply)         \
3682 _(ip_source_and_port_range_check_interface_add_del_reply)\
3683 _(delete_subif_reply)                                   \
3684 _(l2_interface_pbb_tag_rewrite_reply)                   \
3685 _(punt_reply)                                           \
3686 _(feature_enable_disable_reply)                         \
3687 _(sw_interface_tag_add_del_reply)                       \
3688 _(sw_interface_set_mtu_reply)
3689
3690 #if DPDK > 0
3691 #define foreach_standard_dpdk_reply_retval_handler      \
3692 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3693 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3694 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3695 #endif
3696
3697 #define _(n)                                    \
3698     static void vl_api_##n##_t_handler          \
3699     (vl_api_##n##_t * mp)                       \
3700     {                                           \
3701         vat_main_t * vam = &vat_main;           \
3702         i32 retval = ntohl(mp->retval);         \
3703         if (vam->async_mode) {                  \
3704             vam->async_errors += (retval < 0);  \
3705         } else {                                \
3706             vam->retval = retval;               \
3707             vam->result_ready = 1;              \
3708         }                                       \
3709     }
3710 foreach_standard_reply_retval_handler;
3711 #undef _
3712
3713 #define _(n)                                    \
3714     static void vl_api_##n##_t_handler_json     \
3715     (vl_api_##n##_t * mp)                       \
3716     {                                           \
3717         vat_main_t * vam = &vat_main;           \
3718         vat_json_node_t node;                   \
3719         vat_json_init_object(&node);            \
3720         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3721         vat_json_print(vam->ofp, &node);        \
3722         vam->retval = ntohl(mp->retval);        \
3723         vam->result_ready = 1;                  \
3724     }
3725 foreach_standard_reply_retval_handler;
3726 #undef _
3727
3728 #if DPDK > 0
3729 #define _(n)                                    \
3730     static void vl_api_##n##_t_handler          \
3731     (vl_api_##n##_t * mp)                       \
3732     {                                           \
3733         vat_main_t * vam = &vat_main;           \
3734         i32 retval = ntohl(mp->retval);         \
3735         if (vam->async_mode) {                  \
3736             vam->async_errors += (retval < 0);  \
3737         } else {                                \
3738             vam->retval = retval;               \
3739             vam->result_ready = 1;              \
3740         }                                       \
3741     }
3742 foreach_standard_dpdk_reply_retval_handler;
3743 #undef _
3744
3745 #define _(n)                                    \
3746     static void vl_api_##n##_t_handler_json     \
3747     (vl_api_##n##_t * mp)                       \
3748     {                                           \
3749         vat_main_t * vam = &vat_main;           \
3750         vat_json_node_t node;                   \
3751         vat_json_init_object(&node);            \
3752         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3753         vat_json_print(vam->ofp, &node);        \
3754         vam->retval = ntohl(mp->retval);        \
3755         vam->result_ready = 1;                  \
3756     }
3757 foreach_standard_dpdk_reply_retval_handler;
3758 #undef _
3759 #endif
3760
3761 /*
3762  * Table of message reply handlers, must include boilerplate handlers
3763  * we just generated
3764  */
3765
3766 #define foreach_vpe_api_reply_msg                                       \
3767 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3768 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3769 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3770 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3771 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3772 _(CLI_REPLY, cli_reply)                                                 \
3773 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3774 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3775   sw_interface_add_del_address_reply)                                   \
3776 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3777 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3778 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3779 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3780 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3781   sw_interface_set_l2_xconnect_reply)                                   \
3782 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3783   sw_interface_set_l2_bridge_reply)                                     \
3784 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3785 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3786 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3787 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3788 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3789 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3790 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3791 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3792 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3793 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3794 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3795 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3796 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3797 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3798 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3799   proxy_arp_intfc_enable_disable_reply)                                 \
3800 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3801 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3802   sw_interface_set_unnumbered_reply)                                    \
3803 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3804 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3805 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3806 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3807 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3808 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3809 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3810 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3811 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3812 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3813 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3814 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3815   sw_interface_ip6_enable_disable_reply)                                \
3816 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3817   sw_interface_ip6_set_link_local_address_reply)                        \
3818 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3819   sw_interface_ip6nd_ra_prefix_reply)                                   \
3820 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3821   sw_interface_ip6nd_ra_config_reply)                                   \
3822 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3823 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3824 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3825 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3826 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3827 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3828 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3829 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3830 classify_set_interface_ip_table_reply)                                  \
3831 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3832   classify_set_interface_l2_tables_reply)                               \
3833 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3834 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3835 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3836 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3837 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3838   l2tpv3_interface_enable_disable_reply)                                \
3839 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3840 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3841 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3842 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3843 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3844 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3845 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3846 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3847 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3848 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3849 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3850 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3851 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3852 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3853 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3854 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3855 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3856 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3857 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3858 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3859 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3860 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3861 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3862 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3863 _(IP_DETAILS, ip_details)                                               \
3864 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3865 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3866 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3867 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3868 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3869 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3870 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3871 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3872 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3873 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3874 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3875 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3876 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3877 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3878 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3879 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3880 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
3881 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
3882 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3883 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3884 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3885 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3886 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3887 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3888 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3889 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3890 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3891 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3892 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3893 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3894 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3895 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3896 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3897 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3898 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3899 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3900 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3901 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3902 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3903 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3904 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3905 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3906 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3907   lisp_map_register_enable_disable_reply)                               \
3908 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3909   lisp_rloc_probe_enable_disable_reply)                                 \
3910 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3911 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3912 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3913 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3914 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3915 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3916 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3917 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3918 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3919 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3920 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3921 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3922 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3923 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3924   lisp_add_del_map_request_itr_rlocs_reply)                             \
3925 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3926   lisp_get_map_request_itr_rlocs_reply)                                 \
3927 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3928 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3929 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3930 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3931   show_lisp_map_register_state_reply)                                   \
3932 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3933 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3934 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3935 _(POLICER_DETAILS, policer_details)                                     \
3936 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3937 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3938 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3939 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3940 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3941 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3942 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3943 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3944 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3945 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3946 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3947 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3948 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3949 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3950 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3951 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3952 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3953 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3954 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3955 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3956 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3957 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3958 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3959 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3960 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3961  ip_source_and_port_range_check_add_del_reply)                          \
3962 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3963  ip_source_and_port_range_check_interface_add_del_reply)                \
3964 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3965 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3966 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3967 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3968 _(PUNT_REPLY, punt_reply)                                               \
3969 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3970 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3971 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3972 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3973 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3974 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3975 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
3976 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3977
3978 #if DPDK > 0
3979 #define foreach_vpe_dpdk_api_reply_msg                                  \
3980 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3981   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3982 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3983   sw_interface_set_dpdk_hqos_subport_reply)                             \
3984 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3985   sw_interface_set_dpdk_hqos_tctbl_reply)
3986 #endif
3987
3988 typedef struct
3989 {
3990   u8 *name;
3991   u32 value;
3992 } name_sort_t;
3993
3994
3995 #define STR_VTR_OP_CASE(op)     \
3996     case L2_VTR_ ## op:         \
3997         return "" # op;
3998
3999 static const char *
4000 str_vtr_op (u32 vtr_op)
4001 {
4002   switch (vtr_op)
4003     {
4004       STR_VTR_OP_CASE (DISABLED);
4005       STR_VTR_OP_CASE (PUSH_1);
4006       STR_VTR_OP_CASE (PUSH_2);
4007       STR_VTR_OP_CASE (POP_1);
4008       STR_VTR_OP_CASE (POP_2);
4009       STR_VTR_OP_CASE (TRANSLATE_1_1);
4010       STR_VTR_OP_CASE (TRANSLATE_1_2);
4011       STR_VTR_OP_CASE (TRANSLATE_2_1);
4012       STR_VTR_OP_CASE (TRANSLATE_2_2);
4013     }
4014
4015   return "UNKNOWN";
4016 }
4017
4018 static int
4019 dump_sub_interface_table (vat_main_t * vam)
4020 {
4021   const sw_interface_subif_t *sub = NULL;
4022
4023   if (vam->json_output)
4024     {
4025       clib_warning
4026         ("JSON output supported only for VPE API calls and dump_stats_table");
4027       return -99;
4028     }
4029
4030   print (vam->ofp,
4031          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4032          "Interface", "sw_if_index",
4033          "sub id", "dot1ad", "tags", "outer id",
4034          "inner id", "exact", "default", "outer any", "inner any");
4035
4036   vec_foreach (sub, vam->sw_if_subif_table)
4037   {
4038     print (vam->ofp,
4039            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4040            sub->interface_name,
4041            sub->sw_if_index,
4042            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4043            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4044            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4045            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4046     if (sub->vtr_op != L2_VTR_DISABLED)
4047       {
4048         print (vam->ofp,
4049                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4050                "tag1: %d tag2: %d ]",
4051                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4052                sub->vtr_tag1, sub->vtr_tag2);
4053       }
4054   }
4055
4056   return 0;
4057 }
4058
4059 static int
4060 name_sort_cmp (void *a1, void *a2)
4061 {
4062   name_sort_t *n1 = a1;
4063   name_sort_t *n2 = a2;
4064
4065   return strcmp ((char *) n1->name, (char *) n2->name);
4066 }
4067
4068 static int
4069 dump_interface_table (vat_main_t * vam)
4070 {
4071   hash_pair_t *p;
4072   name_sort_t *nses = 0, *ns;
4073
4074   if (vam->json_output)
4075     {
4076       clib_warning
4077         ("JSON output supported only for VPE API calls and dump_stats_table");
4078       return -99;
4079     }
4080
4081   /* *INDENT-OFF* */
4082   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4083   ({
4084     vec_add2 (nses, ns, 1);
4085     ns->name = (u8 *)(p->key);
4086     ns->value = (u32) p->value[0];
4087   }));
4088   /* *INDENT-ON* */
4089
4090   vec_sort_with_function (nses, name_sort_cmp);
4091
4092   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4093   vec_foreach (ns, nses)
4094   {
4095     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4096   }
4097   vec_free (nses);
4098   return 0;
4099 }
4100
4101 static int
4102 dump_ip_table (vat_main_t * vam, int is_ipv6)
4103 {
4104   const ip_details_t *det = NULL;
4105   const ip_address_details_t *address = NULL;
4106   u32 i = ~0;
4107
4108   print (vam->ofp, "%-12s", "sw_if_index");
4109
4110   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4111   {
4112     i++;
4113     if (!det->present)
4114       {
4115         continue;
4116       }
4117     print (vam->ofp, "%-12d", i);
4118     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4119     if (!det->addr)
4120       {
4121         continue;
4122       }
4123     vec_foreach (address, det->addr)
4124     {
4125       print (vam->ofp,
4126              "            %-30U%-13d",
4127              is_ipv6 ? format_ip6_address : format_ip4_address,
4128              address->ip, address->prefix_length);
4129     }
4130   }
4131
4132   return 0;
4133 }
4134
4135 static int
4136 dump_ipv4_table (vat_main_t * vam)
4137 {
4138   if (vam->json_output)
4139     {
4140       clib_warning
4141         ("JSON output supported only for VPE API calls and dump_stats_table");
4142       return -99;
4143     }
4144
4145   return dump_ip_table (vam, 0);
4146 }
4147
4148 static int
4149 dump_ipv6_table (vat_main_t * vam)
4150 {
4151   if (vam->json_output)
4152     {
4153       clib_warning
4154         ("JSON output supported only for VPE API calls and dump_stats_table");
4155       return -99;
4156     }
4157
4158   return dump_ip_table (vam, 1);
4159 }
4160
4161 static char *
4162 counter_type_to_str (u8 counter_type, u8 is_combined)
4163 {
4164   if (!is_combined)
4165     {
4166       switch (counter_type)
4167         {
4168         case VNET_INTERFACE_COUNTER_DROP:
4169           return "drop";
4170         case VNET_INTERFACE_COUNTER_PUNT:
4171           return "punt";
4172         case VNET_INTERFACE_COUNTER_IP4:
4173           return "ip4";
4174         case VNET_INTERFACE_COUNTER_IP6:
4175           return "ip6";
4176         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4177           return "rx-no-buf";
4178         case VNET_INTERFACE_COUNTER_RX_MISS:
4179           return "rx-miss";
4180         case VNET_INTERFACE_COUNTER_RX_ERROR:
4181           return "rx-error";
4182         case VNET_INTERFACE_COUNTER_TX_ERROR:
4183           return "tx-error";
4184         default:
4185           return "INVALID-COUNTER-TYPE";
4186         }
4187     }
4188   else
4189     {
4190       switch (counter_type)
4191         {
4192         case VNET_INTERFACE_COUNTER_RX:
4193           return "rx";
4194         case VNET_INTERFACE_COUNTER_TX:
4195           return "tx";
4196         default:
4197           return "INVALID-COUNTER-TYPE";
4198         }
4199     }
4200 }
4201
4202 static int
4203 dump_stats_table (vat_main_t * vam)
4204 {
4205   vat_json_node_t node;
4206   vat_json_node_t *msg_array;
4207   vat_json_node_t *msg;
4208   vat_json_node_t *counter_array;
4209   vat_json_node_t *counter;
4210   interface_counter_t c;
4211   u64 packets;
4212   ip4_fib_counter_t *c4;
4213   ip6_fib_counter_t *c6;
4214   ip4_nbr_counter_t *n4;
4215   ip6_nbr_counter_t *n6;
4216   int i, j;
4217
4218   if (!vam->json_output)
4219     {
4220       clib_warning ("dump_stats_table supported only in JSON format");
4221       return -99;
4222     }
4223
4224   vat_json_init_object (&node);
4225
4226   /* interface counters */
4227   msg_array = vat_json_object_add (&node, "interface_counters");
4228   vat_json_init_array (msg_array);
4229   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4230     {
4231       msg = vat_json_array_add (msg_array);
4232       vat_json_init_object (msg);
4233       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4234                                        (u8 *) counter_type_to_str (i, 0));
4235       vat_json_object_add_int (msg, "is_combined", 0);
4236       counter_array = vat_json_object_add (msg, "data");
4237       vat_json_init_array (counter_array);
4238       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4239         {
4240           packets = vam->simple_interface_counters[i][j];
4241           vat_json_array_add_uint (counter_array, packets);
4242         }
4243     }
4244   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4245     {
4246       msg = vat_json_array_add (msg_array);
4247       vat_json_init_object (msg);
4248       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4249                                        (u8 *) counter_type_to_str (i, 1));
4250       vat_json_object_add_int (msg, "is_combined", 1);
4251       counter_array = vat_json_object_add (msg, "data");
4252       vat_json_init_array (counter_array);
4253       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4254         {
4255           c = vam->combined_interface_counters[i][j];
4256           counter = vat_json_array_add (counter_array);
4257           vat_json_init_object (counter);
4258           vat_json_object_add_uint (counter, "packets", c.packets);
4259           vat_json_object_add_uint (counter, "bytes", c.bytes);
4260         }
4261     }
4262
4263   /* ip4 fib counters */
4264   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4265   vat_json_init_array (msg_array);
4266   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4267     {
4268       msg = vat_json_array_add (msg_array);
4269       vat_json_init_object (msg);
4270       vat_json_object_add_uint (msg, "vrf_id",
4271                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4272       counter_array = vat_json_object_add (msg, "c");
4273       vat_json_init_array (counter_array);
4274       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4275         {
4276           counter = vat_json_array_add (counter_array);
4277           vat_json_init_object (counter);
4278           c4 = &vam->ip4_fib_counters[i][j];
4279           vat_json_object_add_ip4 (counter, "address", c4->address);
4280           vat_json_object_add_uint (counter, "address_length",
4281                                     c4->address_length);
4282           vat_json_object_add_uint (counter, "packets", c4->packets);
4283           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4284         }
4285     }
4286
4287   /* ip6 fib counters */
4288   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4289   vat_json_init_array (msg_array);
4290   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4291     {
4292       msg = vat_json_array_add (msg_array);
4293       vat_json_init_object (msg);
4294       vat_json_object_add_uint (msg, "vrf_id",
4295                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4296       counter_array = vat_json_object_add (msg, "c");
4297       vat_json_init_array (counter_array);
4298       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4299         {
4300           counter = vat_json_array_add (counter_array);
4301           vat_json_init_object (counter);
4302           c6 = &vam->ip6_fib_counters[i][j];
4303           vat_json_object_add_ip6 (counter, "address", c6->address);
4304           vat_json_object_add_uint (counter, "address_length",
4305                                     c6->address_length);
4306           vat_json_object_add_uint (counter, "packets", c6->packets);
4307           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4308         }
4309     }
4310
4311   /* ip4 nbr counters */
4312   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4313   vat_json_init_array (msg_array);
4314   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4315     {
4316       msg = vat_json_array_add (msg_array);
4317       vat_json_init_object (msg);
4318       vat_json_object_add_uint (msg, "sw_if_index", i);
4319       counter_array = vat_json_object_add (msg, "c");
4320       vat_json_init_array (counter_array);
4321       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4322         {
4323           counter = vat_json_array_add (counter_array);
4324           vat_json_init_object (counter);
4325           n4 = &vam->ip4_nbr_counters[i][j];
4326           vat_json_object_add_ip4 (counter, "address", n4->address);
4327           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4328           vat_json_object_add_uint (counter, "packets", n4->packets);
4329           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4330         }
4331     }
4332
4333   /* ip6 nbr counters */
4334   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4335   vat_json_init_array (msg_array);
4336   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4337     {
4338       msg = vat_json_array_add (msg_array);
4339       vat_json_init_object (msg);
4340       vat_json_object_add_uint (msg, "sw_if_index", i);
4341       counter_array = vat_json_object_add (msg, "c");
4342       vat_json_init_array (counter_array);
4343       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4344         {
4345           counter = vat_json_array_add (counter_array);
4346           vat_json_init_object (counter);
4347           n6 = &vam->ip6_nbr_counters[i][j];
4348           vat_json_object_add_ip6 (counter, "address", n6->address);
4349           vat_json_object_add_uint (counter, "packets", n6->packets);
4350           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4351         }
4352     }
4353
4354   vat_json_print (vam->ofp, &node);
4355   vat_json_free (&node);
4356
4357   return 0;
4358 }
4359
4360 int
4361 exec (vat_main_t * vam)
4362 {
4363   api_main_t *am = &api_main;
4364   vl_api_cli_request_t *mp;
4365   f64 timeout;
4366   void *oldheap;
4367   u8 *cmd = 0;
4368   unformat_input_t *i = vam->input;
4369
4370   if (vec_len (i->buffer) == 0)
4371     return -1;
4372
4373   if (vam->exec_mode == 0 && unformat (i, "mode"))
4374     {
4375       vam->exec_mode = 1;
4376       return 0;
4377     }
4378   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4379     {
4380       vam->exec_mode = 0;
4381       return 0;
4382     }
4383
4384
4385   M (CLI_REQUEST, cli_request);
4386
4387   /*
4388    * Copy cmd into shared memory.
4389    * In order for the CLI command to work, it
4390    * must be a vector ending in \n, not a C-string ending
4391    * in \n\0.
4392    */
4393   pthread_mutex_lock (&am->vlib_rp->mutex);
4394   oldheap = svm_push_data_heap (am->vlib_rp);
4395
4396   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4397   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4398
4399   svm_pop_heap (oldheap);
4400   pthread_mutex_unlock (&am->vlib_rp->mutex);
4401
4402   mp->cmd_in_shmem = (u64) cmd;
4403   S;
4404   timeout = vat_time_now (vam) + 10.0;
4405
4406   while (vat_time_now (vam) < timeout)
4407     {
4408       if (vam->result_ready == 1)
4409         {
4410           u8 *free_me;
4411           if (vam->shmem_result != NULL)
4412             print (vam->ofp, "%s", vam->shmem_result);
4413           pthread_mutex_lock (&am->vlib_rp->mutex);
4414           oldheap = svm_push_data_heap (am->vlib_rp);
4415
4416           free_me = (u8 *) vam->shmem_result;
4417           vec_free (free_me);
4418
4419           svm_pop_heap (oldheap);
4420           pthread_mutex_unlock (&am->vlib_rp->mutex);
4421           return 0;
4422         }
4423     }
4424   return -99;
4425 }
4426
4427 /*
4428  * Future replacement of exec() that passes CLI buffers directly in
4429  * the API messages instead of an additional shared memory area.
4430  */
4431 static int
4432 exec_inband (vat_main_t * vam)
4433 {
4434   vl_api_cli_inband_t *mp;
4435   f64 timeout;
4436   unformat_input_t *i = vam->input;
4437
4438   if (vec_len (i->buffer) == 0)
4439     return -1;
4440
4441   if (vam->exec_mode == 0 && unformat (i, "mode"))
4442     {
4443       vam->exec_mode = 1;
4444       return 0;
4445     }
4446   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4447     {
4448       vam->exec_mode = 0;
4449       return 0;
4450     }
4451
4452   /*
4453    * In order for the CLI command to work, it
4454    * must be a vector ending in \n, not a C-string ending
4455    * in \n\0.
4456    */
4457   u32 len = vec_len (vam->input->buffer);
4458   M2 (CLI_INBAND, cli_inband, len);
4459   clib_memcpy (mp->cmd, vam->input->buffer, len);
4460   mp->length = htonl (len);
4461
4462   S;
4463   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4464 }
4465
4466 static int
4467 api_create_loopback (vat_main_t * vam)
4468 {
4469   unformat_input_t *i = vam->input;
4470   vl_api_create_loopback_t *mp;
4471   f64 timeout;
4472   u8 mac_address[6];
4473   u8 mac_set = 0;
4474
4475   memset (mac_address, 0, sizeof (mac_address));
4476
4477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4478     {
4479       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4480         mac_set = 1;
4481       else
4482         break;
4483     }
4484
4485   /* Construct the API message */
4486   M (CREATE_LOOPBACK, create_loopback);
4487   if (mac_set)
4488     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4489
4490   S;
4491   W;
4492 }
4493
4494 static int
4495 api_delete_loopback (vat_main_t * vam)
4496 {
4497   unformat_input_t *i = vam->input;
4498   vl_api_delete_loopback_t *mp;
4499   f64 timeout;
4500   u32 sw_if_index = ~0;
4501
4502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4503     {
4504       if (unformat (i, "sw_if_index %d", &sw_if_index))
4505         ;
4506       else
4507         break;
4508     }
4509
4510   if (sw_if_index == ~0)
4511     {
4512       errmsg ("missing sw_if_index");
4513       return -99;
4514     }
4515
4516   /* Construct the API message */
4517   M (DELETE_LOOPBACK, delete_loopback);
4518   mp->sw_if_index = ntohl (sw_if_index);
4519
4520   S;
4521   W;
4522 }
4523
4524 static int
4525 api_want_stats (vat_main_t * vam)
4526 {
4527   unformat_input_t *i = vam->input;
4528   vl_api_want_stats_t *mp;
4529   f64 timeout;
4530   int enable = -1;
4531
4532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4533     {
4534       if (unformat (i, "enable"))
4535         enable = 1;
4536       else if (unformat (i, "disable"))
4537         enable = 0;
4538       else
4539         break;
4540     }
4541
4542   if (enable == -1)
4543     {
4544       errmsg ("missing enable|disable");
4545       return -99;
4546     }
4547
4548   M (WANT_STATS, want_stats);
4549   mp->enable_disable = enable;
4550
4551   S;
4552   W;
4553 }
4554
4555 static int
4556 api_want_interface_events (vat_main_t * vam)
4557 {
4558   unformat_input_t *i = vam->input;
4559   vl_api_want_interface_events_t *mp;
4560   f64 timeout;
4561   int enable = -1;
4562
4563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4564     {
4565       if (unformat (i, "enable"))
4566         enable = 1;
4567       else if (unformat (i, "disable"))
4568         enable = 0;
4569       else
4570         break;
4571     }
4572
4573   if (enable == -1)
4574     {
4575       errmsg ("missing enable|disable");
4576       return -99;
4577     }
4578
4579   M (WANT_INTERFACE_EVENTS, want_interface_events);
4580   mp->enable_disable = enable;
4581
4582   vam->interface_event_display = enable;
4583
4584   S;
4585   W;
4586 }
4587
4588
4589 /* Note: non-static, called once to set up the initial intfc table */
4590 int
4591 api_sw_interface_dump (vat_main_t * vam)
4592 {
4593   vl_api_sw_interface_dump_t *mp;
4594   f64 timeout;
4595   hash_pair_t *p;
4596   name_sort_t *nses = 0, *ns;
4597   sw_interface_subif_t *sub = NULL;
4598
4599   /* Toss the old name table */
4600   /* *INDENT-OFF* */
4601   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4602   ({
4603     vec_add2 (nses, ns, 1);
4604     ns->name = (u8 *)(p->key);
4605     ns->value = (u32) p->value[0];
4606   }));
4607   /* *INDENT-ON* */
4608
4609   hash_free (vam->sw_if_index_by_interface_name);
4610
4611   vec_foreach (ns, nses) vec_free (ns->name);
4612
4613   vec_free (nses);
4614
4615   vec_foreach (sub, vam->sw_if_subif_table)
4616   {
4617     vec_free (sub->interface_name);
4618   }
4619   vec_free (vam->sw_if_subif_table);
4620
4621   /* recreate the interface name hash table */
4622   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4623
4624   /* Get list of ethernets */
4625   M (SW_INTERFACE_DUMP, sw_interface_dump);
4626   mp->name_filter_valid = 1;
4627   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4628   S;
4629
4630   /* and local / loopback interfaces */
4631   M (SW_INTERFACE_DUMP, sw_interface_dump);
4632   mp->name_filter_valid = 1;
4633   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4634   S;
4635
4636   /* and packet-generator interfaces */
4637   M (SW_INTERFACE_DUMP, sw_interface_dump);
4638   mp->name_filter_valid = 1;
4639   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4640   S;
4641
4642   /* and vxlan-gpe tunnel interfaces */
4643   M (SW_INTERFACE_DUMP, sw_interface_dump);
4644   mp->name_filter_valid = 1;
4645   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4646            sizeof (mp->name_filter) - 1);
4647   S;
4648
4649   /* and vxlan tunnel interfaces */
4650   M (SW_INTERFACE_DUMP, sw_interface_dump);
4651   mp->name_filter_valid = 1;
4652   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4653   S;
4654
4655   /* and host (af_packet) interfaces */
4656   M (SW_INTERFACE_DUMP, sw_interface_dump);
4657   mp->name_filter_valid = 1;
4658   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4659   S;
4660
4661   /* and l2tpv3 tunnel interfaces */
4662   M (SW_INTERFACE_DUMP, sw_interface_dump);
4663   mp->name_filter_valid = 1;
4664   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4665            sizeof (mp->name_filter) - 1);
4666   S;
4667
4668   /* and GRE tunnel interfaces */
4669   M (SW_INTERFACE_DUMP, sw_interface_dump);
4670   mp->name_filter_valid = 1;
4671   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4672   S;
4673
4674   /* and LISP-GPE interfaces */
4675   M (SW_INTERFACE_DUMP, sw_interface_dump);
4676   mp->name_filter_valid = 1;
4677   strncpy ((char *) mp->name_filter, "lisp_gpe",
4678            sizeof (mp->name_filter) - 1);
4679   S;
4680
4681   /* and IPSEC tunnel interfaces */
4682   M (SW_INTERFACE_DUMP, sw_interface_dump);
4683   mp->name_filter_valid = 1;
4684   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4685   S;
4686
4687   /* Use a control ping for synchronization */
4688   {
4689     vl_api_control_ping_t *mp;
4690     M (CONTROL_PING, control_ping);
4691     S;
4692   }
4693   W;
4694 }
4695
4696 static int
4697 api_sw_interface_set_flags (vat_main_t * vam)
4698 {
4699   unformat_input_t *i = vam->input;
4700   vl_api_sw_interface_set_flags_t *mp;
4701   f64 timeout;
4702   u32 sw_if_index;
4703   u8 sw_if_index_set = 0;
4704   u8 admin_up = 0, link_up = 0;
4705
4706   /* Parse args required to build the message */
4707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4708     {
4709       if (unformat (i, "admin-up"))
4710         admin_up = 1;
4711       else if (unformat (i, "admin-down"))
4712         admin_up = 0;
4713       else if (unformat (i, "link-up"))
4714         link_up = 1;
4715       else if (unformat (i, "link-down"))
4716         link_up = 0;
4717       else
4718         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4719         sw_if_index_set = 1;
4720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4721         sw_if_index_set = 1;
4722       else
4723         break;
4724     }
4725
4726   if (sw_if_index_set == 0)
4727     {
4728       errmsg ("missing interface name or sw_if_index");
4729       return -99;
4730     }
4731
4732   /* Construct the API message */
4733   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4734   mp->sw_if_index = ntohl (sw_if_index);
4735   mp->admin_up_down = admin_up;
4736   mp->link_up_down = link_up;
4737
4738   /* send it... */
4739   S;
4740
4741   /* Wait for a reply, return the good/bad news... */
4742   W;
4743 }
4744
4745 static int
4746 api_sw_interface_clear_stats (vat_main_t * vam)
4747 {
4748   unformat_input_t *i = vam->input;
4749   vl_api_sw_interface_clear_stats_t *mp;
4750   f64 timeout;
4751   u32 sw_if_index;
4752   u8 sw_if_index_set = 0;
4753
4754   /* Parse args required to build the message */
4755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4756     {
4757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4758         sw_if_index_set = 1;
4759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4760         sw_if_index_set = 1;
4761       else
4762         break;
4763     }
4764
4765   /* Construct the API message */
4766   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4767
4768   if (sw_if_index_set == 1)
4769     mp->sw_if_index = ntohl (sw_if_index);
4770   else
4771     mp->sw_if_index = ~0;
4772
4773   /* send it... */
4774   S;
4775
4776   /* Wait for a reply, return the good/bad news... */
4777   W;
4778 }
4779
4780 #if DPDK >0
4781 static int
4782 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4783 {
4784   unformat_input_t *i = vam->input;
4785   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4786   f64 timeout;
4787   u32 sw_if_index;
4788   u8 sw_if_index_set = 0;
4789   u32 subport;
4790   u8 subport_set = 0;
4791   u32 pipe;
4792   u8 pipe_set = 0;
4793   u32 profile;
4794   u8 profile_set = 0;
4795
4796   /* Parse args required to build the message */
4797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4798     {
4799       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4800         sw_if_index_set = 1;
4801       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4802         sw_if_index_set = 1;
4803       else if (unformat (i, "subport %u", &subport))
4804         subport_set = 1;
4805       else
4806         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4807         sw_if_index_set = 1;
4808       else if (unformat (i, "pipe %u", &pipe))
4809         pipe_set = 1;
4810       else if (unformat (i, "profile %u", &profile))
4811         profile_set = 1;
4812       else
4813         break;
4814     }
4815
4816   if (sw_if_index_set == 0)
4817     {
4818       errmsg ("missing interface name or sw_if_index");
4819       return -99;
4820     }
4821
4822   if (subport_set == 0)
4823     {
4824       errmsg ("missing subport ");
4825       return -99;
4826     }
4827
4828   if (pipe_set == 0)
4829     {
4830       errmsg ("missing pipe");
4831       return -99;
4832     }
4833
4834   if (profile_set == 0)
4835     {
4836       errmsg ("missing profile");
4837       return -99;
4838     }
4839
4840   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4841
4842   mp->sw_if_index = ntohl (sw_if_index);
4843   mp->subport = ntohl (subport);
4844   mp->pipe = ntohl (pipe);
4845   mp->profile = ntohl (profile);
4846
4847
4848   S;
4849   W;
4850   /* NOTREACHED */
4851   return 0;
4852 }
4853
4854 static int
4855 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4856 {
4857   unformat_input_t *i = vam->input;
4858   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4859   f64 timeout;
4860   u32 sw_if_index;
4861   u8 sw_if_index_set = 0;
4862   u32 subport;
4863   u8 subport_set = 0;
4864   u32 tb_rate = 1250000000;     /* 10GbE */
4865   u32 tb_size = 1000000;
4866   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4867   u32 tc_period = 10;
4868
4869   /* Parse args required to build the message */
4870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4871     {
4872       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4873         sw_if_index_set = 1;
4874       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4875         sw_if_index_set = 1;
4876       else if (unformat (i, "subport %u", &subport))
4877         subport_set = 1;
4878       else
4879         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4880         sw_if_index_set = 1;
4881       else if (unformat (i, "rate %u", &tb_rate))
4882         {
4883           u32 tc_id;
4884
4885           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4886                tc_id++)
4887             tc_rate[tc_id] = tb_rate;
4888         }
4889       else if (unformat (i, "bktsize %u", &tb_size))
4890         ;
4891       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4892         ;
4893       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4894         ;
4895       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4896         ;
4897       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4898         ;
4899       else if (unformat (i, "period %u", &tc_period))
4900         ;
4901       else
4902         break;
4903     }
4904
4905   if (sw_if_index_set == 0)
4906     {
4907       errmsg ("missing interface name or sw_if_index");
4908       return -99;
4909     }
4910
4911   if (subport_set == 0)
4912     {
4913       errmsg ("missing subport ");
4914       return -99;
4915     }
4916
4917   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4918
4919   mp->sw_if_index = ntohl (sw_if_index);
4920   mp->subport = ntohl (subport);
4921   mp->tb_rate = ntohl (tb_rate);
4922   mp->tb_size = ntohl (tb_size);
4923   mp->tc_rate[0] = ntohl (tc_rate[0]);
4924   mp->tc_rate[1] = ntohl (tc_rate[1]);
4925   mp->tc_rate[2] = ntohl (tc_rate[2]);
4926   mp->tc_rate[3] = ntohl (tc_rate[3]);
4927   mp->tc_period = ntohl (tc_period);
4928
4929   S;
4930   W;
4931   /* NOTREACHED */
4932   return 0;
4933 }
4934
4935 static int
4936 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4937 {
4938   unformat_input_t *i = vam->input;
4939   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4940   f64 timeout;
4941   u32 sw_if_index;
4942   u8 sw_if_index_set = 0;
4943   u8 entry_set = 0;
4944   u8 tc_set = 0;
4945   u8 queue_set = 0;
4946   u32 entry, tc, queue;
4947
4948   /* Parse args required to build the message */
4949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4950     {
4951       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4952         sw_if_index_set = 1;
4953       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4954         sw_if_index_set = 1;
4955       else if (unformat (i, "entry %d", &entry))
4956         entry_set = 1;
4957       else if (unformat (i, "tc %d", &tc))
4958         tc_set = 1;
4959       else if (unformat (i, "queue %d", &queue))
4960         queue_set = 1;
4961       else
4962         break;
4963     }
4964
4965   if (sw_if_index_set == 0)
4966     {
4967       errmsg ("missing interface name or sw_if_index");
4968       return -99;
4969     }
4970
4971   if (entry_set == 0)
4972     {
4973       errmsg ("missing entry ");
4974       return -99;
4975     }
4976
4977   if (tc_set == 0)
4978     {
4979       errmsg ("missing traffic class ");
4980       return -99;
4981     }
4982
4983   if (queue_set == 0)
4984     {
4985       errmsg ("missing queue ");
4986       return -99;
4987     }
4988
4989   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4990
4991   mp->sw_if_index = ntohl (sw_if_index);
4992   mp->entry = ntohl (entry);
4993   mp->tc = ntohl (tc);
4994   mp->queue = ntohl (queue);
4995
4996   S;
4997   W;
4998   /* NOTREACHED */
4999   return 0;
5000 }
5001 #endif
5002
5003 static int
5004 api_sw_interface_add_del_address (vat_main_t * vam)
5005 {
5006   unformat_input_t *i = vam->input;
5007   vl_api_sw_interface_add_del_address_t *mp;
5008   f64 timeout;
5009   u32 sw_if_index;
5010   u8 sw_if_index_set = 0;
5011   u8 is_add = 1, del_all = 0;
5012   u32 address_length = 0;
5013   u8 v4_address_set = 0;
5014   u8 v6_address_set = 0;
5015   ip4_address_t v4address;
5016   ip6_address_t v6address;
5017
5018   /* Parse args required to build the message */
5019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5020     {
5021       if (unformat (i, "del-all"))
5022         del_all = 1;
5023       else if (unformat (i, "del"))
5024         is_add = 0;
5025       else
5026         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5027         sw_if_index_set = 1;
5028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5029         sw_if_index_set = 1;
5030       else if (unformat (i, "%U/%d",
5031                          unformat_ip4_address, &v4address, &address_length))
5032         v4_address_set = 1;
5033       else if (unformat (i, "%U/%d",
5034                          unformat_ip6_address, &v6address, &address_length))
5035         v6_address_set = 1;
5036       else
5037         break;
5038     }
5039
5040   if (sw_if_index_set == 0)
5041     {
5042       errmsg ("missing interface name or sw_if_index");
5043       return -99;
5044     }
5045   if (v4_address_set && v6_address_set)
5046     {
5047       errmsg ("both v4 and v6 addresses set");
5048       return -99;
5049     }
5050   if (!v4_address_set && !v6_address_set && !del_all)
5051     {
5052       errmsg ("no addresses set");
5053       return -99;
5054     }
5055
5056   /* Construct the API message */
5057   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5058
5059   mp->sw_if_index = ntohl (sw_if_index);
5060   mp->is_add = is_add;
5061   mp->del_all = del_all;
5062   if (v6_address_set)
5063     {
5064       mp->is_ipv6 = 1;
5065       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5066     }
5067   else
5068     {
5069       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5070     }
5071   mp->address_length = address_length;
5072
5073   /* send it... */
5074   S;
5075
5076   /* Wait for a reply, return good/bad news  */
5077   W;
5078 }
5079
5080 static int
5081 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5082 {
5083   unformat_input_t *i = vam->input;
5084   vl_api_sw_interface_set_mpls_enable_t *mp;
5085   f64 timeout;
5086   u32 sw_if_index;
5087   u8 sw_if_index_set = 0;
5088   u8 enable = 1;
5089
5090   /* Parse args required to build the message */
5091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5092     {
5093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5094         sw_if_index_set = 1;
5095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5096         sw_if_index_set = 1;
5097       else if (unformat (i, "disable"))
5098         enable = 0;
5099       else if (unformat (i, "dis"))
5100         enable = 0;
5101       else
5102         break;
5103     }
5104
5105   if (sw_if_index_set == 0)
5106     {
5107       errmsg ("missing interface name or sw_if_index");
5108       return -99;
5109     }
5110
5111   /* Construct the API message */
5112   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5113
5114   mp->sw_if_index = ntohl (sw_if_index);
5115   mp->enable = enable;
5116
5117   /* send it... */
5118   S;
5119
5120   /* Wait for a reply... */
5121   W;
5122 }
5123
5124 static int
5125 api_sw_interface_set_table (vat_main_t * vam)
5126 {
5127   unformat_input_t *i = vam->input;
5128   vl_api_sw_interface_set_table_t *mp;
5129   f64 timeout;
5130   u32 sw_if_index, vrf_id = 0;
5131   u8 sw_if_index_set = 0;
5132   u8 is_ipv6 = 0;
5133
5134   /* Parse args required to build the message */
5135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5136     {
5137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5138         sw_if_index_set = 1;
5139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5140         sw_if_index_set = 1;
5141       else if (unformat (i, "vrf %d", &vrf_id))
5142         ;
5143       else if (unformat (i, "ipv6"))
5144         is_ipv6 = 1;
5145       else
5146         break;
5147     }
5148
5149   if (sw_if_index_set == 0)
5150     {
5151       errmsg ("missing interface name or sw_if_index");
5152       return -99;
5153     }
5154
5155   /* Construct the API message */
5156   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5157
5158   mp->sw_if_index = ntohl (sw_if_index);
5159   mp->is_ipv6 = is_ipv6;
5160   mp->vrf_id = ntohl (vrf_id);
5161
5162   /* send it... */
5163   S;
5164
5165   /* Wait for a reply... */
5166   W;
5167 }
5168
5169 static void vl_api_sw_interface_get_table_reply_t_handler
5170   (vl_api_sw_interface_get_table_reply_t * mp)
5171 {
5172   vat_main_t *vam = &vat_main;
5173
5174   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5175
5176   vam->retval = ntohl (mp->retval);
5177   vam->result_ready = 1;
5178
5179 }
5180
5181 static void vl_api_sw_interface_get_table_reply_t_handler_json
5182   (vl_api_sw_interface_get_table_reply_t * mp)
5183 {
5184   vat_main_t *vam = &vat_main;
5185   vat_json_node_t node;
5186
5187   vat_json_init_object (&node);
5188   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5189   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5190
5191   vat_json_print (vam->ofp, &node);
5192   vat_json_free (&node);
5193
5194   vam->retval = ntohl (mp->retval);
5195   vam->result_ready = 1;
5196 }
5197
5198 static int
5199 api_sw_interface_get_table (vat_main_t * vam)
5200 {
5201   unformat_input_t *i = vam->input;
5202   vl_api_sw_interface_get_table_t *mp;
5203   u32 sw_if_index;
5204   u8 sw_if_index_set = 0;
5205   u8 is_ipv6 = 0;
5206   f64 timeout;
5207
5208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5209     {
5210       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5211         sw_if_index_set = 1;
5212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5213         sw_if_index_set = 1;
5214       else if (unformat (i, "ipv6"))
5215         is_ipv6 = 1;
5216       else
5217         break;
5218     }
5219
5220   if (sw_if_index_set == 0)
5221     {
5222       errmsg ("missing interface name or sw_if_index");
5223       return -99;
5224     }
5225
5226   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5227   mp->sw_if_index = htonl (sw_if_index);
5228   mp->is_ipv6 = is_ipv6;
5229
5230   S;
5231   W;
5232 }
5233
5234 static int
5235 api_sw_interface_set_vpath (vat_main_t * vam)
5236 {
5237   unformat_input_t *i = vam->input;
5238   vl_api_sw_interface_set_vpath_t *mp;
5239   f64 timeout;
5240   u32 sw_if_index = 0;
5241   u8 sw_if_index_set = 0;
5242   u8 is_enable = 0;
5243
5244   /* Parse args required to build the message */
5245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5246     {
5247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5248         sw_if_index_set = 1;
5249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5250         sw_if_index_set = 1;
5251       else if (unformat (i, "enable"))
5252         is_enable = 1;
5253       else if (unformat (i, "disable"))
5254         is_enable = 0;
5255       else
5256         break;
5257     }
5258
5259   if (sw_if_index_set == 0)
5260     {
5261       errmsg ("missing interface name or sw_if_index");
5262       return -99;
5263     }
5264
5265   /* Construct the API message */
5266   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5267
5268   mp->sw_if_index = ntohl (sw_if_index);
5269   mp->enable = is_enable;
5270
5271   /* send it... */
5272   S;
5273
5274   /* Wait for a reply... */
5275   W;
5276 }
5277
5278 static int
5279 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5280 {
5281   unformat_input_t *i = vam->input;
5282   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5283   f64 timeout;
5284   u32 sw_if_index = 0;
5285   u8 sw_if_index_set = 0;
5286   u8 is_enable = 0;
5287   u8 is_ipv6 = 0;
5288
5289   /* Parse args required to build the message */
5290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5291     {
5292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5293         sw_if_index_set = 1;
5294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5295         sw_if_index_set = 1;
5296       else if (unformat (i, "enable"))
5297         is_enable = 1;
5298       else if (unformat (i, "disable"))
5299         is_enable = 0;
5300       else if (unformat (i, "ip4"))
5301         is_ipv6 = 0;
5302       else if (unformat (i, "ip6"))
5303         is_ipv6 = 1;
5304       else
5305         break;
5306     }
5307
5308   if (sw_if_index_set == 0)
5309     {
5310       errmsg ("missing interface name or sw_if_index");
5311       return -99;
5312     }
5313
5314   /* Construct the API message */
5315   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5316
5317   mp->sw_if_index = ntohl (sw_if_index);
5318   mp->enable = is_enable;
5319   mp->is_ipv6 = is_ipv6;
5320
5321   /* send it... */
5322   S;
5323
5324   /* Wait for a reply... */
5325   W;
5326 }
5327
5328 static int
5329 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5330 {
5331   unformat_input_t *i = vam->input;
5332   vl_api_sw_interface_set_l2_xconnect_t *mp;
5333   f64 timeout;
5334   u32 rx_sw_if_index;
5335   u8 rx_sw_if_index_set = 0;
5336   u32 tx_sw_if_index;
5337   u8 tx_sw_if_index_set = 0;
5338   u8 enable = 1;
5339
5340   /* Parse args required to build the message */
5341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5342     {
5343       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5344         rx_sw_if_index_set = 1;
5345       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5346         tx_sw_if_index_set = 1;
5347       else if (unformat (i, "rx"))
5348         {
5349           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5350             {
5351               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5352                             &rx_sw_if_index))
5353                 rx_sw_if_index_set = 1;
5354             }
5355           else
5356             break;
5357         }
5358       else if (unformat (i, "tx"))
5359         {
5360           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5361             {
5362               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5363                             &tx_sw_if_index))
5364                 tx_sw_if_index_set = 1;
5365             }
5366           else
5367             break;
5368         }
5369       else if (unformat (i, "enable"))
5370         enable = 1;
5371       else if (unformat (i, "disable"))
5372         enable = 0;
5373       else
5374         break;
5375     }
5376
5377   if (rx_sw_if_index_set == 0)
5378     {
5379       errmsg ("missing rx interface name or rx_sw_if_index");
5380       return -99;
5381     }
5382
5383   if (enable && (tx_sw_if_index_set == 0))
5384     {
5385       errmsg ("missing tx interface name or tx_sw_if_index");
5386       return -99;
5387     }
5388
5389   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5390
5391   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5392   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5393   mp->enable = enable;
5394
5395   S;
5396   W;
5397   /* NOTREACHED */
5398   return 0;
5399 }
5400
5401 static int
5402 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5403 {
5404   unformat_input_t *i = vam->input;
5405   vl_api_sw_interface_set_l2_bridge_t *mp;
5406   f64 timeout;
5407   u32 rx_sw_if_index;
5408   u8 rx_sw_if_index_set = 0;
5409   u32 bd_id;
5410   u8 bd_id_set = 0;
5411   u8 bvi = 0;
5412   u32 shg = 0;
5413   u8 enable = 1;
5414
5415   /* Parse args required to build the message */
5416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5417     {
5418       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5419         rx_sw_if_index_set = 1;
5420       else if (unformat (i, "bd_id %d", &bd_id))
5421         bd_id_set = 1;
5422       else
5423         if (unformat
5424             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5425         rx_sw_if_index_set = 1;
5426       else if (unformat (i, "shg %d", &shg))
5427         ;
5428       else if (unformat (i, "bvi"))
5429         bvi = 1;
5430       else if (unformat (i, "enable"))
5431         enable = 1;
5432       else if (unformat (i, "disable"))
5433         enable = 0;
5434       else
5435         break;
5436     }
5437
5438   if (rx_sw_if_index_set == 0)
5439     {
5440       errmsg ("missing rx interface name or sw_if_index");
5441       return -99;
5442     }
5443
5444   if (enable && (bd_id_set == 0))
5445     {
5446       errmsg ("missing bridge domain");
5447       return -99;
5448     }
5449
5450   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5451
5452   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5453   mp->bd_id = ntohl (bd_id);
5454   mp->shg = (u8) shg;
5455   mp->bvi = bvi;
5456   mp->enable = enable;
5457
5458   S;
5459   W;
5460   /* NOTREACHED */
5461   return 0;
5462 }
5463
5464 static int
5465 api_bridge_domain_dump (vat_main_t * vam)
5466 {
5467   unformat_input_t *i = vam->input;
5468   vl_api_bridge_domain_dump_t *mp;
5469   f64 timeout;
5470   u32 bd_id = ~0;
5471
5472   /* Parse args required to build the message */
5473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5474     {
5475       if (unformat (i, "bd_id %d", &bd_id))
5476         ;
5477       else
5478         break;
5479     }
5480
5481   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5482   mp->bd_id = ntohl (bd_id);
5483   S;
5484
5485   /* Use a control ping for synchronization */
5486   {
5487     vl_api_control_ping_t *mp;
5488     M (CONTROL_PING, control_ping);
5489     S;
5490   }
5491
5492   W;
5493   /* NOTREACHED */
5494   return 0;
5495 }
5496
5497 static int
5498 api_bridge_domain_add_del (vat_main_t * vam)
5499 {
5500   unformat_input_t *i = vam->input;
5501   vl_api_bridge_domain_add_del_t *mp;
5502   f64 timeout;
5503   u32 bd_id = ~0;
5504   u8 is_add = 1;
5505   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5506   u32 mac_age = 0;
5507
5508   /* Parse args required to build the message */
5509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5510     {
5511       if (unformat (i, "bd_id %d", &bd_id))
5512         ;
5513       else if (unformat (i, "flood %d", &flood))
5514         ;
5515       else if (unformat (i, "uu-flood %d", &uu_flood))
5516         ;
5517       else if (unformat (i, "forward %d", &forward))
5518         ;
5519       else if (unformat (i, "learn %d", &learn))
5520         ;
5521       else if (unformat (i, "arp-term %d", &arp_term))
5522         ;
5523       else if (unformat (i, "mac-age %d", &mac_age))
5524         ;
5525       else if (unformat (i, "del"))
5526         {
5527           is_add = 0;
5528           flood = uu_flood = forward = learn = 0;
5529         }
5530       else
5531         break;
5532     }
5533
5534   if (bd_id == ~0)
5535     {
5536       errmsg ("missing bridge domain");
5537       return -99;
5538     }
5539
5540   if (mac_age > 255)
5541     {
5542       errmsg ("mac age must be less than 256 ");
5543       return -99;
5544     }
5545
5546   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5547
5548   mp->bd_id = ntohl (bd_id);
5549   mp->flood = flood;
5550   mp->uu_flood = uu_flood;
5551   mp->forward = forward;
5552   mp->learn = learn;
5553   mp->arp_term = arp_term;
5554   mp->is_add = is_add;
5555   mp->mac_age = (u8) mac_age;
5556
5557   S;
5558   W;
5559   /* NOTREACHED */
5560   return 0;
5561 }
5562
5563 static int
5564 api_l2fib_add_del (vat_main_t * vam)
5565 {
5566   unformat_input_t *i = vam->input;
5567   vl_api_l2fib_add_del_t *mp;
5568   f64 timeout;
5569   u64 mac = 0;
5570   u8 mac_set = 0;
5571   u32 bd_id;
5572   u8 bd_id_set = 0;
5573   u32 sw_if_index = ~0;
5574   u8 sw_if_index_set = 0;
5575   u8 is_add = 1;
5576   u8 static_mac = 0;
5577   u8 filter_mac = 0;
5578   u8 bvi_mac = 0;
5579   int count = 1;
5580   f64 before = 0;
5581   int j;
5582
5583   /* Parse args required to build the message */
5584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5585     {
5586       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5587         mac_set = 1;
5588       else if (unformat (i, "bd_id %d", &bd_id))
5589         bd_id_set = 1;
5590       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5591         sw_if_index_set = 1;
5592       else if (unformat (i, "sw_if"))
5593         {
5594           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5595             {
5596               if (unformat
5597                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5598                 sw_if_index_set = 1;
5599             }
5600           else
5601             break;
5602         }
5603       else if (unformat (i, "static"))
5604         static_mac = 1;
5605       else if (unformat (i, "filter"))
5606         {
5607           filter_mac = 1;
5608           static_mac = 1;
5609         }
5610       else if (unformat (i, "bvi"))
5611         {
5612           bvi_mac = 1;
5613           static_mac = 1;
5614         }
5615       else if (unformat (i, "del"))
5616         is_add = 0;
5617       else if (unformat (i, "count %d", &count))
5618         ;
5619       else
5620         break;
5621     }
5622
5623   if (mac_set == 0)
5624     {
5625       errmsg ("missing mac address");
5626       return -99;
5627     }
5628
5629   if (bd_id_set == 0)
5630     {
5631       errmsg ("missing bridge domain");
5632       return -99;
5633     }
5634
5635   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5636     {
5637       errmsg ("missing interface name or sw_if_index");
5638       return -99;
5639     }
5640
5641   if (count > 1)
5642     {
5643       /* Turn on async mode */
5644       vam->async_mode = 1;
5645       vam->async_errors = 0;
5646       before = vat_time_now (vam);
5647     }
5648
5649   for (j = 0; j < count; j++)
5650     {
5651       M (L2FIB_ADD_DEL, l2fib_add_del);
5652
5653       mp->mac = mac;
5654       mp->bd_id = ntohl (bd_id);
5655       mp->is_add = is_add;
5656
5657       if (is_add)
5658         {
5659           mp->sw_if_index = ntohl (sw_if_index);
5660           mp->static_mac = static_mac;
5661           mp->filter_mac = filter_mac;
5662           mp->bvi_mac = bvi_mac;
5663         }
5664       increment_mac_address (&mac);
5665       /* send it... */
5666       S;
5667     }
5668
5669   if (count > 1)
5670     {
5671       vl_api_control_ping_t *mp;
5672       f64 after;
5673
5674       /* Shut off async mode */
5675       vam->async_mode = 0;
5676
5677       M (CONTROL_PING, control_ping);
5678       S;
5679
5680       timeout = vat_time_now (vam) + 1.0;
5681       while (vat_time_now (vam) < timeout)
5682         if (vam->result_ready == 1)
5683           goto out;
5684       vam->retval = -99;
5685
5686     out:
5687       if (vam->retval == -99)
5688         errmsg ("timeout");
5689
5690       if (vam->async_errors > 0)
5691         {
5692           errmsg ("%d asynchronous errors", vam->async_errors);
5693           vam->retval = -98;
5694         }
5695       vam->async_errors = 0;
5696       after = vat_time_now (vam);
5697
5698       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5699              count, after - before, count / (after - before));
5700     }
5701   else
5702     {
5703       /* Wait for a reply... */
5704       W;
5705     }
5706   /* Return the good/bad news */
5707   return (vam->retval);
5708 }
5709
5710 static int
5711 api_l2_flags (vat_main_t * vam)
5712 {
5713   unformat_input_t *i = vam->input;
5714   vl_api_l2_flags_t *mp;
5715   f64 timeout;
5716   u32 sw_if_index;
5717   u32 feature_bitmap = 0;
5718   u8 sw_if_index_set = 0;
5719
5720   /* Parse args required to build the message */
5721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5722     {
5723       if (unformat (i, "sw_if_index %d", &sw_if_index))
5724         sw_if_index_set = 1;
5725       else if (unformat (i, "sw_if"))
5726         {
5727           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5728             {
5729               if (unformat
5730                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5731                 sw_if_index_set = 1;
5732             }
5733           else
5734             break;
5735         }
5736       else if (unformat (i, "learn"))
5737         feature_bitmap |= L2INPUT_FEAT_LEARN;
5738       else if (unformat (i, "forward"))
5739         feature_bitmap |= L2INPUT_FEAT_FWD;
5740       else if (unformat (i, "flood"))
5741         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5742       else if (unformat (i, "uu-flood"))
5743         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5744       else
5745         break;
5746     }
5747
5748   if (sw_if_index_set == 0)
5749     {
5750       errmsg ("missing interface name or sw_if_index");
5751       return -99;
5752     }
5753
5754   M (L2_FLAGS, l2_flags);
5755
5756   mp->sw_if_index = ntohl (sw_if_index);
5757   mp->feature_bitmap = ntohl (feature_bitmap);
5758
5759   S;
5760   W;
5761   /* NOTREACHED */
5762   return 0;
5763 }
5764
5765 static int
5766 api_bridge_flags (vat_main_t * vam)
5767 {
5768   unformat_input_t *i = vam->input;
5769   vl_api_bridge_flags_t *mp;
5770   f64 timeout;
5771   u32 bd_id;
5772   u8 bd_id_set = 0;
5773   u8 is_set = 1;
5774   u32 flags = 0;
5775
5776   /* Parse args required to build the message */
5777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5778     {
5779       if (unformat (i, "bd_id %d", &bd_id))
5780         bd_id_set = 1;
5781       else if (unformat (i, "learn"))
5782         flags |= L2_LEARN;
5783       else if (unformat (i, "forward"))
5784         flags |= L2_FWD;
5785       else if (unformat (i, "flood"))
5786         flags |= L2_FLOOD;
5787       else if (unformat (i, "uu-flood"))
5788         flags |= L2_UU_FLOOD;
5789       else if (unformat (i, "arp-term"))
5790         flags |= L2_ARP_TERM;
5791       else if (unformat (i, "off"))
5792         is_set = 0;
5793       else if (unformat (i, "disable"))
5794         is_set = 0;
5795       else
5796         break;
5797     }
5798
5799   if (bd_id_set == 0)
5800     {
5801       errmsg ("missing bridge domain");
5802       return -99;
5803     }
5804
5805   M (BRIDGE_FLAGS, bridge_flags);
5806
5807   mp->bd_id = ntohl (bd_id);
5808   mp->feature_bitmap = ntohl (flags);
5809   mp->is_set = is_set;
5810
5811   S;
5812   W;
5813   /* NOTREACHED */
5814   return 0;
5815 }
5816
5817 static int
5818 api_bd_ip_mac_add_del (vat_main_t * vam)
5819 {
5820   unformat_input_t *i = vam->input;
5821   vl_api_bd_ip_mac_add_del_t *mp;
5822   f64 timeout;
5823   u32 bd_id;
5824   u8 is_ipv6 = 0;
5825   u8 is_add = 1;
5826   u8 bd_id_set = 0;
5827   u8 ip_set = 0;
5828   u8 mac_set = 0;
5829   ip4_address_t v4addr;
5830   ip6_address_t v6addr;
5831   u8 macaddr[6];
5832
5833
5834   /* Parse args required to build the message */
5835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5836     {
5837       if (unformat (i, "bd_id %d", &bd_id))
5838         {
5839           bd_id_set++;
5840         }
5841       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5842         {
5843           ip_set++;
5844         }
5845       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5846         {
5847           ip_set++;
5848           is_ipv6++;
5849         }
5850       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5851         {
5852           mac_set++;
5853         }
5854       else if (unformat (i, "del"))
5855         is_add = 0;
5856       else
5857         break;
5858     }
5859
5860   if (bd_id_set == 0)
5861     {
5862       errmsg ("missing bridge domain");
5863       return -99;
5864     }
5865   else if (ip_set == 0)
5866     {
5867       errmsg ("missing IP address");
5868       return -99;
5869     }
5870   else if (mac_set == 0)
5871     {
5872       errmsg ("missing MAC address");
5873       return -99;
5874     }
5875
5876   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5877
5878   mp->bd_id = ntohl (bd_id);
5879   mp->is_ipv6 = is_ipv6;
5880   mp->is_add = is_add;
5881   if (is_ipv6)
5882     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5883   else
5884     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5885   clib_memcpy (mp->mac_address, macaddr, 6);
5886   S;
5887   W;
5888   /* NOTREACHED */
5889   return 0;
5890 }
5891
5892 static int
5893 api_tap_connect (vat_main_t * vam)
5894 {
5895   unformat_input_t *i = vam->input;
5896   vl_api_tap_connect_t *mp;
5897   f64 timeout;
5898   u8 mac_address[6];
5899   u8 random_mac = 1;
5900   u8 name_set = 0;
5901   u8 *tap_name;
5902   u8 *tag = 0;
5903   ip4_address_t ip4_address;
5904   u32 ip4_mask_width;
5905   int ip4_address_set = 0;
5906   ip6_address_t ip6_address;
5907   u32 ip6_mask_width;
5908   int ip6_address_set = 0;
5909
5910   memset (mac_address, 0, sizeof (mac_address));
5911
5912   /* Parse args required to build the message */
5913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5914     {
5915       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5916         {
5917           random_mac = 0;
5918         }
5919       else if (unformat (i, "random-mac"))
5920         random_mac = 1;
5921       else if (unformat (i, "tapname %s", &tap_name))
5922         name_set = 1;
5923       else if (unformat (i, "tag %s", &tag))
5924         ;
5925       else if (unformat (i, "address %U/%d",
5926                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
5927         ip4_address_set = 1;
5928       else if (unformat (i, "address %U/%d",
5929                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
5930         ip6_address_set = 1;
5931       else
5932         break;
5933     }
5934
5935   if (name_set == 0)
5936     {
5937       errmsg ("missing tap name");
5938       return -99;
5939     }
5940   if (vec_len (tap_name) > 63)
5941     {
5942       errmsg ("tap name too long");
5943       return -99;
5944     }
5945   vec_add1 (tap_name, 0);
5946
5947   if (vec_len (tag) > 63)
5948     {
5949       errmsg ("tag too long");
5950       return -99;
5951     }
5952
5953   /* Construct the API message */
5954   M (TAP_CONNECT, tap_connect);
5955
5956   mp->use_random_mac = random_mac;
5957   clib_memcpy (mp->mac_address, mac_address, 6);
5958   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5959   if (tag)
5960     clib_memcpy (mp->tag, tag, vec_len (tag));
5961
5962   if (ip4_address_set)
5963     {
5964       mp->ip4_address_set = 1;
5965       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
5966       mp->ip4_mask_width = ip4_mask_width;
5967     }
5968   if (ip6_address_set)
5969     {
5970       mp->ip6_address_set = 1;
5971       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
5972       mp->ip6_mask_width = ip6_mask_width;
5973     }
5974
5975   vec_free (tap_name);
5976   vec_free (tag);
5977
5978   /* send it... */
5979   S;
5980
5981   /* Wait for a reply... */
5982   W;
5983 }
5984
5985 static int
5986 api_tap_modify (vat_main_t * vam)
5987 {
5988   unformat_input_t *i = vam->input;
5989   vl_api_tap_modify_t *mp;
5990   f64 timeout;
5991   u8 mac_address[6];
5992   u8 random_mac = 1;
5993   u8 name_set = 0;
5994   u8 *tap_name;
5995   u32 sw_if_index = ~0;
5996   u8 sw_if_index_set = 0;
5997
5998   memset (mac_address, 0, sizeof (mac_address));
5999
6000   /* Parse args required to build the message */
6001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6002     {
6003       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6004         sw_if_index_set = 1;
6005       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6006         sw_if_index_set = 1;
6007       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6008         {
6009           random_mac = 0;
6010         }
6011       else if (unformat (i, "random-mac"))
6012         random_mac = 1;
6013       else if (unformat (i, "tapname %s", &tap_name))
6014         name_set = 1;
6015       else
6016         break;
6017     }
6018
6019   if (sw_if_index_set == 0)
6020     {
6021       errmsg ("missing vpp interface name");
6022       return -99;
6023     }
6024   if (name_set == 0)
6025     {
6026       errmsg ("missing tap name");
6027       return -99;
6028     }
6029   if (vec_len (tap_name) > 63)
6030     {
6031       errmsg ("tap name too long");
6032     }
6033   vec_add1 (tap_name, 0);
6034
6035   /* Construct the API message */
6036   M (TAP_MODIFY, tap_modify);
6037
6038   mp->use_random_mac = random_mac;
6039   mp->sw_if_index = ntohl (sw_if_index);
6040   clib_memcpy (mp->mac_address, mac_address, 6);
6041   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6042   vec_free (tap_name);
6043
6044   /* send it... */
6045   S;
6046
6047   /* Wait for a reply... */
6048   W;
6049 }
6050
6051 static int
6052 api_tap_delete (vat_main_t * vam)
6053 {
6054   unformat_input_t *i = vam->input;
6055   vl_api_tap_delete_t *mp;
6056   f64 timeout;
6057   u32 sw_if_index = ~0;
6058   u8 sw_if_index_set = 0;
6059
6060   /* Parse args required to build the message */
6061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6062     {
6063       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6064         sw_if_index_set = 1;
6065       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6066         sw_if_index_set = 1;
6067       else
6068         break;
6069     }
6070
6071   if (sw_if_index_set == 0)
6072     {
6073       errmsg ("missing vpp interface name");
6074       return -99;
6075     }
6076
6077   /* Construct the API message */
6078   M (TAP_DELETE, tap_delete);
6079
6080   mp->sw_if_index = ntohl (sw_if_index);
6081
6082   /* send it... */
6083   S;
6084
6085   /* Wait for a reply... */
6086   W;
6087 }
6088
6089 static int
6090 api_ip_add_del_route (vat_main_t * vam)
6091 {
6092   unformat_input_t *i = vam->input;
6093   vl_api_ip_add_del_route_t *mp;
6094   f64 timeout;
6095   u32 sw_if_index = ~0, vrf_id = 0;
6096   u8 is_ipv6 = 0;
6097   u8 is_local = 0, is_drop = 0;
6098   u8 is_unreach = 0, is_prohibit = 0;
6099   u8 create_vrf_if_needed = 0;
6100   u8 is_add = 1;
6101   u32 next_hop_weight = 1;
6102   u8 not_last = 0;
6103   u8 is_multipath = 0;
6104   u8 address_set = 0;
6105   u8 address_length_set = 0;
6106   u32 next_hop_table_id = 0;
6107   u32 resolve_attempts = 0;
6108   u32 dst_address_length = 0;
6109   u8 next_hop_set = 0;
6110   ip4_address_t v4_dst_address, v4_next_hop_address;
6111   ip6_address_t v6_dst_address, v6_next_hop_address;
6112   int count = 1;
6113   int j;
6114   f64 before = 0;
6115   u32 random_add_del = 0;
6116   u32 *random_vector = 0;
6117   uword *random_hash;
6118   u32 random_seed = 0xdeaddabe;
6119   u32 classify_table_index = ~0;
6120   u8 is_classify = 0;
6121   u8 resolve_host = 0, resolve_attached = 0;
6122   mpls_label_t *next_hop_out_label_stack = NULL;
6123   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6124   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6125
6126   /* Parse args required to build the message */
6127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6128     {
6129       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6130         ;
6131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6132         ;
6133       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6134         {
6135           address_set = 1;
6136           is_ipv6 = 0;
6137         }
6138       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6139         {
6140           address_set = 1;
6141           is_ipv6 = 1;
6142         }
6143       else if (unformat (i, "/%d", &dst_address_length))
6144         {
6145           address_length_set = 1;
6146         }
6147
6148       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6149                                          &v4_next_hop_address))
6150         {
6151           next_hop_set = 1;
6152         }
6153       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6154                                          &v6_next_hop_address))
6155         {
6156           next_hop_set = 1;
6157         }
6158       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6159         ;
6160       else if (unformat (i, "weight %d", &next_hop_weight))
6161         ;
6162       else if (unformat (i, "drop"))
6163         {
6164           is_drop = 1;
6165         }
6166       else if (unformat (i, "null-send-unreach"))
6167         {
6168           is_unreach = 1;
6169         }
6170       else if (unformat (i, "null-send-prohibit"))
6171         {
6172           is_prohibit = 1;
6173         }
6174       else if (unformat (i, "local"))
6175         {
6176           is_local = 1;
6177         }
6178       else if (unformat (i, "classify %d", &classify_table_index))
6179         {
6180           is_classify = 1;
6181         }
6182       else if (unformat (i, "del"))
6183         is_add = 0;
6184       else if (unformat (i, "add"))
6185         is_add = 1;
6186       else if (unformat (i, "not-last"))
6187         not_last = 1;
6188       else if (unformat (i, "resolve-via-host"))
6189         resolve_host = 1;
6190       else if (unformat (i, "resolve-via-attached"))
6191         resolve_attached = 1;
6192       else if (unformat (i, "multipath"))
6193         is_multipath = 1;
6194       else if (unformat (i, "vrf %d", &vrf_id))
6195         ;
6196       else if (unformat (i, "create-vrf"))
6197         create_vrf_if_needed = 1;
6198       else if (unformat (i, "count %d", &count))
6199         ;
6200       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6201         ;
6202       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6203         ;
6204       else if (unformat (i, "out-label %d", &next_hop_out_label))
6205         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6206       else if (unformat (i, "via-label %d", &next_hop_via_label))
6207         ;
6208       else if (unformat (i, "random"))
6209         random_add_del = 1;
6210       else if (unformat (i, "seed %d", &random_seed))
6211         ;
6212       else
6213         {
6214           clib_warning ("parse error '%U'", format_unformat_error, i);
6215           return -99;
6216         }
6217     }
6218
6219   if (!next_hop_set && !is_drop && !is_local &&
6220       !is_classify && !is_unreach && !is_prohibit &&
6221       MPLS_LABEL_INVALID == next_hop_via_label)
6222     {
6223       errmsg
6224         ("next hop / local / drop / unreach / prohibit / classify not set");
6225       return -99;
6226     }
6227
6228   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6229     {
6230       errmsg ("next hop and next-hop via label set");
6231       return -99;
6232     }
6233   if (address_set == 0)
6234     {
6235       errmsg ("missing addresses");
6236       return -99;
6237     }
6238
6239   if (address_length_set == 0)
6240     {
6241       errmsg ("missing address length");
6242       return -99;
6243     }
6244
6245   /* Generate a pile of unique, random routes */
6246   if (random_add_del)
6247     {
6248       u32 this_random_address;
6249       random_hash = hash_create (count, sizeof (uword));
6250
6251       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6252       for (j = 0; j <= count; j++)
6253         {
6254           do
6255             {
6256               this_random_address = random_u32 (&random_seed);
6257               this_random_address =
6258                 clib_host_to_net_u32 (this_random_address);
6259             }
6260           while (hash_get (random_hash, this_random_address));
6261           vec_add1 (random_vector, this_random_address);
6262           hash_set (random_hash, this_random_address, 1);
6263         }
6264       hash_free (random_hash);
6265       v4_dst_address.as_u32 = random_vector[0];
6266     }
6267
6268   if (count > 1)
6269     {
6270       /* Turn on async mode */
6271       vam->async_mode = 1;
6272       vam->async_errors = 0;
6273       before = vat_time_now (vam);
6274     }
6275
6276   for (j = 0; j < count; j++)
6277     {
6278       /* Construct the API message */
6279       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6280           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6281
6282       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6283       mp->table_id = ntohl (vrf_id);
6284       mp->create_vrf_if_needed = create_vrf_if_needed;
6285
6286       mp->is_add = is_add;
6287       mp->is_drop = is_drop;
6288       mp->is_unreach = is_unreach;
6289       mp->is_prohibit = is_prohibit;
6290       mp->is_ipv6 = is_ipv6;
6291       mp->is_local = is_local;
6292       mp->is_classify = is_classify;
6293       mp->is_multipath = is_multipath;
6294       mp->is_resolve_host = resolve_host;
6295       mp->is_resolve_attached = resolve_attached;
6296       mp->not_last = not_last;
6297       mp->next_hop_weight = next_hop_weight;
6298       mp->dst_address_length = dst_address_length;
6299       mp->next_hop_table_id = ntohl (next_hop_table_id);
6300       mp->classify_table_index = ntohl (classify_table_index);
6301       mp->next_hop_via_label = ntohl (next_hop_via_label);
6302       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6303       if (0 != mp->next_hop_n_out_labels)
6304         {
6305           memcpy (mp->next_hop_out_label_stack,
6306                   next_hop_out_label_stack,
6307                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6308           vec_free (next_hop_out_label_stack);
6309         }
6310
6311       if (is_ipv6)
6312         {
6313           clib_memcpy (mp->dst_address, &v6_dst_address,
6314                        sizeof (v6_dst_address));
6315           if (next_hop_set)
6316             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6317                          sizeof (v6_next_hop_address));
6318           increment_v6_address (&v6_dst_address);
6319         }
6320       else
6321         {
6322           clib_memcpy (mp->dst_address, &v4_dst_address,
6323                        sizeof (v4_dst_address));
6324           if (next_hop_set)
6325             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6326                          sizeof (v4_next_hop_address));
6327           if (random_add_del)
6328             v4_dst_address.as_u32 = random_vector[j + 1];
6329           else
6330             increment_v4_address (&v4_dst_address);
6331         }
6332       /* send it... */
6333       S;
6334       /* If we receive SIGTERM, stop now... */
6335       if (vam->do_exit)
6336         break;
6337     }
6338
6339   /* When testing multiple add/del ops, use a control-ping to sync */
6340   if (count > 1)
6341     {
6342       vl_api_control_ping_t *mp;
6343       f64 after;
6344
6345       /* Shut off async mode */
6346       vam->async_mode = 0;
6347
6348       M (CONTROL_PING, control_ping);
6349       S;
6350
6351       timeout = vat_time_now (vam) + 1.0;
6352       while (vat_time_now (vam) < timeout)
6353         if (vam->result_ready == 1)
6354           goto out;
6355       vam->retval = -99;
6356
6357     out:
6358       if (vam->retval == -99)
6359         errmsg ("timeout");
6360
6361       if (vam->async_errors > 0)
6362         {
6363           errmsg ("%d asynchronous errors", vam->async_errors);
6364           vam->retval = -98;
6365         }
6366       vam->async_errors = 0;
6367       after = vat_time_now (vam);
6368
6369       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6370       if (j > 0)
6371         count = j;
6372
6373       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6374              count, after - before, count / (after - before));
6375     }
6376   else
6377     {
6378       /* Wait for a reply... */
6379       W;
6380     }
6381
6382   /* Return the good/bad news */
6383   return (vam->retval);
6384 }
6385
6386 static int
6387 api_mpls_route_add_del (vat_main_t * vam)
6388 {
6389   unformat_input_t *i = vam->input;
6390   vl_api_mpls_route_add_del_t *mp;
6391   f64 timeout;
6392   u32 sw_if_index = ~0, table_id = 0;
6393   u8 create_table_if_needed = 0;
6394   u8 is_add = 1;
6395   u32 next_hop_weight = 1;
6396   u8 is_multipath = 0;
6397   u32 next_hop_table_id = 0;
6398   u8 next_hop_set = 0;
6399   ip4_address_t v4_next_hop_address = {
6400     .as_u32 = 0,
6401   };
6402   ip6_address_t v6_next_hop_address = { {0} };
6403   int count = 1;
6404   int j;
6405   f64 before = 0;
6406   u32 classify_table_index = ~0;
6407   u8 is_classify = 0;
6408   u8 resolve_host = 0, resolve_attached = 0;
6409   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6410   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6411   mpls_label_t *next_hop_out_label_stack = NULL;
6412   mpls_label_t local_label = MPLS_LABEL_INVALID;
6413   u8 is_eos = 0;
6414   u8 next_hop_proto_is_ip4 = 1;
6415
6416   /* Parse args required to build the message */
6417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6418     {
6419       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6420         ;
6421       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6422         ;
6423       else if (unformat (i, "%d", &local_label))
6424         ;
6425       else if (unformat (i, "eos"))
6426         is_eos = 1;
6427       else if (unformat (i, "non-eos"))
6428         is_eos = 0;
6429       else if (unformat (i, "via %U", unformat_ip4_address,
6430                          &v4_next_hop_address))
6431         {
6432           next_hop_set = 1;
6433           next_hop_proto_is_ip4 = 1;
6434         }
6435       else if (unformat (i, "via %U", unformat_ip6_address,
6436                          &v6_next_hop_address))
6437         {
6438           next_hop_set = 1;
6439           next_hop_proto_is_ip4 = 0;
6440         }
6441       else if (unformat (i, "weight %d", &next_hop_weight))
6442         ;
6443       else if (unformat (i, "create-table"))
6444         create_table_if_needed = 1;
6445       else if (unformat (i, "classify %d", &classify_table_index))
6446         {
6447           is_classify = 1;
6448         }
6449       else if (unformat (i, "del"))
6450         is_add = 0;
6451       else if (unformat (i, "add"))
6452         is_add = 1;
6453       else if (unformat (i, "resolve-via-host"))
6454         resolve_host = 1;
6455       else if (unformat (i, "resolve-via-attached"))
6456         resolve_attached = 1;
6457       else if (unformat (i, "multipath"))
6458         is_multipath = 1;
6459       else if (unformat (i, "count %d", &count))
6460         ;
6461       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6462         {
6463           next_hop_set = 1;
6464           next_hop_proto_is_ip4 = 1;
6465         }
6466       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6467         {
6468           next_hop_set = 1;
6469           next_hop_proto_is_ip4 = 0;
6470         }
6471       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6472         ;
6473       else if (unformat (i, "via-label %d", &next_hop_via_label))
6474         ;
6475       else if (unformat (i, "out-label %d", &next_hop_out_label))
6476         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6477       else
6478         {
6479           clib_warning ("parse error '%U'", format_unformat_error, i);
6480           return -99;
6481         }
6482     }
6483
6484   if (!next_hop_set && !is_classify)
6485     {
6486       errmsg ("next hop / classify not set");
6487       return -99;
6488     }
6489
6490   if (MPLS_LABEL_INVALID == local_label)
6491     {
6492       errmsg ("missing label");
6493       return -99;
6494     }
6495
6496   if (count > 1)
6497     {
6498       /* Turn on async mode */
6499       vam->async_mode = 1;
6500       vam->async_errors = 0;
6501       before = vat_time_now (vam);
6502     }
6503
6504   for (j = 0; j < count; j++)
6505     {
6506       /* Construct the API message */
6507       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6508           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6509
6510       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6511       mp->mr_table_id = ntohl (table_id);
6512       mp->mr_create_table_if_needed = create_table_if_needed;
6513
6514       mp->mr_is_add = is_add;
6515       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6516       mp->mr_is_classify = is_classify;
6517       mp->mr_is_multipath = is_multipath;
6518       mp->mr_is_resolve_host = resolve_host;
6519       mp->mr_is_resolve_attached = resolve_attached;
6520       mp->mr_next_hop_weight = next_hop_weight;
6521       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6522       mp->mr_classify_table_index = ntohl (classify_table_index);
6523       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6524       mp->mr_label = ntohl (local_label);
6525       mp->mr_eos = is_eos;
6526
6527       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6528       if (0 != mp->mr_next_hop_n_out_labels)
6529         {
6530           memcpy (mp->mr_next_hop_out_label_stack,
6531                   next_hop_out_label_stack,
6532                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6533           vec_free (next_hop_out_label_stack);
6534         }
6535
6536       if (next_hop_set)
6537         {
6538           if (next_hop_proto_is_ip4)
6539             {
6540               clib_memcpy (mp->mr_next_hop,
6541                            &v4_next_hop_address,
6542                            sizeof (v4_next_hop_address));
6543             }
6544           else
6545             {
6546               clib_memcpy (mp->mr_next_hop,
6547                            &v6_next_hop_address,
6548                            sizeof (v6_next_hop_address));
6549             }
6550         }
6551       local_label++;
6552
6553       /* send it... */
6554       S;
6555       /* If we receive SIGTERM, stop now... */
6556       if (vam->do_exit)
6557         break;
6558     }
6559
6560   /* When testing multiple add/del ops, use a control-ping to sync */
6561   if (count > 1)
6562     {
6563       vl_api_control_ping_t *mp;
6564       f64 after;
6565
6566       /* Shut off async mode */
6567       vam->async_mode = 0;
6568
6569       M (CONTROL_PING, control_ping);
6570       S;
6571
6572       timeout = vat_time_now (vam) + 1.0;
6573       while (vat_time_now (vam) < timeout)
6574         if (vam->result_ready == 1)
6575           goto out;
6576       vam->retval = -99;
6577
6578     out:
6579       if (vam->retval == -99)
6580         errmsg ("timeout");
6581
6582       if (vam->async_errors > 0)
6583         {
6584           errmsg ("%d asynchronous errors", vam->async_errors);
6585           vam->retval = -98;
6586         }
6587       vam->async_errors = 0;
6588       after = vat_time_now (vam);
6589
6590       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6591       if (j > 0)
6592         count = j;
6593
6594       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6595              count, after - before, count / (after - before));
6596     }
6597   else
6598     {
6599       /* Wait for a reply... */
6600       W;
6601     }
6602
6603   /* Return the good/bad news */
6604   return (vam->retval);
6605 }
6606
6607 static int
6608 api_mpls_ip_bind_unbind (vat_main_t * vam)
6609 {
6610   unformat_input_t *i = vam->input;
6611   vl_api_mpls_ip_bind_unbind_t *mp;
6612   f64 timeout;
6613   u32 ip_table_id = 0;
6614   u8 create_table_if_needed = 0;
6615   u8 is_bind = 1;
6616   u8 is_ip4 = 1;
6617   ip4_address_t v4_address;
6618   ip6_address_t v6_address;
6619   u32 address_length;
6620   u8 address_set = 0;
6621   mpls_label_t local_label = MPLS_LABEL_INVALID;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "%U/%d", unformat_ip4_address,
6627                     &v4_address, &address_length))
6628         {
6629           is_ip4 = 1;
6630           address_set = 1;
6631         }
6632       else if (unformat (i, "%U/%d", unformat_ip6_address,
6633                          &v6_address, &address_length))
6634         {
6635           is_ip4 = 0;
6636           address_set = 1;
6637         }
6638       else if (unformat (i, "%d", &local_label))
6639         ;
6640       else if (unformat (i, "create-table"))
6641         create_table_if_needed = 1;
6642       else if (unformat (i, "table-id %d", &ip_table_id))
6643         ;
6644       else if (unformat (i, "unbind"))
6645         is_bind = 0;
6646       else if (unformat (i, "bind"))
6647         is_bind = 1;
6648       else
6649         {
6650           clib_warning ("parse error '%U'", format_unformat_error, i);
6651           return -99;
6652         }
6653     }
6654
6655   if (!address_set)
6656     {
6657       errmsg ("IP addres not set");
6658       return -99;
6659     }
6660
6661   if (MPLS_LABEL_INVALID == local_label)
6662     {
6663       errmsg ("missing label");
6664       return -99;
6665     }
6666
6667   /* Construct the API message */
6668   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6669
6670   mp->mb_create_table_if_needed = create_table_if_needed;
6671   mp->mb_is_bind = is_bind;
6672   mp->mb_is_ip4 = is_ip4;
6673   mp->mb_ip_table_id = ntohl (ip_table_id);
6674   mp->mb_mpls_table_id = 0;
6675   mp->mb_label = ntohl (local_label);
6676   mp->mb_address_length = address_length;
6677
6678   if (is_ip4)
6679     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6680   else
6681     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6682
6683   /* send it... */
6684   S;
6685
6686   /* Wait for a reply... */
6687   W;
6688 }
6689
6690 static int
6691 api_proxy_arp_add_del (vat_main_t * vam)
6692 {
6693   unformat_input_t *i = vam->input;
6694   vl_api_proxy_arp_add_del_t *mp;
6695   f64 timeout;
6696   u32 vrf_id = 0;
6697   u8 is_add = 1;
6698   ip4_address_t lo, hi;
6699   u8 range_set = 0;
6700
6701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6702     {
6703       if (unformat (i, "vrf %d", &vrf_id))
6704         ;
6705       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6706                          unformat_ip4_address, &hi))
6707         range_set = 1;
6708       else if (unformat (i, "del"))
6709         is_add = 0;
6710       else
6711         {
6712           clib_warning ("parse error '%U'", format_unformat_error, i);
6713           return -99;
6714         }
6715     }
6716
6717   if (range_set == 0)
6718     {
6719       errmsg ("address range not set");
6720       return -99;
6721     }
6722
6723   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6724
6725   mp->vrf_id = ntohl (vrf_id);
6726   mp->is_add = is_add;
6727   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6728   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6729
6730   S;
6731   W;
6732   /* NOTREACHED */
6733   return 0;
6734 }
6735
6736 static int
6737 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6738 {
6739   unformat_input_t *i = vam->input;
6740   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6741   f64 timeout;
6742   u32 sw_if_index;
6743   u8 enable = 1;
6744   u8 sw_if_index_set = 0;
6745
6746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6747     {
6748       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6749         sw_if_index_set = 1;
6750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6751         sw_if_index_set = 1;
6752       else if (unformat (i, "enable"))
6753         enable = 1;
6754       else if (unformat (i, "disable"))
6755         enable = 0;
6756       else
6757         {
6758           clib_warning ("parse error '%U'", format_unformat_error, i);
6759           return -99;
6760         }
6761     }
6762
6763   if (sw_if_index_set == 0)
6764     {
6765       errmsg ("missing interface name or sw_if_index");
6766       return -99;
6767     }
6768
6769   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6770
6771   mp->sw_if_index = ntohl (sw_if_index);
6772   mp->enable_disable = enable;
6773
6774   S;
6775   W;
6776   /* NOTREACHED */
6777   return 0;
6778 }
6779
6780 static int
6781 api_mpls_tunnel_add_del (vat_main_t * vam)
6782 {
6783   unformat_input_t *i = vam->input;
6784   vl_api_mpls_tunnel_add_del_t *mp;
6785   f64 timeout;
6786
6787   u8 is_add = 1;
6788   u8 l2_only = 0;
6789   u32 sw_if_index = ~0;
6790   u32 next_hop_sw_if_index = ~0;
6791   u32 next_hop_proto_is_ip4 = 1;
6792
6793   u32 next_hop_table_id = 0;
6794   ip4_address_t v4_next_hop_address = {
6795     .as_u32 = 0,
6796   };
6797   ip6_address_t v6_next_hop_address = { {0} };
6798   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6799
6800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6801     {
6802       if (unformat (i, "add"))
6803         is_add = 1;
6804       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6805         is_add = 0;
6806       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6807         ;
6808       else if (unformat (i, "via %U",
6809                          unformat_ip4_address, &v4_next_hop_address))
6810         {
6811           next_hop_proto_is_ip4 = 1;
6812         }
6813       else if (unformat (i, "via %U",
6814                          unformat_ip6_address, &v6_next_hop_address))
6815         {
6816           next_hop_proto_is_ip4 = 0;
6817         }
6818       else if (unformat (i, "l2-only"))
6819         l2_only = 1;
6820       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6821         ;
6822       else if (unformat (i, "out-label %d", &next_hop_out_label))
6823         vec_add1 (labels, ntohl (next_hop_out_label));
6824       else
6825         {
6826           clib_warning ("parse error '%U'", format_unformat_error, i);
6827           return -99;
6828         }
6829     }
6830
6831   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6832       sizeof (mpls_label_t) * vec_len (labels));
6833
6834   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6835   mp->mt_sw_if_index = ntohl (sw_if_index);
6836   mp->mt_is_add = is_add;
6837   mp->mt_l2_only = l2_only;
6838   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6839   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6840
6841   mp->mt_next_hop_n_out_labels = vec_len (labels);
6842
6843   if (0 != mp->mt_next_hop_n_out_labels)
6844     {
6845       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6846                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6847       vec_free (labels);
6848     }
6849
6850   if (next_hop_proto_is_ip4)
6851     {
6852       clib_memcpy (mp->mt_next_hop,
6853                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6854     }
6855   else
6856     {
6857       clib_memcpy (mp->mt_next_hop,
6858                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6859     }
6860
6861   S;
6862   W;
6863   /* NOTREACHED */
6864   return 0;
6865 }
6866
6867 static int
6868 api_sw_interface_set_unnumbered (vat_main_t * vam)
6869 {
6870   unformat_input_t *i = vam->input;
6871   vl_api_sw_interface_set_unnumbered_t *mp;
6872   f64 timeout;
6873   u32 sw_if_index;
6874   u32 unnum_sw_index = ~0;
6875   u8 is_add = 1;
6876   u8 sw_if_index_set = 0;
6877
6878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6879     {
6880       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6881         sw_if_index_set = 1;
6882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6883         sw_if_index_set = 1;
6884       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6885         ;
6886       else if (unformat (i, "del"))
6887         is_add = 0;
6888       else
6889         {
6890           clib_warning ("parse error '%U'", format_unformat_error, i);
6891           return -99;
6892         }
6893     }
6894
6895   if (sw_if_index_set == 0)
6896     {
6897       errmsg ("missing interface name or sw_if_index");
6898       return -99;
6899     }
6900
6901   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6902
6903   mp->sw_if_index = ntohl (sw_if_index);
6904   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6905   mp->is_add = is_add;
6906
6907   S;
6908   W;
6909   /* NOTREACHED */
6910   return 0;
6911 }
6912
6913 static int
6914 api_ip_neighbor_add_del (vat_main_t * vam)
6915 {
6916   unformat_input_t *i = vam->input;
6917   vl_api_ip_neighbor_add_del_t *mp;
6918   f64 timeout;
6919   u32 sw_if_index;
6920   u8 sw_if_index_set = 0;
6921   u32 vrf_id = 0;
6922   u8 is_add = 1;
6923   u8 is_static = 0;
6924   u8 mac_address[6];
6925   u8 mac_set = 0;
6926   u8 v4_address_set = 0;
6927   u8 v6_address_set = 0;
6928   ip4_address_t v4address;
6929   ip6_address_t v6address;
6930
6931   memset (mac_address, 0, sizeof (mac_address));
6932
6933   /* Parse args required to build the message */
6934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6935     {
6936       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6937         {
6938           mac_set = 1;
6939         }
6940       else if (unformat (i, "del"))
6941         is_add = 0;
6942       else
6943         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6944         sw_if_index_set = 1;
6945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6946         sw_if_index_set = 1;
6947       else if (unformat (i, "is_static"))
6948         is_static = 1;
6949       else if (unformat (i, "vrf %d", &vrf_id))
6950         ;
6951       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6952         v4_address_set = 1;
6953       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6954         v6_address_set = 1;
6955       else
6956         {
6957           clib_warning ("parse error '%U'", format_unformat_error, i);
6958           return -99;
6959         }
6960     }
6961
6962   if (sw_if_index_set == 0)
6963     {
6964       errmsg ("missing interface name or sw_if_index");
6965       return -99;
6966     }
6967   if (v4_address_set && v6_address_set)
6968     {
6969       errmsg ("both v4 and v6 addresses set");
6970       return -99;
6971     }
6972   if (!v4_address_set && !v6_address_set)
6973     {
6974       errmsg ("no address set");
6975       return -99;
6976     }
6977
6978   /* Construct the API message */
6979   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6980
6981   mp->sw_if_index = ntohl (sw_if_index);
6982   mp->is_add = is_add;
6983   mp->vrf_id = ntohl (vrf_id);
6984   mp->is_static = is_static;
6985   if (mac_set)
6986     clib_memcpy (mp->mac_address, mac_address, 6);
6987   if (v6_address_set)
6988     {
6989       mp->is_ipv6 = 1;
6990       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6991     }
6992   else
6993     {
6994       /* mp->is_ipv6 = 0; via memset in M macro above */
6995       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6996     }
6997
6998   /* send it... */
6999   S;
7000
7001   /* Wait for a reply, return good/bad news  */
7002   W;
7003
7004   /* NOTREACHED */
7005   return 0;
7006 }
7007
7008 static int
7009 api_reset_vrf (vat_main_t * vam)
7010 {
7011   unformat_input_t *i = vam->input;
7012   vl_api_reset_vrf_t *mp;
7013   f64 timeout;
7014   u32 vrf_id = 0;
7015   u8 is_ipv6 = 0;
7016   u8 vrf_id_set = 0;
7017
7018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7019     {
7020       if (unformat (i, "vrf %d", &vrf_id))
7021         vrf_id_set = 1;
7022       else if (unformat (i, "ipv6"))
7023         is_ipv6 = 1;
7024       else
7025         {
7026           clib_warning ("parse error '%U'", format_unformat_error, i);
7027           return -99;
7028         }
7029     }
7030
7031   if (vrf_id_set == 0)
7032     {
7033       errmsg ("missing vrf id");
7034       return -99;
7035     }
7036
7037   M (RESET_VRF, reset_vrf);
7038
7039   mp->vrf_id = ntohl (vrf_id);
7040   mp->is_ipv6 = is_ipv6;
7041
7042   S;
7043   W;
7044   /* NOTREACHED */
7045   return 0;
7046 }
7047
7048 static int
7049 api_create_vlan_subif (vat_main_t * vam)
7050 {
7051   unformat_input_t *i = vam->input;
7052   vl_api_create_vlan_subif_t *mp;
7053   f64 timeout;
7054   u32 sw_if_index;
7055   u8 sw_if_index_set = 0;
7056   u32 vlan_id;
7057   u8 vlan_id_set = 0;
7058
7059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7060     {
7061       if (unformat (i, "sw_if_index %d", &sw_if_index))
7062         sw_if_index_set = 1;
7063       else
7064         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7065         sw_if_index_set = 1;
7066       else if (unformat (i, "vlan %d", &vlan_id))
7067         vlan_id_set = 1;
7068       else
7069         {
7070           clib_warning ("parse error '%U'", format_unformat_error, i);
7071           return -99;
7072         }
7073     }
7074
7075   if (sw_if_index_set == 0)
7076     {
7077       errmsg ("missing interface name or sw_if_index");
7078       return -99;
7079     }
7080
7081   if (vlan_id_set == 0)
7082     {
7083       errmsg ("missing vlan_id");
7084       return -99;
7085     }
7086   M (CREATE_VLAN_SUBIF, create_vlan_subif);
7087
7088   mp->sw_if_index = ntohl (sw_if_index);
7089   mp->vlan_id = ntohl (vlan_id);
7090
7091   S;
7092   W;
7093   /* NOTREACHED */
7094   return 0;
7095 }
7096
7097 #define foreach_create_subif_bit                \
7098 _(no_tags)                                      \
7099 _(one_tag)                                      \
7100 _(two_tags)                                     \
7101 _(dot1ad)                                       \
7102 _(exact_match)                                  \
7103 _(default_sub)                                  \
7104 _(outer_vlan_id_any)                            \
7105 _(inner_vlan_id_any)
7106
7107 static int
7108 api_create_subif (vat_main_t * vam)
7109 {
7110   unformat_input_t *i = vam->input;
7111   vl_api_create_subif_t *mp;
7112   f64 timeout;
7113   u32 sw_if_index;
7114   u8 sw_if_index_set = 0;
7115   u32 sub_id;
7116   u8 sub_id_set = 0;
7117   u32 no_tags = 0;
7118   u32 one_tag = 0;
7119   u32 two_tags = 0;
7120   u32 dot1ad = 0;
7121   u32 exact_match = 0;
7122   u32 default_sub = 0;
7123   u32 outer_vlan_id_any = 0;
7124   u32 inner_vlan_id_any = 0;
7125   u32 tmp;
7126   u16 outer_vlan_id = 0;
7127   u16 inner_vlan_id = 0;
7128
7129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7130     {
7131       if (unformat (i, "sw_if_index %d", &sw_if_index))
7132         sw_if_index_set = 1;
7133       else
7134         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7135         sw_if_index_set = 1;
7136       else if (unformat (i, "sub_id %d", &sub_id))
7137         sub_id_set = 1;
7138       else if (unformat (i, "outer_vlan_id %d", &tmp))
7139         outer_vlan_id = tmp;
7140       else if (unformat (i, "inner_vlan_id %d", &tmp))
7141         inner_vlan_id = tmp;
7142
7143 #define _(a) else if (unformat (i, #a)) a = 1 ;
7144       foreach_create_subif_bit
7145 #undef _
7146         else
7147         {
7148           clib_warning ("parse error '%U'", format_unformat_error, i);
7149           return -99;
7150         }
7151     }
7152
7153   if (sw_if_index_set == 0)
7154     {
7155       errmsg ("missing interface name or sw_if_index");
7156       return -99;
7157     }
7158
7159   if (sub_id_set == 0)
7160     {
7161       errmsg ("missing sub_id");
7162       return -99;
7163     }
7164   M (CREATE_SUBIF, create_subif);
7165
7166   mp->sw_if_index = ntohl (sw_if_index);
7167   mp->sub_id = ntohl (sub_id);
7168
7169 #define _(a) mp->a = a;
7170   foreach_create_subif_bit;
7171 #undef _
7172
7173   mp->outer_vlan_id = ntohs (outer_vlan_id);
7174   mp->inner_vlan_id = ntohs (inner_vlan_id);
7175
7176   S;
7177   W;
7178   /* NOTREACHED */
7179   return 0;
7180 }
7181
7182 static int
7183 api_oam_add_del (vat_main_t * vam)
7184 {
7185   unformat_input_t *i = vam->input;
7186   vl_api_oam_add_del_t *mp;
7187   f64 timeout;
7188   u32 vrf_id = 0;
7189   u8 is_add = 1;
7190   ip4_address_t src, dst;
7191   u8 src_set = 0;
7192   u8 dst_set = 0;
7193
7194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7195     {
7196       if (unformat (i, "vrf %d", &vrf_id))
7197         ;
7198       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7199         src_set = 1;
7200       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7201         dst_set = 1;
7202       else if (unformat (i, "del"))
7203         is_add = 0;
7204       else
7205         {
7206           clib_warning ("parse error '%U'", format_unformat_error, i);
7207           return -99;
7208         }
7209     }
7210
7211   if (src_set == 0)
7212     {
7213       errmsg ("missing src addr");
7214       return -99;
7215     }
7216
7217   if (dst_set == 0)
7218     {
7219       errmsg ("missing dst addr");
7220       return -99;
7221     }
7222
7223   M (OAM_ADD_DEL, oam_add_del);
7224
7225   mp->vrf_id = ntohl (vrf_id);
7226   mp->is_add = is_add;
7227   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7228   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7229
7230   S;
7231   W;
7232   /* NOTREACHED */
7233   return 0;
7234 }
7235
7236 static int
7237 api_reset_fib (vat_main_t * vam)
7238 {
7239   unformat_input_t *i = vam->input;
7240   vl_api_reset_fib_t *mp;
7241   f64 timeout;
7242   u32 vrf_id = 0;
7243   u8 is_ipv6 = 0;
7244   u8 vrf_id_set = 0;
7245
7246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7247     {
7248       if (unformat (i, "vrf %d", &vrf_id))
7249         vrf_id_set = 1;
7250       else if (unformat (i, "ipv6"))
7251         is_ipv6 = 1;
7252       else
7253         {
7254           clib_warning ("parse error '%U'", format_unformat_error, i);
7255           return -99;
7256         }
7257     }
7258
7259   if (vrf_id_set == 0)
7260     {
7261       errmsg ("missing vrf id");
7262       return -99;
7263     }
7264
7265   M (RESET_FIB, reset_fib);
7266
7267   mp->vrf_id = ntohl (vrf_id);
7268   mp->is_ipv6 = is_ipv6;
7269
7270   S;
7271   W;
7272   /* NOTREACHED */
7273   return 0;
7274 }
7275
7276 static int
7277 api_dhcp_proxy_config (vat_main_t * vam)
7278 {
7279   unformat_input_t *i = vam->input;
7280   vl_api_dhcp_proxy_config_t *mp;
7281   f64 timeout;
7282   u32 vrf_id = 0;
7283   u8 is_add = 1;
7284   u8 insert_cid = 1;
7285   u8 v4_address_set = 0;
7286   u8 v6_address_set = 0;
7287   ip4_address_t v4address;
7288   ip6_address_t v6address;
7289   u8 v4_src_address_set = 0;
7290   u8 v6_src_address_set = 0;
7291   ip4_address_t v4srcaddress;
7292   ip6_address_t v6srcaddress;
7293
7294   /* Parse args required to build the message */
7295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7296     {
7297       if (unformat (i, "del"))
7298         is_add = 0;
7299       else if (unformat (i, "vrf %d", &vrf_id))
7300         ;
7301       else if (unformat (i, "insert-cid %d", &insert_cid))
7302         ;
7303       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7304         v4_address_set = 1;
7305       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7306         v6_address_set = 1;
7307       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7308         v4_src_address_set = 1;
7309       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7310         v6_src_address_set = 1;
7311       else
7312         break;
7313     }
7314
7315   if (v4_address_set && v6_address_set)
7316     {
7317       errmsg ("both v4 and v6 server addresses set");
7318       return -99;
7319     }
7320   if (!v4_address_set && !v6_address_set)
7321     {
7322       errmsg ("no server addresses set");
7323       return -99;
7324     }
7325
7326   if (v4_src_address_set && v6_src_address_set)
7327     {
7328       errmsg ("both v4 and v6  src addresses set");
7329       return -99;
7330     }
7331   if (!v4_src_address_set && !v6_src_address_set)
7332     {
7333       errmsg ("no src addresses set");
7334       return -99;
7335     }
7336
7337   if (!(v4_src_address_set && v4_address_set) &&
7338       !(v6_src_address_set && v6_address_set))
7339     {
7340       errmsg ("no matching server and src addresses set");
7341       return -99;
7342     }
7343
7344   /* Construct the API message */
7345   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7346
7347   mp->insert_circuit_id = insert_cid;
7348   mp->is_add = is_add;
7349   mp->vrf_id = ntohl (vrf_id);
7350   if (v6_address_set)
7351     {
7352       mp->is_ipv6 = 1;
7353       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7354       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7355     }
7356   else
7357     {
7358       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7359       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7360     }
7361
7362   /* send it... */
7363   S;
7364
7365   /* Wait for a reply, return good/bad news  */
7366   W;
7367   /* NOTREACHED */
7368   return 0;
7369 }
7370
7371 static int
7372 api_dhcp_proxy_config_2 (vat_main_t * vam)
7373 {
7374   unformat_input_t *i = vam->input;
7375   vl_api_dhcp_proxy_config_2_t *mp;
7376   f64 timeout;
7377   u32 rx_vrf_id = 0;
7378   u32 server_vrf_id = 0;
7379   u8 is_add = 1;
7380   u8 insert_cid = 1;
7381   u8 v4_address_set = 0;
7382   u8 v6_address_set = 0;
7383   ip4_address_t v4address;
7384   ip6_address_t v6address;
7385   u8 v4_src_address_set = 0;
7386   u8 v6_src_address_set = 0;
7387   ip4_address_t v4srcaddress;
7388   ip6_address_t v6srcaddress;
7389
7390   /* Parse args required to build the message */
7391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7392     {
7393       if (unformat (i, "del"))
7394         is_add = 0;
7395       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7396         ;
7397       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7398         ;
7399       else if (unformat (i, "insert-cid %d", &insert_cid))
7400         ;
7401       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7402         v4_address_set = 1;
7403       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7404         v6_address_set = 1;
7405       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7406         v4_src_address_set = 1;
7407       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7408         v6_src_address_set = 1;
7409       else
7410         break;
7411     }
7412
7413   if (v4_address_set && v6_address_set)
7414     {
7415       errmsg ("both v4 and v6 server addresses set");
7416       return -99;
7417     }
7418   if (!v4_address_set && !v6_address_set)
7419     {
7420       errmsg ("no server addresses set");
7421       return -99;
7422     }
7423
7424   if (v4_src_address_set && v6_src_address_set)
7425     {
7426       errmsg ("both v4 and v6  src addresses set");
7427       return -99;
7428     }
7429   if (!v4_src_address_set && !v6_src_address_set)
7430     {
7431       errmsg ("no src addresses set");
7432       return -99;
7433     }
7434
7435   if (!(v4_src_address_set && v4_address_set) &&
7436       !(v6_src_address_set && v6_address_set))
7437     {
7438       errmsg ("no matching server and src addresses set");
7439       return -99;
7440     }
7441
7442   /* Construct the API message */
7443   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7444
7445   mp->insert_circuit_id = insert_cid;
7446   mp->is_add = is_add;
7447   mp->rx_vrf_id = ntohl (rx_vrf_id);
7448   mp->server_vrf_id = ntohl (server_vrf_id);
7449   if (v6_address_set)
7450     {
7451       mp->is_ipv6 = 1;
7452       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7453       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7454     }
7455   else
7456     {
7457       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7458       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7459     }
7460
7461   /* send it... */
7462   S;
7463
7464   /* Wait for a reply, return good/bad news  */
7465   W;
7466   /* NOTREACHED */
7467   return 0;
7468 }
7469
7470 static int
7471 api_dhcp_proxy_set_vss (vat_main_t * vam)
7472 {
7473   unformat_input_t *i = vam->input;
7474   vl_api_dhcp_proxy_set_vss_t *mp;
7475   f64 timeout;
7476   u8 is_ipv6 = 0;
7477   u8 is_add = 1;
7478   u32 tbl_id;
7479   u8 tbl_id_set = 0;
7480   u32 oui;
7481   u8 oui_set = 0;
7482   u32 fib_id;
7483   u8 fib_id_set = 0;
7484
7485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7486     {
7487       if (unformat (i, "tbl_id %d", &tbl_id))
7488         tbl_id_set = 1;
7489       if (unformat (i, "fib_id %d", &fib_id))
7490         fib_id_set = 1;
7491       if (unformat (i, "oui %d", &oui))
7492         oui_set = 1;
7493       else if (unformat (i, "ipv6"))
7494         is_ipv6 = 1;
7495       else if (unformat (i, "del"))
7496         is_add = 0;
7497       else
7498         {
7499           clib_warning ("parse error '%U'", format_unformat_error, i);
7500           return -99;
7501         }
7502     }
7503
7504   if (tbl_id_set == 0)
7505     {
7506       errmsg ("missing tbl id");
7507       return -99;
7508     }
7509
7510   if (fib_id_set == 0)
7511     {
7512       errmsg ("missing fib id");
7513       return -99;
7514     }
7515   if (oui_set == 0)
7516     {
7517       errmsg ("missing oui");
7518       return -99;
7519     }
7520
7521   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7522   mp->tbl_id = ntohl (tbl_id);
7523   mp->fib_id = ntohl (fib_id);
7524   mp->oui = ntohl (oui);
7525   mp->is_ipv6 = is_ipv6;
7526   mp->is_add = is_add;
7527
7528   S;
7529   W;
7530   /* NOTREACHED */
7531   return 0;
7532 }
7533
7534 static int
7535 api_dhcp_client_config (vat_main_t * vam)
7536 {
7537   unformat_input_t *i = vam->input;
7538   vl_api_dhcp_client_config_t *mp;
7539   f64 timeout;
7540   u32 sw_if_index;
7541   u8 sw_if_index_set = 0;
7542   u8 is_add = 1;
7543   u8 *hostname = 0;
7544   u8 disable_event = 0;
7545
7546   /* Parse args required to build the message */
7547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7548     {
7549       if (unformat (i, "del"))
7550         is_add = 0;
7551       else
7552         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7553         sw_if_index_set = 1;
7554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7555         sw_if_index_set = 1;
7556       else if (unformat (i, "hostname %s", &hostname))
7557         ;
7558       else if (unformat (i, "disable_event"))
7559         disable_event = 1;
7560       else
7561         break;
7562     }
7563
7564   if (sw_if_index_set == 0)
7565     {
7566       errmsg ("missing interface name or sw_if_index");
7567       return -99;
7568     }
7569
7570   if (vec_len (hostname) > 63)
7571     {
7572       errmsg ("hostname too long");
7573     }
7574   vec_add1 (hostname, 0);
7575
7576   /* Construct the API message */
7577   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7578
7579   mp->sw_if_index = ntohl (sw_if_index);
7580   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7581   vec_free (hostname);
7582   mp->is_add = is_add;
7583   mp->want_dhcp_event = disable_event ? 0 : 1;
7584   mp->pid = getpid ();
7585
7586   /* send it... */
7587   S;
7588
7589   /* Wait for a reply, return good/bad news  */
7590   W;
7591   /* NOTREACHED */
7592   return 0;
7593 }
7594
7595 static int
7596 api_set_ip_flow_hash (vat_main_t * vam)
7597 {
7598   unformat_input_t *i = vam->input;
7599   vl_api_set_ip_flow_hash_t *mp;
7600   f64 timeout;
7601   u32 vrf_id = 0;
7602   u8 is_ipv6 = 0;
7603   u8 vrf_id_set = 0;
7604   u8 src = 0;
7605   u8 dst = 0;
7606   u8 sport = 0;
7607   u8 dport = 0;
7608   u8 proto = 0;
7609   u8 reverse = 0;
7610
7611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7612     {
7613       if (unformat (i, "vrf %d", &vrf_id))
7614         vrf_id_set = 1;
7615       else if (unformat (i, "ipv6"))
7616         is_ipv6 = 1;
7617       else if (unformat (i, "src"))
7618         src = 1;
7619       else if (unformat (i, "dst"))
7620         dst = 1;
7621       else if (unformat (i, "sport"))
7622         sport = 1;
7623       else if (unformat (i, "dport"))
7624         dport = 1;
7625       else if (unformat (i, "proto"))
7626         proto = 1;
7627       else if (unformat (i, "reverse"))
7628         reverse = 1;
7629
7630       else
7631         {
7632           clib_warning ("parse error '%U'", format_unformat_error, i);
7633           return -99;
7634         }
7635     }
7636
7637   if (vrf_id_set == 0)
7638     {
7639       errmsg ("missing vrf id");
7640       return -99;
7641     }
7642
7643   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7644   mp->src = src;
7645   mp->dst = dst;
7646   mp->sport = sport;
7647   mp->dport = dport;
7648   mp->proto = proto;
7649   mp->reverse = reverse;
7650   mp->vrf_id = ntohl (vrf_id);
7651   mp->is_ipv6 = is_ipv6;
7652
7653   S;
7654   W;
7655   /* NOTREACHED */
7656   return 0;
7657 }
7658
7659 static int
7660 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7661 {
7662   unformat_input_t *i = vam->input;
7663   vl_api_sw_interface_ip6_enable_disable_t *mp;
7664   f64 timeout;
7665   u32 sw_if_index;
7666   u8 sw_if_index_set = 0;
7667   u8 enable = 0;
7668
7669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7670     {
7671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7672         sw_if_index_set = 1;
7673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7674         sw_if_index_set = 1;
7675       else if (unformat (i, "enable"))
7676         enable = 1;
7677       else if (unformat (i, "disable"))
7678         enable = 0;
7679       else
7680         {
7681           clib_warning ("parse error '%U'", format_unformat_error, i);
7682           return -99;
7683         }
7684     }
7685
7686   if (sw_if_index_set == 0)
7687     {
7688       errmsg ("missing interface name or sw_if_index");
7689       return -99;
7690     }
7691
7692   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7693
7694   mp->sw_if_index = ntohl (sw_if_index);
7695   mp->enable = enable;
7696
7697   S;
7698   W;
7699   /* NOTREACHED */
7700   return 0;
7701 }
7702
7703 static int
7704 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7705 {
7706   unformat_input_t *i = vam->input;
7707   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7708   f64 timeout;
7709   u32 sw_if_index;
7710   u8 sw_if_index_set = 0;
7711   u8 v6_address_set = 0;
7712   ip6_address_t v6address;
7713
7714   /* Parse args required to build the message */
7715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7716     {
7717       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7718         sw_if_index_set = 1;
7719       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7720         sw_if_index_set = 1;
7721       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7722         v6_address_set = 1;
7723       else
7724         break;
7725     }
7726
7727   if (sw_if_index_set == 0)
7728     {
7729       errmsg ("missing interface name or sw_if_index");
7730       return -99;
7731     }
7732   if (!v6_address_set)
7733     {
7734       errmsg ("no address set");
7735       return -99;
7736     }
7737
7738   /* Construct the API message */
7739   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7740      sw_interface_ip6_set_link_local_address);
7741
7742   mp->sw_if_index = ntohl (sw_if_index);
7743   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7744
7745   /* send it... */
7746   S;
7747
7748   /* Wait for a reply, return good/bad news  */
7749   W;
7750
7751   /* NOTREACHED */
7752   return 0;
7753 }
7754
7755
7756 static int
7757 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7758 {
7759   unformat_input_t *i = vam->input;
7760   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7761   f64 timeout;
7762   u32 sw_if_index;
7763   u8 sw_if_index_set = 0;
7764   u32 address_length = 0;
7765   u8 v6_address_set = 0;
7766   ip6_address_t v6address;
7767   u8 use_default = 0;
7768   u8 no_advertise = 0;
7769   u8 off_link = 0;
7770   u8 no_autoconfig = 0;
7771   u8 no_onlink = 0;
7772   u8 is_no = 0;
7773   u32 val_lifetime = 0;
7774   u32 pref_lifetime = 0;
7775
7776   /* Parse args required to build the message */
7777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7778     {
7779       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7780         sw_if_index_set = 1;
7781       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7782         sw_if_index_set = 1;
7783       else if (unformat (i, "%U/%d",
7784                          unformat_ip6_address, &v6address, &address_length))
7785         v6_address_set = 1;
7786       else if (unformat (i, "val_life %d", &val_lifetime))
7787         ;
7788       else if (unformat (i, "pref_life %d", &pref_lifetime))
7789         ;
7790       else if (unformat (i, "def"))
7791         use_default = 1;
7792       else if (unformat (i, "noadv"))
7793         no_advertise = 1;
7794       else if (unformat (i, "offl"))
7795         off_link = 1;
7796       else if (unformat (i, "noauto"))
7797         no_autoconfig = 1;
7798       else if (unformat (i, "nolink"))
7799         no_onlink = 1;
7800       else if (unformat (i, "isno"))
7801         is_no = 1;
7802       else
7803         {
7804           clib_warning ("parse error '%U'", format_unformat_error, i);
7805           return -99;
7806         }
7807     }
7808
7809   if (sw_if_index_set == 0)
7810     {
7811       errmsg ("missing interface name or sw_if_index");
7812       return -99;
7813     }
7814   if (!v6_address_set)
7815     {
7816       errmsg ("no address set");
7817       return -99;
7818     }
7819
7820   /* Construct the API message */
7821   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7822
7823   mp->sw_if_index = ntohl (sw_if_index);
7824   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7825   mp->address_length = address_length;
7826   mp->use_default = use_default;
7827   mp->no_advertise = no_advertise;
7828   mp->off_link = off_link;
7829   mp->no_autoconfig = no_autoconfig;
7830   mp->no_onlink = no_onlink;
7831   mp->is_no = is_no;
7832   mp->val_lifetime = ntohl (val_lifetime);
7833   mp->pref_lifetime = ntohl (pref_lifetime);
7834
7835   /* send it... */
7836   S;
7837
7838   /* Wait for a reply, return good/bad news  */
7839   W;
7840
7841   /* NOTREACHED */
7842   return 0;
7843 }
7844
7845 static int
7846 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7847 {
7848   unformat_input_t *i = vam->input;
7849   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7850   f64 timeout;
7851   u32 sw_if_index;
7852   u8 sw_if_index_set = 0;
7853   u8 suppress = 0;
7854   u8 managed = 0;
7855   u8 other = 0;
7856   u8 ll_option = 0;
7857   u8 send_unicast = 0;
7858   u8 cease = 0;
7859   u8 is_no = 0;
7860   u8 default_router = 0;
7861   u32 max_interval = 0;
7862   u32 min_interval = 0;
7863   u32 lifetime = 0;
7864   u32 initial_count = 0;
7865   u32 initial_interval = 0;
7866
7867
7868   /* Parse args required to build the message */
7869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7870     {
7871       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7872         sw_if_index_set = 1;
7873       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7874         sw_if_index_set = 1;
7875       else if (unformat (i, "maxint %d", &max_interval))
7876         ;
7877       else if (unformat (i, "minint %d", &min_interval))
7878         ;
7879       else if (unformat (i, "life %d", &lifetime))
7880         ;
7881       else if (unformat (i, "count %d", &initial_count))
7882         ;
7883       else if (unformat (i, "interval %d", &initial_interval))
7884         ;
7885       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7886         suppress = 1;
7887       else if (unformat (i, "managed"))
7888         managed = 1;
7889       else if (unformat (i, "other"))
7890         other = 1;
7891       else if (unformat (i, "ll"))
7892         ll_option = 1;
7893       else if (unformat (i, "send"))
7894         send_unicast = 1;
7895       else if (unformat (i, "cease"))
7896         cease = 1;
7897       else if (unformat (i, "isno"))
7898         is_no = 1;
7899       else if (unformat (i, "def"))
7900         default_router = 1;
7901       else
7902         {
7903           clib_warning ("parse error '%U'", format_unformat_error, i);
7904           return -99;
7905         }
7906     }
7907
7908   if (sw_if_index_set == 0)
7909     {
7910       errmsg ("missing interface name or sw_if_index");
7911       return -99;
7912     }
7913
7914   /* Construct the API message */
7915   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7916
7917   mp->sw_if_index = ntohl (sw_if_index);
7918   mp->max_interval = ntohl (max_interval);
7919   mp->min_interval = ntohl (min_interval);
7920   mp->lifetime = ntohl (lifetime);
7921   mp->initial_count = ntohl (initial_count);
7922   mp->initial_interval = ntohl (initial_interval);
7923   mp->suppress = suppress;
7924   mp->managed = managed;
7925   mp->other = other;
7926   mp->ll_option = ll_option;
7927   mp->send_unicast = send_unicast;
7928   mp->cease = cease;
7929   mp->is_no = is_no;
7930   mp->default_router = default_router;
7931
7932   /* send it... */
7933   S;
7934
7935   /* Wait for a reply, return good/bad news  */
7936   W;
7937
7938   /* NOTREACHED */
7939   return 0;
7940 }
7941
7942 static int
7943 api_set_arp_neighbor_limit (vat_main_t * vam)
7944 {
7945   unformat_input_t *i = vam->input;
7946   vl_api_set_arp_neighbor_limit_t *mp;
7947   f64 timeout;
7948   u32 arp_nbr_limit;
7949   u8 limit_set = 0;
7950   u8 is_ipv6 = 0;
7951
7952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7953     {
7954       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7955         limit_set = 1;
7956       else if (unformat (i, "ipv6"))
7957         is_ipv6 = 1;
7958       else
7959         {
7960           clib_warning ("parse error '%U'", format_unformat_error, i);
7961           return -99;
7962         }
7963     }
7964
7965   if (limit_set == 0)
7966     {
7967       errmsg ("missing limit value");
7968       return -99;
7969     }
7970
7971   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7972
7973   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7974   mp->is_ipv6 = is_ipv6;
7975
7976   S;
7977   W;
7978   /* NOTREACHED */
7979   return 0;
7980 }
7981
7982 static int
7983 api_l2_patch_add_del (vat_main_t * vam)
7984 {
7985   unformat_input_t *i = vam->input;
7986   vl_api_l2_patch_add_del_t *mp;
7987   f64 timeout;
7988   u32 rx_sw_if_index;
7989   u8 rx_sw_if_index_set = 0;
7990   u32 tx_sw_if_index;
7991   u8 tx_sw_if_index_set = 0;
7992   u8 is_add = 1;
7993
7994   /* Parse args required to build the message */
7995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7996     {
7997       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7998         rx_sw_if_index_set = 1;
7999       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8000         tx_sw_if_index_set = 1;
8001       else if (unformat (i, "rx"))
8002         {
8003           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8004             {
8005               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8006                             &rx_sw_if_index))
8007                 rx_sw_if_index_set = 1;
8008             }
8009           else
8010             break;
8011         }
8012       else if (unformat (i, "tx"))
8013         {
8014           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8015             {
8016               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8017                             &tx_sw_if_index))
8018                 tx_sw_if_index_set = 1;
8019             }
8020           else
8021             break;
8022         }
8023       else if (unformat (i, "del"))
8024         is_add = 0;
8025       else
8026         break;
8027     }
8028
8029   if (rx_sw_if_index_set == 0)
8030     {
8031       errmsg ("missing rx interface name or rx_sw_if_index");
8032       return -99;
8033     }
8034
8035   if (tx_sw_if_index_set == 0)
8036     {
8037       errmsg ("missing tx interface name or tx_sw_if_index");
8038       return -99;
8039     }
8040
8041   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
8042
8043   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8044   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8045   mp->is_add = is_add;
8046
8047   S;
8048   W;
8049   /* NOTREACHED */
8050   return 0;
8051 }
8052
8053 static int
8054 api_ioam_enable (vat_main_t * vam)
8055 {
8056   unformat_input_t *input = vam->input;
8057   vl_api_ioam_enable_t *mp;
8058   f64 timeout;
8059   u32 id = 0;
8060   int has_trace_option = 0;
8061   int has_pot_option = 0;
8062   int has_seqno_option = 0;
8063   int has_analyse_option = 0;
8064
8065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8066     {
8067       if (unformat (input, "trace"))
8068         has_trace_option = 1;
8069       else if (unformat (input, "pot"))
8070         has_pot_option = 1;
8071       else if (unformat (input, "seqno"))
8072         has_seqno_option = 1;
8073       else if (unformat (input, "analyse"))
8074         has_analyse_option = 1;
8075       else
8076         break;
8077     }
8078   M (IOAM_ENABLE, ioam_enable);
8079   mp->id = htons (id);
8080   mp->seqno = has_seqno_option;
8081   mp->analyse = has_analyse_option;
8082   mp->pot_enable = has_pot_option;
8083   mp->trace_enable = has_trace_option;
8084
8085   S;
8086   W;
8087
8088   return (0);
8089
8090 }
8091
8092
8093 static int
8094 api_ioam_disable (vat_main_t * vam)
8095 {
8096   vl_api_ioam_disable_t *mp;
8097   f64 timeout;
8098
8099   M (IOAM_DISABLE, ioam_disable);
8100   S;
8101   W;
8102   return 0;
8103 }
8104
8105 static int
8106 api_sr_tunnel_add_del (vat_main_t * vam)
8107 {
8108   unformat_input_t *i = vam->input;
8109   vl_api_sr_tunnel_add_del_t *mp;
8110   f64 timeout;
8111   int is_del = 0;
8112   int pl_index;
8113   ip6_address_t src_address;
8114   int src_address_set = 0;
8115   ip6_address_t dst_address;
8116   u32 dst_mask_width;
8117   int dst_address_set = 0;
8118   u16 flags = 0;
8119   u32 rx_table_id = 0;
8120   u32 tx_table_id = 0;
8121   ip6_address_t *segments = 0;
8122   ip6_address_t *this_seg;
8123   ip6_address_t *tags = 0;
8124   ip6_address_t *this_tag;
8125   ip6_address_t next_address, tag;
8126   u8 *name = 0;
8127   u8 *policy_name = 0;
8128
8129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8130     {
8131       if (unformat (i, "del"))
8132         is_del = 1;
8133       else if (unformat (i, "name %s", &name))
8134         ;
8135       else if (unformat (i, "policy %s", &policy_name))
8136         ;
8137       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8138         ;
8139       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8140         ;
8141       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8142         src_address_set = 1;
8143       else if (unformat (i, "dst %U/%d",
8144                          unformat_ip6_address, &dst_address, &dst_mask_width))
8145         dst_address_set = 1;
8146       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8147         {
8148           vec_add2 (segments, this_seg, 1);
8149           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8150                        sizeof (*this_seg));
8151         }
8152       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8153         {
8154           vec_add2 (tags, this_tag, 1);
8155           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8156         }
8157       else if (unformat (i, "clean"))
8158         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8159       else if (unformat (i, "protected"))
8160         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8161       else if (unformat (i, "InPE %d", &pl_index))
8162         {
8163           if (pl_index <= 0 || pl_index > 4)
8164             {
8165             pl_index_range_error:
8166               errmsg ("pl index %d out of range", pl_index);
8167               return -99;
8168             }
8169           flags |=
8170             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8171         }
8172       else if (unformat (i, "EgPE %d", &pl_index))
8173         {
8174           if (pl_index <= 0 || pl_index > 4)
8175             goto pl_index_range_error;
8176           flags |=
8177             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8178         }
8179       else if (unformat (i, "OrgSrc %d", &pl_index))
8180         {
8181           if (pl_index <= 0 || pl_index > 4)
8182             goto pl_index_range_error;
8183           flags |=
8184             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8185         }
8186       else
8187         break;
8188     }
8189
8190   if (!src_address_set)
8191     {
8192       errmsg ("src address required");
8193       return -99;
8194     }
8195
8196   if (!dst_address_set)
8197     {
8198       errmsg ("dst address required");
8199       return -99;
8200     }
8201
8202   if (!segments)
8203     {
8204       errmsg ("at least one sr segment required");
8205       return -99;
8206     }
8207
8208   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8209       vec_len (segments) * sizeof (ip6_address_t)
8210       + vec_len (tags) * sizeof (ip6_address_t));
8211
8212   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8213   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8214   mp->dst_mask_width = dst_mask_width;
8215   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8216   mp->n_segments = vec_len (segments);
8217   mp->n_tags = vec_len (tags);
8218   mp->is_add = is_del == 0;
8219   clib_memcpy (mp->segs_and_tags, segments,
8220                vec_len (segments) * sizeof (ip6_address_t));
8221   clib_memcpy (mp->segs_and_tags +
8222                vec_len (segments) * sizeof (ip6_address_t), tags,
8223                vec_len (tags) * sizeof (ip6_address_t));
8224
8225   mp->outer_vrf_id = ntohl (rx_table_id);
8226   mp->inner_vrf_id = ntohl (tx_table_id);
8227   memcpy (mp->name, name, vec_len (name));
8228   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8229
8230   vec_free (segments);
8231   vec_free (tags);
8232
8233   S;
8234   W;
8235   /* NOTREACHED */
8236 }
8237
8238 static int
8239 api_sr_policy_add_del (vat_main_t * vam)
8240 {
8241   unformat_input_t *input = vam->input;
8242   vl_api_sr_policy_add_del_t *mp;
8243   f64 timeout;
8244   int is_del = 0;
8245   u8 *name = 0;
8246   u8 *tunnel_name = 0;
8247   u8 **tunnel_names = 0;
8248
8249   int name_set = 0;
8250   int tunnel_set = 0;
8251   int j = 0;
8252   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8253   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8254
8255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8256     {
8257       if (unformat (input, "del"))
8258         is_del = 1;
8259       else if (unformat (input, "name %s", &name))
8260         name_set = 1;
8261       else if (unformat (input, "tunnel %s", &tunnel_name))
8262         {
8263           if (tunnel_name)
8264             {
8265               vec_add1 (tunnel_names, tunnel_name);
8266               /* For serializer:
8267                  - length = #bytes to store in serial vector
8268                  - +1 = byte to store that length
8269                */
8270               tunnel_names_length += (vec_len (tunnel_name) + 1);
8271               tunnel_set = 1;
8272               tunnel_name = 0;
8273             }
8274         }
8275       else
8276         break;
8277     }
8278
8279   if (!name_set)
8280     {
8281       errmsg ("policy name required");
8282       return -99;
8283     }
8284
8285   if ((!tunnel_set) && (!is_del))
8286     {
8287       errmsg ("tunnel name required");
8288       return -99;
8289     }
8290
8291   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8292
8293
8294
8295   mp->is_add = !is_del;
8296
8297   memcpy (mp->name, name, vec_len (name));
8298   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8299   u8 *serial_orig = 0;
8300   vec_validate (serial_orig, tunnel_names_length);
8301   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8302   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8303
8304   for (j = 0; j < vec_len (tunnel_names); j++)
8305     {
8306       tun_name_len = vec_len (tunnel_names[j]);
8307       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8308       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8309       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8310       serial_orig += tun_name_len;      // Advance past the copy
8311     }
8312   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8313
8314   vec_free (tunnel_names);
8315   vec_free (tunnel_name);
8316
8317   S;
8318   W;
8319   /* NOTREACHED */
8320 }
8321
8322 static int
8323 api_sr_multicast_map_add_del (vat_main_t * vam)
8324 {
8325   unformat_input_t *input = vam->input;
8326   vl_api_sr_multicast_map_add_del_t *mp;
8327   f64 timeout;
8328   int is_del = 0;
8329   ip6_address_t multicast_address;
8330   u8 *policy_name = 0;
8331   int multicast_address_set = 0;
8332
8333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8334     {
8335       if (unformat (input, "del"))
8336         is_del = 1;
8337       else
8338         if (unformat
8339             (input, "address %U", unformat_ip6_address, &multicast_address))
8340         multicast_address_set = 1;
8341       else if (unformat (input, "sr-policy %s", &policy_name))
8342         ;
8343       else
8344         break;
8345     }
8346
8347   if (!is_del && !policy_name)
8348     {
8349       errmsg ("sr-policy name required");
8350       return -99;
8351     }
8352
8353
8354   if (!multicast_address_set)
8355     {
8356       errmsg ("address required");
8357       return -99;
8358     }
8359
8360   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8361
8362   mp->is_add = !is_del;
8363   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8364   clib_memcpy (mp->multicast_address, &multicast_address,
8365                sizeof (mp->multicast_address));
8366
8367
8368   vec_free (policy_name);
8369
8370   S;
8371   W;
8372   /* NOTREACHED */
8373 }
8374
8375
8376 #define foreach_tcp_proto_field                 \
8377 _(src_port)                                     \
8378 _(dst_port)
8379
8380 #define foreach_udp_proto_field                 \
8381 _(src_port)                                     \
8382 _(dst_port)
8383
8384 #define foreach_ip4_proto_field                 \
8385 _(src_address)                                  \
8386 _(dst_address)                                  \
8387 _(tos)                                          \
8388 _(length)                                       \
8389 _(fragment_id)                                  \
8390 _(ttl)                                          \
8391 _(protocol)                                     \
8392 _(checksum)
8393
8394 uword
8395 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8396 {
8397   u8 **maskp = va_arg (*args, u8 **);
8398   u8 *mask = 0;
8399   u8 found_something = 0;
8400   tcp_header_t *tcp;
8401
8402 #define _(a) u8 a=0;
8403   foreach_tcp_proto_field;
8404 #undef _
8405
8406   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8407     {
8408       if (0);
8409 #define _(a) else if (unformat (input, #a)) a=1;
8410       foreach_tcp_proto_field
8411 #undef _
8412         else
8413         break;
8414     }
8415
8416 #define _(a) found_something += a;
8417   foreach_tcp_proto_field;
8418 #undef _
8419
8420   if (found_something == 0)
8421     return 0;
8422
8423   vec_validate (mask, sizeof (*tcp) - 1);
8424
8425   tcp = (tcp_header_t *) mask;
8426
8427 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8428   foreach_tcp_proto_field;
8429 #undef _
8430
8431   *maskp = mask;
8432   return 1;
8433 }
8434
8435 uword
8436 unformat_udp_mask (unformat_input_t * input, va_list * args)
8437 {
8438   u8 **maskp = va_arg (*args, u8 **);
8439   u8 *mask = 0;
8440   u8 found_something = 0;
8441   udp_header_t *udp;
8442
8443 #define _(a) u8 a=0;
8444   foreach_udp_proto_field;
8445 #undef _
8446
8447   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8448     {
8449       if (0);
8450 #define _(a) else if (unformat (input, #a)) a=1;
8451       foreach_udp_proto_field
8452 #undef _
8453         else
8454         break;
8455     }
8456
8457 #define _(a) found_something += a;
8458   foreach_udp_proto_field;
8459 #undef _
8460
8461   if (found_something == 0)
8462     return 0;
8463
8464   vec_validate (mask, sizeof (*udp) - 1);
8465
8466   udp = (udp_header_t *) mask;
8467
8468 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8469   foreach_udp_proto_field;
8470 #undef _
8471
8472   *maskp = mask;
8473   return 1;
8474 }
8475
8476 typedef struct
8477 {
8478   u16 src_port, dst_port;
8479 } tcpudp_header_t;
8480
8481 uword
8482 unformat_l4_mask (unformat_input_t * input, va_list * args)
8483 {
8484   u8 **maskp = va_arg (*args, u8 **);
8485   u16 src_port = 0, dst_port = 0;
8486   tcpudp_header_t *tcpudp;
8487
8488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8489     {
8490       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8491         return 1;
8492       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8493         return 1;
8494       else if (unformat (input, "src_port"))
8495         src_port = 0xFFFF;
8496       else if (unformat (input, "dst_port"))
8497         dst_port = 0xFFFF;
8498       else
8499         return 0;
8500     }
8501
8502   if (!src_port && !dst_port)
8503     return 0;
8504
8505   u8 *mask = 0;
8506   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8507
8508   tcpudp = (tcpudp_header_t *) mask;
8509   tcpudp->src_port = src_port;
8510   tcpudp->dst_port = dst_port;
8511
8512   *maskp = mask;
8513
8514   return 1;
8515 }
8516
8517 uword
8518 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8519 {
8520   u8 **maskp = va_arg (*args, u8 **);
8521   u8 *mask = 0;
8522   u8 found_something = 0;
8523   ip4_header_t *ip;
8524
8525 #define _(a) u8 a=0;
8526   foreach_ip4_proto_field;
8527 #undef _
8528   u8 version = 0;
8529   u8 hdr_length = 0;
8530
8531
8532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8533     {
8534       if (unformat (input, "version"))
8535         version = 1;
8536       else if (unformat (input, "hdr_length"))
8537         hdr_length = 1;
8538       else if (unformat (input, "src"))
8539         src_address = 1;
8540       else if (unformat (input, "dst"))
8541         dst_address = 1;
8542       else if (unformat (input, "proto"))
8543         protocol = 1;
8544
8545 #define _(a) else if (unformat (input, #a)) a=1;
8546       foreach_ip4_proto_field
8547 #undef _
8548         else
8549         break;
8550     }
8551
8552 #define _(a) found_something += a;
8553   foreach_ip4_proto_field;
8554 #undef _
8555
8556   if (found_something == 0)
8557     return 0;
8558
8559   vec_validate (mask, sizeof (*ip) - 1);
8560
8561   ip = (ip4_header_t *) mask;
8562
8563 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8564   foreach_ip4_proto_field;
8565 #undef _
8566
8567   ip->ip_version_and_header_length = 0;
8568
8569   if (version)
8570     ip->ip_version_and_header_length |= 0xF0;
8571
8572   if (hdr_length)
8573     ip->ip_version_and_header_length |= 0x0F;
8574
8575   *maskp = mask;
8576   return 1;
8577 }
8578
8579 #define foreach_ip6_proto_field                 \
8580 _(src_address)                                  \
8581 _(dst_address)                                  \
8582 _(payload_length)                               \
8583 _(hop_limit)                                    \
8584 _(protocol)
8585
8586 uword
8587 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8588 {
8589   u8 **maskp = va_arg (*args, u8 **);
8590   u8 *mask = 0;
8591   u8 found_something = 0;
8592   ip6_header_t *ip;
8593   u32 ip_version_traffic_class_and_flow_label;
8594
8595 #define _(a) u8 a=0;
8596   foreach_ip6_proto_field;
8597 #undef _
8598   u8 version = 0;
8599   u8 traffic_class = 0;
8600   u8 flow_label = 0;
8601
8602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8603     {
8604       if (unformat (input, "version"))
8605         version = 1;
8606       else if (unformat (input, "traffic-class"))
8607         traffic_class = 1;
8608       else if (unformat (input, "flow-label"))
8609         flow_label = 1;
8610       else if (unformat (input, "src"))
8611         src_address = 1;
8612       else if (unformat (input, "dst"))
8613         dst_address = 1;
8614       else if (unformat (input, "proto"))
8615         protocol = 1;
8616
8617 #define _(a) else if (unformat (input, #a)) a=1;
8618       foreach_ip6_proto_field
8619 #undef _
8620         else
8621         break;
8622     }
8623
8624 #define _(a) found_something += a;
8625   foreach_ip6_proto_field;
8626 #undef _
8627
8628   if (found_something == 0)
8629     return 0;
8630
8631   vec_validate (mask, sizeof (*ip) - 1);
8632
8633   ip = (ip6_header_t *) mask;
8634
8635 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8636   foreach_ip6_proto_field;
8637 #undef _
8638
8639   ip_version_traffic_class_and_flow_label = 0;
8640
8641   if (version)
8642     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8643
8644   if (traffic_class)
8645     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8646
8647   if (flow_label)
8648     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8649
8650   ip->ip_version_traffic_class_and_flow_label =
8651     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8652
8653   *maskp = mask;
8654   return 1;
8655 }
8656
8657 uword
8658 unformat_l3_mask (unformat_input_t * input, va_list * args)
8659 {
8660   u8 **maskp = va_arg (*args, u8 **);
8661
8662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8663     {
8664       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8665         return 1;
8666       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8667         return 1;
8668       else
8669         break;
8670     }
8671   return 0;
8672 }
8673
8674 uword
8675 unformat_l2_mask (unformat_input_t * input, va_list * args)
8676 {
8677   u8 **maskp = va_arg (*args, u8 **);
8678   u8 *mask = 0;
8679   u8 src = 0;
8680   u8 dst = 0;
8681   u8 proto = 0;
8682   u8 tag1 = 0;
8683   u8 tag2 = 0;
8684   u8 ignore_tag1 = 0;
8685   u8 ignore_tag2 = 0;
8686   u8 cos1 = 0;
8687   u8 cos2 = 0;
8688   u8 dot1q = 0;
8689   u8 dot1ad = 0;
8690   int len = 14;
8691
8692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8693     {
8694       if (unformat (input, "src"))
8695         src = 1;
8696       else if (unformat (input, "dst"))
8697         dst = 1;
8698       else if (unformat (input, "proto"))
8699         proto = 1;
8700       else if (unformat (input, "tag1"))
8701         tag1 = 1;
8702       else if (unformat (input, "tag2"))
8703         tag2 = 1;
8704       else if (unformat (input, "ignore-tag1"))
8705         ignore_tag1 = 1;
8706       else if (unformat (input, "ignore-tag2"))
8707         ignore_tag2 = 1;
8708       else if (unformat (input, "cos1"))
8709         cos1 = 1;
8710       else if (unformat (input, "cos2"))
8711         cos2 = 1;
8712       else if (unformat (input, "dot1q"))
8713         dot1q = 1;
8714       else if (unformat (input, "dot1ad"))
8715         dot1ad = 1;
8716       else
8717         break;
8718     }
8719   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8720        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8721     return 0;
8722
8723   if (tag1 || ignore_tag1 || cos1 || dot1q)
8724     len = 18;
8725   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8726     len = 22;
8727
8728   vec_validate (mask, len - 1);
8729
8730   if (dst)
8731     memset (mask, 0xff, 6);
8732
8733   if (src)
8734     memset (mask + 6, 0xff, 6);
8735
8736   if (tag2 || dot1ad)
8737     {
8738       /* inner vlan tag */
8739       if (tag2)
8740         {
8741           mask[19] = 0xff;
8742           mask[18] = 0x0f;
8743         }
8744       if (cos2)
8745         mask[18] |= 0xe0;
8746       if (proto)
8747         mask[21] = mask[20] = 0xff;
8748       if (tag1)
8749         {
8750           mask[15] = 0xff;
8751           mask[14] = 0x0f;
8752         }
8753       if (cos1)
8754         mask[14] |= 0xe0;
8755       *maskp = mask;
8756       return 1;
8757     }
8758   if (tag1 | dot1q)
8759     {
8760       if (tag1)
8761         {
8762           mask[15] = 0xff;
8763           mask[14] = 0x0f;
8764         }
8765       if (cos1)
8766         mask[14] |= 0xe0;
8767       if (proto)
8768         mask[16] = mask[17] = 0xff;
8769
8770       *maskp = mask;
8771       return 1;
8772     }
8773   if (cos2)
8774     mask[18] |= 0xe0;
8775   if (cos1)
8776     mask[14] |= 0xe0;
8777   if (proto)
8778     mask[12] = mask[13] = 0xff;
8779
8780   *maskp = mask;
8781   return 1;
8782 }
8783
8784 uword
8785 unformat_classify_mask (unformat_input_t * input, va_list * args)
8786 {
8787   u8 **maskp = va_arg (*args, u8 **);
8788   u32 *skipp = va_arg (*args, u32 *);
8789   u32 *matchp = va_arg (*args, u32 *);
8790   u32 match;
8791   u8 *mask = 0;
8792   u8 *l2 = 0;
8793   u8 *l3 = 0;
8794   u8 *l4 = 0;
8795   int i;
8796
8797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8798     {
8799       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8800         ;
8801       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8802         ;
8803       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8804         ;
8805       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8806         ;
8807       else
8808         break;
8809     }
8810
8811   if (l4 && !l3)
8812     {
8813       vec_free (mask);
8814       vec_free (l2);
8815       vec_free (l4);
8816       return 0;
8817     }
8818
8819   if (mask || l2 || l3 || l4)
8820     {
8821       if (l2 || l3 || l4)
8822         {
8823           /* "With a free Ethernet header in every package" */
8824           if (l2 == 0)
8825             vec_validate (l2, 13);
8826           mask = l2;
8827           if (vec_len (l3))
8828             {
8829               vec_append (mask, l3);
8830               vec_free (l3);
8831             }
8832           if (vec_len (l4))
8833             {
8834               vec_append (mask, l4);
8835               vec_free (l4);
8836             }
8837         }
8838
8839       /* Scan forward looking for the first significant mask octet */
8840       for (i = 0; i < vec_len (mask); i++)
8841         if (mask[i])
8842           break;
8843
8844       /* compute (skip, match) params */
8845       *skipp = i / sizeof (u32x4);
8846       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8847
8848       /* Pad mask to an even multiple of the vector size */
8849       while (vec_len (mask) % sizeof (u32x4))
8850         vec_add1 (mask, 0);
8851
8852       match = vec_len (mask) / sizeof (u32x4);
8853
8854       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8855         {
8856           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8857           if (*tmp || *(tmp + 1))
8858             break;
8859           match--;
8860         }
8861       if (match == 0)
8862         clib_warning ("BUG: match 0");
8863
8864       _vec_len (mask) = match * sizeof (u32x4);
8865
8866       *matchp = match;
8867       *maskp = mask;
8868
8869       return 1;
8870     }
8871
8872   return 0;
8873 }
8874
8875 #define foreach_l2_next                         \
8876 _(drop, DROP)                                   \
8877 _(ethernet, ETHERNET_INPUT)                     \
8878 _(ip4, IP4_INPUT)                               \
8879 _(ip6, IP6_INPUT)
8880
8881 uword
8882 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8883 {
8884   u32 *miss_next_indexp = va_arg (*args, u32 *);
8885   u32 next_index = 0;
8886   u32 tmp;
8887
8888 #define _(n,N) \
8889   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8890   foreach_l2_next;
8891 #undef _
8892
8893   if (unformat (input, "%d", &tmp))
8894     {
8895       next_index = tmp;
8896       goto out;
8897     }
8898
8899   return 0;
8900
8901 out:
8902   *miss_next_indexp = next_index;
8903   return 1;
8904 }
8905
8906 #define foreach_ip_next                         \
8907 _(drop, DROP)                                   \
8908 _(local, LOCAL)                                 \
8909 _(rewrite, REWRITE)
8910
8911 uword
8912 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8913 {
8914   u32 *miss_next_indexp = va_arg (*args, u32 *);
8915   u32 next_index = 0;
8916   u32 tmp;
8917
8918 #define _(n,N) \
8919   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8920   foreach_ip_next;
8921 #undef _
8922
8923   if (unformat (input, "%d", &tmp))
8924     {
8925       next_index = tmp;
8926       goto out;
8927     }
8928
8929   return 0;
8930
8931 out:
8932   *miss_next_indexp = next_index;
8933   return 1;
8934 }
8935
8936 #define foreach_acl_next                        \
8937 _(deny, DENY)
8938
8939 uword
8940 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8941 {
8942   u32 *miss_next_indexp = va_arg (*args, u32 *);
8943   u32 next_index = 0;
8944   u32 tmp;
8945
8946 #define _(n,N) \
8947   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8948   foreach_acl_next;
8949 #undef _
8950
8951   if (unformat (input, "permit"))
8952     {
8953       next_index = ~0;
8954       goto out;
8955     }
8956   else if (unformat (input, "%d", &tmp))
8957     {
8958       next_index = tmp;
8959       goto out;
8960     }
8961
8962   return 0;
8963
8964 out:
8965   *miss_next_indexp = next_index;
8966   return 1;
8967 }
8968
8969 uword
8970 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8971 {
8972   u32 *r = va_arg (*args, u32 *);
8973
8974   if (unformat (input, "conform-color"))
8975     *r = POLICE_CONFORM;
8976   else if (unformat (input, "exceed-color"))
8977     *r = POLICE_EXCEED;
8978   else
8979     return 0;
8980
8981   return 1;
8982 }
8983
8984 static int
8985 api_classify_add_del_table (vat_main_t * vam)
8986 {
8987   unformat_input_t *i = vam->input;
8988   vl_api_classify_add_del_table_t *mp;
8989
8990   u32 nbuckets = 2;
8991   u32 skip = ~0;
8992   u32 match = ~0;
8993   int is_add = 1;
8994   int del_chain = 0;
8995   u32 table_index = ~0;
8996   u32 next_table_index = ~0;
8997   u32 miss_next_index = ~0;
8998   u32 memory_size = 32 << 20;
8999   u8 *mask = 0;
9000   f64 timeout;
9001   u32 current_data_flag = 0;
9002   int current_data_offset = 0;
9003
9004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9005     {
9006       if (unformat (i, "del"))
9007         is_add = 0;
9008       else if (unformat (i, "del-chain"))
9009         {
9010           is_add = 0;
9011           del_chain = 1;
9012         }
9013       else if (unformat (i, "buckets %d", &nbuckets))
9014         ;
9015       else if (unformat (i, "memory_size %d", &memory_size))
9016         ;
9017       else if (unformat (i, "skip %d", &skip))
9018         ;
9019       else if (unformat (i, "match %d", &match))
9020         ;
9021       else if (unformat (i, "table %d", &table_index))
9022         ;
9023       else if (unformat (i, "mask %U", unformat_classify_mask,
9024                          &mask, &skip, &match))
9025         ;
9026       else if (unformat (i, "next-table %d", &next_table_index))
9027         ;
9028       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9029                          &miss_next_index))
9030         ;
9031       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9032                          &miss_next_index))
9033         ;
9034       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9035                          &miss_next_index))
9036         ;
9037       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9038         ;
9039       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9040         ;
9041       else
9042         break;
9043     }
9044
9045   if (is_add && mask == 0)
9046     {
9047       errmsg ("Mask required");
9048       return -99;
9049     }
9050
9051   if (is_add && skip == ~0)
9052     {
9053       errmsg ("skip count required");
9054       return -99;
9055     }
9056
9057   if (is_add && match == ~0)
9058     {
9059       errmsg ("match count required");
9060       return -99;
9061     }
9062
9063   if (!is_add && table_index == ~0)
9064     {
9065       errmsg ("table index required for delete");
9066       return -99;
9067     }
9068
9069   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
9070
9071   mp->is_add = is_add;
9072   mp->del_chain = del_chain;
9073   mp->table_index = ntohl (table_index);
9074   mp->nbuckets = ntohl (nbuckets);
9075   mp->memory_size = ntohl (memory_size);
9076   mp->skip_n_vectors = ntohl (skip);
9077   mp->match_n_vectors = ntohl (match);
9078   mp->next_table_index = ntohl (next_table_index);
9079   mp->miss_next_index = ntohl (miss_next_index);
9080   mp->current_data_flag = ntohl (current_data_flag);
9081   mp->current_data_offset = ntohl (current_data_offset);
9082   clib_memcpy (mp->mask, mask, vec_len (mask));
9083
9084   vec_free (mask);
9085
9086   S;
9087   W;
9088   /* NOTREACHED */
9089 }
9090
9091 uword
9092 unformat_l4_match (unformat_input_t * input, va_list * args)
9093 {
9094   u8 **matchp = va_arg (*args, u8 **);
9095
9096   u8 *proto_header = 0;
9097   int src_port = 0;
9098   int dst_port = 0;
9099
9100   tcpudp_header_t h;
9101
9102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9103     {
9104       if (unformat (input, "src_port %d", &src_port))
9105         ;
9106       else if (unformat (input, "dst_port %d", &dst_port))
9107         ;
9108       else
9109         return 0;
9110     }
9111
9112   h.src_port = clib_host_to_net_u16 (src_port);
9113   h.dst_port = clib_host_to_net_u16 (dst_port);
9114   vec_validate (proto_header, sizeof (h) - 1);
9115   memcpy (proto_header, &h, sizeof (h));
9116
9117   *matchp = proto_header;
9118
9119   return 1;
9120 }
9121
9122 uword
9123 unformat_ip4_match (unformat_input_t * input, va_list * args)
9124 {
9125   u8 **matchp = va_arg (*args, u8 **);
9126   u8 *match = 0;
9127   ip4_header_t *ip;
9128   int version = 0;
9129   u32 version_val;
9130   int hdr_length = 0;
9131   u32 hdr_length_val;
9132   int src = 0, dst = 0;
9133   ip4_address_t src_val, dst_val;
9134   int proto = 0;
9135   u32 proto_val;
9136   int tos = 0;
9137   u32 tos_val;
9138   int length = 0;
9139   u32 length_val;
9140   int fragment_id = 0;
9141   u32 fragment_id_val;
9142   int ttl = 0;
9143   int ttl_val;
9144   int checksum = 0;
9145   u32 checksum_val;
9146
9147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9148     {
9149       if (unformat (input, "version %d", &version_val))
9150         version = 1;
9151       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9152         hdr_length = 1;
9153       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9154         src = 1;
9155       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9156         dst = 1;
9157       else if (unformat (input, "proto %d", &proto_val))
9158         proto = 1;
9159       else if (unformat (input, "tos %d", &tos_val))
9160         tos = 1;
9161       else if (unformat (input, "length %d", &length_val))
9162         length = 1;
9163       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9164         fragment_id = 1;
9165       else if (unformat (input, "ttl %d", &ttl_val))
9166         ttl = 1;
9167       else if (unformat (input, "checksum %d", &checksum_val))
9168         checksum = 1;
9169       else
9170         break;
9171     }
9172
9173   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9174       + ttl + checksum == 0)
9175     return 0;
9176
9177   /*
9178    * Aligned because we use the real comparison functions
9179    */
9180   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9181
9182   ip = (ip4_header_t *) match;
9183
9184   /* These are realistically matched in practice */
9185   if (src)
9186     ip->src_address.as_u32 = src_val.as_u32;
9187
9188   if (dst)
9189     ip->dst_address.as_u32 = dst_val.as_u32;
9190
9191   if (proto)
9192     ip->protocol = proto_val;
9193
9194
9195   /* These are not, but they're included for completeness */
9196   if (version)
9197     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9198
9199   if (hdr_length)
9200     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9201
9202   if (tos)
9203     ip->tos = tos_val;
9204
9205   if (length)
9206     ip->length = clib_host_to_net_u16 (length_val);
9207
9208   if (ttl)
9209     ip->ttl = ttl_val;
9210
9211   if (checksum)
9212     ip->checksum = clib_host_to_net_u16 (checksum_val);
9213
9214   *matchp = match;
9215   return 1;
9216 }
9217
9218 uword
9219 unformat_ip6_match (unformat_input_t * input, va_list * args)
9220 {
9221   u8 **matchp = va_arg (*args, u8 **);
9222   u8 *match = 0;
9223   ip6_header_t *ip;
9224   int version = 0;
9225   u32 version_val;
9226   u8 traffic_class = 0;
9227   u32 traffic_class_val = 0;
9228   u8 flow_label = 0;
9229   u8 flow_label_val;
9230   int src = 0, dst = 0;
9231   ip6_address_t src_val, dst_val;
9232   int proto = 0;
9233   u32 proto_val;
9234   int payload_length = 0;
9235   u32 payload_length_val;
9236   int hop_limit = 0;
9237   int hop_limit_val;
9238   u32 ip_version_traffic_class_and_flow_label;
9239
9240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9241     {
9242       if (unformat (input, "version %d", &version_val))
9243         version = 1;
9244       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9245         traffic_class = 1;
9246       else if (unformat (input, "flow_label %d", &flow_label_val))
9247         flow_label = 1;
9248       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9249         src = 1;
9250       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9251         dst = 1;
9252       else if (unformat (input, "proto %d", &proto_val))
9253         proto = 1;
9254       else if (unformat (input, "payload_length %d", &payload_length_val))
9255         payload_length = 1;
9256       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9257         hop_limit = 1;
9258       else
9259         break;
9260     }
9261
9262   if (version + traffic_class + flow_label + src + dst + proto +
9263       payload_length + hop_limit == 0)
9264     return 0;
9265
9266   /*
9267    * Aligned because we use the real comparison functions
9268    */
9269   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9270
9271   ip = (ip6_header_t *) match;
9272
9273   if (src)
9274     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9275
9276   if (dst)
9277     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9278
9279   if (proto)
9280     ip->protocol = proto_val;
9281
9282   ip_version_traffic_class_and_flow_label = 0;
9283
9284   if (version)
9285     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9286
9287   if (traffic_class)
9288     ip_version_traffic_class_and_flow_label |=
9289       (traffic_class_val & 0xFF) << 20;
9290
9291   if (flow_label)
9292     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9293
9294   ip->ip_version_traffic_class_and_flow_label =
9295     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9296
9297   if (payload_length)
9298     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9299
9300   if (hop_limit)
9301     ip->hop_limit = hop_limit_val;
9302
9303   *matchp = match;
9304   return 1;
9305 }
9306
9307 uword
9308 unformat_l3_match (unformat_input_t * input, va_list * args)
9309 {
9310   u8 **matchp = va_arg (*args, u8 **);
9311
9312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9313     {
9314       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9315         return 1;
9316       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9317         return 1;
9318       else
9319         break;
9320     }
9321   return 0;
9322 }
9323
9324 uword
9325 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9326 {
9327   u8 *tagp = va_arg (*args, u8 *);
9328   u32 tag;
9329
9330   if (unformat (input, "%d", &tag))
9331     {
9332       tagp[0] = (tag >> 8) & 0x0F;
9333       tagp[1] = tag & 0xFF;
9334       return 1;
9335     }
9336
9337   return 0;
9338 }
9339
9340 uword
9341 unformat_l2_match (unformat_input_t * input, va_list * args)
9342 {
9343   u8 **matchp = va_arg (*args, u8 **);
9344   u8 *match = 0;
9345   u8 src = 0;
9346   u8 src_val[6];
9347   u8 dst = 0;
9348   u8 dst_val[6];
9349   u8 proto = 0;
9350   u16 proto_val;
9351   u8 tag1 = 0;
9352   u8 tag1_val[2];
9353   u8 tag2 = 0;
9354   u8 tag2_val[2];
9355   int len = 14;
9356   u8 ignore_tag1 = 0;
9357   u8 ignore_tag2 = 0;
9358   u8 cos1 = 0;
9359   u8 cos2 = 0;
9360   u32 cos1_val = 0;
9361   u32 cos2_val = 0;
9362
9363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9364     {
9365       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9366         src = 1;
9367       else
9368         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9369         dst = 1;
9370       else if (unformat (input, "proto %U",
9371                          unformat_ethernet_type_host_byte_order, &proto_val))
9372         proto = 1;
9373       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9374         tag1 = 1;
9375       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9376         tag2 = 1;
9377       else if (unformat (input, "ignore-tag1"))
9378         ignore_tag1 = 1;
9379       else if (unformat (input, "ignore-tag2"))
9380         ignore_tag2 = 1;
9381       else if (unformat (input, "cos1 %d", &cos1_val))
9382         cos1 = 1;
9383       else if (unformat (input, "cos2 %d", &cos2_val))
9384         cos2 = 1;
9385       else
9386         break;
9387     }
9388   if ((src + dst + proto + tag1 + tag2 +
9389        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9390     return 0;
9391
9392   if (tag1 || ignore_tag1 || cos1)
9393     len = 18;
9394   if (tag2 || ignore_tag2 || cos2)
9395     len = 22;
9396
9397   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9398
9399   if (dst)
9400     clib_memcpy (match, dst_val, 6);
9401
9402   if (src)
9403     clib_memcpy (match + 6, src_val, 6);
9404
9405   if (tag2)
9406     {
9407       /* inner vlan tag */
9408       match[19] = tag2_val[1];
9409       match[18] = tag2_val[0];
9410       if (cos2)
9411         match[18] |= (cos2_val & 0x7) << 5;
9412       if (proto)
9413         {
9414           match[21] = proto_val & 0xff;
9415           match[20] = proto_val >> 8;
9416         }
9417       if (tag1)
9418         {
9419           match[15] = tag1_val[1];
9420           match[14] = tag1_val[0];
9421         }
9422       if (cos1)
9423         match[14] |= (cos1_val & 0x7) << 5;
9424       *matchp = match;
9425       return 1;
9426     }
9427   if (tag1)
9428     {
9429       match[15] = tag1_val[1];
9430       match[14] = tag1_val[0];
9431       if (proto)
9432         {
9433           match[17] = proto_val & 0xff;
9434           match[16] = proto_val >> 8;
9435         }
9436       if (cos1)
9437         match[14] |= (cos1_val & 0x7) << 5;
9438
9439       *matchp = match;
9440       return 1;
9441     }
9442   if (cos2)
9443     match[18] |= (cos2_val & 0x7) << 5;
9444   if (cos1)
9445     match[14] |= (cos1_val & 0x7) << 5;
9446   if (proto)
9447     {
9448       match[13] = proto_val & 0xff;
9449       match[12] = proto_val >> 8;
9450     }
9451
9452   *matchp = match;
9453   return 1;
9454 }
9455
9456
9457 uword
9458 unformat_classify_match (unformat_input_t * input, va_list * args)
9459 {
9460   u8 **matchp = va_arg (*args, u8 **);
9461   u32 skip_n_vectors = va_arg (*args, u32);
9462   u32 match_n_vectors = va_arg (*args, u32);
9463
9464   u8 *match = 0;
9465   u8 *l2 = 0;
9466   u8 *l3 = 0;
9467   u8 *l4 = 0;
9468
9469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9470     {
9471       if (unformat (input, "hex %U", unformat_hex_string, &match))
9472         ;
9473       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9474         ;
9475       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9476         ;
9477       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9478         ;
9479       else
9480         break;
9481     }
9482
9483   if (l4 && !l3)
9484     {
9485       vec_free (match);
9486       vec_free (l2);
9487       vec_free (l4);
9488       return 0;
9489     }
9490
9491   if (match || l2 || l3 || l4)
9492     {
9493       if (l2 || l3 || l4)
9494         {
9495           /* "Win a free Ethernet header in every packet" */
9496           if (l2 == 0)
9497             vec_validate_aligned (l2, 13, sizeof (u32x4));
9498           match = l2;
9499           if (vec_len (l3))
9500             {
9501               vec_append_aligned (match, l3, sizeof (u32x4));
9502               vec_free (l3);
9503             }
9504           if (vec_len (l4))
9505             {
9506               vec_append_aligned (match, l4, sizeof (u32x4));
9507               vec_free (l4);
9508             }
9509         }
9510
9511       /* Make sure the vector is big enough even if key is all 0's */
9512       vec_validate_aligned
9513         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9514          sizeof (u32x4));
9515
9516       /* Set size, include skipped vectors */
9517       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9518
9519       *matchp = match;
9520
9521       return 1;
9522     }
9523
9524   return 0;
9525 }
9526
9527 static int
9528 api_classify_add_del_session (vat_main_t * vam)
9529 {
9530   unformat_input_t *i = vam->input;
9531   vl_api_classify_add_del_session_t *mp;
9532   int is_add = 1;
9533   u32 table_index = ~0;
9534   u32 hit_next_index = ~0;
9535   u32 opaque_index = ~0;
9536   u8 *match = 0;
9537   i32 advance = 0;
9538   f64 timeout;
9539   u32 skip_n_vectors = 0;
9540   u32 match_n_vectors = 0;
9541   u32 action = 0;
9542   u32 metadata = 0;
9543
9544   /*
9545    * Warning: you have to supply skip_n and match_n
9546    * because the API client cant simply look at the classify
9547    * table object.
9548    */
9549
9550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9551     {
9552       if (unformat (i, "del"))
9553         is_add = 0;
9554       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9555                          &hit_next_index))
9556         ;
9557       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9558                          &hit_next_index))
9559         ;
9560       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9561                          &hit_next_index))
9562         ;
9563       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9564         ;
9565       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9566         ;
9567       else if (unformat (i, "opaque-index %d", &opaque_index))
9568         ;
9569       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9570         ;
9571       else if (unformat (i, "match_n %d", &match_n_vectors))
9572         ;
9573       else if (unformat (i, "match %U", unformat_classify_match,
9574                          &match, skip_n_vectors, match_n_vectors))
9575         ;
9576       else if (unformat (i, "advance %d", &advance))
9577         ;
9578       else if (unformat (i, "table-index %d", &table_index))
9579         ;
9580       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9581         action = 1;
9582       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9583         action = 2;
9584       else if (unformat (i, "action %d", &action))
9585         ;
9586       else if (unformat (i, "metadata %d", &metadata))
9587         ;
9588       else
9589         break;
9590     }
9591
9592   if (table_index == ~0)
9593     {
9594       errmsg ("Table index required");
9595       return -99;
9596     }
9597
9598   if (is_add && match == 0)
9599     {
9600       errmsg ("Match value required");
9601       return -99;
9602     }
9603
9604   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9605
9606   mp->is_add = is_add;
9607   mp->table_index = ntohl (table_index);
9608   mp->hit_next_index = ntohl (hit_next_index);
9609   mp->opaque_index = ntohl (opaque_index);
9610   mp->advance = ntohl (advance);
9611   mp->action = action;
9612   mp->metadata = ntohl (metadata);
9613   clib_memcpy (mp->match, match, vec_len (match));
9614   vec_free (match);
9615
9616   S;
9617   W;
9618   /* NOTREACHED */
9619 }
9620
9621 static int
9622 api_classify_set_interface_ip_table (vat_main_t * vam)
9623 {
9624   unformat_input_t *i = vam->input;
9625   vl_api_classify_set_interface_ip_table_t *mp;
9626   f64 timeout;
9627   u32 sw_if_index;
9628   int sw_if_index_set;
9629   u32 table_index = ~0;
9630   u8 is_ipv6 = 0;
9631
9632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9633     {
9634       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9635         sw_if_index_set = 1;
9636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9637         sw_if_index_set = 1;
9638       else if (unformat (i, "table %d", &table_index))
9639         ;
9640       else
9641         {
9642           clib_warning ("parse error '%U'", format_unformat_error, i);
9643           return -99;
9644         }
9645     }
9646
9647   if (sw_if_index_set == 0)
9648     {
9649       errmsg ("missing interface name or sw_if_index");
9650       return -99;
9651     }
9652
9653
9654   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9655
9656   mp->sw_if_index = ntohl (sw_if_index);
9657   mp->table_index = ntohl (table_index);
9658   mp->is_ipv6 = is_ipv6;
9659
9660   S;
9661   W;
9662   /* NOTREACHED */
9663   return 0;
9664 }
9665
9666 static int
9667 api_classify_set_interface_l2_tables (vat_main_t * vam)
9668 {
9669   unformat_input_t *i = vam->input;
9670   vl_api_classify_set_interface_l2_tables_t *mp;
9671   f64 timeout;
9672   u32 sw_if_index;
9673   int sw_if_index_set;
9674   u32 ip4_table_index = ~0;
9675   u32 ip6_table_index = ~0;
9676   u32 other_table_index = ~0;
9677   u32 is_input = 1;
9678
9679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9680     {
9681       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9682         sw_if_index_set = 1;
9683       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9684         sw_if_index_set = 1;
9685       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9686         ;
9687       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9688         ;
9689       else if (unformat (i, "other-table %d", &other_table_index))
9690         ;
9691       else if (unformat (i, "is-input %d", &is_input))
9692         ;
9693       else
9694         {
9695           clib_warning ("parse error '%U'", format_unformat_error, i);
9696           return -99;
9697         }
9698     }
9699
9700   if (sw_if_index_set == 0)
9701     {
9702       errmsg ("missing interface name or sw_if_index");
9703       return -99;
9704     }
9705
9706
9707   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9708
9709   mp->sw_if_index = ntohl (sw_if_index);
9710   mp->ip4_table_index = ntohl (ip4_table_index);
9711   mp->ip6_table_index = ntohl (ip6_table_index);
9712   mp->other_table_index = ntohl (other_table_index);
9713   mp->is_input = (u8) is_input;
9714
9715   S;
9716   W;
9717   /* NOTREACHED */
9718   return 0;
9719 }
9720
9721 static int
9722 api_set_ipfix_exporter (vat_main_t * vam)
9723 {
9724   unformat_input_t *i = vam->input;
9725   vl_api_set_ipfix_exporter_t *mp;
9726   ip4_address_t collector_address;
9727   u8 collector_address_set = 0;
9728   u32 collector_port = ~0;
9729   ip4_address_t src_address;
9730   u8 src_address_set = 0;
9731   u32 vrf_id = ~0;
9732   u32 path_mtu = ~0;
9733   u32 template_interval = ~0;
9734   u8 udp_checksum = 0;
9735   f64 timeout;
9736
9737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9738     {
9739       if (unformat (i, "collector_address %U", unformat_ip4_address,
9740                     &collector_address))
9741         collector_address_set = 1;
9742       else if (unformat (i, "collector_port %d", &collector_port))
9743         ;
9744       else if (unformat (i, "src_address %U", unformat_ip4_address,
9745                          &src_address))
9746         src_address_set = 1;
9747       else if (unformat (i, "vrf_id %d", &vrf_id))
9748         ;
9749       else if (unformat (i, "path_mtu %d", &path_mtu))
9750         ;
9751       else if (unformat (i, "template_interval %d", &template_interval))
9752         ;
9753       else if (unformat (i, "udp_checksum"))
9754         udp_checksum = 1;
9755       else
9756         break;
9757     }
9758
9759   if (collector_address_set == 0)
9760     {
9761       errmsg ("collector_address required");
9762       return -99;
9763     }
9764
9765   if (src_address_set == 0)
9766     {
9767       errmsg ("src_address required");
9768       return -99;
9769     }
9770
9771   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9772
9773   memcpy (mp->collector_address, collector_address.data,
9774           sizeof (collector_address.data));
9775   mp->collector_port = htons ((u16) collector_port);
9776   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9777   mp->vrf_id = htonl (vrf_id);
9778   mp->path_mtu = htonl (path_mtu);
9779   mp->template_interval = htonl (template_interval);
9780   mp->udp_checksum = udp_checksum;
9781
9782   S;
9783   W;
9784   /* NOTREACHED */
9785 }
9786
9787 static int
9788 api_set_ipfix_classify_stream (vat_main_t * vam)
9789 {
9790   unformat_input_t *i = vam->input;
9791   vl_api_set_ipfix_classify_stream_t *mp;
9792   u32 domain_id = 0;
9793   u32 src_port = UDP_DST_PORT_ipfix;
9794   f64 timeout;
9795
9796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9797     {
9798       if (unformat (i, "domain %d", &domain_id))
9799         ;
9800       else if (unformat (i, "src_port %d", &src_port))
9801         ;
9802       else
9803         {
9804           errmsg ("unknown input `%U'", format_unformat_error, i);
9805           return -99;
9806         }
9807     }
9808
9809   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9810
9811   mp->domain_id = htonl (domain_id);
9812   mp->src_port = htons ((u16) src_port);
9813
9814   S;
9815   W;
9816   /* NOTREACHED */
9817 }
9818
9819 static int
9820 api_ipfix_classify_table_add_del (vat_main_t * vam)
9821 {
9822   unformat_input_t *i = vam->input;
9823   vl_api_ipfix_classify_table_add_del_t *mp;
9824   int is_add = -1;
9825   u32 classify_table_index = ~0;
9826   u8 ip_version = 0;
9827   u8 transport_protocol = 255;
9828   f64 timeout;
9829
9830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9831     {
9832       if (unformat (i, "add"))
9833         is_add = 1;
9834       else if (unformat (i, "del"))
9835         is_add = 0;
9836       else if (unformat (i, "table %d", &classify_table_index))
9837         ;
9838       else if (unformat (i, "ip4"))
9839         ip_version = 4;
9840       else if (unformat (i, "ip6"))
9841         ip_version = 6;
9842       else if (unformat (i, "tcp"))
9843         transport_protocol = 6;
9844       else if (unformat (i, "udp"))
9845         transport_protocol = 17;
9846       else
9847         {
9848           errmsg ("unknown input `%U'", format_unformat_error, i);
9849           return -99;
9850         }
9851     }
9852
9853   if (is_add == -1)
9854     {
9855       errmsg ("expecting: add|del");
9856       return -99;
9857     }
9858   if (classify_table_index == ~0)
9859     {
9860       errmsg ("classifier table not specified");
9861       return -99;
9862     }
9863   if (ip_version == 0)
9864     {
9865       errmsg ("IP version not specified");
9866       return -99;
9867     }
9868
9869   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9870
9871   mp->is_add = is_add;
9872   mp->table_id = htonl (classify_table_index);
9873   mp->ip_version = ip_version;
9874   mp->transport_protocol = transport_protocol;
9875
9876   S;
9877   W;
9878   /* NOTREACHED */
9879 }
9880
9881 static int
9882 api_get_node_index (vat_main_t * vam)
9883 {
9884   unformat_input_t *i = vam->input;
9885   vl_api_get_node_index_t *mp;
9886   f64 timeout;
9887   u8 *name = 0;
9888
9889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9890     {
9891       if (unformat (i, "node %s", &name))
9892         ;
9893       else
9894         break;
9895     }
9896   if (name == 0)
9897     {
9898       errmsg ("node name required");
9899       return -99;
9900     }
9901   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9902     {
9903       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9904       return -99;
9905     }
9906
9907   M (GET_NODE_INDEX, get_node_index);
9908   clib_memcpy (mp->node_name, name, vec_len (name));
9909   vec_free (name);
9910
9911   S;
9912   W;
9913   /* NOTREACHED */
9914   return 0;
9915 }
9916
9917 static int
9918 api_get_next_index (vat_main_t * vam)
9919 {
9920   unformat_input_t *i = vam->input;
9921   vl_api_get_next_index_t *mp;
9922   f64 timeout;
9923   u8 *node_name = 0, *next_node_name = 0;
9924
9925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9926     {
9927       if (unformat (i, "node-name %s", &node_name))
9928         ;
9929       else if (unformat (i, "next-node-name %s", &next_node_name))
9930         break;
9931     }
9932
9933   if (node_name == 0)
9934     {
9935       errmsg ("node name required");
9936       return -99;
9937     }
9938   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9939     {
9940       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9941       return -99;
9942     }
9943
9944   if (next_node_name == 0)
9945     {
9946       errmsg ("next node name required");
9947       return -99;
9948     }
9949   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9950     {
9951       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9952       return -99;
9953     }
9954
9955   M (GET_NEXT_INDEX, get_next_index);
9956   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9957   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9958   vec_free (node_name);
9959   vec_free (next_node_name);
9960
9961   S;
9962   W;
9963   /* NOTREACHED */
9964   return 0;
9965 }
9966
9967 static int
9968 api_add_node_next (vat_main_t * vam)
9969 {
9970   unformat_input_t *i = vam->input;
9971   vl_api_add_node_next_t *mp;
9972   f64 timeout;
9973   u8 *name = 0;
9974   u8 *next = 0;
9975
9976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9977     {
9978       if (unformat (i, "node %s", &name))
9979         ;
9980       else if (unformat (i, "next %s", &next))
9981         ;
9982       else
9983         break;
9984     }
9985   if (name == 0)
9986     {
9987       errmsg ("node name required");
9988       return -99;
9989     }
9990   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9991     {
9992       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9993       return -99;
9994     }
9995   if (next == 0)
9996     {
9997       errmsg ("next node required");
9998       return -99;
9999     }
10000   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10001     {
10002       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10003       return -99;
10004     }
10005
10006   M (ADD_NODE_NEXT, add_node_next);
10007   clib_memcpy (mp->node_name, name, vec_len (name));
10008   clib_memcpy (mp->next_name, next, vec_len (next));
10009   vec_free (name);
10010   vec_free (next);
10011
10012   S;
10013   W;
10014   /* NOTREACHED */
10015   return 0;
10016 }
10017
10018 static int
10019 api_l2tpv3_create_tunnel (vat_main_t * vam)
10020 {
10021   unformat_input_t *i = vam->input;
10022   ip6_address_t client_address, our_address;
10023   int client_address_set = 0;
10024   int our_address_set = 0;
10025   u32 local_session_id = 0;
10026   u32 remote_session_id = 0;
10027   u64 local_cookie = 0;
10028   u64 remote_cookie = 0;
10029   u8 l2_sublayer_present = 0;
10030   vl_api_l2tpv3_create_tunnel_t *mp;
10031   f64 timeout;
10032
10033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10034     {
10035       if (unformat (i, "client_address %U", unformat_ip6_address,
10036                     &client_address))
10037         client_address_set = 1;
10038       else if (unformat (i, "our_address %U", unformat_ip6_address,
10039                          &our_address))
10040         our_address_set = 1;
10041       else if (unformat (i, "local_session_id %d", &local_session_id))
10042         ;
10043       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10044         ;
10045       else if (unformat (i, "local_cookie %lld", &local_cookie))
10046         ;
10047       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10048         ;
10049       else if (unformat (i, "l2-sublayer-present"))
10050         l2_sublayer_present = 1;
10051       else
10052         break;
10053     }
10054
10055   if (client_address_set == 0)
10056     {
10057       errmsg ("client_address required");
10058       return -99;
10059     }
10060
10061   if (our_address_set == 0)
10062     {
10063       errmsg ("our_address required");
10064       return -99;
10065     }
10066
10067   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
10068
10069   clib_memcpy (mp->client_address, client_address.as_u8,
10070                sizeof (mp->client_address));
10071
10072   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10073
10074   mp->local_session_id = ntohl (local_session_id);
10075   mp->remote_session_id = ntohl (remote_session_id);
10076   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10077   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10078   mp->l2_sublayer_present = l2_sublayer_present;
10079   mp->is_ipv6 = 1;
10080
10081   S;
10082   W;
10083   /* NOTREACHED */
10084   return 0;
10085 }
10086
10087 static int
10088 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10089 {
10090   unformat_input_t *i = vam->input;
10091   u32 sw_if_index;
10092   u8 sw_if_index_set = 0;
10093   u64 new_local_cookie = 0;
10094   u64 new_remote_cookie = 0;
10095   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10096   f64 timeout;
10097
10098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10099     {
10100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10101         sw_if_index_set = 1;
10102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10103         sw_if_index_set = 1;
10104       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10105         ;
10106       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10107         ;
10108       else
10109         break;
10110     }
10111
10112   if (sw_if_index_set == 0)
10113     {
10114       errmsg ("missing interface name or sw_if_index");
10115       return -99;
10116     }
10117
10118   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10119
10120   mp->sw_if_index = ntohl (sw_if_index);
10121   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10122   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10123
10124   S;
10125   W;
10126   /* NOTREACHED */
10127   return 0;
10128 }
10129
10130 static int
10131 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10132 {
10133   unformat_input_t *i = vam->input;
10134   vl_api_l2tpv3_interface_enable_disable_t *mp;
10135   f64 timeout;
10136   u32 sw_if_index;
10137   u8 sw_if_index_set = 0;
10138   u8 enable_disable = 1;
10139
10140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10141     {
10142       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10143         sw_if_index_set = 1;
10144       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10145         sw_if_index_set = 1;
10146       else if (unformat (i, "enable"))
10147         enable_disable = 1;
10148       else if (unformat (i, "disable"))
10149         enable_disable = 0;
10150       else
10151         break;
10152     }
10153
10154   if (sw_if_index_set == 0)
10155     {
10156       errmsg ("missing interface name or sw_if_index");
10157       return -99;
10158     }
10159
10160   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10161
10162   mp->sw_if_index = ntohl (sw_if_index);
10163   mp->enable_disable = enable_disable;
10164
10165   S;
10166   W;
10167   /* NOTREACHED */
10168   return 0;
10169 }
10170
10171 static int
10172 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10173 {
10174   unformat_input_t *i = vam->input;
10175   vl_api_l2tpv3_set_lookup_key_t *mp;
10176   f64 timeout;
10177   u8 key = ~0;
10178
10179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10180     {
10181       if (unformat (i, "lookup_v6_src"))
10182         key = L2T_LOOKUP_SRC_ADDRESS;
10183       else if (unformat (i, "lookup_v6_dst"))
10184         key = L2T_LOOKUP_DST_ADDRESS;
10185       else if (unformat (i, "lookup_session_id"))
10186         key = L2T_LOOKUP_SESSION_ID;
10187       else
10188         break;
10189     }
10190
10191   if (key == (u8) ~ 0)
10192     {
10193       errmsg ("l2tp session lookup key unset");
10194       return -99;
10195     }
10196
10197   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10198
10199   mp->key = key;
10200
10201   S;
10202   W;
10203   /* NOTREACHED */
10204   return 0;
10205 }
10206
10207 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10208   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10209 {
10210   vat_main_t *vam = &vat_main;
10211
10212   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10213          format_ip6_address, mp->our_address,
10214          format_ip6_address, mp->client_address,
10215          clib_net_to_host_u32 (mp->sw_if_index));
10216
10217   print (vam->ofp,
10218          "   local cookies %016llx %016llx remote cookie %016llx",
10219          clib_net_to_host_u64 (mp->local_cookie[0]),
10220          clib_net_to_host_u64 (mp->local_cookie[1]),
10221          clib_net_to_host_u64 (mp->remote_cookie));
10222
10223   print (vam->ofp, "   local session-id %d remote session-id %d",
10224          clib_net_to_host_u32 (mp->local_session_id),
10225          clib_net_to_host_u32 (mp->remote_session_id));
10226
10227   print (vam->ofp, "   l2 specific sublayer %s\n",
10228          mp->l2_sublayer_present ? "preset" : "absent");
10229
10230 }
10231
10232 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10233   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10234 {
10235   vat_main_t *vam = &vat_main;
10236   vat_json_node_t *node = NULL;
10237   struct in6_addr addr;
10238
10239   if (VAT_JSON_ARRAY != vam->json_tree.type)
10240     {
10241       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10242       vat_json_init_array (&vam->json_tree);
10243     }
10244   node = vat_json_array_add (&vam->json_tree);
10245
10246   vat_json_init_object (node);
10247
10248   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10249   vat_json_object_add_ip6 (node, "our_address", addr);
10250   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10251   vat_json_object_add_ip6 (node, "client_address", addr);
10252
10253   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10254   vat_json_init_array (lc);
10255   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10256   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10257   vat_json_object_add_uint (node, "remote_cookie",
10258                             clib_net_to_host_u64 (mp->remote_cookie));
10259
10260   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10261   vat_json_object_add_uint (node, "local_session_id",
10262                             clib_net_to_host_u32 (mp->local_session_id));
10263   vat_json_object_add_uint (node, "remote_session_id",
10264                             clib_net_to_host_u32 (mp->remote_session_id));
10265   vat_json_object_add_string_copy (node, "l2_sublayer",
10266                                    mp->l2_sublayer_present ? (u8 *) "present"
10267                                    : (u8 *) "absent");
10268 }
10269
10270 static int
10271 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10272 {
10273   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10274   f64 timeout;
10275
10276   /* Get list of l2tpv3-tunnel interfaces */
10277   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10278   S;
10279
10280   /* Use a control ping for synchronization */
10281   {
10282     vl_api_control_ping_t *mp;
10283     M (CONTROL_PING, control_ping);
10284     S;
10285   }
10286   W;
10287 }
10288
10289
10290 static void vl_api_sw_interface_tap_details_t_handler
10291   (vl_api_sw_interface_tap_details_t * mp)
10292 {
10293   vat_main_t *vam = &vat_main;
10294
10295   print (vam->ofp, "%-16s %d",
10296          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10297 }
10298
10299 static void vl_api_sw_interface_tap_details_t_handler_json
10300   (vl_api_sw_interface_tap_details_t * mp)
10301 {
10302   vat_main_t *vam = &vat_main;
10303   vat_json_node_t *node = NULL;
10304
10305   if (VAT_JSON_ARRAY != vam->json_tree.type)
10306     {
10307       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10308       vat_json_init_array (&vam->json_tree);
10309     }
10310   node = vat_json_array_add (&vam->json_tree);
10311
10312   vat_json_init_object (node);
10313   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10314   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10315 }
10316
10317 static int
10318 api_sw_interface_tap_dump (vat_main_t * vam)
10319 {
10320   vl_api_sw_interface_tap_dump_t *mp;
10321   f64 timeout;
10322
10323   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10324   /* Get list of tap interfaces */
10325   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10326   S;
10327
10328   /* Use a control ping for synchronization */
10329   {
10330     vl_api_control_ping_t *mp;
10331     M (CONTROL_PING, control_ping);
10332     S;
10333   }
10334   W;
10335 }
10336
10337 static uword unformat_vxlan_decap_next
10338   (unformat_input_t * input, va_list * args)
10339 {
10340   u32 *result = va_arg (*args, u32 *);
10341   u32 tmp;
10342
10343   if (unformat (input, "l2"))
10344     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10345   else if (unformat (input, "%d", &tmp))
10346     *result = tmp;
10347   else
10348     return 0;
10349   return 1;
10350 }
10351
10352 static int
10353 api_vxlan_add_del_tunnel (vat_main_t * vam)
10354 {
10355   unformat_input_t *line_input = vam->input;
10356   vl_api_vxlan_add_del_tunnel_t *mp;
10357   f64 timeout;
10358   ip46_address_t src, dst;
10359   u8 is_add = 1;
10360   u8 ipv4_set = 0, ipv6_set = 0;
10361   u8 src_set = 0;
10362   u8 dst_set = 0;
10363   u8 grp_set = 0;
10364   u32 mcast_sw_if_index = ~0;
10365   u32 encap_vrf_id = 0;
10366   u32 decap_next_index = ~0;
10367   u32 vni = 0;
10368
10369   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10370   memset (&src, 0, sizeof src);
10371   memset (&dst, 0, sizeof dst);
10372
10373   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10374     {
10375       if (unformat (line_input, "del"))
10376         is_add = 0;
10377       else
10378         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10379         {
10380           ipv4_set = 1;
10381           src_set = 1;
10382         }
10383       else
10384         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10385         {
10386           ipv4_set = 1;
10387           dst_set = 1;
10388         }
10389       else
10390         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10391         {
10392           ipv6_set = 1;
10393           src_set = 1;
10394         }
10395       else
10396         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10397         {
10398           ipv6_set = 1;
10399           dst_set = 1;
10400         }
10401       else if (unformat (line_input, "group %U %U",
10402                          unformat_ip4_address, &dst.ip4,
10403                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10404         {
10405           grp_set = dst_set = 1;
10406           ipv4_set = 1;
10407         }
10408       else if (unformat (line_input, "group %U",
10409                          unformat_ip4_address, &dst.ip4))
10410         {
10411           grp_set = dst_set = 1;
10412           ipv4_set = 1;
10413         }
10414       else if (unformat (line_input, "group %U %U",
10415                          unformat_ip6_address, &dst.ip6,
10416                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10417         {
10418           grp_set = dst_set = 1;
10419           ipv6_set = 1;
10420         }
10421       else if (unformat (line_input, "group %U",
10422                          unformat_ip6_address, &dst.ip6))
10423         {
10424           grp_set = dst_set = 1;
10425           ipv6_set = 1;
10426         }
10427       else
10428         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10429         ;
10430       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10431         ;
10432       else if (unformat (line_input, "decap-next %U",
10433                          unformat_vxlan_decap_next, &decap_next_index))
10434         ;
10435       else if (unformat (line_input, "vni %d", &vni))
10436         ;
10437       else
10438         {
10439           errmsg ("parse error '%U'", format_unformat_error, line_input);
10440           return -99;
10441         }
10442     }
10443
10444   if (src_set == 0)
10445     {
10446       errmsg ("tunnel src address not specified");
10447       return -99;
10448     }
10449   if (dst_set == 0)
10450     {
10451       errmsg ("tunnel dst address not specified");
10452       return -99;
10453     }
10454
10455   if (grp_set && !ip46_address_is_multicast (&dst))
10456     {
10457       errmsg ("tunnel group address not multicast");
10458       return -99;
10459     }
10460   if (grp_set && mcast_sw_if_index == ~0)
10461     {
10462       errmsg ("tunnel nonexistent multicast device");
10463       return -99;
10464     }
10465   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10466     {
10467       errmsg ("tunnel dst address must be unicast");
10468       return -99;
10469     }
10470
10471
10472   if (ipv4_set && ipv6_set)
10473     {
10474       errmsg ("both IPv4 and IPv6 addresses specified");
10475       return -99;
10476     }
10477
10478   if ((vni == 0) || (vni >> 24))
10479     {
10480       errmsg ("vni not specified or out of range");
10481       return -99;
10482     }
10483
10484   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10485
10486   if (ipv6_set)
10487     {
10488       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10489       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10490     }
10491   else
10492     {
10493       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10494       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10495     }
10496   mp->encap_vrf_id = ntohl (encap_vrf_id);
10497   mp->decap_next_index = ntohl (decap_next_index);
10498   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10499   mp->vni = ntohl (vni);
10500   mp->is_add = is_add;
10501   mp->is_ipv6 = ipv6_set;
10502
10503   S;
10504   W;
10505   /* NOTREACHED */
10506   return 0;
10507 }
10508
10509 static void vl_api_vxlan_tunnel_details_t_handler
10510   (vl_api_vxlan_tunnel_details_t * mp)
10511 {
10512   vat_main_t *vam = &vat_main;
10513   ip46_address_t src, dst;
10514
10515   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10516   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10517
10518   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10519          ntohl (mp->sw_if_index),
10520          format_ip46_address, &src, IP46_TYPE_ANY,
10521          format_ip46_address, &dst, IP46_TYPE_ANY,
10522          ntohl (mp->encap_vrf_id),
10523          ntohl (mp->decap_next_index), ntohl (mp->vni),
10524          ntohl (mp->mcast_sw_if_index));
10525 }
10526
10527 static void vl_api_vxlan_tunnel_details_t_handler_json
10528   (vl_api_vxlan_tunnel_details_t * mp)
10529 {
10530   vat_main_t *vam = &vat_main;
10531   vat_json_node_t *node = NULL;
10532
10533   if (VAT_JSON_ARRAY != vam->json_tree.type)
10534     {
10535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10536       vat_json_init_array (&vam->json_tree);
10537     }
10538   node = vat_json_array_add (&vam->json_tree);
10539
10540   vat_json_init_object (node);
10541   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10542   if (mp->is_ipv6)
10543     {
10544       struct in6_addr ip6;
10545
10546       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10547       vat_json_object_add_ip6 (node, "src_address", ip6);
10548       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10549       vat_json_object_add_ip6 (node, "dst_address", ip6);
10550     }
10551   else
10552     {
10553       struct in_addr ip4;
10554
10555       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10556       vat_json_object_add_ip4 (node, "src_address", ip4);
10557       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10558       vat_json_object_add_ip4 (node, "dst_address", ip4);
10559     }
10560   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10561   vat_json_object_add_uint (node, "decap_next_index",
10562                             ntohl (mp->decap_next_index));
10563   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10564   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10565   vat_json_object_add_uint (node, "mcast_sw_if_index",
10566                             ntohl (mp->mcast_sw_if_index));
10567 }
10568
10569 static int
10570 api_vxlan_tunnel_dump (vat_main_t * vam)
10571 {
10572   unformat_input_t *i = vam->input;
10573   vl_api_vxlan_tunnel_dump_t *mp;
10574   f64 timeout;
10575   u32 sw_if_index;
10576   u8 sw_if_index_set = 0;
10577
10578   /* Parse args required to build the message */
10579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10580     {
10581       if (unformat (i, "sw_if_index %d", &sw_if_index))
10582         sw_if_index_set = 1;
10583       else
10584         break;
10585     }
10586
10587   if (sw_if_index_set == 0)
10588     {
10589       sw_if_index = ~0;
10590     }
10591
10592   if (!vam->json_output)
10593     {
10594       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10595              "sw_if_index", "src_address", "dst_address",
10596              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10597     }
10598
10599   /* Get list of vxlan-tunnel interfaces */
10600   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10601
10602   mp->sw_if_index = htonl (sw_if_index);
10603
10604   S;
10605
10606   /* Use a control ping for synchronization */
10607   {
10608     vl_api_control_ping_t *mp;
10609     M (CONTROL_PING, control_ping);
10610     S;
10611   }
10612   W;
10613 }
10614
10615 static int
10616 api_gre_add_del_tunnel (vat_main_t * vam)
10617 {
10618   unformat_input_t *line_input = vam->input;
10619   vl_api_gre_add_del_tunnel_t *mp;
10620   f64 timeout;
10621   ip4_address_t src4, dst4;
10622   u8 is_add = 1;
10623   u8 teb = 0;
10624   u8 src_set = 0;
10625   u8 dst_set = 0;
10626   u32 outer_fib_id = 0;
10627
10628   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10629     {
10630       if (unformat (line_input, "del"))
10631         is_add = 0;
10632       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10633         src_set = 1;
10634       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10635         dst_set = 1;
10636       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10637         ;
10638       else if (unformat (line_input, "teb"))
10639         teb = 1;
10640       else
10641         {
10642           errmsg ("parse error '%U'", format_unformat_error, line_input);
10643           return -99;
10644         }
10645     }
10646
10647   if (src_set == 0)
10648     {
10649       errmsg ("tunnel src address not specified");
10650       return -99;
10651     }
10652   if (dst_set == 0)
10653     {
10654       errmsg ("tunnel dst address not specified");
10655       return -99;
10656     }
10657
10658
10659   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10660
10661   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10662   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10663   mp->outer_fib_id = ntohl (outer_fib_id);
10664   mp->is_add = is_add;
10665   mp->teb = teb;
10666
10667   S;
10668   W;
10669   /* NOTREACHED */
10670   return 0;
10671 }
10672
10673 static void vl_api_gre_tunnel_details_t_handler
10674   (vl_api_gre_tunnel_details_t * mp)
10675 {
10676   vat_main_t *vam = &vat_main;
10677
10678   print (vam->ofp, "%11d%15U%15U%6d%14d",
10679          ntohl (mp->sw_if_index),
10680          format_ip4_address, &mp->src_address,
10681          format_ip4_address, &mp->dst_address,
10682          mp->teb, ntohl (mp->outer_fib_id));
10683 }
10684
10685 static void vl_api_gre_tunnel_details_t_handler_json
10686   (vl_api_gre_tunnel_details_t * mp)
10687 {
10688   vat_main_t *vam = &vat_main;
10689   vat_json_node_t *node = NULL;
10690   struct in_addr ip4;
10691
10692   if (VAT_JSON_ARRAY != vam->json_tree.type)
10693     {
10694       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10695       vat_json_init_array (&vam->json_tree);
10696     }
10697   node = vat_json_array_add (&vam->json_tree);
10698
10699   vat_json_init_object (node);
10700   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10701   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10702   vat_json_object_add_ip4 (node, "src_address", ip4);
10703   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10704   vat_json_object_add_ip4 (node, "dst_address", ip4);
10705   vat_json_object_add_uint (node, "teb", mp->teb);
10706   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10707 }
10708
10709 static int
10710 api_gre_tunnel_dump (vat_main_t * vam)
10711 {
10712   unformat_input_t *i = vam->input;
10713   vl_api_gre_tunnel_dump_t *mp;
10714   f64 timeout;
10715   u32 sw_if_index;
10716   u8 sw_if_index_set = 0;
10717
10718   /* Parse args required to build the message */
10719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10720     {
10721       if (unformat (i, "sw_if_index %d", &sw_if_index))
10722         sw_if_index_set = 1;
10723       else
10724         break;
10725     }
10726
10727   if (sw_if_index_set == 0)
10728     {
10729       sw_if_index = ~0;
10730     }
10731
10732   if (!vam->json_output)
10733     {
10734       print (vam->ofp, "%11s%15s%15s%6s%14s",
10735              "sw_if_index", "src_address", "dst_address", "teb",
10736              "outer_fib_id");
10737     }
10738
10739   /* Get list of gre-tunnel interfaces */
10740   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10741
10742   mp->sw_if_index = htonl (sw_if_index);
10743
10744   S;
10745
10746   /* Use a control ping for synchronization */
10747   {
10748     vl_api_control_ping_t *mp;
10749     M (CONTROL_PING, control_ping);
10750     S;
10751   }
10752   W;
10753 }
10754
10755 static int
10756 api_l2_fib_clear_table (vat_main_t * vam)
10757 {
10758 //  unformat_input_t * i = vam->input;
10759   vl_api_l2_fib_clear_table_t *mp;
10760   f64 timeout;
10761
10762   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10763
10764   S;
10765   W;
10766   /* NOTREACHED */
10767   return 0;
10768 }
10769
10770 static int
10771 api_l2_interface_efp_filter (vat_main_t * vam)
10772 {
10773   unformat_input_t *i = vam->input;
10774   vl_api_l2_interface_efp_filter_t *mp;
10775   f64 timeout;
10776   u32 sw_if_index;
10777   u8 enable = 1;
10778   u8 sw_if_index_set = 0;
10779
10780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10781     {
10782       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10783         sw_if_index_set = 1;
10784       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10785         sw_if_index_set = 1;
10786       else if (unformat (i, "enable"))
10787         enable = 1;
10788       else if (unformat (i, "disable"))
10789         enable = 0;
10790       else
10791         {
10792           clib_warning ("parse error '%U'", format_unformat_error, i);
10793           return -99;
10794         }
10795     }
10796
10797   if (sw_if_index_set == 0)
10798     {
10799       errmsg ("missing sw_if_index");
10800       return -99;
10801     }
10802
10803   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10804
10805   mp->sw_if_index = ntohl (sw_if_index);
10806   mp->enable_disable = enable;
10807
10808   S;
10809   W;
10810   /* NOTREACHED */
10811   return 0;
10812 }
10813
10814 #define foreach_vtr_op                          \
10815 _("disable",  L2_VTR_DISABLED)                  \
10816 _("push-1",  L2_VTR_PUSH_1)                     \
10817 _("push-2",  L2_VTR_PUSH_2)                     \
10818 _("pop-1",  L2_VTR_POP_1)                       \
10819 _("pop-2",  L2_VTR_POP_2)                       \
10820 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10821 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10822 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10823 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10824
10825 static int
10826 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10827 {
10828   unformat_input_t *i = vam->input;
10829   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10830   f64 timeout;
10831   u32 sw_if_index;
10832   u8 sw_if_index_set = 0;
10833   u8 vtr_op_set = 0;
10834   u32 vtr_op = 0;
10835   u32 push_dot1q = 1;
10836   u32 tag1 = ~0;
10837   u32 tag2 = ~0;
10838
10839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10840     {
10841       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10842         sw_if_index_set = 1;
10843       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10844         sw_if_index_set = 1;
10845       else if (unformat (i, "vtr_op %d", &vtr_op))
10846         vtr_op_set = 1;
10847 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10848       foreach_vtr_op
10849 #undef _
10850         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10851         ;
10852       else if (unformat (i, "tag1 %d", &tag1))
10853         ;
10854       else if (unformat (i, "tag2 %d", &tag2))
10855         ;
10856       else
10857         {
10858           clib_warning ("parse error '%U'", format_unformat_error, i);
10859           return -99;
10860         }
10861     }
10862
10863   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10864     {
10865       errmsg ("missing vtr operation or sw_if_index");
10866       return -99;
10867     }
10868
10869   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10870     mp->sw_if_index = ntohl (sw_if_index);
10871   mp->vtr_op = ntohl (vtr_op);
10872   mp->push_dot1q = ntohl (push_dot1q);
10873   mp->tag1 = ntohl (tag1);
10874   mp->tag2 = ntohl (tag2);
10875
10876   S;
10877   W;
10878   /* NOTREACHED */
10879   return 0;
10880 }
10881
10882 static int
10883 api_create_vhost_user_if (vat_main_t * vam)
10884 {
10885   unformat_input_t *i = vam->input;
10886   vl_api_create_vhost_user_if_t *mp;
10887   f64 timeout;
10888   u8 *file_name;
10889   u8 is_server = 0;
10890   u8 file_name_set = 0;
10891   u32 custom_dev_instance = ~0;
10892   u8 hwaddr[6];
10893   u8 use_custom_mac = 0;
10894   u8 *tag = 0;
10895
10896   /* Shut up coverity */
10897   memset (hwaddr, 0, sizeof (hwaddr));
10898
10899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10900     {
10901       if (unformat (i, "socket %s", &file_name))
10902         {
10903           file_name_set = 1;
10904         }
10905       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10906         ;
10907       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10908         use_custom_mac = 1;
10909       else if (unformat (i, "server"))
10910         is_server = 1;
10911       else if (unformat (i, "tag %s", &tag))
10912         ;
10913       else
10914         break;
10915     }
10916
10917   if (file_name_set == 0)
10918     {
10919       errmsg ("missing socket file name");
10920       return -99;
10921     }
10922
10923   if (vec_len (file_name) > 255)
10924     {
10925       errmsg ("socket file name too long");
10926       return -99;
10927     }
10928   vec_add1 (file_name, 0);
10929
10930   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10931
10932   mp->is_server = is_server;
10933   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10934   vec_free (file_name);
10935   if (custom_dev_instance != ~0)
10936     {
10937       mp->renumber = 1;
10938       mp->custom_dev_instance = ntohl (custom_dev_instance);
10939     }
10940   mp->use_custom_mac = use_custom_mac;
10941   clib_memcpy (mp->mac_address, hwaddr, 6);
10942   if (tag)
10943     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10944   vec_free (tag);
10945
10946   S;
10947   W;
10948   /* NOTREACHED */
10949   return 0;
10950 }
10951
10952 static int
10953 api_modify_vhost_user_if (vat_main_t * vam)
10954 {
10955   unformat_input_t *i = vam->input;
10956   vl_api_modify_vhost_user_if_t *mp;
10957   f64 timeout;
10958   u8 *file_name;
10959   u8 is_server = 0;
10960   u8 file_name_set = 0;
10961   u32 custom_dev_instance = ~0;
10962   u8 sw_if_index_set = 0;
10963   u32 sw_if_index = (u32) ~ 0;
10964
10965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10966     {
10967       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10968         sw_if_index_set = 1;
10969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10970         sw_if_index_set = 1;
10971       else if (unformat (i, "socket %s", &file_name))
10972         {
10973           file_name_set = 1;
10974         }
10975       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10976         ;
10977       else if (unformat (i, "server"))
10978         is_server = 1;
10979       else
10980         break;
10981     }
10982
10983   if (sw_if_index_set == 0)
10984     {
10985       errmsg ("missing sw_if_index or interface name");
10986       return -99;
10987     }
10988
10989   if (file_name_set == 0)
10990     {
10991       errmsg ("missing socket file name");
10992       return -99;
10993     }
10994
10995   if (vec_len (file_name) > 255)
10996     {
10997       errmsg ("socket file name too long");
10998       return -99;
10999     }
11000   vec_add1 (file_name, 0);
11001
11002   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
11003
11004   mp->sw_if_index = ntohl (sw_if_index);
11005   mp->is_server = is_server;
11006   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11007   vec_free (file_name);
11008   if (custom_dev_instance != ~0)
11009     {
11010       mp->renumber = 1;
11011       mp->custom_dev_instance = ntohl (custom_dev_instance);
11012     }
11013
11014   S;
11015   W;
11016   /* NOTREACHED */
11017   return 0;
11018 }
11019
11020 static int
11021 api_delete_vhost_user_if (vat_main_t * vam)
11022 {
11023   unformat_input_t *i = vam->input;
11024   vl_api_delete_vhost_user_if_t *mp;
11025   f64 timeout;
11026   u32 sw_if_index = ~0;
11027   u8 sw_if_index_set = 0;
11028
11029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11030     {
11031       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11032         sw_if_index_set = 1;
11033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11034         sw_if_index_set = 1;
11035       else
11036         break;
11037     }
11038
11039   if (sw_if_index_set == 0)
11040     {
11041       errmsg ("missing sw_if_index or interface name");
11042       return -99;
11043     }
11044
11045
11046   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
11047
11048   mp->sw_if_index = ntohl (sw_if_index);
11049
11050   S;
11051   W;
11052   /* NOTREACHED */
11053   return 0;
11054 }
11055
11056 static void vl_api_sw_interface_vhost_user_details_t_handler
11057   (vl_api_sw_interface_vhost_user_details_t * mp)
11058 {
11059   vat_main_t *vam = &vat_main;
11060
11061   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11062          (char *) mp->interface_name,
11063          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11064          clib_net_to_host_u64 (mp->features), mp->is_server,
11065          ntohl (mp->num_regions), (char *) mp->sock_filename);
11066   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11067 }
11068
11069 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11070   (vl_api_sw_interface_vhost_user_details_t * mp)
11071 {
11072   vat_main_t *vam = &vat_main;
11073   vat_json_node_t *node = NULL;
11074
11075   if (VAT_JSON_ARRAY != vam->json_tree.type)
11076     {
11077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11078       vat_json_init_array (&vam->json_tree);
11079     }
11080   node = vat_json_array_add (&vam->json_tree);
11081
11082   vat_json_init_object (node);
11083   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11084   vat_json_object_add_string_copy (node, "interface_name",
11085                                    mp->interface_name);
11086   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11087                             ntohl (mp->virtio_net_hdr_sz));
11088   vat_json_object_add_uint (node, "features",
11089                             clib_net_to_host_u64 (mp->features));
11090   vat_json_object_add_uint (node, "is_server", mp->is_server);
11091   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11092   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11093   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11094 }
11095
11096 static int
11097 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11098 {
11099   vl_api_sw_interface_vhost_user_dump_t *mp;
11100   f64 timeout;
11101   print (vam->ofp,
11102          "Interface name           idx hdr_sz features server regions filename");
11103
11104   /* Get list of vhost-user interfaces */
11105   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11106   S;
11107
11108   /* Use a control ping for synchronization */
11109   {
11110     vl_api_control_ping_t *mp;
11111     M (CONTROL_PING, control_ping);
11112     S;
11113   }
11114   W;
11115 }
11116
11117 static int
11118 api_show_version (vat_main_t * vam)
11119 {
11120   vl_api_show_version_t *mp;
11121   f64 timeout;
11122
11123   M (SHOW_VERSION, show_version);
11124
11125   S;
11126   W;
11127   /* NOTREACHED */
11128   return 0;
11129 }
11130
11131
11132 static int
11133 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11134 {
11135   unformat_input_t *line_input = vam->input;
11136   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11137   f64 timeout;
11138   ip4_address_t local4, remote4;
11139   ip6_address_t local6, remote6;
11140   u8 is_add = 1;
11141   u8 ipv4_set = 0, ipv6_set = 0;
11142   u8 local_set = 0;
11143   u8 remote_set = 0;
11144   u32 encap_vrf_id = 0;
11145   u32 decap_vrf_id = 0;
11146   u8 protocol = ~0;
11147   u32 vni;
11148   u8 vni_set = 0;
11149
11150   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11151     {
11152       if (unformat (line_input, "del"))
11153         is_add = 0;
11154       else if (unformat (line_input, "local %U",
11155                          unformat_ip4_address, &local4))
11156         {
11157           local_set = 1;
11158           ipv4_set = 1;
11159         }
11160       else if (unformat (line_input, "remote %U",
11161                          unformat_ip4_address, &remote4))
11162         {
11163           remote_set = 1;
11164           ipv4_set = 1;
11165         }
11166       else if (unformat (line_input, "local %U",
11167                          unformat_ip6_address, &local6))
11168         {
11169           local_set = 1;
11170           ipv6_set = 1;
11171         }
11172       else if (unformat (line_input, "remote %U",
11173                          unformat_ip6_address, &remote6))
11174         {
11175           remote_set = 1;
11176           ipv6_set = 1;
11177         }
11178       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11179         ;
11180       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11181         ;
11182       else if (unformat (line_input, "vni %d", &vni))
11183         vni_set = 1;
11184       else if (unformat (line_input, "next-ip4"))
11185         protocol = 1;
11186       else if (unformat (line_input, "next-ip6"))
11187         protocol = 2;
11188       else if (unformat (line_input, "next-ethernet"))
11189         protocol = 3;
11190       else if (unformat (line_input, "next-nsh"))
11191         protocol = 4;
11192       else
11193         {
11194           errmsg ("parse error '%U'", format_unformat_error, line_input);
11195           return -99;
11196         }
11197     }
11198
11199   if (local_set == 0)
11200     {
11201       errmsg ("tunnel local address not specified");
11202       return -99;
11203     }
11204   if (remote_set == 0)
11205     {
11206       errmsg ("tunnel remote address not specified");
11207       return -99;
11208     }
11209   if (ipv4_set && ipv6_set)
11210     {
11211       errmsg ("both IPv4 and IPv6 addresses specified");
11212       return -99;
11213     }
11214
11215   if (vni_set == 0)
11216     {
11217       errmsg ("vni not specified");
11218       return -99;
11219     }
11220
11221   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11222
11223
11224   if (ipv6_set)
11225     {
11226       clib_memcpy (&mp->local, &local6, sizeof (local6));
11227       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11228     }
11229   else
11230     {
11231       clib_memcpy (&mp->local, &local4, sizeof (local4));
11232       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11233     }
11234
11235   mp->encap_vrf_id = ntohl (encap_vrf_id);
11236   mp->decap_vrf_id = ntohl (decap_vrf_id);
11237   mp->protocol = protocol;
11238   mp->vni = ntohl (vni);
11239   mp->is_add = is_add;
11240   mp->is_ipv6 = ipv6_set;
11241
11242   S;
11243   W;
11244   /* NOTREACHED */
11245   return 0;
11246 }
11247
11248 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11249   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11250 {
11251   vat_main_t *vam = &vat_main;
11252
11253   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11254          ntohl (mp->sw_if_index),
11255          format_ip46_address, &(mp->local[0]),
11256          format_ip46_address, &(mp->remote[0]),
11257          ntohl (mp->vni),
11258          ntohl (mp->protocol),
11259          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11260 }
11261
11262 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11263   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11264 {
11265   vat_main_t *vam = &vat_main;
11266   vat_json_node_t *node = NULL;
11267   struct in_addr ip4;
11268   struct in6_addr ip6;
11269
11270   if (VAT_JSON_ARRAY != vam->json_tree.type)
11271     {
11272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11273       vat_json_init_array (&vam->json_tree);
11274     }
11275   node = vat_json_array_add (&vam->json_tree);
11276
11277   vat_json_init_object (node);
11278   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11279   if (mp->is_ipv6)
11280     {
11281       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11282       vat_json_object_add_ip6 (node, "local", ip6);
11283       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11284       vat_json_object_add_ip6 (node, "remote", ip6);
11285     }
11286   else
11287     {
11288       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11289       vat_json_object_add_ip4 (node, "local", ip4);
11290       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11291       vat_json_object_add_ip4 (node, "remote", ip4);
11292     }
11293   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11294   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11295   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11296   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11297   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11298 }
11299
11300 static int
11301 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11302 {
11303   unformat_input_t *i = vam->input;
11304   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11305   f64 timeout;
11306   u32 sw_if_index;
11307   u8 sw_if_index_set = 0;
11308
11309   /* Parse args required to build the message */
11310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11311     {
11312       if (unformat (i, "sw_if_index %d", &sw_if_index))
11313         sw_if_index_set = 1;
11314       else
11315         break;
11316     }
11317
11318   if (sw_if_index_set == 0)
11319     {
11320       sw_if_index = ~0;
11321     }
11322
11323   if (!vam->json_output)
11324     {
11325       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11326              "sw_if_index", "local", "remote", "vni",
11327              "protocol", "encap_vrf_id", "decap_vrf_id");
11328     }
11329
11330   /* Get list of vxlan-tunnel interfaces */
11331   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11332
11333   mp->sw_if_index = htonl (sw_if_index);
11334
11335   S;
11336
11337   /* Use a control ping for synchronization */
11338   {
11339     vl_api_control_ping_t *mp;
11340     M (CONTROL_PING, control_ping);
11341     S;
11342   }
11343   W;
11344 }
11345
11346 u8 *
11347 format_l2_fib_mac_address (u8 * s, va_list * args)
11348 {
11349   u8 *a = va_arg (*args, u8 *);
11350
11351   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11352                  a[2], a[3], a[4], a[5], a[6], a[7]);
11353 }
11354
11355 static void vl_api_l2_fib_table_entry_t_handler
11356   (vl_api_l2_fib_table_entry_t * mp)
11357 {
11358   vat_main_t *vam = &vat_main;
11359
11360   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11361          "       %d       %d     %d",
11362          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11363          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11364          mp->bvi_mac);
11365 }
11366
11367 static void vl_api_l2_fib_table_entry_t_handler_json
11368   (vl_api_l2_fib_table_entry_t * mp)
11369 {
11370   vat_main_t *vam = &vat_main;
11371   vat_json_node_t *node = NULL;
11372
11373   if (VAT_JSON_ARRAY != vam->json_tree.type)
11374     {
11375       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11376       vat_json_init_array (&vam->json_tree);
11377     }
11378   node = vat_json_array_add (&vam->json_tree);
11379
11380   vat_json_init_object (node);
11381   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11382   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11383   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11384   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11385   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11386   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11387 }
11388
11389 static int
11390 api_l2_fib_table_dump (vat_main_t * vam)
11391 {
11392   unformat_input_t *i = vam->input;
11393   vl_api_l2_fib_table_dump_t *mp;
11394   f64 timeout;
11395   u32 bd_id;
11396   u8 bd_id_set = 0;
11397
11398   /* Parse args required to build the message */
11399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11400     {
11401       if (unformat (i, "bd_id %d", &bd_id))
11402         bd_id_set = 1;
11403       else
11404         break;
11405     }
11406
11407   if (bd_id_set == 0)
11408     {
11409       errmsg ("missing bridge domain");
11410       return -99;
11411     }
11412
11413   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11414
11415   /* Get list of l2 fib entries */
11416   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11417
11418   mp->bd_id = ntohl (bd_id);
11419   S;
11420
11421   /* Use a control ping for synchronization */
11422   {
11423     vl_api_control_ping_t *mp;
11424     M (CONTROL_PING, control_ping);
11425     S;
11426   }
11427   W;
11428 }
11429
11430
11431 static int
11432 api_interface_name_renumber (vat_main_t * vam)
11433 {
11434   unformat_input_t *line_input = vam->input;
11435   vl_api_interface_name_renumber_t *mp;
11436   u32 sw_if_index = ~0;
11437   f64 timeout;
11438   u32 new_show_dev_instance = ~0;
11439
11440   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11441     {
11442       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11443                     &sw_if_index))
11444         ;
11445       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11446         ;
11447       else if (unformat (line_input, "new_show_dev_instance %d",
11448                          &new_show_dev_instance))
11449         ;
11450       else
11451         break;
11452     }
11453
11454   if (sw_if_index == ~0)
11455     {
11456       errmsg ("missing interface name or sw_if_index");
11457       return -99;
11458     }
11459
11460   if (new_show_dev_instance == ~0)
11461     {
11462       errmsg ("missing new_show_dev_instance");
11463       return -99;
11464     }
11465
11466   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11467
11468   mp->sw_if_index = ntohl (sw_if_index);
11469   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11470
11471   S;
11472   W;
11473 }
11474
11475 static int
11476 api_want_ip4_arp_events (vat_main_t * vam)
11477 {
11478   unformat_input_t *line_input = vam->input;
11479   vl_api_want_ip4_arp_events_t *mp;
11480   f64 timeout;
11481   ip4_address_t address;
11482   int address_set = 0;
11483   u32 enable_disable = 1;
11484
11485   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11486     {
11487       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11488         address_set = 1;
11489       else if (unformat (line_input, "del"))
11490         enable_disable = 0;
11491       else
11492         break;
11493     }
11494
11495   if (address_set == 0)
11496     {
11497       errmsg ("missing addresses");
11498       return -99;
11499     }
11500
11501   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11502   mp->enable_disable = enable_disable;
11503   mp->pid = getpid ();
11504   mp->address = address.as_u32;
11505
11506   S;
11507   W;
11508 }
11509
11510 static int
11511 api_want_ip6_nd_events (vat_main_t * vam)
11512 {
11513   unformat_input_t *line_input = vam->input;
11514   vl_api_want_ip6_nd_events_t *mp;
11515   f64 timeout;
11516   ip6_address_t address;
11517   int address_set = 0;
11518   u32 enable_disable = 1;
11519
11520   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11521     {
11522       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11523         address_set = 1;
11524       else if (unformat (line_input, "del"))
11525         enable_disable = 0;
11526       else
11527         break;
11528     }
11529
11530   if (address_set == 0)
11531     {
11532       errmsg ("missing addresses");
11533       return -99;
11534     }
11535
11536   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11537   mp->enable_disable = enable_disable;
11538   mp->pid = getpid ();
11539   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11540
11541   S;
11542   W;
11543 }
11544
11545 static int
11546 api_input_acl_set_interface (vat_main_t * vam)
11547 {
11548   unformat_input_t *i = vam->input;
11549   vl_api_input_acl_set_interface_t *mp;
11550   f64 timeout;
11551   u32 sw_if_index;
11552   int sw_if_index_set;
11553   u32 ip4_table_index = ~0;
11554   u32 ip6_table_index = ~0;
11555   u32 l2_table_index = ~0;
11556   u8 is_add = 1;
11557
11558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11559     {
11560       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11561         sw_if_index_set = 1;
11562       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11563         sw_if_index_set = 1;
11564       else if (unformat (i, "del"))
11565         is_add = 0;
11566       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11567         ;
11568       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11569         ;
11570       else if (unformat (i, "l2-table %d", &l2_table_index))
11571         ;
11572       else
11573         {
11574           clib_warning ("parse error '%U'", format_unformat_error, i);
11575           return -99;
11576         }
11577     }
11578
11579   if (sw_if_index_set == 0)
11580     {
11581       errmsg ("missing interface name or sw_if_index");
11582       return -99;
11583     }
11584
11585   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11586
11587   mp->sw_if_index = ntohl (sw_if_index);
11588   mp->ip4_table_index = ntohl (ip4_table_index);
11589   mp->ip6_table_index = ntohl (ip6_table_index);
11590   mp->l2_table_index = ntohl (l2_table_index);
11591   mp->is_add = is_add;
11592
11593   S;
11594   W;
11595   /* NOTREACHED */
11596   return 0;
11597 }
11598
11599 static int
11600 api_ip_address_dump (vat_main_t * vam)
11601 {
11602   unformat_input_t *i = vam->input;
11603   vl_api_ip_address_dump_t *mp;
11604   u32 sw_if_index = ~0;
11605   u8 sw_if_index_set = 0;
11606   u8 ipv4_set = 0;
11607   u8 ipv6_set = 0;
11608   f64 timeout;
11609
11610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11611     {
11612       if (unformat (i, "sw_if_index %d", &sw_if_index))
11613         sw_if_index_set = 1;
11614       else
11615         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11616         sw_if_index_set = 1;
11617       else if (unformat (i, "ipv4"))
11618         ipv4_set = 1;
11619       else if (unformat (i, "ipv6"))
11620         ipv6_set = 1;
11621       else
11622         break;
11623     }
11624
11625   if (ipv4_set && ipv6_set)
11626     {
11627       errmsg ("ipv4 and ipv6 flags cannot be both set");
11628       return -99;
11629     }
11630
11631   if ((!ipv4_set) && (!ipv6_set))
11632     {
11633       errmsg ("no ipv4 nor ipv6 flag set");
11634       return -99;
11635     }
11636
11637   if (sw_if_index_set == 0)
11638     {
11639       errmsg ("missing interface name or sw_if_index");
11640       return -99;
11641     }
11642
11643   vam->current_sw_if_index = sw_if_index;
11644   vam->is_ipv6 = ipv6_set;
11645
11646   M (IP_ADDRESS_DUMP, ip_address_dump);
11647   mp->sw_if_index = ntohl (sw_if_index);
11648   mp->is_ipv6 = ipv6_set;
11649   S;
11650
11651   /* Use a control ping for synchronization */
11652   {
11653     vl_api_control_ping_t *mp;
11654     M (CONTROL_PING, control_ping);
11655     S;
11656   }
11657   W;
11658 }
11659
11660 static int
11661 api_ip_dump (vat_main_t * vam)
11662 {
11663   vl_api_ip_dump_t *mp;
11664   unformat_input_t *in = vam->input;
11665   int ipv4_set = 0;
11666   int ipv6_set = 0;
11667   int is_ipv6;
11668   f64 timeout;
11669   int i;
11670
11671   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11672     {
11673       if (unformat (in, "ipv4"))
11674         ipv4_set = 1;
11675       else if (unformat (in, "ipv6"))
11676         ipv6_set = 1;
11677       else
11678         break;
11679     }
11680
11681   if (ipv4_set && ipv6_set)
11682     {
11683       errmsg ("ipv4 and ipv6 flags cannot be both set");
11684       return -99;
11685     }
11686
11687   if ((!ipv4_set) && (!ipv6_set))
11688     {
11689       errmsg ("no ipv4 nor ipv6 flag set");
11690       return -99;
11691     }
11692
11693   is_ipv6 = ipv6_set;
11694   vam->is_ipv6 = is_ipv6;
11695
11696   /* free old data */
11697   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11698     {
11699       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11700     }
11701   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11702
11703   M (IP_DUMP, ip_dump);
11704   mp->is_ipv6 = ipv6_set;
11705   S;
11706
11707   /* Use a control ping for synchronization */
11708   {
11709     vl_api_control_ping_t *mp;
11710     M (CONTROL_PING, control_ping);
11711     S;
11712   }
11713   W;
11714 }
11715
11716 static int
11717 api_ipsec_spd_add_del (vat_main_t * vam)
11718 {
11719   unformat_input_t *i = vam->input;
11720   vl_api_ipsec_spd_add_del_t *mp;
11721   f64 timeout;
11722   u32 spd_id = ~0;
11723   u8 is_add = 1;
11724
11725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11726     {
11727       if (unformat (i, "spd_id %d", &spd_id))
11728         ;
11729       else if (unformat (i, "del"))
11730         is_add = 0;
11731       else
11732         {
11733           clib_warning ("parse error '%U'", format_unformat_error, i);
11734           return -99;
11735         }
11736     }
11737   if (spd_id == ~0)
11738     {
11739       errmsg ("spd_id must be set");
11740       return -99;
11741     }
11742
11743   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11744
11745   mp->spd_id = ntohl (spd_id);
11746   mp->is_add = is_add;
11747
11748   S;
11749   W;
11750   /* NOTREACHED */
11751   return 0;
11752 }
11753
11754 static int
11755 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11756 {
11757   unformat_input_t *i = vam->input;
11758   vl_api_ipsec_interface_add_del_spd_t *mp;
11759   f64 timeout;
11760   u32 sw_if_index;
11761   u8 sw_if_index_set = 0;
11762   u32 spd_id = (u32) ~ 0;
11763   u8 is_add = 1;
11764
11765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11766     {
11767       if (unformat (i, "del"))
11768         is_add = 0;
11769       else if (unformat (i, "spd_id %d", &spd_id))
11770         ;
11771       else
11772         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11773         sw_if_index_set = 1;
11774       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11775         sw_if_index_set = 1;
11776       else
11777         {
11778           clib_warning ("parse error '%U'", format_unformat_error, i);
11779           return -99;
11780         }
11781
11782     }
11783
11784   if (spd_id == (u32) ~ 0)
11785     {
11786       errmsg ("spd_id must be set");
11787       return -99;
11788     }
11789
11790   if (sw_if_index_set == 0)
11791     {
11792       errmsg ("missing interface name or sw_if_index");
11793       return -99;
11794     }
11795
11796   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11797
11798   mp->spd_id = ntohl (spd_id);
11799   mp->sw_if_index = ntohl (sw_if_index);
11800   mp->is_add = is_add;
11801
11802   S;
11803   W;
11804   /* NOTREACHED */
11805   return 0;
11806 }
11807
11808 static int
11809 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11810 {
11811   unformat_input_t *i = vam->input;
11812   vl_api_ipsec_spd_add_del_entry_t *mp;
11813   f64 timeout;
11814   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11815   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11816   i32 priority = 0;
11817   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11818   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11819   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11820   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11821
11822   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11823   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11824   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11825   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11826   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11827   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11828
11829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11830     {
11831       if (unformat (i, "del"))
11832         is_add = 0;
11833       if (unformat (i, "outbound"))
11834         is_outbound = 1;
11835       if (unformat (i, "inbound"))
11836         is_outbound = 0;
11837       else if (unformat (i, "spd_id %d", &spd_id))
11838         ;
11839       else if (unformat (i, "sa_id %d", &sa_id))
11840         ;
11841       else if (unformat (i, "priority %d", &priority))
11842         ;
11843       else if (unformat (i, "protocol %d", &protocol))
11844         ;
11845       else if (unformat (i, "lport_start %d", &lport_start))
11846         ;
11847       else if (unformat (i, "lport_stop %d", &lport_stop))
11848         ;
11849       else if (unformat (i, "rport_start %d", &rport_start))
11850         ;
11851       else if (unformat (i, "rport_stop %d", &rport_stop))
11852         ;
11853       else
11854         if (unformat
11855             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11856         {
11857           is_ipv6 = 0;
11858           is_ip_any = 0;
11859         }
11860       else
11861         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11862         {
11863           is_ipv6 = 0;
11864           is_ip_any = 0;
11865         }
11866       else
11867         if (unformat
11868             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11869         {
11870           is_ipv6 = 0;
11871           is_ip_any = 0;
11872         }
11873       else
11874         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11875         {
11876           is_ipv6 = 0;
11877           is_ip_any = 0;
11878         }
11879       else
11880         if (unformat
11881             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11882         {
11883           is_ipv6 = 1;
11884           is_ip_any = 0;
11885         }
11886       else
11887         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11888         {
11889           is_ipv6 = 1;
11890           is_ip_any = 0;
11891         }
11892       else
11893         if (unformat
11894             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11895         {
11896           is_ipv6 = 1;
11897           is_ip_any = 0;
11898         }
11899       else
11900         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11901         {
11902           is_ipv6 = 1;
11903           is_ip_any = 0;
11904         }
11905       else
11906         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11907         {
11908           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11909             {
11910               clib_warning ("unsupported action: 'resolve'");
11911               return -99;
11912             }
11913         }
11914       else
11915         {
11916           clib_warning ("parse error '%U'", format_unformat_error, i);
11917           return -99;
11918         }
11919
11920     }
11921
11922   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11923
11924   mp->spd_id = ntohl (spd_id);
11925   mp->priority = ntohl (priority);
11926   mp->is_outbound = is_outbound;
11927
11928   mp->is_ipv6 = is_ipv6;
11929   if (is_ipv6 || is_ip_any)
11930     {
11931       clib_memcpy (mp->remote_address_start, &raddr6_start,
11932                    sizeof (ip6_address_t));
11933       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11934                    sizeof (ip6_address_t));
11935       clib_memcpy (mp->local_address_start, &laddr6_start,
11936                    sizeof (ip6_address_t));
11937       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11938                    sizeof (ip6_address_t));
11939     }
11940   else
11941     {
11942       clib_memcpy (mp->remote_address_start, &raddr4_start,
11943                    sizeof (ip4_address_t));
11944       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11945                    sizeof (ip4_address_t));
11946       clib_memcpy (mp->local_address_start, &laddr4_start,
11947                    sizeof (ip4_address_t));
11948       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11949                    sizeof (ip4_address_t));
11950     }
11951   mp->protocol = (u8) protocol;
11952   mp->local_port_start = ntohs ((u16) lport_start);
11953   mp->local_port_stop = ntohs ((u16) lport_stop);
11954   mp->remote_port_start = ntohs ((u16) rport_start);
11955   mp->remote_port_stop = ntohs ((u16) rport_stop);
11956   mp->policy = (u8) policy;
11957   mp->sa_id = ntohl (sa_id);
11958   mp->is_add = is_add;
11959   mp->is_ip_any = is_ip_any;
11960   S;
11961   W;
11962   /* NOTREACHED */
11963   return 0;
11964 }
11965
11966 static int
11967 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11968 {
11969   unformat_input_t *i = vam->input;
11970   vl_api_ipsec_sad_add_del_entry_t *mp;
11971   f64 timeout;
11972   u32 sad_id = 0, spi = 0;
11973   u8 *ck = 0, *ik = 0;
11974   u8 is_add = 1;
11975
11976   u8 protocol = IPSEC_PROTOCOL_AH;
11977   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11978   u32 crypto_alg = 0, integ_alg = 0;
11979   ip4_address_t tun_src4;
11980   ip4_address_t tun_dst4;
11981   ip6_address_t tun_src6;
11982   ip6_address_t tun_dst6;
11983
11984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11985     {
11986       if (unformat (i, "del"))
11987         is_add = 0;
11988       else if (unformat (i, "sad_id %d", &sad_id))
11989         ;
11990       else if (unformat (i, "spi %d", &spi))
11991         ;
11992       else if (unformat (i, "esp"))
11993         protocol = IPSEC_PROTOCOL_ESP;
11994       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11995         {
11996           is_tunnel = 1;
11997           is_tunnel_ipv6 = 0;
11998         }
11999       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12000         {
12001           is_tunnel = 1;
12002           is_tunnel_ipv6 = 0;
12003         }
12004       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12005         {
12006           is_tunnel = 1;
12007           is_tunnel_ipv6 = 1;
12008         }
12009       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12010         {
12011           is_tunnel = 1;
12012           is_tunnel_ipv6 = 1;
12013         }
12014       else
12015         if (unformat
12016             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12017         {
12018           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12019               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12020             {
12021               clib_warning ("unsupported crypto-alg: '%U'",
12022                             format_ipsec_crypto_alg, crypto_alg);
12023               return -99;
12024             }
12025         }
12026       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12027         ;
12028       else
12029         if (unformat
12030             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12031         {
12032 #if DPDK_CRYPTO==1
12033           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
12034 #else
12035           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12036 #endif
12037               integ_alg >= IPSEC_INTEG_N_ALG)
12038             {
12039               clib_warning ("unsupported integ-alg: '%U'",
12040                             format_ipsec_integ_alg, integ_alg);
12041               return -99;
12042             }
12043         }
12044       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12045         ;
12046       else
12047         {
12048           clib_warning ("parse error '%U'", format_unformat_error, i);
12049           return -99;
12050         }
12051
12052     }
12053
12054 #if DPDK_CRYPTO==1
12055   /*Special cases, aes-gcm-128 encryption */
12056   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
12057     {
12058       if (integ_alg != IPSEC_INTEG_ALG_NONE
12059           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
12060         {
12061           clib_warning
12062             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
12063           return -99;
12064         }
12065       else                      /*set integ-alg internally to aes-gcm-128 */
12066         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
12067     }
12068   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
12069     {
12070       clib_warning ("unsupported integ-alg: aes-gcm-128");
12071       return -99;
12072     }
12073   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
12074     {
12075       clib_warning ("unsupported integ-alg: none");
12076       return -99;
12077     }
12078 #endif
12079
12080
12081   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12082
12083   mp->sad_id = ntohl (sad_id);
12084   mp->is_add = is_add;
12085   mp->protocol = protocol;
12086   mp->spi = ntohl (spi);
12087   mp->is_tunnel = is_tunnel;
12088   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12089   mp->crypto_algorithm = crypto_alg;
12090   mp->integrity_algorithm = integ_alg;
12091   mp->crypto_key_length = vec_len (ck);
12092   mp->integrity_key_length = vec_len (ik);
12093
12094   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12095     mp->crypto_key_length = sizeof (mp->crypto_key);
12096
12097   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12098     mp->integrity_key_length = sizeof (mp->integrity_key);
12099
12100   if (ck)
12101     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12102   if (ik)
12103     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12104
12105   if (is_tunnel)
12106     {
12107       if (is_tunnel_ipv6)
12108         {
12109           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12110                        sizeof (ip6_address_t));
12111           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12112                        sizeof (ip6_address_t));
12113         }
12114       else
12115         {
12116           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12117                        sizeof (ip4_address_t));
12118           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12119                        sizeof (ip4_address_t));
12120         }
12121     }
12122
12123   S;
12124   W;
12125   /* NOTREACHED */
12126   return 0;
12127 }
12128
12129 static int
12130 api_ipsec_sa_set_key (vat_main_t * vam)
12131 {
12132   unformat_input_t *i = vam->input;
12133   vl_api_ipsec_sa_set_key_t *mp;
12134   f64 timeout;
12135   u32 sa_id;
12136   u8 *ck = 0, *ik = 0;
12137
12138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12139     {
12140       if (unformat (i, "sa_id %d", &sa_id))
12141         ;
12142       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12143         ;
12144       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12145         ;
12146       else
12147         {
12148           clib_warning ("parse error '%U'", format_unformat_error, i);
12149           return -99;
12150         }
12151     }
12152
12153   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12154
12155   mp->sa_id = ntohl (sa_id);
12156   mp->crypto_key_length = vec_len (ck);
12157   mp->integrity_key_length = vec_len (ik);
12158
12159   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12160     mp->crypto_key_length = sizeof (mp->crypto_key);
12161
12162   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12163     mp->integrity_key_length = sizeof (mp->integrity_key);
12164
12165   if (ck)
12166     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12167   if (ik)
12168     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12169
12170   S;
12171   W;
12172   /* NOTREACHED */
12173   return 0;
12174 }
12175
12176 static int
12177 api_ikev2_profile_add_del (vat_main_t * vam)
12178 {
12179   unformat_input_t *i = vam->input;
12180   vl_api_ikev2_profile_add_del_t *mp;
12181   f64 timeout;
12182   u8 is_add = 1;
12183   u8 *name = 0;
12184
12185   const char *valid_chars = "a-zA-Z0-9_";
12186
12187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12188     {
12189       if (unformat (i, "del"))
12190         is_add = 0;
12191       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12192         vec_add1 (name, 0);
12193       else
12194         {
12195           errmsg ("parse error '%U'", format_unformat_error, i);
12196           return -99;
12197         }
12198     }
12199
12200   if (!vec_len (name))
12201     {
12202       errmsg ("profile name must be specified");
12203       return -99;
12204     }
12205
12206   if (vec_len (name) > 64)
12207     {
12208       errmsg ("profile name too long");
12209       return -99;
12210     }
12211
12212   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12213
12214   clib_memcpy (mp->name, name, vec_len (name));
12215   mp->is_add = is_add;
12216   vec_free (name);
12217
12218   S;
12219   W;
12220   /* NOTREACHED */
12221   return 0;
12222 }
12223
12224 static int
12225 api_ikev2_profile_set_auth (vat_main_t * vam)
12226 {
12227   unformat_input_t *i = vam->input;
12228   vl_api_ikev2_profile_set_auth_t *mp;
12229   f64 timeout;
12230   u8 *name = 0;
12231   u8 *data = 0;
12232   u32 auth_method = 0;
12233   u8 is_hex = 0;
12234
12235   const char *valid_chars = "a-zA-Z0-9_";
12236
12237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12238     {
12239       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12240         vec_add1 (name, 0);
12241       else if (unformat (i, "auth_method %U",
12242                          unformat_ikev2_auth_method, &auth_method))
12243         ;
12244       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12245         is_hex = 1;
12246       else if (unformat (i, "auth_data %v", &data))
12247         ;
12248       else
12249         {
12250           errmsg ("parse error '%U'", format_unformat_error, i);
12251           return -99;
12252         }
12253     }
12254
12255   if (!vec_len (name))
12256     {
12257       errmsg ("profile name must be specified");
12258       return -99;
12259     }
12260
12261   if (vec_len (name) > 64)
12262     {
12263       errmsg ("profile name too long");
12264       return -99;
12265     }
12266
12267   if (!vec_len (data))
12268     {
12269       errmsg ("auth_data must be specified");
12270       return -99;
12271     }
12272
12273   if (!auth_method)
12274     {
12275       errmsg ("auth_method must be specified");
12276       return -99;
12277     }
12278
12279   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12280
12281   mp->is_hex = is_hex;
12282   mp->auth_method = (u8) auth_method;
12283   mp->data_len = vec_len (data);
12284   clib_memcpy (mp->name, name, vec_len (name));
12285   clib_memcpy (mp->data, data, vec_len (data));
12286   vec_free (name);
12287   vec_free (data);
12288
12289   S;
12290   W;
12291   /* NOTREACHED */
12292   return 0;
12293 }
12294
12295 static int
12296 api_ikev2_profile_set_id (vat_main_t * vam)
12297 {
12298   unformat_input_t *i = vam->input;
12299   vl_api_ikev2_profile_set_id_t *mp;
12300   f64 timeout;
12301   u8 *name = 0;
12302   u8 *data = 0;
12303   u8 is_local = 0;
12304   u32 id_type = 0;
12305   ip4_address_t ip4;
12306
12307   const char *valid_chars = "a-zA-Z0-9_";
12308
12309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12310     {
12311       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12312         vec_add1 (name, 0);
12313       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12314         ;
12315       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12316         {
12317           data = vec_new (u8, 4);
12318           clib_memcpy (data, ip4.as_u8, 4);
12319         }
12320       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12321         ;
12322       else if (unformat (i, "id_data %v", &data))
12323         ;
12324       else if (unformat (i, "local"))
12325         is_local = 1;
12326       else if (unformat (i, "remote"))
12327         is_local = 0;
12328       else
12329         {
12330           errmsg ("parse error '%U'", format_unformat_error, i);
12331           return -99;
12332         }
12333     }
12334
12335   if (!vec_len (name))
12336     {
12337       errmsg ("profile name must be specified");
12338       return -99;
12339     }
12340
12341   if (vec_len (name) > 64)
12342     {
12343       errmsg ("profile name too long");
12344       return -99;
12345     }
12346
12347   if (!vec_len (data))
12348     {
12349       errmsg ("id_data must be specified");
12350       return -99;
12351     }
12352
12353   if (!id_type)
12354     {
12355       errmsg ("id_type must be specified");
12356       return -99;
12357     }
12358
12359   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12360
12361   mp->is_local = is_local;
12362   mp->id_type = (u8) id_type;
12363   mp->data_len = vec_len (data);
12364   clib_memcpy (mp->name, name, vec_len (name));
12365   clib_memcpy (mp->data, data, vec_len (data));
12366   vec_free (name);
12367   vec_free (data);
12368
12369   S;
12370   W;
12371   /* NOTREACHED */
12372   return 0;
12373 }
12374
12375 static int
12376 api_ikev2_profile_set_ts (vat_main_t * vam)
12377 {
12378   unformat_input_t *i = vam->input;
12379   vl_api_ikev2_profile_set_ts_t *mp;
12380   f64 timeout;
12381   u8 *name = 0;
12382   u8 is_local = 0;
12383   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12384   ip4_address_t start_addr, end_addr;
12385
12386   const char *valid_chars = "a-zA-Z0-9_";
12387
12388   start_addr.as_u32 = 0;
12389   end_addr.as_u32 = (u32) ~ 0;
12390
12391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12392     {
12393       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12394         vec_add1 (name, 0);
12395       else if (unformat (i, "protocol %d", &proto))
12396         ;
12397       else if (unformat (i, "start_port %d", &start_port))
12398         ;
12399       else if (unformat (i, "end_port %d", &end_port))
12400         ;
12401       else
12402         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12403         ;
12404       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12405         ;
12406       else if (unformat (i, "local"))
12407         is_local = 1;
12408       else if (unformat (i, "remote"))
12409         is_local = 0;
12410       else
12411         {
12412           errmsg ("parse error '%U'", format_unformat_error, i);
12413           return -99;
12414         }
12415     }
12416
12417   if (!vec_len (name))
12418     {
12419       errmsg ("profile name must be specified");
12420       return -99;
12421     }
12422
12423   if (vec_len (name) > 64)
12424     {
12425       errmsg ("profile name too long");
12426       return -99;
12427     }
12428
12429   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12430
12431   mp->is_local = is_local;
12432   mp->proto = (u8) proto;
12433   mp->start_port = (u16) start_port;
12434   mp->end_port = (u16) end_port;
12435   mp->start_addr = start_addr.as_u32;
12436   mp->end_addr = end_addr.as_u32;
12437   clib_memcpy (mp->name, name, vec_len (name));
12438   vec_free (name);
12439
12440   S;
12441   W;
12442   /* NOTREACHED */
12443   return 0;
12444 }
12445
12446 static int
12447 api_ikev2_set_local_key (vat_main_t * vam)
12448 {
12449   unformat_input_t *i = vam->input;
12450   vl_api_ikev2_set_local_key_t *mp;
12451   f64 timeout;
12452   u8 *file = 0;
12453
12454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12455     {
12456       if (unformat (i, "file %v", &file))
12457         vec_add1 (file, 0);
12458       else
12459         {
12460           errmsg ("parse error '%U'", format_unformat_error, i);
12461           return -99;
12462         }
12463     }
12464
12465   if (!vec_len (file))
12466     {
12467       errmsg ("RSA key file must be specified");
12468       return -99;
12469     }
12470
12471   if (vec_len (file) > 256)
12472     {
12473       errmsg ("file name too long");
12474       return -99;
12475     }
12476
12477   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12478
12479   clib_memcpy (mp->key_file, file, vec_len (file));
12480   vec_free (file);
12481
12482   S;
12483   W;
12484   /* NOTREACHED */
12485   return 0;
12486 }
12487
12488 /*
12489  * MAP
12490  */
12491 static int
12492 api_map_add_domain (vat_main_t * vam)
12493 {
12494   unformat_input_t *i = vam->input;
12495   vl_api_map_add_domain_t *mp;
12496   f64 timeout;
12497
12498   ip4_address_t ip4_prefix;
12499   ip6_address_t ip6_prefix;
12500   ip6_address_t ip6_src;
12501   u32 num_m_args = 0;
12502   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12503     0, psid_length = 0;
12504   u8 is_translation = 0;
12505   u32 mtu = 0;
12506   u32 ip6_src_len = 128;
12507
12508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12509     {
12510       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12511                     &ip4_prefix, &ip4_prefix_len))
12512         num_m_args++;
12513       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12514                          &ip6_prefix, &ip6_prefix_len))
12515         num_m_args++;
12516       else
12517         if (unformat
12518             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12519              &ip6_src_len))
12520         num_m_args++;
12521       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12522         num_m_args++;
12523       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12524         num_m_args++;
12525       else if (unformat (i, "psid-offset %d", &psid_offset))
12526         num_m_args++;
12527       else if (unformat (i, "psid-len %d", &psid_length))
12528         num_m_args++;
12529       else if (unformat (i, "mtu %d", &mtu))
12530         num_m_args++;
12531       else if (unformat (i, "map-t"))
12532         is_translation = 1;
12533       else
12534         {
12535           clib_warning ("parse error '%U'", format_unformat_error, i);
12536           return -99;
12537         }
12538     }
12539
12540   if (num_m_args < 3)
12541     {
12542       errmsg ("mandatory argument(s) missing");
12543       return -99;
12544     }
12545
12546   /* Construct the API message */
12547   M (MAP_ADD_DOMAIN, map_add_domain);
12548
12549   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12550   mp->ip4_prefix_len = ip4_prefix_len;
12551
12552   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12553   mp->ip6_prefix_len = ip6_prefix_len;
12554
12555   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12556   mp->ip6_src_prefix_len = ip6_src_len;
12557
12558   mp->ea_bits_len = ea_bits_len;
12559   mp->psid_offset = psid_offset;
12560   mp->psid_length = psid_length;
12561   mp->is_translation = is_translation;
12562   mp->mtu = htons (mtu);
12563
12564   /* send it... */
12565   S;
12566
12567   /* Wait for a reply, return good/bad news  */
12568   W;
12569 }
12570
12571 static int
12572 api_map_del_domain (vat_main_t * vam)
12573 {
12574   unformat_input_t *i = vam->input;
12575   vl_api_map_del_domain_t *mp;
12576   f64 timeout;
12577
12578   u32 num_m_args = 0;
12579   u32 index;
12580
12581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12582     {
12583       if (unformat (i, "index %d", &index))
12584         num_m_args++;
12585       else
12586         {
12587           clib_warning ("parse error '%U'", format_unformat_error, i);
12588           return -99;
12589         }
12590     }
12591
12592   if (num_m_args != 1)
12593     {
12594       errmsg ("mandatory argument(s) missing");
12595       return -99;
12596     }
12597
12598   /* Construct the API message */
12599   M (MAP_DEL_DOMAIN, map_del_domain);
12600
12601   mp->index = ntohl (index);
12602
12603   /* send it... */
12604   S;
12605
12606   /* Wait for a reply, return good/bad news  */
12607   W;
12608 }
12609
12610 static int
12611 api_map_add_del_rule (vat_main_t * vam)
12612 {
12613   unformat_input_t *i = vam->input;
12614   vl_api_map_add_del_rule_t *mp;
12615   f64 timeout;
12616   u8 is_add = 1;
12617   ip6_address_t ip6_dst;
12618   u32 num_m_args = 0, index, psid = 0;
12619
12620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12621     {
12622       if (unformat (i, "index %d", &index))
12623         num_m_args++;
12624       else if (unformat (i, "psid %d", &psid))
12625         num_m_args++;
12626       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12627         num_m_args++;
12628       else if (unformat (i, "del"))
12629         {
12630           is_add = 0;
12631         }
12632       else
12633         {
12634           clib_warning ("parse error '%U'", format_unformat_error, i);
12635           return -99;
12636         }
12637     }
12638
12639   /* Construct the API message */
12640   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12641
12642   mp->index = ntohl (index);
12643   mp->is_add = is_add;
12644   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12645   mp->psid = ntohs (psid);
12646
12647   /* send it... */
12648   S;
12649
12650   /* Wait for a reply, return good/bad news  */
12651   W;
12652 }
12653
12654 static int
12655 api_map_domain_dump (vat_main_t * vam)
12656 {
12657   vl_api_map_domain_dump_t *mp;
12658   f64 timeout;
12659
12660   /* Construct the API message */
12661   M (MAP_DOMAIN_DUMP, map_domain_dump);
12662
12663   /* send it... */
12664   S;
12665
12666   /* Use a control ping for synchronization */
12667   {
12668     vl_api_control_ping_t *mp;
12669     M (CONTROL_PING, control_ping);
12670     S;
12671   }
12672   W;
12673 }
12674
12675 static int
12676 api_map_rule_dump (vat_main_t * vam)
12677 {
12678   unformat_input_t *i = vam->input;
12679   vl_api_map_rule_dump_t *mp;
12680   f64 timeout;
12681   u32 domain_index = ~0;
12682
12683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12684     {
12685       if (unformat (i, "index %u", &domain_index))
12686         ;
12687       else
12688         break;
12689     }
12690
12691   if (domain_index == ~0)
12692     {
12693       clib_warning ("parse error: domain index expected");
12694       return -99;
12695     }
12696
12697   /* Construct the API message */
12698   M (MAP_RULE_DUMP, map_rule_dump);
12699
12700   mp->domain_index = htonl (domain_index);
12701
12702   /* send it... */
12703   S;
12704
12705   /* Use a control ping for synchronization */
12706   {
12707     vl_api_control_ping_t *mp;
12708     M (CONTROL_PING, control_ping);
12709     S;
12710   }
12711   W;
12712 }
12713
12714 static void vl_api_map_add_domain_reply_t_handler
12715   (vl_api_map_add_domain_reply_t * mp)
12716 {
12717   vat_main_t *vam = &vat_main;
12718   i32 retval = ntohl (mp->retval);
12719
12720   if (vam->async_mode)
12721     {
12722       vam->async_errors += (retval < 0);
12723     }
12724   else
12725     {
12726       vam->retval = retval;
12727       vam->result_ready = 1;
12728     }
12729 }
12730
12731 static void vl_api_map_add_domain_reply_t_handler_json
12732   (vl_api_map_add_domain_reply_t * mp)
12733 {
12734   vat_main_t *vam = &vat_main;
12735   vat_json_node_t node;
12736
12737   vat_json_init_object (&node);
12738   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12739   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12740
12741   vat_json_print (vam->ofp, &node);
12742   vat_json_free (&node);
12743
12744   vam->retval = ntohl (mp->retval);
12745   vam->result_ready = 1;
12746 }
12747
12748 static int
12749 api_get_first_msg_id (vat_main_t * vam)
12750 {
12751   vl_api_get_first_msg_id_t *mp;
12752   f64 timeout;
12753   unformat_input_t *i = vam->input;
12754   u8 *name;
12755   u8 name_set = 0;
12756
12757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12758     {
12759       if (unformat (i, "client %s", &name))
12760         name_set = 1;
12761       else
12762         break;
12763     }
12764
12765   if (name_set == 0)
12766     {
12767       errmsg ("missing client name");
12768       return -99;
12769     }
12770   vec_add1 (name, 0);
12771
12772   if (vec_len (name) > 63)
12773     {
12774       errmsg ("client name too long");
12775       return -99;
12776     }
12777
12778   M (GET_FIRST_MSG_ID, get_first_msg_id);
12779   clib_memcpy (mp->name, name, vec_len (name));
12780   S;
12781   W;
12782   /* NOTREACHED */
12783   return 0;
12784 }
12785
12786 static int
12787 api_cop_interface_enable_disable (vat_main_t * vam)
12788 {
12789   unformat_input_t *line_input = vam->input;
12790   vl_api_cop_interface_enable_disable_t *mp;
12791   f64 timeout;
12792   u32 sw_if_index = ~0;
12793   u8 enable_disable = 1;
12794
12795   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12796     {
12797       if (unformat (line_input, "disable"))
12798         enable_disable = 0;
12799       if (unformat (line_input, "enable"))
12800         enable_disable = 1;
12801       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12802                          vam, &sw_if_index))
12803         ;
12804       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12805         ;
12806       else
12807         break;
12808     }
12809
12810   if (sw_if_index == ~0)
12811     {
12812       errmsg ("missing interface name or sw_if_index");
12813       return -99;
12814     }
12815
12816   /* Construct the API message */
12817   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12818   mp->sw_if_index = ntohl (sw_if_index);
12819   mp->enable_disable = enable_disable;
12820
12821   /* send it... */
12822   S;
12823   /* Wait for the reply */
12824   W;
12825 }
12826
12827 static int
12828 api_cop_whitelist_enable_disable (vat_main_t * vam)
12829 {
12830   unformat_input_t *line_input = vam->input;
12831   vl_api_cop_whitelist_enable_disable_t *mp;
12832   f64 timeout;
12833   u32 sw_if_index = ~0;
12834   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12835   u32 fib_id = 0;
12836
12837   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12838     {
12839       if (unformat (line_input, "ip4"))
12840         ip4 = 1;
12841       else if (unformat (line_input, "ip6"))
12842         ip6 = 1;
12843       else if (unformat (line_input, "default"))
12844         default_cop = 1;
12845       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12846                          vam, &sw_if_index))
12847         ;
12848       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12849         ;
12850       else if (unformat (line_input, "fib-id %d", &fib_id))
12851         ;
12852       else
12853         break;
12854     }
12855
12856   if (sw_if_index == ~0)
12857     {
12858       errmsg ("missing interface name or sw_if_index");
12859       return -99;
12860     }
12861
12862   /* Construct the API message */
12863   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12864   mp->sw_if_index = ntohl (sw_if_index);
12865   mp->fib_id = ntohl (fib_id);
12866   mp->ip4 = ip4;
12867   mp->ip6 = ip6;
12868   mp->default_cop = default_cop;
12869
12870   /* send it... */
12871   S;
12872   /* Wait for the reply */
12873   W;
12874 }
12875
12876 static int
12877 api_get_node_graph (vat_main_t * vam)
12878 {
12879   vl_api_get_node_graph_t *mp;
12880   f64 timeout;
12881
12882   M (GET_NODE_GRAPH, get_node_graph);
12883
12884   /* send it... */
12885   S;
12886   /* Wait for the reply */
12887   W;
12888 }
12889
12890 /* *INDENT-OFF* */
12891 /** Used for parsing LISP eids */
12892 typedef CLIB_PACKED(struct{
12893   u8 addr[16];   /**< eid address */
12894   u32 len;       /**< prefix length if IP */
12895   u8 type;      /**< type of eid */
12896 }) lisp_eid_vat_t;
12897 /* *INDENT-ON* */
12898
12899 static uword
12900 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12901 {
12902   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12903
12904   memset (a, 0, sizeof (a[0]));
12905
12906   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12907     {
12908       a->type = 0;              /* ipv4 type */
12909     }
12910   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12911     {
12912       a->type = 1;              /* ipv6 type */
12913     }
12914   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12915     {
12916       a->type = 2;              /* mac type */
12917     }
12918   else
12919     {
12920       return 0;
12921     }
12922
12923   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12924     {
12925       return 0;
12926     }
12927
12928   return 1;
12929 }
12930
12931 static int
12932 lisp_eid_size_vat (u8 type)
12933 {
12934   switch (type)
12935     {
12936     case 0:
12937       return 4;
12938     case 1:
12939       return 16;
12940     case 2:
12941       return 6;
12942     }
12943   return 0;
12944 }
12945
12946 static void
12947 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12948 {
12949   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12950 }
12951
12952 /* *INDENT-OFF* */
12953 /** Used for transferring locators via VPP API */
12954 typedef CLIB_PACKED(struct
12955 {
12956   u32 sw_if_index; /**< locator sw_if_index */
12957   u8 priority; /**< locator priority */
12958   u8 weight;   /**< locator weight */
12959 }) ls_locator_t;
12960 /* *INDENT-ON* */
12961
12962 static int
12963 api_lisp_add_del_locator_set (vat_main_t * vam)
12964 {
12965   unformat_input_t *input = vam->input;
12966   vl_api_lisp_add_del_locator_set_t *mp;
12967   f64 timeout = ~0;
12968   u8 is_add = 1;
12969   u8 *locator_set_name = NULL;
12970   u8 locator_set_name_set = 0;
12971   ls_locator_t locator, *locators = 0;
12972   u32 sw_if_index, priority, weight;
12973   u32 data_len = 0;
12974
12975   /* Parse args required to build the message */
12976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12977     {
12978       if (unformat (input, "del"))
12979         {
12980           is_add = 0;
12981         }
12982       else if (unformat (input, "locator-set %s", &locator_set_name))
12983         {
12984           locator_set_name_set = 1;
12985         }
12986       else if (unformat (input, "sw_if_index %u p %u w %u",
12987                          &sw_if_index, &priority, &weight))
12988         {
12989           locator.sw_if_index = htonl (sw_if_index);
12990           locator.priority = priority;
12991           locator.weight = weight;
12992           vec_add1 (locators, locator);
12993         }
12994       else
12995         if (unformat
12996             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12997              &sw_if_index, &priority, &weight))
12998         {
12999           locator.sw_if_index = htonl (sw_if_index);
13000           locator.priority = priority;
13001           locator.weight = weight;
13002           vec_add1 (locators, locator);
13003         }
13004       else
13005         break;
13006     }
13007
13008   if (locator_set_name_set == 0)
13009     {
13010       errmsg ("missing locator-set name");
13011       vec_free (locators);
13012       return -99;
13013     }
13014
13015   if (vec_len (locator_set_name) > 64)
13016     {
13017       errmsg ("locator-set name too long");
13018       vec_free (locator_set_name);
13019       vec_free (locators);
13020       return -99;
13021     }
13022   vec_add1 (locator_set_name, 0);
13023
13024   data_len = sizeof (ls_locator_t) * vec_len (locators);
13025
13026   /* Construct the API message */
13027   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
13028
13029   mp->is_add = is_add;
13030   clib_memcpy (mp->locator_set_name, locator_set_name,
13031                vec_len (locator_set_name));
13032   vec_free (locator_set_name);
13033
13034   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13035   if (locators)
13036     clib_memcpy (mp->locators, locators, data_len);
13037   vec_free (locators);
13038
13039   /* send it... */
13040   S;
13041
13042   /* Wait for a reply... */
13043   W;
13044
13045   /* NOTREACHED */
13046   return 0;
13047 }
13048
13049 static int
13050 api_lisp_add_del_locator (vat_main_t * vam)
13051 {
13052   unformat_input_t *input = vam->input;
13053   vl_api_lisp_add_del_locator_t *mp;
13054   f64 timeout = ~0;
13055   u32 tmp_if_index = ~0;
13056   u32 sw_if_index = ~0;
13057   u8 sw_if_index_set = 0;
13058   u8 sw_if_index_if_name_set = 0;
13059   u32 priority = ~0;
13060   u8 priority_set = 0;
13061   u32 weight = ~0;
13062   u8 weight_set = 0;
13063   u8 is_add = 1;
13064   u8 *locator_set_name = NULL;
13065   u8 locator_set_name_set = 0;
13066
13067   /* Parse args required to build the message */
13068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13069     {
13070       if (unformat (input, "del"))
13071         {
13072           is_add = 0;
13073         }
13074       else if (unformat (input, "locator-set %s", &locator_set_name))
13075         {
13076           locator_set_name_set = 1;
13077         }
13078       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13079                          &tmp_if_index))
13080         {
13081           sw_if_index_if_name_set = 1;
13082           sw_if_index = tmp_if_index;
13083         }
13084       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13085         {
13086           sw_if_index_set = 1;
13087           sw_if_index = tmp_if_index;
13088         }
13089       else if (unformat (input, "p %d", &priority))
13090         {
13091           priority_set = 1;
13092         }
13093       else if (unformat (input, "w %d", &weight))
13094         {
13095           weight_set = 1;
13096         }
13097       else
13098         break;
13099     }
13100
13101   if (locator_set_name_set == 0)
13102     {
13103       errmsg ("missing locator-set name");
13104       return -99;
13105     }
13106
13107   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13108     {
13109       errmsg ("missing sw_if_index");
13110       vec_free (locator_set_name);
13111       return -99;
13112     }
13113
13114   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13115     {
13116       errmsg ("cannot use both params interface name and sw_if_index");
13117       vec_free (locator_set_name);
13118       return -99;
13119     }
13120
13121   if (priority_set == 0)
13122     {
13123       errmsg ("missing locator-set priority");
13124       vec_free (locator_set_name);
13125       return -99;
13126     }
13127
13128   if (weight_set == 0)
13129     {
13130       errmsg ("missing locator-set weight");
13131       vec_free (locator_set_name);
13132       return -99;
13133     }
13134
13135   if (vec_len (locator_set_name) > 64)
13136     {
13137       errmsg ("locator-set name too long");
13138       vec_free (locator_set_name);
13139       return -99;
13140     }
13141   vec_add1 (locator_set_name, 0);
13142
13143   /* Construct the API message */
13144   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13145
13146   mp->is_add = is_add;
13147   mp->sw_if_index = ntohl (sw_if_index);
13148   mp->priority = priority;
13149   mp->weight = weight;
13150   clib_memcpy (mp->locator_set_name, locator_set_name,
13151                vec_len (locator_set_name));
13152   vec_free (locator_set_name);
13153
13154   /* send it... */
13155   S;
13156
13157   /* Wait for a reply... */
13158   W;
13159
13160   /* NOTREACHED */
13161   return 0;
13162 }
13163
13164 uword
13165 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13166 {
13167   u32 *key_id = va_arg (*args, u32 *);
13168   u8 *s = 0;
13169
13170   if (unformat (input, "%s", &s))
13171     {
13172       if (!strcmp ((char *) s, "sha1"))
13173         key_id[0] = HMAC_SHA_1_96;
13174       else if (!strcmp ((char *) s, "sha256"))
13175         key_id[0] = HMAC_SHA_256_128;
13176       else
13177         {
13178           clib_warning ("invalid key_id: '%s'", s);
13179           key_id[0] = HMAC_NO_KEY;
13180         }
13181     }
13182   else
13183     return 0;
13184
13185   vec_free (s);
13186   return 1;
13187 }
13188
13189 static int
13190 api_lisp_add_del_local_eid (vat_main_t * vam)
13191 {
13192   unformat_input_t *input = vam->input;
13193   vl_api_lisp_add_del_local_eid_t *mp;
13194   f64 timeout = ~0;
13195   u8 is_add = 1;
13196   u8 eid_set = 0;
13197   lisp_eid_vat_t _eid, *eid = &_eid;
13198   u8 *locator_set_name = 0;
13199   u8 locator_set_name_set = 0;
13200   u32 vni = 0;
13201   u16 key_id = 0;
13202   u8 *key = 0;
13203
13204   /* Parse args required to build the message */
13205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13206     {
13207       if (unformat (input, "del"))
13208         {
13209           is_add = 0;
13210         }
13211       else if (unformat (input, "vni %d", &vni))
13212         {
13213           ;
13214         }
13215       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13216         {
13217           eid_set = 1;
13218         }
13219       else if (unformat (input, "locator-set %s", &locator_set_name))
13220         {
13221           locator_set_name_set = 1;
13222         }
13223       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13224         ;
13225       else if (unformat (input, "secret-key %_%v%_", &key))
13226         ;
13227       else
13228         break;
13229     }
13230
13231   if (locator_set_name_set == 0)
13232     {
13233       errmsg ("missing locator-set name");
13234       return -99;
13235     }
13236
13237   if (0 == eid_set)
13238     {
13239       errmsg ("EID address not set!");
13240       vec_free (locator_set_name);
13241       return -99;
13242     }
13243
13244   if (key && (0 == key_id))
13245     {
13246       errmsg ("invalid key_id!");
13247       return -99;
13248     }
13249
13250   if (vec_len (key) > 64)
13251     {
13252       errmsg ("key too long");
13253       vec_free (key);
13254       return -99;
13255     }
13256
13257   if (vec_len (locator_set_name) > 64)
13258     {
13259       errmsg ("locator-set name too long");
13260       vec_free (locator_set_name);
13261       return -99;
13262     }
13263   vec_add1 (locator_set_name, 0);
13264
13265   /* Construct the API message */
13266   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13267
13268   mp->is_add = is_add;
13269   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13270   mp->eid_type = eid->type;
13271   mp->prefix_len = eid->len;
13272   mp->vni = clib_host_to_net_u32 (vni);
13273   mp->key_id = clib_host_to_net_u16 (key_id);
13274   clib_memcpy (mp->locator_set_name, locator_set_name,
13275                vec_len (locator_set_name));
13276   clib_memcpy (mp->key, key, vec_len (key));
13277
13278   vec_free (locator_set_name);
13279   vec_free (key);
13280
13281   /* send it... */
13282   S;
13283
13284   /* Wait for a reply... */
13285   W;
13286
13287   /* NOTREACHED */
13288   return 0;
13289 }
13290
13291 /* *INDENT-OFF* */
13292 /** Used for transferring locators via VPP API */
13293 typedef CLIB_PACKED(struct
13294 {
13295   u8 is_ip4; /**< is locator an IPv4 address? */
13296   u8 priority; /**< locator priority */
13297   u8 weight;   /**< locator weight */
13298   u8 addr[16]; /**< IPv4/IPv6 address */
13299 }) rloc_t;
13300 /* *INDENT-ON* */
13301
13302 static int
13303 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13304 {
13305   u32 dp_table = 0, vni = 0;;
13306   unformat_input_t *input = vam->input;
13307   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13308   f64 timeout = ~0;
13309   u8 is_add = 1;
13310   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13311   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13312   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13313   u32 action = ~0, w;
13314   ip4_address_t rmt_rloc4, lcl_rloc4;
13315   ip6_address_t rmt_rloc6, lcl_rloc6;
13316   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13317     0;
13318
13319   memset (&rloc, 0, sizeof (rloc));
13320
13321   /* Parse args required to build the message */
13322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13323     {
13324       if (unformat (input, "del"))
13325         is_add = 0;
13326       else if (unformat (input, "add"))
13327         is_add = 1;
13328       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13329         {
13330           rmt_eid_set = 1;
13331         }
13332       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13333         {
13334           lcl_eid_set = 1;
13335         }
13336       else if (unformat (input, "vrf %d", &dp_table))
13337         ;
13338       else if (unformat (input, "bd %d", &dp_table))
13339         ;
13340       else if (unformat (input, "vni %d", &vni))
13341         ;
13342       else if (unformat (input, "w %d", &w))
13343         {
13344           if (!curr_rloc)
13345             {
13346               errmsg ("No RLOC configured for setting priority/weight!");
13347               return -99;
13348             }
13349           curr_rloc->weight = w;
13350         }
13351       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13352                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13353         {
13354           rloc.is_ip4 = 1;
13355
13356           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13357           rloc.weight = 0;
13358           vec_add1 (lcl_locs, rloc);
13359
13360           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13361           vec_add1 (rmt_locs, rloc);
13362           /* weight saved in rmt loc */
13363           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13364         }
13365       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13366                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13367         {
13368           rloc.is_ip4 = 0;
13369           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13370           rloc.weight = 0;
13371           vec_add1 (lcl_locs, rloc);
13372
13373           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13374           vec_add1 (rmt_locs, rloc);
13375           /* weight saved in rmt loc */
13376           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13377         }
13378       else if (unformat (input, "action %d", &action))
13379         {
13380           ;
13381         }
13382       else
13383         {
13384           clib_warning ("parse error '%U'", format_unformat_error, input);
13385           return -99;
13386         }
13387     }
13388
13389   if (!rmt_eid_set)
13390     {
13391       errmsg ("remote eid addresses not set");
13392       return -99;
13393     }
13394
13395   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13396     {
13397       errmsg ("eid types don't match");
13398       return -99;
13399     }
13400
13401   if (0 == rmt_locs && (u32) ~ 0 == action)
13402     {
13403       errmsg ("action not set for negative mapping");
13404       return -99;
13405     }
13406
13407   /* Construct the API message */
13408   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry,
13409       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13410
13411   mp->is_add = is_add;
13412   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13413   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13414   mp->eid_type = rmt_eid->type;
13415   mp->dp_table = clib_host_to_net_u32 (dp_table);
13416   mp->vni = clib_host_to_net_u32 (vni);
13417   mp->rmt_len = rmt_eid->len;
13418   mp->lcl_len = lcl_eid->len;
13419   mp->action = action;
13420
13421   if (0 != rmt_locs && 0 != lcl_locs)
13422     {
13423       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13424       clib_memcpy (mp->locs, lcl_locs,
13425                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13426
13427       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13428       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13429                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13430     }
13431   vec_free (lcl_locs);
13432   vec_free (rmt_locs);
13433
13434   /* send it... */
13435   S;
13436
13437   /* Wait for a reply... */
13438   W;
13439
13440   /* NOTREACHED */
13441   return 0;
13442 }
13443
13444 static int
13445 api_lisp_add_del_map_server (vat_main_t * vam)
13446 {
13447   unformat_input_t *input = vam->input;
13448   vl_api_lisp_add_del_map_server_t *mp;
13449   f64 timeout = ~0;
13450   u8 is_add = 1;
13451   u8 ipv4_set = 0;
13452   u8 ipv6_set = 0;
13453   ip4_address_t ipv4;
13454   ip6_address_t ipv6;
13455
13456   /* Parse args required to build the message */
13457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13458     {
13459       if (unformat (input, "del"))
13460         {
13461           is_add = 0;
13462         }
13463       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13464         {
13465           ipv4_set = 1;
13466         }
13467       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13468         {
13469           ipv6_set = 1;
13470         }
13471       else
13472         break;
13473     }
13474
13475   if (ipv4_set && ipv6_set)
13476     {
13477       errmsg ("both eid v4 and v6 addresses set");
13478       return -99;
13479     }
13480
13481   if (!ipv4_set && !ipv6_set)
13482     {
13483       errmsg ("eid addresses not set");
13484       return -99;
13485     }
13486
13487   /* Construct the API message */
13488   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13489
13490   mp->is_add = is_add;
13491   if (ipv6_set)
13492     {
13493       mp->is_ipv6 = 1;
13494       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13495     }
13496   else
13497     {
13498       mp->is_ipv6 = 0;
13499       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13500     }
13501
13502   /* send it... */
13503   S;
13504
13505   /* Wait for a reply... */
13506   W;
13507
13508   /* NOTREACHED */
13509   return 0;
13510 }
13511
13512 static int
13513 api_lisp_add_del_map_resolver (vat_main_t * vam)
13514 {
13515   unformat_input_t *input = vam->input;
13516   vl_api_lisp_add_del_map_resolver_t *mp;
13517   f64 timeout = ~0;
13518   u8 is_add = 1;
13519   u8 ipv4_set = 0;
13520   u8 ipv6_set = 0;
13521   ip4_address_t ipv4;
13522   ip6_address_t ipv6;
13523
13524   /* Parse args required to build the message */
13525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13526     {
13527       if (unformat (input, "del"))
13528         {
13529           is_add = 0;
13530         }
13531       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13532         {
13533           ipv4_set = 1;
13534         }
13535       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13536         {
13537           ipv6_set = 1;
13538         }
13539       else
13540         break;
13541     }
13542
13543   if (ipv4_set && ipv6_set)
13544     {
13545       errmsg ("both eid v4 and v6 addresses set");
13546       return -99;
13547     }
13548
13549   if (!ipv4_set && !ipv6_set)
13550     {
13551       errmsg ("eid addresses not set");
13552       return -99;
13553     }
13554
13555   /* Construct the API message */
13556   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13557
13558   mp->is_add = is_add;
13559   if (ipv6_set)
13560     {
13561       mp->is_ipv6 = 1;
13562       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13563     }
13564   else
13565     {
13566       mp->is_ipv6 = 0;
13567       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13568     }
13569
13570   /* send it... */
13571   S;
13572
13573   /* Wait for a reply... */
13574   W;
13575
13576   /* NOTREACHED */
13577   return 0;
13578 }
13579
13580 static int
13581 api_lisp_gpe_enable_disable (vat_main_t * vam)
13582 {
13583   unformat_input_t *input = vam->input;
13584   vl_api_lisp_gpe_enable_disable_t *mp;
13585   f64 timeout = ~0;
13586   u8 is_set = 0;
13587   u8 is_en = 1;
13588
13589   /* Parse args required to build the message */
13590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13591     {
13592       if (unformat (input, "enable"))
13593         {
13594           is_set = 1;
13595           is_en = 1;
13596         }
13597       else if (unformat (input, "disable"))
13598         {
13599           is_set = 1;
13600           is_en = 0;
13601         }
13602       else
13603         break;
13604     }
13605
13606   if (is_set == 0)
13607     {
13608       errmsg ("Value not set");
13609       return -99;
13610     }
13611
13612   /* Construct the API message */
13613   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13614
13615   mp->is_en = is_en;
13616
13617   /* send it... */
13618   S;
13619
13620   /* Wait for a reply... */
13621   W;
13622
13623   /* NOTREACHED */
13624   return 0;
13625 }
13626
13627 static int
13628 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13629 {
13630   unformat_input_t *input = vam->input;
13631   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13632   f64 timeout = ~0;
13633   u8 is_set = 0;
13634   u8 is_en = 0;
13635
13636   /* Parse args required to build the message */
13637   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13638     {
13639       if (unformat (input, "enable"))
13640         {
13641           is_set = 1;
13642           is_en = 1;
13643         }
13644       else if (unformat (input, "disable"))
13645         is_set = 1;
13646       else
13647         break;
13648     }
13649
13650   if (!is_set)
13651     {
13652       errmsg ("Value not set");
13653       return -99;
13654     }
13655
13656   /* Construct the API message */
13657   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13658
13659   mp->is_enabled = is_en;
13660
13661   /* send it... */
13662   S;
13663
13664   /* Wait for a reply... */
13665   W;
13666
13667   /* NOTREACHED */
13668   return 0;
13669 }
13670
13671 static int
13672 api_lisp_map_register_enable_disable (vat_main_t * vam)
13673 {
13674   unformat_input_t *input = vam->input;
13675   vl_api_lisp_map_register_enable_disable_t *mp;
13676   f64 timeout = ~0;
13677   u8 is_set = 0;
13678   u8 is_en = 0;
13679
13680   /* Parse args required to build the message */
13681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13682     {
13683       if (unformat (input, "enable"))
13684         {
13685           is_set = 1;
13686           is_en = 1;
13687         }
13688       else if (unformat (input, "disable"))
13689         is_set = 1;
13690       else
13691         break;
13692     }
13693
13694   if (!is_set)
13695     {
13696       errmsg ("Value not set");
13697       return -99;
13698     }
13699
13700   /* Construct the API message */
13701   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13702
13703   mp->is_enabled = is_en;
13704
13705   /* send it... */
13706   S;
13707
13708   /* Wait for a reply... */
13709   W;
13710
13711   /* NOTREACHED */
13712   return 0;
13713 }
13714
13715 static int
13716 api_lisp_enable_disable (vat_main_t * vam)
13717 {
13718   unformat_input_t *input = vam->input;
13719   vl_api_lisp_enable_disable_t *mp;
13720   f64 timeout = ~0;
13721   u8 is_set = 0;
13722   u8 is_en = 0;
13723
13724   /* Parse args required to build the message */
13725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13726     {
13727       if (unformat (input, "enable"))
13728         {
13729           is_set = 1;
13730           is_en = 1;
13731         }
13732       else if (unformat (input, "disable"))
13733         {
13734           is_set = 1;
13735         }
13736       else
13737         break;
13738     }
13739
13740   if (!is_set)
13741     {
13742       errmsg ("Value not set");
13743       return -99;
13744     }
13745
13746   /* Construct the API message */
13747   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13748
13749   mp->is_en = is_en;
13750
13751   /* send it... */
13752   S;
13753
13754   /* Wait for a reply... */
13755   W;
13756
13757   /* NOTREACHED */
13758   return 0;
13759 }
13760
13761 static int
13762 api_show_lisp_map_register_state (vat_main_t * vam)
13763 {
13764   f64 timeout = ~0;
13765   vl_api_show_lisp_map_register_state_t *mp;
13766
13767   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13768
13769   /* send */
13770   S;
13771
13772   /* wait for reply */
13773   W;
13774
13775   return 0;
13776 }
13777
13778 static int
13779 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13780 {
13781   f64 timeout = ~0;
13782   vl_api_show_lisp_rloc_probe_state_t *mp;
13783
13784   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13785
13786   /* send */
13787   S;
13788
13789   /* wait for reply */
13790   W;
13791
13792   return 0;
13793 }
13794
13795 static int
13796 api_show_lisp_map_request_mode (vat_main_t * vam)
13797 {
13798   f64 timeout = ~0;
13799   vl_api_show_lisp_map_request_mode_t *mp;
13800
13801   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13802
13803   /* send */
13804   S;
13805
13806   /* wait for reply */
13807   W;
13808
13809   return 0;
13810 }
13811
13812 static int
13813 api_lisp_map_request_mode (vat_main_t * vam)
13814 {
13815   f64 timeout = ~0;
13816   unformat_input_t *input = vam->input;
13817   vl_api_lisp_map_request_mode_t *mp;
13818   u8 mode = 0;
13819
13820   /* Parse args required to build the message */
13821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13822     {
13823       if (unformat (input, "dst-only"))
13824         mode = 0;
13825       else if (unformat (input, "src-dst"))
13826         mode = 1;
13827       else
13828         {
13829           errmsg ("parse error '%U'", format_unformat_error, input);
13830           return -99;
13831         }
13832     }
13833
13834   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13835
13836   mp->mode = mode;
13837
13838   /* send */
13839   S;
13840
13841   /* wait for reply */
13842   W;
13843
13844   /* notreached */
13845   return 0;
13846 }
13847
13848 /**
13849  * Enable/disable LISP proxy ITR.
13850  *
13851  * @param vam vpp API test context
13852  * @return return code
13853  */
13854 static int
13855 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13856 {
13857   f64 timeout = ~0;
13858   u8 ls_name_set = 0;
13859   unformat_input_t *input = vam->input;
13860   vl_api_lisp_pitr_set_locator_set_t *mp;
13861   u8 is_add = 1;
13862   u8 *ls_name = 0;
13863
13864   /* Parse args required to build the message */
13865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13866     {
13867       if (unformat (input, "del"))
13868         is_add = 0;
13869       else if (unformat (input, "locator-set %s", &ls_name))
13870         ls_name_set = 1;
13871       else
13872         {
13873           errmsg ("parse error '%U'", format_unformat_error, input);
13874           return -99;
13875         }
13876     }
13877
13878   if (!ls_name_set)
13879     {
13880       errmsg ("locator-set name not set!");
13881       return -99;
13882     }
13883
13884   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13885
13886   mp->is_add = is_add;
13887   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13888   vec_free (ls_name);
13889
13890   /* send */
13891   S;
13892
13893   /* wait for reply */
13894   W;
13895
13896   /* notreached */
13897   return 0;
13898 }
13899
13900 static int
13901 api_show_lisp_pitr (vat_main_t * vam)
13902 {
13903   vl_api_show_lisp_pitr_t *mp;
13904   f64 timeout = ~0;
13905
13906   if (!vam->json_output)
13907     {
13908       print (vam->ofp, "%=20s", "lisp status:");
13909     }
13910
13911   M (SHOW_LISP_PITR, show_lisp_pitr);
13912   /* send it... */
13913   S;
13914
13915   /* Wait for a reply... */
13916   W;
13917
13918   /* NOTREACHED */
13919   return 0;
13920 }
13921
13922 /**
13923  * Add/delete mapping between vni and vrf
13924  */
13925 static int
13926 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13927 {
13928   f64 timeout = ~0;
13929   unformat_input_t *input = vam->input;
13930   vl_api_lisp_eid_table_add_del_map_t *mp;
13931   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13932   u32 vni, vrf, bd_index;
13933
13934   /* Parse args required to build the message */
13935   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13936     {
13937       if (unformat (input, "del"))
13938         is_add = 0;
13939       else if (unformat (input, "vrf %d", &vrf))
13940         vrf_set = 1;
13941       else if (unformat (input, "bd_index %d", &bd_index))
13942         bd_index_set = 1;
13943       else if (unformat (input, "vni %d", &vni))
13944         vni_set = 1;
13945       else
13946         break;
13947     }
13948
13949   if (!vni_set || (!vrf_set && !bd_index_set))
13950     {
13951       errmsg ("missing arguments!");
13952       return -99;
13953     }
13954
13955   if (vrf_set && bd_index_set)
13956     {
13957       errmsg ("error: both vrf and bd entered!");
13958       return -99;
13959     }
13960
13961   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13962
13963   mp->is_add = is_add;
13964   mp->vni = htonl (vni);
13965   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13966   mp->is_l2 = bd_index_set;
13967
13968   /* send */
13969   S;
13970
13971   /* wait for reply */
13972   W;
13973
13974   /* notreached */
13975   return 0;
13976 }
13977
13978 uword
13979 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13980 {
13981   u32 *action = va_arg (*args, u32 *);
13982   u8 *s = 0;
13983
13984   if (unformat (input, "%s", &s))
13985     {
13986       if (!strcmp ((char *) s, "no-action"))
13987         action[0] = 0;
13988       else if (!strcmp ((char *) s, "natively-forward"))
13989         action[0] = 1;
13990       else if (!strcmp ((char *) s, "send-map-request"))
13991         action[0] = 2;
13992       else if (!strcmp ((char *) s, "drop"))
13993         action[0] = 3;
13994       else
13995         {
13996           clib_warning ("invalid action: '%s'", s);
13997           action[0] = 3;
13998         }
13999     }
14000   else
14001     return 0;
14002
14003   vec_free (s);
14004   return 1;
14005 }
14006
14007 /**
14008  * Add/del remote mapping to/from LISP control plane
14009  *
14010  * @param vam vpp API test context
14011  * @return return code
14012  */
14013 static int
14014 api_lisp_add_del_remote_mapping (vat_main_t * vam)
14015 {
14016   unformat_input_t *input = vam->input;
14017   vl_api_lisp_add_del_remote_mapping_t *mp;
14018   f64 timeout = ~0;
14019   u32 vni = 0;
14020   lisp_eid_vat_t _eid, *eid = &_eid;
14021   lisp_eid_vat_t _seid, *seid = &_seid;
14022   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14023   u32 action = ~0, p, w, data_len;
14024   ip4_address_t rloc4;
14025   ip6_address_t rloc6;
14026   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
14027
14028   memset (&rloc, 0, sizeof (rloc));
14029
14030   /* Parse args required to build the message */
14031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14032     {
14033       if (unformat (input, "del-all"))
14034         {
14035           del_all = 1;
14036         }
14037       else if (unformat (input, "del"))
14038         {
14039           is_add = 0;
14040         }
14041       else if (unformat (input, "add"))
14042         {
14043           is_add = 1;
14044         }
14045       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14046         {
14047           eid_set = 1;
14048         }
14049       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14050         {
14051           seid_set = 1;
14052         }
14053       else if (unformat (input, "vni %d", &vni))
14054         {
14055           ;
14056         }
14057       else if (unformat (input, "p %d w %d", &p, &w))
14058         {
14059           if (!curr_rloc)
14060             {
14061               errmsg ("No RLOC configured for setting priority/weight!");
14062               return -99;
14063             }
14064           curr_rloc->priority = p;
14065           curr_rloc->weight = w;
14066         }
14067       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14068         {
14069           rloc.is_ip4 = 1;
14070           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14071           vec_add1 (rlocs, rloc);
14072           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14073         }
14074       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14075         {
14076           rloc.is_ip4 = 0;
14077           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14078           vec_add1 (rlocs, rloc);
14079           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14080         }
14081       else if (unformat (input, "action %U",
14082                          unformat_negative_mapping_action, &action))
14083         {
14084           ;
14085         }
14086       else
14087         {
14088           clib_warning ("parse error '%U'", format_unformat_error, input);
14089           return -99;
14090         }
14091     }
14092
14093   if (0 == eid_set)
14094     {
14095       errmsg ("missing params!");
14096       return -99;
14097     }
14098
14099   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14100     {
14101       errmsg ("no action set for negative map-reply!");
14102       return -99;
14103     }
14104
14105   data_len = vec_len (rlocs) * sizeof (rloc_t);
14106
14107   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14108   mp->is_add = is_add;
14109   mp->vni = htonl (vni);
14110   mp->action = (u8) action;
14111   mp->is_src_dst = seid_set;
14112   mp->eid_len = eid->len;
14113   mp->seid_len = seid->len;
14114   mp->del_all = del_all;
14115   mp->eid_type = eid->type;
14116   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14117   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14118
14119   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14120   clib_memcpy (mp->rlocs, rlocs, data_len);
14121   vec_free (rlocs);
14122
14123   /* send it... */
14124   S;
14125
14126   /* Wait for a reply... */
14127   W;
14128
14129   /* NOTREACHED */
14130   return 0;
14131 }
14132
14133 /**
14134  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14135  * forwarding entries in data-plane accordingly.
14136  *
14137  * @param vam vpp API test context
14138  * @return return code
14139  */
14140 static int
14141 api_lisp_add_del_adjacency (vat_main_t * vam)
14142 {
14143   unformat_input_t *input = vam->input;
14144   vl_api_lisp_add_del_adjacency_t *mp;
14145   f64 timeout = ~0;
14146   u32 vni = 0;
14147   ip4_address_t leid4, reid4;
14148   ip6_address_t leid6, reid6;
14149   u8 reid_mac[6] = { 0 };
14150   u8 leid_mac[6] = { 0 };
14151   u8 reid_type, leid_type;
14152   u32 leid_len = 0, reid_len = 0, len;
14153   u8 is_add = 1;
14154
14155   leid_type = reid_type = (u8) ~ 0;
14156
14157   /* Parse args required to build the message */
14158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14159     {
14160       if (unformat (input, "del"))
14161         {
14162           is_add = 0;
14163         }
14164       else if (unformat (input, "add"))
14165         {
14166           is_add = 1;
14167         }
14168       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14169                          &reid4, &len))
14170         {
14171           reid_type = 0;        /* ipv4 */
14172           reid_len = len;
14173         }
14174       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14175                          &reid6, &len))
14176         {
14177           reid_type = 1;        /* ipv6 */
14178           reid_len = len;
14179         }
14180       else if (unformat (input, "reid %U", unformat_ethernet_address,
14181                          reid_mac))
14182         {
14183           reid_type = 2;        /* mac */
14184         }
14185       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14186                          &leid4, &len))
14187         {
14188           leid_type = 0;        /* ipv4 */
14189           leid_len = len;
14190         }
14191       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14192                          &leid6, &len))
14193         {
14194           leid_type = 1;        /* ipv6 */
14195           leid_len = len;
14196         }
14197       else if (unformat (input, "leid %U", unformat_ethernet_address,
14198                          leid_mac))
14199         {
14200           leid_type = 2;        /* mac */
14201         }
14202       else if (unformat (input, "vni %d", &vni))
14203         {
14204           ;
14205         }
14206       else
14207         {
14208           errmsg ("parse error '%U'", format_unformat_error, input);
14209           return -99;
14210         }
14211     }
14212
14213   if ((u8) ~ 0 == reid_type)
14214     {
14215       errmsg ("missing params!");
14216       return -99;
14217     }
14218
14219   if (leid_type != reid_type)
14220     {
14221       errmsg ("remote and local EIDs are of different types!");
14222       return -99;
14223     }
14224
14225   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14226   mp->is_add = is_add;
14227   mp->vni = htonl (vni);
14228   mp->leid_len = leid_len;
14229   mp->reid_len = reid_len;
14230   mp->eid_type = reid_type;
14231
14232   switch (mp->eid_type)
14233     {
14234     case 0:
14235       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14236       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14237       break;
14238     case 1:
14239       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14240       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14241       break;
14242     case 2:
14243       clib_memcpy (mp->leid, leid_mac, 6);
14244       clib_memcpy (mp->reid, reid_mac, 6);
14245       break;
14246     default:
14247       errmsg ("unknown EID type %d!", mp->eid_type);
14248       return 0;
14249     }
14250
14251   /* send it... */
14252   S;
14253
14254   /* Wait for a reply... */
14255   W;
14256
14257   /* NOTREACHED */
14258   return 0;
14259 }
14260
14261 static int
14262 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14263 {
14264   unformat_input_t *input = vam->input;
14265   vl_api_lisp_gpe_add_del_iface_t *mp;
14266   f64 timeout = ~0;
14267   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14268   u32 dp_table = 0, vni = 0;
14269
14270   /* Parse args required to build the message */
14271   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14272     {
14273       if (unformat (input, "up"))
14274         {
14275           action_set = 1;
14276           is_add = 1;
14277         }
14278       else if (unformat (input, "down"))
14279         {
14280           action_set = 1;
14281           is_add = 0;
14282         }
14283       else if (unformat (input, "table_id %d", &dp_table))
14284         {
14285           dp_table_set = 1;
14286         }
14287       else if (unformat (input, "bd_id %d", &dp_table))
14288         {
14289           dp_table_set = 1;
14290           is_l2 = 1;
14291         }
14292       else if (unformat (input, "vni %d", &vni))
14293         {
14294           vni_set = 1;
14295         }
14296       else
14297         break;
14298     }
14299
14300   if (action_set == 0)
14301     {
14302       errmsg ("Action not set");
14303       return -99;
14304     }
14305   if (dp_table_set == 0 || vni_set == 0)
14306     {
14307       errmsg ("vni and dp_table must be set");
14308       return -99;
14309     }
14310
14311   /* Construct the API message */
14312   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14313
14314   mp->is_add = is_add;
14315   mp->dp_table = dp_table;
14316   mp->is_l2 = is_l2;
14317   mp->vni = vni;
14318
14319   /* send it... */
14320   S;
14321
14322   /* Wait for a reply... */
14323   W;
14324
14325   /* NOTREACHED */
14326   return 0;
14327 }
14328
14329 /**
14330  * Add/del map request itr rlocs from LISP control plane and updates
14331  *
14332  * @param vam vpp API test context
14333  * @return return code
14334  */
14335 static int
14336 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14337 {
14338   unformat_input_t *input = vam->input;
14339   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14340   f64 timeout = ~0;
14341   u8 *locator_set_name = 0;
14342   u8 locator_set_name_set = 0;
14343   u8 is_add = 1;
14344
14345   /* Parse args required to build the message */
14346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14347     {
14348       if (unformat (input, "del"))
14349         {
14350           is_add = 0;
14351         }
14352       else if (unformat (input, "%_%v%_", &locator_set_name))
14353         {
14354           locator_set_name_set = 1;
14355         }
14356       else
14357         {
14358           clib_warning ("parse error '%U'", format_unformat_error, input);
14359           return -99;
14360         }
14361     }
14362
14363   if (is_add && !locator_set_name_set)
14364     {
14365       errmsg ("itr-rloc is not set!");
14366       return -99;
14367     }
14368
14369   if (is_add && vec_len (locator_set_name) > 64)
14370     {
14371       errmsg ("itr-rloc locator-set name too long");
14372       vec_free (locator_set_name);
14373       return -99;
14374     }
14375
14376   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14377   mp->is_add = is_add;
14378   if (is_add)
14379     {
14380       clib_memcpy (mp->locator_set_name, locator_set_name,
14381                    vec_len (locator_set_name));
14382     }
14383   else
14384     {
14385       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14386     }
14387   vec_free (locator_set_name);
14388
14389   /* send it... */
14390   S;
14391
14392   /* Wait for a reply... */
14393   W;
14394
14395   /* NOTREACHED */
14396   return 0;
14397 }
14398
14399 static int
14400 api_lisp_locator_dump (vat_main_t * vam)
14401 {
14402   unformat_input_t *input = vam->input;
14403   vl_api_lisp_locator_dump_t *mp;
14404   f64 timeout = ~0;
14405   u8 is_index_set = 0, is_name_set = 0;
14406   u8 *ls_name = 0;
14407   u32 ls_index = ~0;
14408
14409   /* Parse args required to build the message */
14410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14411     {
14412       if (unformat (input, "ls_name %_%v%_", &ls_name))
14413         {
14414           is_name_set = 1;
14415         }
14416       else if (unformat (input, "ls_index %d", &ls_index))
14417         {
14418           is_index_set = 1;
14419         }
14420       else
14421         {
14422           errmsg ("parse error '%U'", format_unformat_error, input);
14423           return -99;
14424         }
14425     }
14426
14427   if (!is_index_set && !is_name_set)
14428     {
14429       errmsg ("error: expected one of index or name!");
14430       return -99;
14431     }
14432
14433   if (is_index_set && is_name_set)
14434     {
14435       errmsg ("error: only one param expected!");
14436       return -99;
14437     }
14438
14439   if (vec_len (ls_name) > 62)
14440     {
14441       errmsg ("error: locator set name too long!");
14442       return -99;
14443     }
14444
14445   if (!vam->json_output)
14446     {
14447       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14448     }
14449
14450   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14451   mp->is_index_set = is_index_set;
14452
14453   if (is_index_set)
14454     mp->ls_index = clib_host_to_net_u32 (ls_index);
14455   else
14456     {
14457       vec_add1 (ls_name, 0);
14458       strncpy ((char *) mp->ls_name, (char *) ls_name,
14459                sizeof (mp->ls_name) - 1);
14460     }
14461
14462   /* send it... */
14463   S;
14464
14465   /* Use a control ping for synchronization */
14466   {
14467     vl_api_control_ping_t *mp;
14468     M (CONTROL_PING, control_ping);
14469     S;
14470   }
14471   /* Wait for a reply... */
14472   W;
14473
14474   /* NOTREACHED */
14475   return 0;
14476 }
14477
14478 static int
14479 api_lisp_locator_set_dump (vat_main_t * vam)
14480 {
14481   vl_api_lisp_locator_set_dump_t *mp;
14482   unformat_input_t *input = vam->input;
14483   f64 timeout = ~0;
14484   u8 filter = 0;
14485
14486   /* Parse args required to build the message */
14487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14488     {
14489       if (unformat (input, "local"))
14490         {
14491           filter = 1;
14492         }
14493       else if (unformat (input, "remote"))
14494         {
14495           filter = 2;
14496         }
14497       else
14498         {
14499           errmsg ("parse error '%U'", format_unformat_error, input);
14500           return -99;
14501         }
14502     }
14503
14504   if (!vam->json_output)
14505     {
14506       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14507     }
14508
14509   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14510
14511   mp->filter = filter;
14512
14513   /* send it... */
14514   S;
14515
14516   /* Use a control ping for synchronization */
14517   {
14518     vl_api_control_ping_t *mp;
14519     M (CONTROL_PING, control_ping);
14520     S;
14521   }
14522   /* Wait for a reply... */
14523   W;
14524
14525   /* NOTREACHED */
14526   return 0;
14527 }
14528
14529 static int
14530 api_lisp_eid_table_map_dump (vat_main_t * vam)
14531 {
14532   u8 is_l2 = 0;
14533   u8 mode_set = 0;
14534   unformat_input_t *input = vam->input;
14535   vl_api_lisp_eid_table_map_dump_t *mp;
14536   f64 timeout = ~0;
14537
14538   /* Parse args required to build the message */
14539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14540     {
14541       if (unformat (input, "l2"))
14542         {
14543           is_l2 = 1;
14544           mode_set = 1;
14545         }
14546       else if (unformat (input, "l3"))
14547         {
14548           is_l2 = 0;
14549           mode_set = 1;
14550         }
14551       else
14552         {
14553           errmsg ("parse error '%U'", format_unformat_error, input);
14554           return -99;
14555         }
14556     }
14557
14558   if (!mode_set)
14559     {
14560       errmsg ("expected one of 'l2' or 'l3' parameter!");
14561       return -99;
14562     }
14563
14564   if (!vam->json_output)
14565     {
14566       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14567     }
14568
14569   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14570   mp->is_l2 = is_l2;
14571
14572   /* send it... */
14573   S;
14574
14575   /* Use a control ping for synchronization */
14576   {
14577     vl_api_control_ping_t *mp;
14578     M (CONTROL_PING, control_ping);
14579     S;
14580   }
14581   /* Wait for a reply... */
14582   W;
14583
14584   /* NOTREACHED */
14585   return 0;
14586 }
14587
14588 static int
14589 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14590 {
14591   vl_api_lisp_eid_table_vni_dump_t *mp;
14592   f64 timeout = ~0;
14593
14594   if (!vam->json_output)
14595     {
14596       print (vam->ofp, "VNI");
14597     }
14598
14599   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14600
14601   /* send it... */
14602   S;
14603
14604   /* Use a control ping for synchronization */
14605   {
14606     vl_api_control_ping_t *mp;
14607     M (CONTROL_PING, control_ping);
14608     S;
14609   }
14610   /* Wait for a reply... */
14611   W;
14612
14613   /* NOTREACHED */
14614   return 0;
14615 }
14616
14617 static int
14618 api_lisp_eid_table_dump (vat_main_t * vam)
14619 {
14620   unformat_input_t *i = vam->input;
14621   vl_api_lisp_eid_table_dump_t *mp;
14622   f64 timeout = ~0;
14623   struct in_addr ip4;
14624   struct in6_addr ip6;
14625   u8 mac[6];
14626   u8 eid_type = ~0, eid_set = 0;
14627   u32 prefix_length = ~0, t, vni = 0;
14628   u8 filter = 0;
14629
14630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14631     {
14632       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14633         {
14634           eid_set = 1;
14635           eid_type = 0;
14636           prefix_length = t;
14637         }
14638       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14639         {
14640           eid_set = 1;
14641           eid_type = 1;
14642           prefix_length = t;
14643         }
14644       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14645         {
14646           eid_set = 1;
14647           eid_type = 2;
14648         }
14649       else if (unformat (i, "vni %d", &t))
14650         {
14651           vni = t;
14652         }
14653       else if (unformat (i, "local"))
14654         {
14655           filter = 1;
14656         }
14657       else if (unformat (i, "remote"))
14658         {
14659           filter = 2;
14660         }
14661       else
14662         {
14663           errmsg ("parse error '%U'", format_unformat_error, i);
14664           return -99;
14665         }
14666     }
14667
14668   if (!vam->json_output)
14669     {
14670       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14671              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14672     }
14673
14674   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14675
14676   mp->filter = filter;
14677   if (eid_set)
14678     {
14679       mp->eid_set = 1;
14680       mp->vni = htonl (vni);
14681       mp->eid_type = eid_type;
14682       switch (eid_type)
14683         {
14684         case 0:
14685           mp->prefix_length = prefix_length;
14686           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14687           break;
14688         case 1:
14689           mp->prefix_length = prefix_length;
14690           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14691           break;
14692         case 2:
14693           clib_memcpy (mp->eid, mac, sizeof (mac));
14694           break;
14695         default:
14696           errmsg ("unknown EID type %d!", eid_type);
14697           return -99;
14698         }
14699     }
14700
14701   /* send it... */
14702   S;
14703
14704   /* Use a control ping for synchronization */
14705   {
14706     vl_api_control_ping_t *mp;
14707     M (CONTROL_PING, control_ping);
14708     S;
14709   }
14710
14711   /* Wait for a reply... */
14712   W;
14713
14714   /* NOTREACHED */
14715   return 0;
14716 }
14717
14718 static int
14719 api_lisp_adjacencies_get (vat_main_t * vam)
14720 {
14721   unformat_input_t *i = vam->input;
14722   vl_api_lisp_adjacencies_get_t *mp;
14723   f64 timeout = ~0;
14724   u8 vni_set = 0;
14725   u32 vni = ~0;
14726
14727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14728     {
14729       if (unformat (i, "vni %d", &vni))
14730         {
14731           vni_set = 1;
14732         }
14733       else
14734         {
14735           errmsg ("parse error '%U'", format_unformat_error, i);
14736           return -99;
14737         }
14738     }
14739
14740   if (!vni_set)
14741     {
14742       errmsg ("vni not set!");
14743       return -99;
14744     }
14745
14746   if (!vam->json_output)
14747     {
14748       print (vam->ofp, "%s %40s", "leid", "reid");
14749     }
14750
14751   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14752   mp->vni = clib_host_to_net_u32 (vni);
14753
14754   /* send it... */
14755   S;
14756
14757   /* Wait for a reply... */
14758   W;
14759
14760   /* NOTREACHED */
14761   return 0;
14762 }
14763
14764 static int
14765 api_lisp_map_server_dump (vat_main_t * vam)
14766 {
14767   vl_api_lisp_map_server_dump_t *mp;
14768   f64 timeout = ~0;
14769
14770   if (!vam->json_output)
14771     {
14772       print (vam->ofp, "%=20s", "Map server");
14773     }
14774
14775   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14776   /* send it... */
14777   S;
14778
14779   /* Use a control ping for synchronization */
14780   {
14781     vl_api_control_ping_t *mp;
14782     M (CONTROL_PING, control_ping);
14783     S;
14784   }
14785   /* Wait for a reply... */
14786   W;
14787
14788   /* NOTREACHED */
14789   return 0;
14790 }
14791
14792 static int
14793 api_lisp_map_resolver_dump (vat_main_t * vam)
14794 {
14795   vl_api_lisp_map_resolver_dump_t *mp;
14796   f64 timeout = ~0;
14797
14798   if (!vam->json_output)
14799     {
14800       print (vam->ofp, "%=20s", "Map resolver");
14801     }
14802
14803   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14804   /* send it... */
14805   S;
14806
14807   /* Use a control ping for synchronization */
14808   {
14809     vl_api_control_ping_t *mp;
14810     M (CONTROL_PING, control_ping);
14811     S;
14812   }
14813   /* Wait for a reply... */
14814   W;
14815
14816   /* NOTREACHED */
14817   return 0;
14818 }
14819
14820 static int
14821 api_show_lisp_status (vat_main_t * vam)
14822 {
14823   vl_api_show_lisp_status_t *mp;
14824   f64 timeout = ~0;
14825
14826   if (!vam->json_output)
14827     {
14828       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14829     }
14830
14831   M (SHOW_LISP_STATUS, show_lisp_status);
14832   /* send it... */
14833   S;
14834   /* Wait for a reply... */
14835   W;
14836
14837   /* NOTREACHED */
14838   return 0;
14839 }
14840
14841 static int
14842 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14843 {
14844   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14845   f64 timeout = ~0;
14846
14847   if (!vam->json_output)
14848     {
14849       print (vam->ofp, "%=20s", "itr-rlocs:");
14850     }
14851
14852   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14853   /* send it... */
14854   S;
14855   /* Wait for a reply... */
14856   W;
14857
14858   /* NOTREACHED */
14859   return 0;
14860 }
14861
14862 static int
14863 api_af_packet_create (vat_main_t * vam)
14864 {
14865   unformat_input_t *i = vam->input;
14866   vl_api_af_packet_create_t *mp;
14867   f64 timeout;
14868   u8 *host_if_name = 0;
14869   u8 hw_addr[6];
14870   u8 random_hw_addr = 1;
14871
14872   memset (hw_addr, 0, sizeof (hw_addr));
14873
14874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14875     {
14876       if (unformat (i, "name %s", &host_if_name))
14877         vec_add1 (host_if_name, 0);
14878       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14879         random_hw_addr = 0;
14880       else
14881         break;
14882     }
14883
14884   if (!vec_len (host_if_name))
14885     {
14886       errmsg ("host-interface name must be specified");
14887       return -99;
14888     }
14889
14890   if (vec_len (host_if_name) > 64)
14891     {
14892       errmsg ("host-interface name too long");
14893       return -99;
14894     }
14895
14896   M (AF_PACKET_CREATE, af_packet_create);
14897
14898   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14899   clib_memcpy (mp->hw_addr, hw_addr, 6);
14900   mp->use_random_hw_addr = random_hw_addr;
14901   vec_free (host_if_name);
14902
14903   S;
14904   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14905   /* NOTREACHED */
14906   return 0;
14907 }
14908
14909 static int
14910 api_af_packet_delete (vat_main_t * vam)
14911 {
14912   unformat_input_t *i = vam->input;
14913   vl_api_af_packet_delete_t *mp;
14914   f64 timeout;
14915   u8 *host_if_name = 0;
14916
14917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14918     {
14919       if (unformat (i, "name %s", &host_if_name))
14920         vec_add1 (host_if_name, 0);
14921       else
14922         break;
14923     }
14924
14925   if (!vec_len (host_if_name))
14926     {
14927       errmsg ("host-interface name must be specified");
14928       return -99;
14929     }
14930
14931   if (vec_len (host_if_name) > 64)
14932     {
14933       errmsg ("host-interface name too long");
14934       return -99;
14935     }
14936
14937   M (AF_PACKET_DELETE, af_packet_delete);
14938
14939   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14940   vec_free (host_if_name);
14941
14942   S;
14943   W;
14944   /* NOTREACHED */
14945   return 0;
14946 }
14947
14948 static int
14949 api_policer_add_del (vat_main_t * vam)
14950 {
14951   unformat_input_t *i = vam->input;
14952   vl_api_policer_add_del_t *mp;
14953   f64 timeout;
14954   u8 is_add = 1;
14955   u8 *name = 0;
14956   u32 cir = 0;
14957   u32 eir = 0;
14958   u64 cb = 0;
14959   u64 eb = 0;
14960   u8 rate_type = 0;
14961   u8 round_type = 0;
14962   u8 type = 0;
14963   u8 color_aware = 0;
14964   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14965
14966   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14967   conform_action.dscp = 0;
14968   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14969   exceed_action.dscp = 0;
14970   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14971   violate_action.dscp = 0;
14972
14973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14974     {
14975       if (unformat (i, "del"))
14976         is_add = 0;
14977       else if (unformat (i, "name %s", &name))
14978         vec_add1 (name, 0);
14979       else if (unformat (i, "cir %u", &cir))
14980         ;
14981       else if (unformat (i, "eir %u", &eir))
14982         ;
14983       else if (unformat (i, "cb %u", &cb))
14984         ;
14985       else if (unformat (i, "eb %u", &eb))
14986         ;
14987       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14988                          &rate_type))
14989         ;
14990       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14991                          &round_type))
14992         ;
14993       else if (unformat (i, "type %U", unformat_policer_type, &type))
14994         ;
14995       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14996                          &conform_action))
14997         ;
14998       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14999                          &exceed_action))
15000         ;
15001       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15002                          &violate_action))
15003         ;
15004       else if (unformat (i, "color-aware"))
15005         color_aware = 1;
15006       else
15007         break;
15008     }
15009
15010   if (!vec_len (name))
15011     {
15012       errmsg ("policer name must be specified");
15013       return -99;
15014     }
15015
15016   if (vec_len (name) > 64)
15017     {
15018       errmsg ("policer name too long");
15019       return -99;
15020     }
15021
15022   M (POLICER_ADD_DEL, policer_add_del);
15023
15024   clib_memcpy (mp->name, name, vec_len (name));
15025   vec_free (name);
15026   mp->is_add = is_add;
15027   mp->cir = cir;
15028   mp->eir = eir;
15029   mp->cb = cb;
15030   mp->eb = eb;
15031   mp->rate_type = rate_type;
15032   mp->round_type = round_type;
15033   mp->type = type;
15034   mp->conform_action_type = conform_action.action_type;
15035   mp->conform_dscp = conform_action.dscp;
15036   mp->exceed_action_type = exceed_action.action_type;
15037   mp->exceed_dscp = exceed_action.dscp;
15038   mp->violate_action_type = violate_action.action_type;
15039   mp->violate_dscp = violate_action.dscp;
15040   mp->color_aware = color_aware;
15041
15042   S;
15043   W;
15044   /* NOTREACHED */
15045   return 0;
15046 }
15047
15048 static int
15049 api_policer_dump (vat_main_t * vam)
15050 {
15051   unformat_input_t *i = vam->input;
15052   vl_api_policer_dump_t *mp;
15053   f64 timeout = ~0;
15054   u8 *match_name = 0;
15055   u8 match_name_valid = 0;
15056
15057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15058     {
15059       if (unformat (i, "name %s", &match_name))
15060         {
15061           vec_add1 (match_name, 0);
15062           match_name_valid = 1;
15063         }
15064       else
15065         break;
15066     }
15067
15068   M (POLICER_DUMP, policer_dump);
15069   mp->match_name_valid = match_name_valid;
15070   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15071   vec_free (match_name);
15072   /* send it... */
15073   S;
15074
15075   /* Use a control ping for synchronization */
15076   {
15077     vl_api_control_ping_t *mp;
15078     M (CONTROL_PING, control_ping);
15079     S;
15080   }
15081   /* Wait for a reply... */
15082   W;
15083
15084   /* NOTREACHED */
15085   return 0;
15086 }
15087
15088 static int
15089 api_policer_classify_set_interface (vat_main_t * vam)
15090 {
15091   unformat_input_t *i = vam->input;
15092   vl_api_policer_classify_set_interface_t *mp;
15093   f64 timeout;
15094   u32 sw_if_index;
15095   int sw_if_index_set;
15096   u32 ip4_table_index = ~0;
15097   u32 ip6_table_index = ~0;
15098   u32 l2_table_index = ~0;
15099   u8 is_add = 1;
15100
15101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15102     {
15103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15104         sw_if_index_set = 1;
15105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15106         sw_if_index_set = 1;
15107       else if (unformat (i, "del"))
15108         is_add = 0;
15109       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15110         ;
15111       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15112         ;
15113       else if (unformat (i, "l2-table %d", &l2_table_index))
15114         ;
15115       else
15116         {
15117           clib_warning ("parse error '%U'", format_unformat_error, i);
15118           return -99;
15119         }
15120     }
15121
15122   if (sw_if_index_set == 0)
15123     {
15124       errmsg ("missing interface name or sw_if_index");
15125       return -99;
15126     }
15127
15128   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15129
15130   mp->sw_if_index = ntohl (sw_if_index);
15131   mp->ip4_table_index = ntohl (ip4_table_index);
15132   mp->ip6_table_index = ntohl (ip6_table_index);
15133   mp->l2_table_index = ntohl (l2_table_index);
15134   mp->is_add = is_add;
15135
15136   S;
15137   W;
15138   /* NOTREACHED */
15139   return 0;
15140 }
15141
15142 static int
15143 api_policer_classify_dump (vat_main_t * vam)
15144 {
15145   unformat_input_t *i = vam->input;
15146   vl_api_policer_classify_dump_t *mp;
15147   f64 timeout = ~0;
15148   u8 type = POLICER_CLASSIFY_N_TABLES;
15149
15150   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15151     ;
15152   else
15153     {
15154       errmsg ("classify table type must be specified");
15155       return -99;
15156     }
15157
15158   if (!vam->json_output)
15159     {
15160       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15161     }
15162
15163   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15164   mp->type = type;
15165   /* send it... */
15166   S;
15167
15168   /* Use a control ping for synchronization */
15169   {
15170     vl_api_control_ping_t *mp;
15171     M (CONTROL_PING, control_ping);
15172     S;
15173   }
15174   /* Wait for a reply... */
15175   W;
15176
15177   /* NOTREACHED */
15178   return 0;
15179 }
15180
15181 static int
15182 api_netmap_create (vat_main_t * vam)
15183 {
15184   unformat_input_t *i = vam->input;
15185   vl_api_netmap_create_t *mp;
15186   f64 timeout;
15187   u8 *if_name = 0;
15188   u8 hw_addr[6];
15189   u8 random_hw_addr = 1;
15190   u8 is_pipe = 0;
15191   u8 is_master = 0;
15192
15193   memset (hw_addr, 0, sizeof (hw_addr));
15194
15195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15196     {
15197       if (unformat (i, "name %s", &if_name))
15198         vec_add1 (if_name, 0);
15199       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15200         random_hw_addr = 0;
15201       else if (unformat (i, "pipe"))
15202         is_pipe = 1;
15203       else if (unformat (i, "master"))
15204         is_master = 1;
15205       else if (unformat (i, "slave"))
15206         is_master = 0;
15207       else
15208         break;
15209     }
15210
15211   if (!vec_len (if_name))
15212     {
15213       errmsg ("interface name must be specified");
15214       return -99;
15215     }
15216
15217   if (vec_len (if_name) > 64)
15218     {
15219       errmsg ("interface name too long");
15220       return -99;
15221     }
15222
15223   M (NETMAP_CREATE, netmap_create);
15224
15225   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15226   clib_memcpy (mp->hw_addr, hw_addr, 6);
15227   mp->use_random_hw_addr = random_hw_addr;
15228   mp->is_pipe = is_pipe;
15229   mp->is_master = is_master;
15230   vec_free (if_name);
15231
15232   S;
15233   W;
15234   /* NOTREACHED */
15235   return 0;
15236 }
15237
15238 static int
15239 api_netmap_delete (vat_main_t * vam)
15240 {
15241   unformat_input_t *i = vam->input;
15242   vl_api_netmap_delete_t *mp;
15243   f64 timeout;
15244   u8 *if_name = 0;
15245
15246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15247     {
15248       if (unformat (i, "name %s", &if_name))
15249         vec_add1 (if_name, 0);
15250       else
15251         break;
15252     }
15253
15254   if (!vec_len (if_name))
15255     {
15256       errmsg ("interface name must be specified");
15257       return -99;
15258     }
15259
15260   if (vec_len (if_name) > 64)
15261     {
15262       errmsg ("interface name too long");
15263       return -99;
15264     }
15265
15266   M (NETMAP_DELETE, netmap_delete);
15267
15268   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15269   vec_free (if_name);
15270
15271   S;
15272   W;
15273   /* NOTREACHED */
15274   return 0;
15275 }
15276
15277 static void vl_api_mpls_tunnel_details_t_handler
15278   (vl_api_mpls_tunnel_details_t * mp)
15279 {
15280   vat_main_t *vam = &vat_main;
15281   i32 len = mp->mt_next_hop_n_labels;
15282   i32 i;
15283
15284   print (vam->ofp, "[%d]: via %U %d labels ",
15285          mp->tunnel_index,
15286          format_ip4_address, mp->mt_next_hop,
15287          ntohl (mp->mt_next_hop_sw_if_index));
15288   for (i = 0; i < len; i++)
15289     {
15290       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15291     }
15292   print (vam->ofp, "");
15293 }
15294
15295 static void vl_api_mpls_tunnel_details_t_handler_json
15296   (vl_api_mpls_tunnel_details_t * mp)
15297 {
15298   vat_main_t *vam = &vat_main;
15299   vat_json_node_t *node = NULL;
15300   struct in_addr ip4;
15301   i32 i;
15302   i32 len = mp->mt_next_hop_n_labels;
15303
15304   if (VAT_JSON_ARRAY != vam->json_tree.type)
15305     {
15306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15307       vat_json_init_array (&vam->json_tree);
15308     }
15309   node = vat_json_array_add (&vam->json_tree);
15310
15311   vat_json_init_object (node);
15312   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15313   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15314   vat_json_object_add_ip4 (node, "next_hop", ip4);
15315   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15316                             ntohl (mp->mt_next_hop_sw_if_index));
15317   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15318   vat_json_object_add_uint (node, "label_count", len);
15319   for (i = 0; i < len; i++)
15320     {
15321       vat_json_object_add_uint (node, "label",
15322                                 ntohl (mp->mt_next_hop_out_labels[i]));
15323     }
15324 }
15325
15326 static int
15327 api_mpls_tunnel_dump (vat_main_t * vam)
15328 {
15329   vl_api_mpls_tunnel_dump_t *mp;
15330   f64 timeout;
15331   i32 index = -1;
15332
15333   /* Parse args required to build the message */
15334   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15335     {
15336       if (!unformat (vam->input, "tunnel_index %d", &index))
15337         {
15338           index = -1;
15339           break;
15340         }
15341     }
15342
15343   print (vam->ofp, "  tunnel_index %d", index);
15344
15345   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15346   mp->tunnel_index = htonl (index);
15347   S;
15348
15349   /* Use a control ping for synchronization */
15350   {
15351     vl_api_control_ping_t *mp;
15352     M (CONTROL_PING, control_ping);
15353     S;
15354   }
15355   W;
15356 }
15357
15358 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15359 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15360
15361 static void
15362 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15363 {
15364   vat_main_t *vam = &vat_main;
15365   int count = ntohl (mp->count);
15366   vl_api_fib_path2_t *fp;
15367   int i;
15368
15369   print (vam->ofp,
15370          "table-id %d, label %u, ess_bit %u",
15371          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15372   fp = mp->path;
15373   for (i = 0; i < count; i++)
15374     {
15375       if (fp->afi == IP46_TYPE_IP6)
15376         print (vam->ofp,
15377                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15378                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15379                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15380                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15381                format_ip6_address, fp->next_hop);
15382       else if (fp->afi == IP46_TYPE_IP4)
15383         print (vam->ofp,
15384                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15385                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15386                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15387                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15388                format_ip4_address, fp->next_hop);
15389       fp++;
15390     }
15391 }
15392
15393 static void vl_api_mpls_fib_details_t_handler_json
15394   (vl_api_mpls_fib_details_t * mp)
15395 {
15396   vat_main_t *vam = &vat_main;
15397   int count = ntohl (mp->count);
15398   vat_json_node_t *node = NULL;
15399   struct in_addr ip4;
15400   struct in6_addr ip6;
15401   vl_api_fib_path2_t *fp;
15402   int i;
15403
15404   if (VAT_JSON_ARRAY != vam->json_tree.type)
15405     {
15406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15407       vat_json_init_array (&vam->json_tree);
15408     }
15409   node = vat_json_array_add (&vam->json_tree);
15410
15411   vat_json_init_object (node);
15412   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15413   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15414   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15415   vat_json_object_add_uint (node, "path_count", count);
15416   fp = mp->path;
15417   for (i = 0; i < count; i++)
15418     {
15419       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15420       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15421       vat_json_object_add_uint (node, "is_local", fp->is_local);
15422       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15423       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15424       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15425       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15426       if (fp->afi == IP46_TYPE_IP4)
15427         {
15428           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15429           vat_json_object_add_ip4 (node, "next_hop", ip4);
15430         }
15431       else if (fp->afi == IP46_TYPE_IP6)
15432         {
15433           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15434           vat_json_object_add_ip6 (node, "next_hop", ip6);
15435         }
15436     }
15437 }
15438
15439 static int
15440 api_mpls_fib_dump (vat_main_t * vam)
15441 {
15442   vl_api_mpls_fib_dump_t *mp;
15443   f64 timeout;
15444
15445   M (MPLS_FIB_DUMP, mpls_fib_dump);
15446   S;
15447
15448   /* Use a control ping for synchronization */
15449   {
15450     vl_api_control_ping_t *mp;
15451     M (CONTROL_PING, control_ping);
15452     S;
15453   }
15454   W;
15455 }
15456
15457 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15458 #define vl_api_ip_fib_details_t_print vl_noop_handler
15459
15460 static void
15461 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15462 {
15463   vat_main_t *vam = &vat_main;
15464   int count = ntohl (mp->count);
15465   vl_api_fib_path_t *fp;
15466   int i;
15467
15468   print (vam->ofp,
15469          "table-id %d, prefix %U/%d",
15470          ntohl (mp->table_id), format_ip4_address, mp->address,
15471          mp->address_length);
15472   fp = mp->path;
15473   for (i = 0; i < count; i++)
15474     {
15475       if (fp->afi == IP46_TYPE_IP6)
15476         print (vam->ofp,
15477                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15478                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15479                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15480                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15481                format_ip6_address, fp->next_hop);
15482       else if (fp->afi == IP46_TYPE_IP4)
15483         print (vam->ofp,
15484                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15485                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15486                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15487                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15488                format_ip4_address, fp->next_hop);
15489       fp++;
15490     }
15491 }
15492
15493 static void vl_api_ip_fib_details_t_handler_json
15494   (vl_api_ip_fib_details_t * mp)
15495 {
15496   vat_main_t *vam = &vat_main;
15497   int count = ntohl (mp->count);
15498   vat_json_node_t *node = NULL;
15499   struct in_addr ip4;
15500   struct in6_addr ip6;
15501   vl_api_fib_path_t *fp;
15502   int i;
15503
15504   if (VAT_JSON_ARRAY != vam->json_tree.type)
15505     {
15506       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15507       vat_json_init_array (&vam->json_tree);
15508     }
15509   node = vat_json_array_add (&vam->json_tree);
15510
15511   vat_json_init_object (node);
15512   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15513   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15514   vat_json_object_add_ip4 (node, "prefix", ip4);
15515   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15516   vat_json_object_add_uint (node, "path_count", count);
15517   fp = mp->path;
15518   for (i = 0; i < count; i++)
15519     {
15520       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15521       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15522       vat_json_object_add_uint (node, "is_local", fp->is_local);
15523       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15524       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15525       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15526       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15527       if (fp->afi == IP46_TYPE_IP4)
15528         {
15529           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15530           vat_json_object_add_ip4 (node, "next_hop", ip4);
15531         }
15532       else if (fp->afi == IP46_TYPE_IP6)
15533         {
15534           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15535           vat_json_object_add_ip6 (node, "next_hop", ip6);
15536         }
15537     }
15538 }
15539
15540 static int
15541 api_ip_fib_dump (vat_main_t * vam)
15542 {
15543   vl_api_ip_fib_dump_t *mp;
15544   f64 timeout;
15545
15546   M (IP_FIB_DUMP, ip_fib_dump);
15547   S;
15548
15549   /* Use a control ping for synchronization */
15550   {
15551     vl_api_control_ping_t *mp;
15552     M (CONTROL_PING, control_ping);
15553     S;
15554   }
15555   W;
15556 }
15557
15558 static void vl_api_ip_neighbor_details_t_handler
15559   (vl_api_ip_neighbor_details_t * mp)
15560 {
15561   vat_main_t *vam = &vat_main;
15562
15563   print (vam->ofp, "%c %U %U",
15564          (mp->is_static) ? 'S' : 'D',
15565          format_ethernet_address, &mp->mac_address,
15566          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15567          &mp->ip_address);
15568 }
15569
15570 static void vl_api_ip_neighbor_details_t_handler_json
15571   (vl_api_ip_neighbor_details_t * mp)
15572 {
15573
15574   vat_main_t *vam = &vat_main;
15575   vat_json_node_t *node;
15576   struct in_addr ip4;
15577   struct in6_addr ip6;
15578
15579   if (VAT_JSON_ARRAY != vam->json_tree.type)
15580     {
15581       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15582       vat_json_init_array (&vam->json_tree);
15583     }
15584   node = vat_json_array_add (&vam->json_tree);
15585
15586   vat_json_init_object (node);
15587   vat_json_object_add_string_copy (node, "flag",
15588                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15589                                    "dynamic");
15590
15591   vat_json_object_add_string_copy (node, "link_layer",
15592                                    format (0, "%U", format_ethernet_address,
15593                                            &mp->mac_address));
15594
15595   if (mp->is_ipv6)
15596     {
15597       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15598       vat_json_object_add_ip6 (node, "ip_address", ip6);
15599     }
15600   else
15601     {
15602       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15603       vat_json_object_add_ip4 (node, "ip_address", ip4);
15604     }
15605 }
15606
15607 static int
15608 api_ip_neighbor_dump (vat_main_t * vam)
15609 {
15610   unformat_input_t *i = vam->input;
15611   vl_api_ip_neighbor_dump_t *mp;
15612   f64 timeout;
15613   u8 is_ipv6 = 0;
15614   u32 sw_if_index = ~0;
15615
15616   /* Parse args required to build the message */
15617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15618     {
15619       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15620         ;
15621       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15622         ;
15623       else if (unformat (i, "ip6"))
15624         is_ipv6 = 1;
15625       else
15626         break;
15627     }
15628
15629   if (sw_if_index == ~0)
15630     {
15631       errmsg ("missing interface name or sw_if_index");
15632       return -99;
15633     }
15634
15635   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15636   mp->is_ipv6 = (u8) is_ipv6;
15637   mp->sw_if_index = ntohl (sw_if_index);
15638   S;
15639
15640   /* Use a control ping for synchronization */
15641   {
15642     vl_api_control_ping_t *mp;
15643     M (CONTROL_PING, control_ping);
15644     S;
15645   }
15646   W;
15647 }
15648
15649 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15650 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15651
15652 static void
15653 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15654 {
15655   vat_main_t *vam = &vat_main;
15656   int count = ntohl (mp->count);
15657   vl_api_fib_path_t *fp;
15658   int i;
15659
15660   print (vam->ofp,
15661          "table-id %d, prefix %U/%d",
15662          ntohl (mp->table_id), format_ip6_address, mp->address,
15663          mp->address_length);
15664   fp = mp->path;
15665   for (i = 0; i < count; i++)
15666     {
15667       if (fp->afi == IP46_TYPE_IP6)
15668         print (vam->ofp,
15669                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15670                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15671                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15672                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15673                format_ip6_address, fp->next_hop);
15674       else if (fp->afi == IP46_TYPE_IP4)
15675         print (vam->ofp,
15676                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15677                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15678                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15679                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15680                format_ip4_address, fp->next_hop);
15681       fp++;
15682     }
15683 }
15684
15685 static void vl_api_ip6_fib_details_t_handler_json
15686   (vl_api_ip6_fib_details_t * mp)
15687 {
15688   vat_main_t *vam = &vat_main;
15689   int count = ntohl (mp->count);
15690   vat_json_node_t *node = NULL;
15691   struct in_addr ip4;
15692   struct in6_addr ip6;
15693   vl_api_fib_path_t *fp;
15694   int i;
15695
15696   if (VAT_JSON_ARRAY != vam->json_tree.type)
15697     {
15698       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15699       vat_json_init_array (&vam->json_tree);
15700     }
15701   node = vat_json_array_add (&vam->json_tree);
15702
15703   vat_json_init_object (node);
15704   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15705   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15706   vat_json_object_add_ip6 (node, "prefix", ip6);
15707   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15708   vat_json_object_add_uint (node, "path_count", count);
15709   fp = mp->path;
15710   for (i = 0; i < count; i++)
15711     {
15712       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15713       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15714       vat_json_object_add_uint (node, "is_local", fp->is_local);
15715       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15716       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15717       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15718       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15719       if (fp->afi == IP46_TYPE_IP4)
15720         {
15721           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15722           vat_json_object_add_ip4 (node, "next_hop", ip4);
15723         }
15724       else if (fp->afi == IP46_TYPE_IP6)
15725         {
15726           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15727           vat_json_object_add_ip6 (node, "next_hop", ip6);
15728         }
15729     }
15730 }
15731
15732 static int
15733 api_ip6_fib_dump (vat_main_t * vam)
15734 {
15735   vl_api_ip6_fib_dump_t *mp;
15736   f64 timeout;
15737
15738   M (IP6_FIB_DUMP, ip6_fib_dump);
15739   S;
15740
15741   /* Use a control ping for synchronization */
15742   {
15743     vl_api_control_ping_t *mp;
15744     M (CONTROL_PING, control_ping);
15745     S;
15746   }
15747   W;
15748 }
15749
15750 int
15751 api_classify_table_ids (vat_main_t * vam)
15752 {
15753   vl_api_classify_table_ids_t *mp;
15754   f64 timeout;
15755
15756   /* Construct the API message */
15757   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15758   mp->context = 0;
15759
15760   S;
15761   W;
15762   /* NOTREACHED */
15763   return 0;
15764 }
15765
15766 int
15767 api_classify_table_by_interface (vat_main_t * vam)
15768 {
15769   unformat_input_t *input = vam->input;
15770   vl_api_classify_table_by_interface_t *mp;
15771   f64 timeout;
15772
15773   u32 sw_if_index = ~0;
15774   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15775     {
15776       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15777         ;
15778       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15779         ;
15780       else
15781         break;
15782     }
15783   if (sw_if_index == ~0)
15784     {
15785       errmsg ("missing interface name or sw_if_index");
15786       return -99;
15787     }
15788
15789   /* Construct the API message */
15790   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15791   mp->context = 0;
15792   mp->sw_if_index = ntohl (sw_if_index);
15793
15794   S;
15795   W;
15796   /* NOTREACHED */
15797   return 0;
15798 }
15799
15800 int
15801 api_classify_table_info (vat_main_t * vam)
15802 {
15803   unformat_input_t *input = vam->input;
15804   vl_api_classify_table_info_t *mp;
15805   f64 timeout;
15806
15807   u32 table_id = ~0;
15808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15809     {
15810       if (unformat (input, "table_id %d", &table_id))
15811         ;
15812       else
15813         break;
15814     }
15815   if (table_id == ~0)
15816     {
15817       errmsg ("missing table id");
15818       return -99;
15819     }
15820
15821   /* Construct the API message */
15822   M (CLASSIFY_TABLE_INFO, classify_table_info);
15823   mp->context = 0;
15824   mp->table_id = ntohl (table_id);
15825
15826   S;
15827   W;
15828   /* NOTREACHED */
15829   return 0;
15830 }
15831
15832 int
15833 api_classify_session_dump (vat_main_t * vam)
15834 {
15835   unformat_input_t *input = vam->input;
15836   vl_api_classify_session_dump_t *mp;
15837   f64 timeout;
15838
15839   u32 table_id = ~0;
15840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15841     {
15842       if (unformat (input, "table_id %d", &table_id))
15843         ;
15844       else
15845         break;
15846     }
15847   if (table_id == ~0)
15848     {
15849       errmsg ("missing table id");
15850       return -99;
15851     }
15852
15853   /* Construct the API message */
15854   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15855   mp->context = 0;
15856   mp->table_id = ntohl (table_id);
15857   S;
15858
15859   /* Use a control ping for synchronization */
15860   {
15861     vl_api_control_ping_t *mp;
15862     M (CONTROL_PING, control_ping);
15863     S;
15864   }
15865   W;
15866   /* NOTREACHED */
15867   return 0;
15868 }
15869
15870 static void
15871 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15872 {
15873   vat_main_t *vam = &vat_main;
15874
15875   print (vam->ofp, "collector_address %U, collector_port %d, "
15876          "src_address %U, vrf_id %d, path_mtu %u, "
15877          "template_interval %u, udp_checksum %d",
15878          format_ip4_address, mp->collector_address,
15879          ntohs (mp->collector_port),
15880          format_ip4_address, mp->src_address,
15881          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15882          ntohl (mp->template_interval), mp->udp_checksum);
15883
15884   vam->retval = 0;
15885   vam->result_ready = 1;
15886 }
15887
15888 static void
15889   vl_api_ipfix_exporter_details_t_handler_json
15890   (vl_api_ipfix_exporter_details_t * mp)
15891 {
15892   vat_main_t *vam = &vat_main;
15893   vat_json_node_t node;
15894   struct in_addr collector_address;
15895   struct in_addr src_address;
15896
15897   vat_json_init_object (&node);
15898   clib_memcpy (&collector_address, &mp->collector_address,
15899                sizeof (collector_address));
15900   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15901   vat_json_object_add_uint (&node, "collector_port",
15902                             ntohs (mp->collector_port));
15903   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15904   vat_json_object_add_ip4 (&node, "src_address", src_address);
15905   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15906   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15907   vat_json_object_add_uint (&node, "template_interval",
15908                             ntohl (mp->template_interval));
15909   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15910
15911   vat_json_print (vam->ofp, &node);
15912   vat_json_free (&node);
15913   vam->retval = 0;
15914   vam->result_ready = 1;
15915 }
15916
15917 int
15918 api_ipfix_exporter_dump (vat_main_t * vam)
15919 {
15920   vl_api_ipfix_exporter_dump_t *mp;
15921   f64 timeout;
15922
15923   /* Construct the API message */
15924   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15925   mp->context = 0;
15926
15927   S;
15928   W;
15929   /* NOTREACHED */
15930   return 0;
15931 }
15932
15933 static int
15934 api_ipfix_classify_stream_dump (vat_main_t * vam)
15935 {
15936   vl_api_ipfix_classify_stream_dump_t *mp;
15937   f64 timeout;
15938
15939   /* Construct the API message */
15940   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15941   mp->context = 0;
15942
15943   S;
15944   W;
15945   /* NOTREACHED */
15946   return 0;
15947 }
15948
15949 static void
15950   vl_api_ipfix_classify_stream_details_t_handler
15951   (vl_api_ipfix_classify_stream_details_t * mp)
15952 {
15953   vat_main_t *vam = &vat_main;
15954   print (vam->ofp, "domain_id %d, src_port %d",
15955          ntohl (mp->domain_id), ntohs (mp->src_port));
15956   vam->retval = 0;
15957   vam->result_ready = 1;
15958 }
15959
15960 static void
15961   vl_api_ipfix_classify_stream_details_t_handler_json
15962   (vl_api_ipfix_classify_stream_details_t * mp)
15963 {
15964   vat_main_t *vam = &vat_main;
15965   vat_json_node_t node;
15966
15967   vat_json_init_object (&node);
15968   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15969   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15970
15971   vat_json_print (vam->ofp, &node);
15972   vat_json_free (&node);
15973   vam->retval = 0;
15974   vam->result_ready = 1;
15975 }
15976
15977 static int
15978 api_ipfix_classify_table_dump (vat_main_t * vam)
15979 {
15980   vl_api_ipfix_classify_table_dump_t *mp;
15981   f64 timeout;
15982
15983   if (!vam->json_output)
15984     {
15985       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15986              "transport_protocol");
15987     }
15988
15989   /* Construct the API message */
15990   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15991
15992   /* send it... */
15993   S;
15994
15995   /* Use a control ping for synchronization */
15996   {
15997     vl_api_control_ping_t *mp;
15998     M (CONTROL_PING, control_ping);
15999     S;
16000   }
16001   W;
16002 }
16003
16004 static void
16005   vl_api_ipfix_classify_table_details_t_handler
16006   (vl_api_ipfix_classify_table_details_t * mp)
16007 {
16008   vat_main_t *vam = &vat_main;
16009   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16010          mp->transport_protocol);
16011 }
16012
16013 static void
16014   vl_api_ipfix_classify_table_details_t_handler_json
16015   (vl_api_ipfix_classify_table_details_t * mp)
16016 {
16017   vat_json_node_t *node = NULL;
16018   vat_main_t *vam = &vat_main;
16019
16020   if (VAT_JSON_ARRAY != vam->json_tree.type)
16021     {
16022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16023       vat_json_init_array (&vam->json_tree);
16024     }
16025
16026   node = vat_json_array_add (&vam->json_tree);
16027   vat_json_init_object (node);
16028
16029   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16030   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16031   vat_json_object_add_uint (node, "transport_protocol",
16032                             mp->transport_protocol);
16033 }
16034
16035 static int
16036 api_sw_interface_span_enable_disable (vat_main_t * vam)
16037 {
16038   unformat_input_t *i = vam->input;
16039   vl_api_sw_interface_span_enable_disable_t *mp;
16040   f64 timeout;
16041   u32 src_sw_if_index = ~0;
16042   u32 dst_sw_if_index = ~0;
16043   u8 state = 3;
16044
16045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16046     {
16047       if (unformat
16048           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16049         ;
16050       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16051         ;
16052       else
16053         if (unformat
16054             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16055         ;
16056       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16057         ;
16058       else if (unformat (i, "disable"))
16059         state = 0;
16060       else if (unformat (i, "rx"))
16061         state = 1;
16062       else if (unformat (i, "tx"))
16063         state = 2;
16064       else if (unformat (i, "both"))
16065         state = 3;
16066       else
16067         break;
16068     }
16069
16070   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16071
16072   mp->sw_if_index_from = htonl (src_sw_if_index);
16073   mp->sw_if_index_to = htonl (dst_sw_if_index);
16074   mp->state = state;
16075
16076   S;
16077   W;
16078   /* NOTREACHED */
16079   return 0;
16080 }
16081
16082 static void
16083 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16084                                             * mp)
16085 {
16086   vat_main_t *vam = &vat_main;
16087   u8 *sw_if_from_name = 0;
16088   u8 *sw_if_to_name = 0;
16089   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16090   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16091   char *states[] = { "none", "rx", "tx", "both" };
16092   hash_pair_t *p;
16093
16094   /* *INDENT-OFF* */
16095   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16096   ({
16097     if ((u32) p->value[0] == sw_if_index_from)
16098       {
16099         sw_if_from_name = (u8 *)(p->key);
16100         if (sw_if_to_name)
16101           break;
16102       }
16103     if ((u32) p->value[0] == sw_if_index_to)
16104       {
16105         sw_if_to_name = (u8 *)(p->key);
16106         if (sw_if_from_name)
16107           break;
16108       }
16109   }));
16110   /* *INDENT-ON* */
16111   print (vam->ofp, "%20s => %20s (%s)",
16112          sw_if_from_name, sw_if_to_name, states[mp->state]);
16113 }
16114
16115 static void
16116   vl_api_sw_interface_span_details_t_handler_json
16117   (vl_api_sw_interface_span_details_t * mp)
16118 {
16119   vat_main_t *vam = &vat_main;
16120   vat_json_node_t *node = NULL;
16121   u8 *sw_if_from_name = 0;
16122   u8 *sw_if_to_name = 0;
16123   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16124   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16125   hash_pair_t *p;
16126
16127   /* *INDENT-OFF* */
16128   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16129   ({
16130     if ((u32) p->value[0] == sw_if_index_from)
16131       {
16132         sw_if_from_name = (u8 *)(p->key);
16133         if (sw_if_to_name)
16134           break;
16135       }
16136     if ((u32) p->value[0] == sw_if_index_to)
16137       {
16138         sw_if_to_name = (u8 *)(p->key);
16139         if (sw_if_from_name)
16140           break;
16141       }
16142   }));
16143   /* *INDENT-ON* */
16144
16145   if (VAT_JSON_ARRAY != vam->json_tree.type)
16146     {
16147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16148       vat_json_init_array (&vam->json_tree);
16149     }
16150   node = vat_json_array_add (&vam->json_tree);
16151
16152   vat_json_init_object (node);
16153   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16154   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16155   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16156   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16157   vat_json_object_add_uint (node, "state", mp->state);
16158 }
16159
16160 static int
16161 api_sw_interface_span_dump (vat_main_t * vam)
16162 {
16163   vl_api_sw_interface_span_dump_t *mp;
16164   f64 timeout;
16165
16166   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16167   S;
16168
16169   /* Use a control ping for synchronization */
16170   {
16171     vl_api_control_ping_t *mp;
16172     M (CONTROL_PING, control_ping);
16173     S;
16174   }
16175   W;
16176 }
16177
16178 int
16179 api_pg_create_interface (vat_main_t * vam)
16180 {
16181   unformat_input_t *input = vam->input;
16182   vl_api_pg_create_interface_t *mp;
16183   f64 timeout;
16184
16185   u32 if_id = ~0;
16186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16187     {
16188       if (unformat (input, "if_id %d", &if_id))
16189         ;
16190       else
16191         break;
16192     }
16193   if (if_id == ~0)
16194     {
16195       errmsg ("missing pg interface index");
16196       return -99;
16197     }
16198
16199   /* Construct the API message */
16200   M (PG_CREATE_INTERFACE, pg_create_interface);
16201   mp->context = 0;
16202   mp->interface_id = ntohl (if_id);
16203
16204   S;
16205   W;
16206   /* NOTREACHED */
16207   return 0;
16208 }
16209
16210 int
16211 api_pg_capture (vat_main_t * vam)
16212 {
16213   unformat_input_t *input = vam->input;
16214   vl_api_pg_capture_t *mp;
16215   f64 timeout;
16216
16217   u32 if_id = ~0;
16218   u8 enable = 1;
16219   u32 count = 1;
16220   u8 pcap_file_set = 0;
16221   u8 *pcap_file = 0;
16222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16223     {
16224       if (unformat (input, "if_id %d", &if_id))
16225         ;
16226       else if (unformat (input, "pcap %s", &pcap_file))
16227         pcap_file_set = 1;
16228       else if (unformat (input, "count %d", &count))
16229         ;
16230       else if (unformat (input, "disable"))
16231         enable = 0;
16232       else
16233         break;
16234     }
16235   if (if_id == ~0)
16236     {
16237       errmsg ("missing pg interface index");
16238       return -99;
16239     }
16240   if (pcap_file_set > 0)
16241     {
16242       if (vec_len (pcap_file) > 255)
16243         {
16244           errmsg ("pcap file name is too long");
16245           return -99;
16246         }
16247     }
16248
16249   u32 name_len = vec_len (pcap_file);
16250   /* Construct the API message */
16251   M (PG_CAPTURE, pg_capture);
16252   mp->context = 0;
16253   mp->interface_id = ntohl (if_id);
16254   mp->is_enabled = enable;
16255   mp->count = ntohl (count);
16256   mp->pcap_name_length = ntohl (name_len);
16257   if (pcap_file_set != 0)
16258     {
16259       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16260     }
16261   vec_free (pcap_file);
16262
16263   S;
16264   W;
16265   /* NOTREACHED */
16266   return 0;
16267 }
16268
16269 int
16270 api_pg_enable_disable (vat_main_t * vam)
16271 {
16272   unformat_input_t *input = vam->input;
16273   vl_api_pg_enable_disable_t *mp;
16274   f64 timeout;
16275
16276   u8 enable = 1;
16277   u8 stream_name_set = 0;
16278   u8 *stream_name = 0;
16279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16280     {
16281       if (unformat (input, "stream %s", &stream_name))
16282         stream_name_set = 1;
16283       else if (unformat (input, "disable"))
16284         enable = 0;
16285       else
16286         break;
16287     }
16288
16289   if (stream_name_set > 0)
16290     {
16291       if (vec_len (stream_name) > 255)
16292         {
16293           errmsg ("stream name too long");
16294           return -99;
16295         }
16296     }
16297
16298   u32 name_len = vec_len (stream_name);
16299   /* Construct the API message */
16300   M (PG_ENABLE_DISABLE, pg_enable_disable);
16301   mp->context = 0;
16302   mp->is_enabled = enable;
16303   if (stream_name_set != 0)
16304     {
16305       mp->stream_name_length = ntohl (name_len);
16306       clib_memcpy (mp->stream_name, stream_name, name_len);
16307     }
16308   vec_free (stream_name);
16309
16310   S;
16311   W;
16312   /* NOTREACHED */
16313   return 0;
16314 }
16315
16316 int
16317 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16318 {
16319   unformat_input_t *input = vam->input;
16320   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16321   f64 timeout;
16322
16323   u16 *low_ports = 0;
16324   u16 *high_ports = 0;
16325   u16 this_low;
16326   u16 this_hi;
16327   ip4_address_t ip4_addr;
16328   ip6_address_t ip6_addr;
16329   u32 length;
16330   u32 tmp, tmp2;
16331   u8 prefix_set = 0;
16332   u32 vrf_id = ~0;
16333   u8 is_add = 1;
16334   u8 is_ipv6 = 0;
16335
16336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16337     {
16338       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16339         {
16340           prefix_set = 1;
16341         }
16342       else
16343         if (unformat
16344             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16345         {
16346           prefix_set = 1;
16347           is_ipv6 = 1;
16348         }
16349       else if (unformat (input, "vrf %d", &vrf_id))
16350         ;
16351       else if (unformat (input, "del"))
16352         is_add = 0;
16353       else if (unformat (input, "port %d", &tmp))
16354         {
16355           if (tmp == 0 || tmp > 65535)
16356             {
16357               errmsg ("port %d out of range", tmp);
16358               return -99;
16359             }
16360           this_low = tmp;
16361           this_hi = this_low + 1;
16362           vec_add1 (low_ports, this_low);
16363           vec_add1 (high_ports, this_hi);
16364         }
16365       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16366         {
16367           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16368             {
16369               errmsg ("incorrect range parameters");
16370               return -99;
16371             }
16372           this_low = tmp;
16373           /* Note: in debug CLI +1 is added to high before
16374              passing to real fn that does "the work"
16375              (ip_source_and_port_range_check_add_del).
16376              This fn is a wrapper around the binary API fn a
16377              control plane will call, which expects this increment
16378              to have occurred. Hence letting the binary API control
16379              plane fn do the increment for consistency between VAT
16380              and other control planes.
16381            */
16382           this_hi = tmp2;
16383           vec_add1 (low_ports, this_low);
16384           vec_add1 (high_ports, this_hi);
16385         }
16386       else
16387         break;
16388     }
16389
16390   if (prefix_set == 0)
16391     {
16392       errmsg ("<address>/<mask> not specified");
16393       return -99;
16394     }
16395
16396   if (vrf_id == ~0)
16397     {
16398       errmsg ("VRF ID required, not specified");
16399       return -99;
16400     }
16401
16402   if (vrf_id == 0)
16403     {
16404       errmsg
16405         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16406       return -99;
16407     }
16408
16409   if (vec_len (low_ports) == 0)
16410     {
16411       errmsg ("At least one port or port range required");
16412       return -99;
16413     }
16414
16415   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16416      ip_source_and_port_range_check_add_del);
16417
16418   mp->is_add = is_add;
16419
16420   if (is_ipv6)
16421     {
16422       mp->is_ipv6 = 1;
16423       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16424     }
16425   else
16426     {
16427       mp->is_ipv6 = 0;
16428       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16429     }
16430
16431   mp->mask_length = length;
16432   mp->number_of_ranges = vec_len (low_ports);
16433
16434   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16435   vec_free (low_ports);
16436
16437   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16438   vec_free (high_ports);
16439
16440   mp->vrf_id = ntohl (vrf_id);
16441
16442   S;
16443   W;
16444   /* NOTREACHED */
16445   return 0;
16446 }
16447
16448 int
16449 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16450 {
16451   unformat_input_t *input = vam->input;
16452   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16453   f64 timeout;
16454   u32 sw_if_index = ~0;
16455   int vrf_set = 0;
16456   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16457   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16458   u8 is_add = 1;
16459
16460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16461     {
16462       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16463         ;
16464       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16465         ;
16466       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16467         vrf_set = 1;
16468       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16469         vrf_set = 1;
16470       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16471         vrf_set = 1;
16472       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16473         vrf_set = 1;
16474       else if (unformat (input, "del"))
16475         is_add = 0;
16476       else
16477         break;
16478     }
16479
16480   if (sw_if_index == ~0)
16481     {
16482       errmsg ("Interface required but not specified");
16483       return -99;
16484     }
16485
16486   if (vrf_set == 0)
16487     {
16488       errmsg ("VRF ID required but not specified");
16489       return -99;
16490     }
16491
16492   if (tcp_out_vrf_id == 0
16493       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16494     {
16495       errmsg
16496         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16497       return -99;
16498     }
16499
16500   /* Construct the API message */
16501   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16502      ip_source_and_port_range_check_interface_add_del);
16503
16504   mp->sw_if_index = ntohl (sw_if_index);
16505   mp->is_add = is_add;
16506   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16507   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16508   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16509   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16510
16511   /* send it... */
16512   S;
16513
16514   /* Wait for a reply... */
16515   W;
16516 }
16517
16518 static int
16519 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16520 {
16521   unformat_input_t *i = vam->input;
16522   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16523   f64 timeout;
16524   u32 local_sa_id = 0;
16525   u32 remote_sa_id = 0;
16526   ip4_address_t src_address;
16527   ip4_address_t dst_address;
16528   u8 is_add = 1;
16529
16530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16531     {
16532       if (unformat (i, "local_sa %d", &local_sa_id))
16533         ;
16534       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16535         ;
16536       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16537         ;
16538       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16539         ;
16540       else if (unformat (i, "del"))
16541         is_add = 0;
16542       else
16543         {
16544           clib_warning ("parse error '%U'", format_unformat_error, i);
16545           return -99;
16546         }
16547     }
16548
16549   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16550
16551   mp->local_sa_id = ntohl (local_sa_id);
16552   mp->remote_sa_id = ntohl (remote_sa_id);
16553   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16554   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16555   mp->is_add = is_add;
16556
16557   S;
16558   W;
16559   /* NOTREACHED */
16560   return 0;
16561 }
16562
16563 static int
16564 api_punt (vat_main_t * vam)
16565 {
16566   unformat_input_t *i = vam->input;
16567   vl_api_punt_t *mp;
16568   f64 timeout;
16569   u32 ipv = ~0;
16570   u32 protocol = ~0;
16571   u32 port = ~0;
16572   int is_add = 1;
16573
16574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16575     {
16576       if (unformat (i, "ip %d", &ipv))
16577         ;
16578       else if (unformat (i, "protocol %d", &protocol))
16579         ;
16580       else if (unformat (i, "port %d", &port))
16581         ;
16582       else if (unformat (i, "del"))
16583         is_add = 0;
16584       else
16585         {
16586           clib_warning ("parse error '%U'", format_unformat_error, i);
16587           return -99;
16588         }
16589     }
16590
16591   M (PUNT, punt);
16592
16593   mp->is_add = (u8) is_add;
16594   mp->ipv = (u8) ipv;
16595   mp->l4_protocol = (u8) protocol;
16596   mp->l4_port = htons ((u16) port);
16597
16598   S;
16599   W;
16600   /* NOTREACHED */
16601   return 0;
16602 }
16603
16604 static void vl_api_ipsec_gre_tunnel_details_t_handler
16605   (vl_api_ipsec_gre_tunnel_details_t * mp)
16606 {
16607   vat_main_t *vam = &vat_main;
16608
16609   print (vam->ofp, "%11d%15U%15U%14d%14d",
16610          ntohl (mp->sw_if_index),
16611          format_ip4_address, &mp->src_address,
16612          format_ip4_address, &mp->dst_address,
16613          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16614 }
16615
16616 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16617   (vl_api_ipsec_gre_tunnel_details_t * mp)
16618 {
16619   vat_main_t *vam = &vat_main;
16620   vat_json_node_t *node = NULL;
16621   struct in_addr ip4;
16622
16623   if (VAT_JSON_ARRAY != vam->json_tree.type)
16624     {
16625       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16626       vat_json_init_array (&vam->json_tree);
16627     }
16628   node = vat_json_array_add (&vam->json_tree);
16629
16630   vat_json_init_object (node);
16631   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16632   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16633   vat_json_object_add_ip4 (node, "src_address", ip4);
16634   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16635   vat_json_object_add_ip4 (node, "dst_address", ip4);
16636   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16637   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16638 }
16639
16640 static int
16641 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16642 {
16643   unformat_input_t *i = vam->input;
16644   vl_api_ipsec_gre_tunnel_dump_t *mp;
16645   f64 timeout;
16646   u32 sw_if_index;
16647   u8 sw_if_index_set = 0;
16648
16649   /* Parse args required to build the message */
16650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16651     {
16652       if (unformat (i, "sw_if_index %d", &sw_if_index))
16653         sw_if_index_set = 1;
16654       else
16655         break;
16656     }
16657
16658   if (sw_if_index_set == 0)
16659     {
16660       sw_if_index = ~0;
16661     }
16662
16663   if (!vam->json_output)
16664     {
16665       print (vam->ofp, "%11s%15s%15s%14s%14s",
16666              "sw_if_index", "src_address", "dst_address",
16667              "local_sa_id", "remote_sa_id");
16668     }
16669
16670   /* Get list of gre-tunnel interfaces */
16671   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16672
16673   mp->sw_if_index = htonl (sw_if_index);
16674
16675   S;
16676
16677   /* Use a control ping for synchronization */
16678   {
16679     vl_api_control_ping_t *mp;
16680     M (CONTROL_PING, control_ping);
16681     S;
16682   }
16683   W;
16684 }
16685
16686 static int
16687 api_delete_subif (vat_main_t * vam)
16688 {
16689   unformat_input_t *i = vam->input;
16690   vl_api_delete_subif_t *mp;
16691   f64 timeout;
16692   u32 sw_if_index = ~0;
16693
16694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16695     {
16696       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16697         ;
16698       if (unformat (i, "sw_if_index %d", &sw_if_index))
16699         ;
16700       else
16701         break;
16702     }
16703
16704   if (sw_if_index == ~0)
16705     {
16706       errmsg ("missing sw_if_index");
16707       return -99;
16708     }
16709
16710   /* Construct the API message */
16711   M (DELETE_SUBIF, delete_subif);
16712   mp->sw_if_index = ntohl (sw_if_index);
16713
16714   S;
16715   W;
16716 }
16717
16718 #define foreach_pbb_vtr_op      \
16719 _("disable",  L2_VTR_DISABLED)  \
16720 _("pop",  L2_VTR_POP_2)         \
16721 _("push",  L2_VTR_PUSH_2)
16722
16723 static int
16724 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16725 {
16726   unformat_input_t *i = vam->input;
16727   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16728   f64 timeout;
16729   u32 sw_if_index = ~0, vtr_op = ~0;
16730   u16 outer_tag = ~0;
16731   u8 dmac[6], smac[6];
16732   u8 dmac_set = 0, smac_set = 0;
16733   u16 vlanid = 0;
16734   u32 sid = ~0;
16735   u32 tmp;
16736
16737   /* Shut up coverity */
16738   memset (dmac, 0, sizeof (dmac));
16739   memset (smac, 0, sizeof (smac));
16740
16741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16742     {
16743       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16744         ;
16745       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16746         ;
16747       else if (unformat (i, "vtr_op %d", &vtr_op))
16748         ;
16749 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16750       foreach_pbb_vtr_op
16751 #undef _
16752         else if (unformat (i, "translate_pbb_stag"))
16753         {
16754           if (unformat (i, "%d", &tmp))
16755             {
16756               vtr_op = L2_VTR_TRANSLATE_2_1;
16757               outer_tag = tmp;
16758             }
16759           else
16760             {
16761               errmsg
16762                 ("translate_pbb_stag operation requires outer tag definition");
16763               return -99;
16764             }
16765         }
16766       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16767         dmac_set++;
16768       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16769         smac_set++;
16770       else if (unformat (i, "sid %d", &sid))
16771         ;
16772       else if (unformat (i, "vlanid %d", &tmp))
16773         vlanid = tmp;
16774       else
16775         {
16776           clib_warning ("parse error '%U'", format_unformat_error, i);
16777           return -99;
16778         }
16779     }
16780
16781   if ((sw_if_index == ~0) || (vtr_op == ~0))
16782     {
16783       errmsg ("missing sw_if_index or vtr operation");
16784       return -99;
16785     }
16786   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16787       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16788     {
16789       errmsg
16790         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16791       return -99;
16792     }
16793
16794   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16795   mp->sw_if_index = ntohl (sw_if_index);
16796   mp->vtr_op = ntohl (vtr_op);
16797   mp->outer_tag = ntohs (outer_tag);
16798   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16799   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16800   mp->b_vlanid = ntohs (vlanid);
16801   mp->i_sid = ntohl (sid);
16802
16803   S;
16804   W;
16805   /* NOTREACHED */
16806   return 0;
16807 }
16808
16809 static int
16810 api_flow_classify_set_interface (vat_main_t * vam)
16811 {
16812   unformat_input_t *i = vam->input;
16813   vl_api_flow_classify_set_interface_t *mp;
16814   f64 timeout;
16815   u32 sw_if_index;
16816   int sw_if_index_set;
16817   u32 ip4_table_index = ~0;
16818   u32 ip6_table_index = ~0;
16819   u8 is_add = 1;
16820
16821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16822     {
16823       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16824         sw_if_index_set = 1;
16825       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16826         sw_if_index_set = 1;
16827       else if (unformat (i, "del"))
16828         is_add = 0;
16829       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16830         ;
16831       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16832         ;
16833       else
16834         {
16835           clib_warning ("parse error '%U'", format_unformat_error, i);
16836           return -99;
16837         }
16838     }
16839
16840   if (sw_if_index_set == 0)
16841     {
16842       errmsg ("missing interface name or sw_if_index");
16843       return -99;
16844     }
16845
16846   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16847
16848   mp->sw_if_index = ntohl (sw_if_index);
16849   mp->ip4_table_index = ntohl (ip4_table_index);
16850   mp->ip6_table_index = ntohl (ip6_table_index);
16851   mp->is_add = is_add;
16852
16853   S;
16854   W;
16855   /* NOTREACHED */
16856   return 0;
16857 }
16858
16859 static int
16860 api_flow_classify_dump (vat_main_t * vam)
16861 {
16862   unformat_input_t *i = vam->input;
16863   vl_api_flow_classify_dump_t *mp;
16864   f64 timeout = ~0;
16865   u8 type = FLOW_CLASSIFY_N_TABLES;
16866
16867   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16868     ;
16869   else
16870     {
16871       errmsg ("classify table type must be specified");
16872       return -99;
16873     }
16874
16875   if (!vam->json_output)
16876     {
16877       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16878     }
16879
16880   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16881   mp->type = type;
16882   /* send it... */
16883   S;
16884
16885   /* Use a control ping for synchronization */
16886   {
16887     vl_api_control_ping_t *mp;
16888     M (CONTROL_PING, control_ping);
16889     S;
16890   }
16891   /* Wait for a reply... */
16892   W;
16893
16894   /* NOTREACHED */
16895   return 0;
16896 }
16897
16898 static int
16899 api_feature_enable_disable (vat_main_t * vam)
16900 {
16901   unformat_input_t *i = vam->input;
16902   vl_api_feature_enable_disable_t *mp;
16903   f64 timeout;
16904   u8 *arc_name = 0;
16905   u8 *feature_name = 0;
16906   u32 sw_if_index = ~0;
16907   u8 enable = 1;
16908
16909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16910     {
16911       if (unformat (i, "arc_name %s", &arc_name))
16912         ;
16913       else if (unformat (i, "feature_name %s", &feature_name))
16914         ;
16915       else
16916         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16917         ;
16918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16919         ;
16920       else if (unformat (i, "disable"))
16921         enable = 0;
16922       else
16923         break;
16924     }
16925
16926   if (arc_name == 0)
16927     {
16928       errmsg ("missing arc name");
16929       return -99;
16930     }
16931   if (vec_len (arc_name) > 63)
16932     {
16933       errmsg ("arc name too long");
16934     }
16935
16936   if (feature_name == 0)
16937     {
16938       errmsg ("missing feature name");
16939       return -99;
16940     }
16941   if (vec_len (feature_name) > 63)
16942     {
16943       errmsg ("feature name too long");
16944     }
16945
16946   if (sw_if_index == ~0)
16947     {
16948       errmsg ("missing interface name or sw_if_index");
16949       return -99;
16950     }
16951
16952   /* Construct the API message */
16953   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16954   mp->sw_if_index = ntohl (sw_if_index);
16955   mp->enable = enable;
16956   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16957   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16958   vec_free (arc_name);
16959   vec_free (feature_name);
16960
16961   S;
16962   W;
16963 }
16964
16965 static int
16966 api_sw_interface_tag_add_del (vat_main_t * vam)
16967 {
16968   unformat_input_t *i = vam->input;
16969   vl_api_sw_interface_tag_add_del_t *mp;
16970   f64 timeout;
16971   u32 sw_if_index = ~0;
16972   u8 *tag = 0;
16973   u8 enable = 1;
16974
16975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16976     {
16977       if (unformat (i, "tag %s", &tag))
16978         ;
16979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16980         ;
16981       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16982         ;
16983       else if (unformat (i, "del"))
16984         enable = 0;
16985       else
16986         break;
16987     }
16988
16989   if (sw_if_index == ~0)
16990     {
16991       errmsg ("missing interface name or sw_if_index");
16992       return -99;
16993     }
16994
16995   if (enable && (tag == 0))
16996     {
16997       errmsg ("no tag specified");
16998       return -99;
16999     }
17000
17001   /* Construct the API message */
17002   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
17003   mp->sw_if_index = ntohl (sw_if_index);
17004   mp->is_add = enable;
17005   if (enable)
17006     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17007   vec_free (tag);
17008
17009   S;
17010   W;
17011 }
17012
17013 static void vl_api_l2_xconnect_details_t_handler
17014   (vl_api_l2_xconnect_details_t * mp)
17015 {
17016   vat_main_t *vam = &vat_main;
17017
17018   print (vam->ofp, "%15d%15d",
17019          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17020 }
17021
17022 static void vl_api_l2_xconnect_details_t_handler_json
17023   (vl_api_l2_xconnect_details_t * mp)
17024 {
17025   vat_main_t *vam = &vat_main;
17026   vat_json_node_t *node = NULL;
17027
17028   if (VAT_JSON_ARRAY != vam->json_tree.type)
17029     {
17030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17031       vat_json_init_array (&vam->json_tree);
17032     }
17033   node = vat_json_array_add (&vam->json_tree);
17034
17035   vat_json_init_object (node);
17036   vat_json_object_add_uint (node, "rx_sw_if_index",
17037                             ntohl (mp->rx_sw_if_index));
17038   vat_json_object_add_uint (node, "tx_sw_if_index",
17039                             ntohl (mp->tx_sw_if_index));
17040 }
17041
17042 static int
17043 api_l2_xconnect_dump (vat_main_t * vam)
17044 {
17045   vl_api_l2_xconnect_dump_t *mp;
17046   f64 timeout;
17047
17048   if (!vam->json_output)
17049     {
17050       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17051     }
17052
17053   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
17054
17055   S;
17056
17057   /* Use a control ping for synchronization */
17058   {
17059     vl_api_control_ping_t *mp;
17060     M (CONTROL_PING, control_ping);
17061     S;
17062   }
17063   W;
17064 }
17065
17066 static int
17067 api_sw_interface_set_mtu (vat_main_t * vam)
17068 {
17069   unformat_input_t *i = vam->input;
17070   vl_api_sw_interface_set_mtu_t *mp;
17071   f64 timeout;
17072   u32 sw_if_index = ~0;
17073   u32 mtu = 0;
17074
17075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17076     {
17077       if (unformat (i, "mtu %d", &mtu))
17078         ;
17079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17080         ;
17081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17082         ;
17083       else
17084         break;
17085     }
17086
17087   if (sw_if_index == ~0)
17088     {
17089       errmsg ("missing interface name or sw_if_index");
17090       return -99;
17091     }
17092
17093   if (mtu == 0)
17094     {
17095       errmsg ("no mtu specified");
17096       return -99;
17097     }
17098
17099   /* Construct the API message */
17100   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17101   mp->sw_if_index = ntohl (sw_if_index);
17102   mp->mtu = ntohs ((u16) mtu);
17103
17104   S;
17105   W;
17106 }
17107
17108
17109 static int
17110 q_or_quit (vat_main_t * vam)
17111 {
17112   longjmp (vam->jump_buf, 1);
17113   return 0;                     /* not so much */
17114 }
17115
17116 static int
17117 q (vat_main_t * vam)
17118 {
17119   return q_or_quit (vam);
17120 }
17121
17122 static int
17123 quit (vat_main_t * vam)
17124 {
17125   return q_or_quit (vam);
17126 }
17127
17128 static int
17129 comment (vat_main_t * vam)
17130 {
17131   return 0;
17132 }
17133
17134 static int
17135 cmd_cmp (void *a1, void *a2)
17136 {
17137   u8 **c1 = a1;
17138   u8 **c2 = a2;
17139
17140   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17141 }
17142
17143 static int
17144 help (vat_main_t * vam)
17145 {
17146   u8 **cmds = 0;
17147   u8 *name = 0;
17148   hash_pair_t *p;
17149   unformat_input_t *i = vam->input;
17150   int j;
17151
17152   if (unformat (i, "%s", &name))
17153     {
17154       uword *hs;
17155
17156       vec_add1 (name, 0);
17157
17158       hs = hash_get_mem (vam->help_by_name, name);
17159       if (hs)
17160         print (vam->ofp, "usage: %s %s", name, hs[0]);
17161       else
17162         print (vam->ofp, "No such msg / command '%s'", name);
17163       vec_free (name);
17164       return 0;
17165     }
17166
17167   print (vam->ofp, "Help is available for the following:");
17168
17169     /* *INDENT-OFF* */
17170     hash_foreach_pair (p, vam->function_by_name,
17171     ({
17172       vec_add1 (cmds, (u8 *)(p->key));
17173     }));
17174     /* *INDENT-ON* */
17175
17176   vec_sort_with_function (cmds, cmd_cmp);
17177
17178   for (j = 0; j < vec_len (cmds); j++)
17179     print (vam->ofp, "%s", cmds[j]);
17180
17181   vec_free (cmds);
17182   return 0;
17183 }
17184
17185 static int
17186 set (vat_main_t * vam)
17187 {
17188   u8 *name = 0, *value = 0;
17189   unformat_input_t *i = vam->input;
17190
17191   if (unformat (i, "%s", &name))
17192     {
17193       /* The input buffer is a vector, not a string. */
17194       value = vec_dup (i->buffer);
17195       vec_delete (value, i->index, 0);
17196       /* Almost certainly has a trailing newline */
17197       if (value[vec_len (value) - 1] == '\n')
17198         value[vec_len (value) - 1] = 0;
17199       /* Make sure it's a proper string, one way or the other */
17200       vec_add1 (value, 0);
17201       (void) clib_macro_set_value (&vam->macro_main,
17202                                    (char *) name, (char *) value);
17203     }
17204   else
17205     errmsg ("usage: set <name> <value>");
17206
17207   vec_free (name);
17208   vec_free (value);
17209   return 0;
17210 }
17211
17212 static int
17213 unset (vat_main_t * vam)
17214 {
17215   u8 *name = 0;
17216
17217   if (unformat (vam->input, "%s", &name))
17218     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17219       errmsg ("unset: %s wasn't set", name);
17220   vec_free (name);
17221   return 0;
17222 }
17223
17224 typedef struct
17225 {
17226   u8 *name;
17227   u8 *value;
17228 } macro_sort_t;
17229
17230
17231 static int
17232 macro_sort_cmp (void *a1, void *a2)
17233 {
17234   macro_sort_t *s1 = a1;
17235   macro_sort_t *s2 = a2;
17236
17237   return strcmp ((char *) (s1->name), (char *) (s2->name));
17238 }
17239
17240 static int
17241 dump_macro_table (vat_main_t * vam)
17242 {
17243   macro_sort_t *sort_me = 0, *sm;
17244   int i;
17245   hash_pair_t *p;
17246
17247     /* *INDENT-OFF* */
17248     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17249     ({
17250       vec_add2 (sort_me, sm, 1);
17251       sm->name = (u8 *)(p->key);
17252       sm->value = (u8 *) (p->value[0]);
17253     }));
17254     /* *INDENT-ON* */
17255
17256   vec_sort_with_function (sort_me, macro_sort_cmp);
17257
17258   if (vec_len (sort_me))
17259     print (vam->ofp, "%-15s%s", "Name", "Value");
17260   else
17261     print (vam->ofp, "The macro table is empty...");
17262
17263   for (i = 0; i < vec_len (sort_me); i++)
17264     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17265   return 0;
17266 }
17267
17268 static int
17269 dump_node_table (vat_main_t * vam)
17270 {
17271   int i, j;
17272   vlib_node_t *node, *next_node;
17273
17274   if (vec_len (vam->graph_nodes) == 0)
17275     {
17276       print (vam->ofp, "Node table empty, issue get_node_graph...");
17277       return 0;
17278     }
17279
17280   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17281     {
17282       node = vam->graph_nodes[i];
17283       print (vam->ofp, "[%d] %s", i, node->name);
17284       for (j = 0; j < vec_len (node->next_nodes); j++)
17285         {
17286           if (node->next_nodes[j] != ~0)
17287             {
17288               next_node = vam->graph_nodes[node->next_nodes[j]];
17289               print (vam->ofp, "  [%d] %s", j, next_node->name);
17290             }
17291         }
17292     }
17293   return 0;
17294 }
17295
17296 static int
17297 value_sort_cmp (void *a1, void *a2)
17298 {
17299   name_sort_t *n1 = a1;
17300   name_sort_t *n2 = a2;
17301
17302   if (n1->value < n2->value)
17303     return -1;
17304   if (n1->value > n2->value)
17305     return 1;
17306   return 0;
17307 }
17308
17309
17310 static int
17311 dump_msg_api_table (vat_main_t * vam)
17312 {
17313   api_main_t *am = &api_main;
17314   name_sort_t *nses = 0, *ns;
17315   hash_pair_t *hp;
17316   int i;
17317
17318   /* *INDENT-OFF* */
17319   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17320   ({
17321     vec_add2 (nses, ns, 1);
17322     ns->name = (u8 *)(hp->key);
17323     ns->value = (u32) hp->value[0];
17324   }));
17325   /* *INDENT-ON* */
17326
17327   vec_sort_with_function (nses, value_sort_cmp);
17328
17329   for (i = 0; i < vec_len (nses); i++)
17330     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17331   vec_free (nses);
17332   return 0;
17333 }
17334
17335 static int
17336 get_msg_id (vat_main_t * vam)
17337 {
17338   u8 *name_and_crc;
17339   u32 message_index;
17340
17341   if (unformat (vam->input, "%s", &name_and_crc))
17342     {
17343       message_index = vl_api_get_msg_index (name_and_crc);
17344       if (message_index == ~0)
17345         {
17346           print (vam->ofp, " '%s' not found", name_and_crc);
17347           return 0;
17348         }
17349       print (vam->ofp, " '%s' has message index %d",
17350              name_and_crc, message_index);
17351       return 0;
17352     }
17353   errmsg ("name_and_crc required...");
17354   return 0;
17355 }
17356
17357 static int
17358 search_node_table (vat_main_t * vam)
17359 {
17360   unformat_input_t *line_input = vam->input;
17361   u8 *node_to_find;
17362   int j;
17363   vlib_node_t *node, *next_node;
17364   uword *p;
17365
17366   if (vam->graph_node_index_by_name == 0)
17367     {
17368       print (vam->ofp, "Node table empty, issue get_node_graph...");
17369       return 0;
17370     }
17371
17372   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17373     {
17374       if (unformat (line_input, "%s", &node_to_find))
17375         {
17376           vec_add1 (node_to_find, 0);
17377           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17378           if (p == 0)
17379             {
17380               print (vam->ofp, "%s not found...", node_to_find);
17381               goto out;
17382             }
17383           node = vam->graph_nodes[p[0]];
17384           print (vam->ofp, "[%d] %s", p[0], node->name);
17385           for (j = 0; j < vec_len (node->next_nodes); j++)
17386             {
17387               if (node->next_nodes[j] != ~0)
17388                 {
17389                   next_node = vam->graph_nodes[node->next_nodes[j]];
17390                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17391                 }
17392             }
17393         }
17394
17395       else
17396         {
17397           clib_warning ("parse error '%U'", format_unformat_error,
17398                         line_input);
17399           return -99;
17400         }
17401
17402     out:
17403       vec_free (node_to_find);
17404
17405     }
17406
17407   return 0;
17408 }
17409
17410
17411 static int
17412 script (vat_main_t * vam)
17413 {
17414 #if (VPP_API_TEST_BUILTIN==0)
17415   u8 *s = 0;
17416   char *save_current_file;
17417   unformat_input_t save_input;
17418   jmp_buf save_jump_buf;
17419   u32 save_line_number;
17420
17421   FILE *new_fp, *save_ifp;
17422
17423   if (unformat (vam->input, "%s", &s))
17424     {
17425       new_fp = fopen ((char *) s, "r");
17426       if (new_fp == 0)
17427         {
17428           errmsg ("Couldn't open script file %s", s);
17429           vec_free (s);
17430           return -99;
17431         }
17432     }
17433   else
17434     {
17435       errmsg ("Missing script name");
17436       return -99;
17437     }
17438
17439   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17440   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17441   save_ifp = vam->ifp;
17442   save_line_number = vam->input_line_number;
17443   save_current_file = (char *) vam->current_file;
17444
17445   vam->input_line_number = 0;
17446   vam->ifp = new_fp;
17447   vam->current_file = s;
17448   do_one_file (vam);
17449
17450   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17451   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17452   vam->ifp = save_ifp;
17453   vam->input_line_number = save_line_number;
17454   vam->current_file = (u8 *) save_current_file;
17455   vec_free (s);
17456
17457   return 0;
17458 #else
17459   clib_warning ("use the exec command...");
17460   return -99;
17461 #endif
17462 }
17463
17464 static int
17465 echo (vat_main_t * vam)
17466 {
17467   print (vam->ofp, "%v", vam->input->buffer);
17468   return 0;
17469 }
17470
17471 /* List of API message constructors, CLI names map to api_xxx */
17472 #define foreach_vpe_api_msg                                             \
17473 _(create_loopback,"[mac <mac-addr>]")                                   \
17474 _(sw_interface_dump,"")                                                 \
17475 _(sw_interface_set_flags,                                               \
17476   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17477 _(sw_interface_add_del_address,                                         \
17478   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17479 _(sw_interface_set_table,                                               \
17480   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17481 _(sw_interface_set_mpls_enable,                                         \
17482   "<intfc> | sw_if_index [disable | dis]")                              \
17483 _(sw_interface_set_vpath,                                               \
17484   "<intfc> | sw_if_index <id> enable | disable")                        \
17485 _(sw_interface_set_vxlan_bypass,                                        \
17486   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17487 _(sw_interface_set_l2_xconnect,                                         \
17488   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17489   "enable | disable")                                                   \
17490 _(sw_interface_set_l2_bridge,                                           \
17491   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17492   "[shg <split-horizon-group>] [bvi]\n"                                 \
17493   "enable | disable")                                                   \
17494 _(bridge_domain_add_del,                                                \
17495   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17496 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17497 _(l2fib_add_del,                                                        \
17498   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17499 _(l2_flags,                                                             \
17500   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17501 _(bridge_flags,                                                         \
17502   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17503 _(tap_connect,                                                          \
17504   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17505 _(tap_modify,                                                           \
17506   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17507 _(tap_delete,                                                           \
17508   "<vpp-if-name> | sw_if_index <id>")                                   \
17509 _(sw_interface_tap_dump, "")                                            \
17510 _(ip_add_del_route,                                                     \
17511   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17512   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17513   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17514   "[multipath] [count <n>]")                                            \
17515 _(mpls_route_add_del,                                                   \
17516   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17517   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17518   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17519   "[multipath] [count <n>]")                                            \
17520 _(mpls_ip_bind_unbind,                                                  \
17521   "<label> <addr/len>")                                                 \
17522 _(mpls_tunnel_add_del,                                                  \
17523   " via <addr> [table-id <n>]\n"                                        \
17524   "sw_if_index <id>] [l2]  [del]")                                      \
17525 _(proxy_arp_add_del,                                                    \
17526   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17527 _(proxy_arp_intfc_enable_disable,                                       \
17528   "<intfc> | sw_if_index <id> enable | disable")                        \
17529 _(sw_interface_set_unnumbered,                                          \
17530   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17531 _(ip_neighbor_add_del,                                                  \
17532   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17533   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17534 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17535 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17536 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17537   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17538   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17539   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17540 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17541 _(reset_fib, "vrf <n> [ipv6]")                                          \
17542 _(dhcp_proxy_config,                                                    \
17543   "svr <v46-address> src <v46-address>\n"                               \
17544    "insert-cid <n> [del]")                                              \
17545 _(dhcp_proxy_config_2,                                                  \
17546   "svr <v46-address> src <v46-address>\n"                               \
17547    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17548 _(dhcp_proxy_set_vss,                                                   \
17549   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17550 _(dhcp_client_config,                                                   \
17551   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17552 _(set_ip_flow_hash,                                                     \
17553   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17554 _(sw_interface_ip6_enable_disable,                                      \
17555   "<intfc> | sw_if_index <id> enable | disable")                        \
17556 _(sw_interface_ip6_set_link_local_address,                              \
17557   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17558 _(sw_interface_ip6nd_ra_prefix,                                         \
17559   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17560   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17561   "[nolink] [isno]")                                                    \
17562 _(sw_interface_ip6nd_ra_config,                                         \
17563   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17564   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17565   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17566 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17567 _(l2_patch_add_del,                                                     \
17568   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17569   "enable | disable")                                                   \
17570 _(sr_tunnel_add_del,                                                    \
17571   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17572   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17573   "[policy <policy_name>]")                                             \
17574 _(sr_policy_add_del,                                                    \
17575   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17576 _(sr_multicast_map_add_del,                                             \
17577   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17578 _(classify_add_del_table,                                               \
17579   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17580   " [del] [del-chain] mask <mask-value>\n"                              \
17581   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17582   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17583 _(classify_add_del_session,                                             \
17584   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17585   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17586   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17587   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17588 _(classify_set_interface_ip_table,                                      \
17589   "<intfc> | sw_if_index <nn> table <nn>")                              \
17590 _(classify_set_interface_l2_tables,                                     \
17591   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17592   "  [other-table <nn>]")                                               \
17593 _(get_node_index, "node <node-name")                                    \
17594 _(add_node_next, "node <node-name> next <next-node-name>")              \
17595 _(l2tpv3_create_tunnel,                                                 \
17596   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17597   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17598   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17599 _(l2tpv3_set_tunnel_cookies,                                            \
17600   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17601   "[new_remote_cookie <nn>]\n")                                         \
17602 _(l2tpv3_interface_enable_disable,                                      \
17603   "<intfc> | sw_if_index <nn> enable | disable")                        \
17604 _(l2tpv3_set_lookup_key,                                                \
17605   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17606 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17607 _(vxlan_add_del_tunnel,                                                 \
17608   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17609   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17610   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17611 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17612 _(gre_add_del_tunnel,                                                   \
17613   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17614 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17615 _(l2_fib_clear_table, "")                                               \
17616 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17617 _(l2_interface_vlan_tag_rewrite,                                        \
17618   "<intfc> | sw_if_index <nn> \n"                                       \
17619   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17620   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17621 _(create_vhost_user_if,                                                 \
17622         "socket <filename> [server] [renumber <dev_instance>] "         \
17623         "[mac <mac_address>]")                                          \
17624 _(modify_vhost_user_if,                                                 \
17625         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17626         "[server] [renumber <dev_instance>]")                           \
17627 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17628 _(sw_interface_vhost_user_dump, "")                                     \
17629 _(show_version, "")                                                     \
17630 _(vxlan_gpe_add_del_tunnel,                                             \
17631   "local <addr> remote <addr> vni <nn>\n"                               \
17632     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17633   "[next-ethernet] [next-nsh]\n")                                       \
17634 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17635 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17636 _(interface_name_renumber,                                              \
17637   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17638 _(input_acl_set_interface,                                              \
17639   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17640   "  [l2-table <nn>] [del]")                                            \
17641 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17642 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17643 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17644 _(ip_dump, "ipv4 | ipv6")                                               \
17645 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17646 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17647   "  spid_id <n> ")                                                     \
17648 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17649   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17650   "  integ_alg <alg> integ_key <hex>")                                  \
17651 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17652   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17653   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17654   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17655 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17656 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17657 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17658   "(auth_data 0x<data> | auth_data <data>)")                            \
17659 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17660   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17661 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17662   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17663   "(local|remote)")                                                     \
17664 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17665 _(delete_loopback,"sw_if_index <nn>")                                   \
17666 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17667 _(map_add_domain,                                                       \
17668   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17669   "ip6-src <ip6addr> "                                                  \
17670   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17671 _(map_del_domain, "index <n>")                                          \
17672 _(map_add_del_rule,                                                     \
17673   "index <n> psid <n> dst <ip6addr> [del]")                             \
17674 _(map_domain_dump, "")                                                  \
17675 _(map_rule_dump, "index <map-domain>")                                  \
17676 _(want_interface_events,  "enable|disable")                             \
17677 _(want_stats,"enable|disable")                                          \
17678 _(get_first_msg_id, "client <name>")                                    \
17679 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17680 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17681   "fib-id <nn> [ip4][ip6][default]")                                    \
17682 _(get_node_graph, " ")                                                  \
17683 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17684 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17685 _(ioam_disable, "")                                                     \
17686 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17687                             " sw_if_index <sw_if_index> p <priority> "  \
17688                             "w <weight>] [del]")                        \
17689 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17690                         "iface <intf> | sw_if_index <sw_if_index> "     \
17691                         "p <priority> w <weight> [del]")                \
17692 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17693                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17694                          "locator-set <locator_name> [del]"             \
17695                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17696 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
17697   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
17698 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17699 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17700 _(lisp_gpe_enable_disable, "enable|disable")                            \
17701 _(lisp_enable_disable, "enable|disable")                                \
17702 _(lisp_map_register_enable_disable, "enable|disable")                   \
17703 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17704 _(lisp_gpe_add_del_iface, "up|down")                                    \
17705 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17706                                "[seid <seid>] "                         \
17707                                "rloc <locator> p <prio> "               \
17708                                "w <weight> [rloc <loc> ... ] "          \
17709                                "action <action> [del-all]")             \
17710 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17711                           "<local-eid>")                                \
17712 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17713 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17714 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17715 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17716 _(lisp_locator_set_dump, "[local | remote]")                            \
17717 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17718 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17719                        "[local] | [remote]")                            \
17720 _(lisp_eid_table_vni_dump, "")                                          \
17721 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17722 _(lisp_map_resolver_dump, "")                                           \
17723 _(lisp_map_server_dump, "")                                             \
17724 _(lisp_adjacencies_get, "vni <vni>")                                    \
17725 _(show_lisp_rloc_probe_state, "")                                       \
17726 _(show_lisp_map_register_state, "")                                     \
17727 _(show_lisp_status, "")                                                 \
17728 _(lisp_get_map_request_itr_rlocs, "")                                   \
17729 _(show_lisp_pitr, "")                                                   \
17730 _(show_lisp_map_request_mode, "")                                       \
17731 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17732 _(af_packet_delete, "name <host interface name>")                       \
17733 _(policer_add_del, "name <policer name> <params> [del]")                \
17734 _(policer_dump, "[name <policer name>]")                                \
17735 _(policer_classify_set_interface,                                       \
17736   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17737   "  [l2-table <nn>] [del]")                                            \
17738 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17739 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17740     "[master|slave]")                                                   \
17741 _(netmap_delete, "name <interface name>")                               \
17742 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17743 _(mpls_fib_dump, "")                                                    \
17744 _(classify_table_ids, "")                                               \
17745 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17746 _(classify_table_info, "table_id <nn>")                                 \
17747 _(classify_session_dump, "table_id <nn>")                               \
17748 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17749     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17750     "[template_interval <nn>] [udp_checksum]")                          \
17751 _(ipfix_exporter_dump, "")                                              \
17752 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17753 _(ipfix_classify_stream_dump, "")                                       \
17754 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17755 _(ipfix_classify_table_dump, "")                                        \
17756 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17757 _(sw_interface_span_dump, "")                                           \
17758 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17759 _(pg_create_interface, "if_id <nn>")                                    \
17760 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17761 _(pg_enable_disable, "[stream <id>] disable")                           \
17762 _(ip_source_and_port_range_check_add_del,                               \
17763   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17764 _(ip_source_and_port_range_check_interface_add_del,                     \
17765   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17766   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17767 _(ipsec_gre_add_del_tunnel,                                             \
17768   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17769 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17770 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17771 _(l2_interface_pbb_tag_rewrite,                                         \
17772   "<intfc> | sw_if_index <nn> \n"                                       \
17773   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17774   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17775 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17776 _(flow_classify_set_interface,                                          \
17777   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17778 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17779 _(ip_fib_dump, "")                                                      \
17780 _(ip6_fib_dump, "")                                                     \
17781 _(feature_enable_disable, "arc_name <arc_name> "                        \
17782   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17783 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17784 "[disable]")                                                            \
17785 _(l2_xconnect_dump, "")                                                 \
17786 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17787 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17788 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17789
17790 #if DPDK > 0
17791 #define foreach_vpe_dpdk_api_msg                                        \
17792 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17793   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17794   "profile <profile-id>\n")                                             \
17795 _(sw_interface_set_dpdk_hqos_subport,                                   \
17796   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17797   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17798 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17799   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17800 #endif
17801
17802 /* List of command functions, CLI names map directly to functions */
17803 #define foreach_cli_function                                    \
17804 _(comment, "usage: comment <ignore-rest-of-line>")              \
17805 _(dump_interface_table, "usage: dump_interface_table")          \
17806 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17807 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17808 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17809 _(dump_stats_table, "usage: dump_stats_table")                  \
17810 _(dump_macro_table, "usage: dump_macro_table ")                 \
17811 _(dump_node_table, "usage: dump_node_table")                    \
17812 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17813 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17814 _(echo, "usage: echo <message>")                                \
17815 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17816 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17817 _(help, "usage: help")                                          \
17818 _(q, "usage: quit")                                             \
17819 _(quit, "usage: quit")                                          \
17820 _(search_node_table, "usage: search_node_table <name>...")      \
17821 _(set, "usage: set <variable-name> <value>")                    \
17822 _(script, "usage: script <file-name>")                          \
17823 _(unset, "usage: unset <variable-name>")
17824
17825 #define _(N,n)                                  \
17826     static void vl_api_##n##_t_handler_uni      \
17827     (vl_api_##n##_t * mp)                       \
17828     {                                           \
17829         vat_main_t * vam = &vat_main;           \
17830         if (vam->json_output) {                 \
17831             vl_api_##n##_t_handler_json(mp);    \
17832         } else {                                \
17833             vl_api_##n##_t_handler(mp);         \
17834         }                                       \
17835     }
17836 foreach_vpe_api_reply_msg;
17837 #undef _
17838
17839 #if DPDK > 0
17840 #define _(N,n)                                  \
17841     static void vl_api_##n##_t_handler_uni      \
17842     (vl_api_##n##_t * mp)                       \
17843     {                                           \
17844         vat_main_t * vam = &vat_main;           \
17845         if (vam->json_output) {                 \
17846             vl_api_##n##_t_handler_json(mp);    \
17847         } else {                                \
17848             vl_api_##n##_t_handler(mp);         \
17849         }                                       \
17850     }
17851 foreach_vpe_dpdk_api_reply_msg;
17852 #undef _
17853 #endif
17854
17855 void
17856 vat_api_hookup (vat_main_t * vam)
17857 {
17858 #define _(N,n)                                                  \
17859     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17860                            vl_api_##n##_t_handler_uni,          \
17861                            vl_noop_handler,                     \
17862                            vl_api_##n##_t_endian,               \
17863                            vl_api_##n##_t_print,                \
17864                            sizeof(vl_api_##n##_t), 1);
17865   foreach_vpe_api_reply_msg;
17866 #undef _
17867
17868 #if DPDK > 0
17869 #define _(N,n)                                                  \
17870     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17871                            vl_api_##n##_t_handler_uni,          \
17872                            vl_noop_handler,                     \
17873                            vl_api_##n##_t_endian,               \
17874                            vl_api_##n##_t_print,                \
17875                            sizeof(vl_api_##n##_t), 1);
17876   foreach_vpe_dpdk_api_reply_msg;
17877 #undef _
17878 #endif
17879
17880 #if (VPP_API_TEST_BUILTIN==0)
17881   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17882 #endif
17883
17884   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17885
17886   vam->function_by_name = hash_create_string (0, sizeof (uword));
17887
17888   vam->help_by_name = hash_create_string (0, sizeof (uword));
17889
17890   /* API messages we can send */
17891 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17892   foreach_vpe_api_msg;
17893 #undef _
17894 #if DPDK >0
17895 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17896   foreach_vpe_dpdk_api_msg;
17897 #undef _
17898 #endif
17899
17900   /* Help strings */
17901 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17902   foreach_vpe_api_msg;
17903 #undef _
17904 #if DPDK >0
17905 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17906   foreach_vpe_dpdk_api_msg;
17907 #undef _
17908 #endif
17909
17910   /* CLI functions */
17911 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17912   foreach_cli_function;
17913 #undef _
17914
17915   /* Help strings */
17916 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17917   foreach_cli_function;
17918 #undef _
17919 }
17920
17921 /*
17922  * fd.io coding-style-patch-verification: ON
17923  *
17924  * Local Variables:
17925  * eval: (c-set-style "gnu")
17926  * End:
17927  */