Support IETF routing Yang models (VPP-503).
[vpp.git] / vpp-api-test / 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 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53
54 #include "vat/json_format.h"
55
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp-api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp-api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp-api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 uword
75 unformat_sw_if_index (unformat_input_t * input, va_list * args)
76 {
77   vat_main_t *vam = va_arg (*args, vat_main_t *);
78   u32 *result = va_arg (*args, u32 *);
79   u8 *if_name;
80   uword *p;
81
82   if (!unformat (input, "%s", &if_name))
83     return 0;
84
85   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
86   if (p == 0)
87     return 0;
88   *result = p[0];
89   return 1;
90 }
91
92 /* Parse an IP4 address %d.%d.%d.%d. */
93 uword
94 unformat_ip4_address (unformat_input_t * input, va_list * args)
95 {
96   u8 *result = va_arg (*args, u8 *);
97   unsigned a[4];
98
99   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
100     return 0;
101
102   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
103     return 0;
104
105   result[0] = a[0];
106   result[1] = a[1];
107   result[2] = a[2];
108   result[3] = a[3];
109
110   return 1;
111 }
112
113
114 uword
115 unformat_ethernet_address (unformat_input_t * input, va_list * args)
116 {
117   u8 *result = va_arg (*args, u8 *);
118   u32 i, a[6];
119
120   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
121                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
122     return 0;
123
124   /* Check range. */
125   for (i = 0; i < 6; i++)
126     if (a[i] >= (1 << 8))
127       return 0;
128
129   for (i = 0; i < 6; i++)
130     result[i] = a[i];
131
132   return 1;
133 }
134
135 /* Returns ethernet type as an int in host byte order. */
136 uword
137 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
138                                         va_list * args)
139 {
140   u16 *result = va_arg (*args, u16 *);
141   int type;
142
143   /* Numeric type. */
144   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
145     {
146       if (type >= (1 << 16))
147         return 0;
148       *result = type;
149       return 1;
150     }
151   return 0;
152 }
153
154 /* Parse an IP6 address. */
155 uword
156 unformat_ip6_address (unformat_input_t * input, va_list * args)
157 {
158   ip6_address_t *result = va_arg (*args, ip6_address_t *);
159   u16 hex_quads[8];
160   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
161   uword c, n_colon, double_colon_index;
162
163   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
164   double_colon_index = ARRAY_LEN (hex_quads);
165   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
166     {
167       hex_digit = 16;
168       if (c >= '0' && c <= '9')
169         hex_digit = c - '0';
170       else if (c >= 'a' && c <= 'f')
171         hex_digit = c + 10 - 'a';
172       else if (c >= 'A' && c <= 'F')
173         hex_digit = c + 10 - 'A';
174       else if (c == ':' && n_colon < 2)
175         n_colon++;
176       else
177         {
178           unformat_put_input (input);
179           break;
180         }
181
182       /* Too many hex quads. */
183       if (n_hex_quads >= ARRAY_LEN (hex_quads))
184         return 0;
185
186       if (hex_digit < 16)
187         {
188           hex_quad = (hex_quad << 4) | hex_digit;
189
190           /* Hex quad must fit in 16 bits. */
191           if (n_hex_digits >= 4)
192             return 0;
193
194           n_colon = 0;
195           n_hex_digits++;
196         }
197
198       /* Save position of :: */
199       if (n_colon == 2)
200         {
201           /* More than one :: ? */
202           if (double_colon_index < ARRAY_LEN (hex_quads))
203             return 0;
204           double_colon_index = n_hex_quads;
205         }
206
207       if (n_colon > 0 && n_hex_digits > 0)
208         {
209           hex_quads[n_hex_quads++] = hex_quad;
210           hex_quad = 0;
211           n_hex_digits = 0;
212         }
213     }
214
215   if (n_hex_digits > 0)
216     hex_quads[n_hex_quads++] = hex_quad;
217
218   {
219     word i;
220
221     /* Expand :: to appropriate number of zero hex quads. */
222     if (double_colon_index < ARRAY_LEN (hex_quads))
223       {
224         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
225
226         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
227           hex_quads[n_zero + i] = hex_quads[i];
228
229         for (i = 0; i < n_zero; i++)
230           hex_quads[double_colon_index + i] = 0;
231
232         n_hex_quads = ARRAY_LEN (hex_quads);
233       }
234
235     /* Too few hex quads given. */
236     if (n_hex_quads < ARRAY_LEN (hex_quads))
237       return 0;
238
239     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
240       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
241
242     return 1;
243   }
244 }
245
246 uword
247 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
248 {
249 #if DPDK > 0
250   u32 *r = va_arg (*args, u32 *);
251
252   if (0);
253 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254   foreach_ipsec_policy_action
255 #undef _
256     else
257     return 0;
258   return 1;
259 #else
260   return 0;
261 #endif
262 }
263
264 uword
265 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
266 {
267 #if DPDK > 0
268   u32 *r = va_arg (*args, u32 *);
269
270   if (0);
271 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
272   foreach_ipsec_crypto_alg
273 #undef _
274     else
275     return 0;
276   return 1;
277 #else
278   return 0;
279 #endif
280 }
281
282 u8 *
283 format_ipsec_crypto_alg (u8 * s, va_list * args)
284 {
285 #if DPDK > 0
286   u32 i = va_arg (*args, u32);
287   u8 *t = 0;
288
289   switch (i)
290     {
291 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
292       foreach_ipsec_crypto_alg
293 #undef _
294     default:
295       return format (s, "unknown");
296     }
297   return format (s, "%s", t);
298 #else
299   return format (s, "Unimplemented");
300 #endif
301 }
302
303 uword
304 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
305 {
306 #if DPDK > 0
307   u32 *r = va_arg (*args, u32 *);
308
309   if (0);
310 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
311   foreach_ipsec_integ_alg
312 #undef _
313     else
314     return 0;
315   return 1;
316 #else
317   return 0;
318 #endif
319 }
320
321 u8 *
322 format_ipsec_integ_alg (u8 * s, va_list * args)
323 {
324 #if DPDK > 0
325   u32 i = va_arg (*args, u32);
326   u8 *t = 0;
327
328   switch (i)
329     {
330 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
331       foreach_ipsec_integ_alg
332 #undef _
333     default:
334       return format (s, "unknown");
335     }
336   return format (s, "%s", t);
337 #else
338   return format (s, "Unsupported");
339 #endif
340 }
341
342 uword
343 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
344 {
345 #if DPDK > 0
346   u32 *r = va_arg (*args, u32 *);
347
348   if (0);
349 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
350   foreach_ikev2_auth_method
351 #undef _
352     else
353     return 0;
354   return 1;
355 #else
356   return 0;
357 #endif
358 }
359
360 uword
361 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
362 {
363 #if DPDK > 0
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
368   foreach_ikev2_id_type
369 #undef _
370     else
371     return 0;
372   return 1;
373 #else
374   return 0;
375 #endif
376 }
377
378 uword
379 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
380 {
381   u8 *r = va_arg (*args, u8 *);
382
383   if (unformat (input, "kbps"))
384     *r = SSE2_QOS_RATE_KBPS;
385   else if (unformat (input, "pps"))
386     *r = SSE2_QOS_RATE_PPS;
387   else
388     return 0;
389   return 1;
390 }
391
392 uword
393 unformat_policer_round_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "closest"))
398     *r = SSE2_QOS_ROUND_TO_CLOSEST;
399   else if (unformat (input, "up"))
400     *r = SSE2_QOS_ROUND_TO_UP;
401   else if (unformat (input, "down"))
402     *r = SSE2_QOS_ROUND_TO_DOWN;
403   else
404     return 0;
405   return 1;
406 }
407
408 uword
409 unformat_policer_type (unformat_input_t * input, va_list * args)
410 {
411   u8 *r = va_arg (*args, u8 *);
412
413   if (unformat (input, "1r2c"))
414     *r = SSE2_QOS_POLICER_TYPE_1R2C;
415   else if (unformat (input, "1r3c"))
416     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
417   else if (unformat (input, "2r3c-2698"))
418     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
419   else if (unformat (input, "2r3c-4115"))
420     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
421   else if (unformat (input, "2r3c-mef5cf1"))
422     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
423   else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_dscp (unformat_input_t * input, va_list * va)
430 {
431   u8 *r = va_arg (*va, u8 *);
432
433   if (0);
434 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
435   foreach_vnet_dscp
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_policer_action_type (unformat_input_t * input, va_list * va)
444 {
445   sse2_qos_pol_action_params_st *a
446     = va_arg (*va, sse2_qos_pol_action_params_st *);
447
448   if (unformat (input, "drop"))
449     a->action_type = SSE2_QOS_ACTION_DROP;
450   else if (unformat (input, "transmit"))
451     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
452   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
453     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
454   else
455     return 0;
456   return 1;
457 }
458
459 uword
460 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
461 {
462   u32 *r = va_arg (*va, u32 *);
463   u32 tid;
464
465   if (unformat (input, "ip4"))
466     tid = POLICER_CLASSIFY_TABLE_IP4;
467   else if (unformat (input, "ip6"))
468     tid = POLICER_CLASSIFY_TABLE_IP6;
469   else if (unformat (input, "l2"))
470     tid = POLICER_CLASSIFY_TABLE_L2;
471   else
472     return 0;
473
474   *r = tid;
475   return 1;
476 }
477
478 uword
479 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
480 {
481   u32 *r = va_arg (*va, u32 *);
482   u32 tid;
483
484   if (unformat (input, "ip4"))
485     tid = FLOW_CLASSIFY_TABLE_IP4;
486   else if (unformat (input, "ip6"))
487     tid = FLOW_CLASSIFY_TABLE_IP6;
488   else
489     return 0;
490
491   *r = tid;
492   return 1;
493 }
494
495 u8 *
496 format_ip4_address (u8 * s, va_list * args)
497 {
498   u8 *a = va_arg (*args, u8 *);
499   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
500 }
501
502 u8 *
503 format_ip6_address (u8 * s, va_list * args)
504 {
505   ip6_address_t *a = va_arg (*args, ip6_address_t *);
506   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
507
508   i_max_n_zero = ARRAY_LEN (a->as_u16);
509   max_n_zeros = 0;
510   i_first_zero = i_max_n_zero;
511   n_zeros = 0;
512   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
513     {
514       u32 is_zero = a->as_u16[i] == 0;
515       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
516         {
517           i_first_zero = i;
518           n_zeros = 0;
519         }
520       n_zeros += is_zero;
521       if ((!is_zero && n_zeros > max_n_zeros)
522           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
523         {
524           i_max_n_zero = i_first_zero;
525           max_n_zeros = n_zeros;
526           i_first_zero = ARRAY_LEN (a->as_u16);
527           n_zeros = 0;
528         }
529     }
530
531   last_double_colon = 0;
532   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
533     {
534       if (i == i_max_n_zero && max_n_zeros > 1)
535         {
536           s = format (s, "::");
537           i += max_n_zeros - 1;
538           last_double_colon = 1;
539         }
540       else
541         {
542           s = format (s, "%s%x",
543                       (last_double_colon || i == 0) ? "" : ":",
544                       clib_net_to_host_u16 (a->as_u16[i]));
545           last_double_colon = 0;
546         }
547     }
548
549   return s;
550 }
551
552 /* Format an IP46 address. */
553 u8 *
554 format_ip46_address (u8 * s, va_list * args)
555 {
556   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
557   ip46_type_t type = va_arg (*args, ip46_type_t);
558   int is_ip4 = 1;
559
560   switch (type)
561     {
562     case IP46_TYPE_ANY:
563       is_ip4 = ip46_address_is_ip4 (ip46);
564       break;
565     case IP46_TYPE_IP4:
566       is_ip4 = 1;
567       break;
568     case IP46_TYPE_IP6:
569       is_ip4 = 0;
570       break;
571     }
572
573   return is_ip4 ?
574     format (s, "%U", format_ip4_address, &ip46->ip4) :
575     format (s, "%U", format_ip6_address, &ip46->ip6);
576 }
577
578 u8 *
579 format_ethernet_address (u8 * s, va_list * args)
580 {
581   u8 *a = va_arg (*args, u8 *);
582
583   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
584                  a[0], a[1], a[2], a[3], a[4], a[5]);
585 }
586
587 void
588 increment_v4_address (ip4_address_t * a)
589 {
590   u32 v;
591
592   v = ntohl (a->as_u32) + 1;
593   a->as_u32 = ntohl (v);
594 }
595
596 void
597 increment_v6_address (ip6_address_t * a)
598 {
599   u64 v0, v1;
600
601   v0 = clib_net_to_host_u64 (a->as_u64[0]);
602   v1 = clib_net_to_host_u64 (a->as_u64[1]);
603
604   v1 += 1;
605   if (v1 == 0)
606     v0 += 1;
607   a->as_u64[0] = clib_net_to_host_u64 (v0);
608   a->as_u64[1] = clib_net_to_host_u64 (v1);
609 }
610
611 void
612 increment_mac_address (u64 * mac)
613 {
614   u64 tmp = *mac;
615
616   tmp = clib_net_to_host_u64 (tmp);
617   tmp += 1 << 16;               /* skip unused (least significant) octets */
618   tmp = clib_host_to_net_u64 (tmp);
619   *mac = tmp;
620 }
621
622 static void vl_api_create_loopback_reply_t_handler
623   (vl_api_create_loopback_reply_t * mp)
624 {
625   vat_main_t *vam = &vat_main;
626   i32 retval = ntohl (mp->retval);
627
628   vam->retval = retval;
629   vam->regenerate_interface_table = 1;
630   vam->sw_if_index = ntohl (mp->sw_if_index);
631   vam->result_ready = 1;
632 }
633
634 static void vl_api_create_loopback_reply_t_handler_json
635   (vl_api_create_loopback_reply_t * mp)
636 {
637   vat_main_t *vam = &vat_main;
638   vat_json_node_t node;
639
640   vat_json_init_object (&node);
641   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
642   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
643
644   vat_json_print (vam->ofp, &node);
645   vat_json_free (&node);
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_af_packet_create_reply_t_handler
651   (vl_api_af_packet_create_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_af_packet_create_reply_t_handler_json
663   (vl_api_af_packet_create_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_vlan_subif_reply_t_handler
680   (vl_api_create_vlan_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_vlan_subif_reply_t_handler_json
692   (vl_api_create_vlan_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_create_subif_reply_t_handler
709   (vl_api_create_subif_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->sw_if_index = ntohl (mp->sw_if_index);
717   vam->result_ready = 1;
718 }
719
720 static void vl_api_create_subif_reply_t_handler_json
721   (vl_api_create_subif_reply_t * mp)
722 {
723   vat_main_t *vam = &vat_main;
724   vat_json_node_t node;
725
726   vat_json_init_object (&node);
727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
729
730   vat_json_print (vam->ofp, &node);
731   vat_json_free (&node);
732
733   vam->retval = ntohl (mp->retval);
734   vam->result_ready = 1;
735 }
736
737 static void vl_api_interface_name_renumber_reply_t_handler
738   (vl_api_interface_name_renumber_reply_t * mp)
739 {
740   vat_main_t *vam = &vat_main;
741   i32 retval = ntohl (mp->retval);
742
743   vam->retval = retval;
744   vam->regenerate_interface_table = 1;
745   vam->result_ready = 1;
746 }
747
748 static void vl_api_interface_name_renumber_reply_t_handler_json
749   (vl_api_interface_name_renumber_reply_t * mp)
750 {
751   vat_main_t *vam = &vat_main;
752   vat_json_node_t node;
753
754   vat_json_init_object (&node);
755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
756
757   vat_json_print (vam->ofp, &node);
758   vat_json_free (&node);
759
760   vam->retval = ntohl (mp->retval);
761   vam->result_ready = 1;
762 }
763
764 /*
765  * Special-case: build the interface table, maintain
766  * the next loopback sw_if_index vbl.
767  */
768 static void vl_api_sw_interface_details_t_handler
769   (vl_api_sw_interface_details_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   u8 *s = format (0, "%s%c", mp->interface_name, 0);
773
774   hash_set_mem (vam->sw_if_index_by_interface_name, s,
775                 ntohl (mp->sw_if_index));
776
777   /* In sub interface case, fill the sub interface table entry */
778   if (mp->sw_if_index != mp->sup_sw_if_index)
779     {
780       sw_interface_subif_t *sub = NULL;
781
782       vec_add2 (vam->sw_if_subif_table, sub, 1);
783
784       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
785       strncpy ((char *) sub->interface_name, (char *) s,
786                vec_len (sub->interface_name));
787       sub->sw_if_index = ntohl (mp->sw_if_index);
788       sub->sub_id = ntohl (mp->sub_id);
789
790       sub->sub_dot1ad = mp->sub_dot1ad;
791       sub->sub_number_of_tags = mp->sub_number_of_tags;
792       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
793       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
794       sub->sub_exact_match = mp->sub_exact_match;
795       sub->sub_default = mp->sub_default;
796       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
797       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
798
799       /* vlan tag rewrite */
800       sub->vtr_op = ntohl (mp->vtr_op);
801       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
802       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
803       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
804     }
805 }
806
807 static void vl_api_sw_interface_details_t_handler_json
808   (vl_api_sw_interface_details_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t *node = NULL;
812
813   if (VAT_JSON_ARRAY != vam->json_tree.type)
814     {
815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
816       vat_json_init_array (&vam->json_tree);
817     }
818   node = vat_json_array_add (&vam->json_tree);
819
820   vat_json_init_object (node);
821   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
822   vat_json_object_add_uint (node, "sup_sw_if_index",
823                             ntohl (mp->sup_sw_if_index));
824   vat_json_object_add_uint (node, "l2_address_length",
825                             ntohl (mp->l2_address_length));
826   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
827                              sizeof (mp->l2_address));
828   vat_json_object_add_string_copy (node, "interface_name",
829                                    mp->interface_name);
830   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
831   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
832   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
833   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
834   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
835   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
836   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
837   vat_json_object_add_uint (node, "sub_number_of_tags",
838                             mp->sub_number_of_tags);
839   vat_json_object_add_uint (node, "sub_outer_vlan_id",
840                             ntohs (mp->sub_outer_vlan_id));
841   vat_json_object_add_uint (node, "sub_inner_vlan_id",
842                             ntohs (mp->sub_inner_vlan_id));
843   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
844   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
845   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
846                             mp->sub_outer_vlan_id_any);
847   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
848                             mp->sub_inner_vlan_id_any);
849   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
850   vat_json_object_add_uint (node, "vtr_push_dot1q",
851                             ntohl (mp->vtr_push_dot1q));
852   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
853   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
854 }
855
856 static void vl_api_sw_interface_set_flags_t_handler
857   (vl_api_sw_interface_set_flags_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   if (vam->interface_event_display)
861     errmsg ("interface flags: sw_if_index %d %s %s\n",
862             ntohl (mp->sw_if_index),
863             mp->admin_up_down ? "admin-up" : "admin-down",
864             mp->link_up_down ? "link-up" : "link-down");
865 }
866
867 static void vl_api_sw_interface_set_flags_t_handler_json
868   (vl_api_sw_interface_set_flags_t * mp)
869 {
870   /* JSON output not supported */
871 }
872
873 static void
874 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   i32 retval = ntohl (mp->retval);
878
879   vam->retval = retval;
880   vam->shmem_result = (u8 *) mp->reply_in_shmem;
881   vam->result_ready = 1;
882 }
883
884 static void
885 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   vat_json_node_t node;
889   api_main_t *am = &api_main;
890   void *oldheap;
891   u8 *reply;
892
893   vat_json_init_object (&node);
894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
895   vat_json_object_add_uint (&node, "reply_in_shmem",
896                             ntohl (mp->reply_in_shmem));
897   /* Toss the shared-memory original... */
898   pthread_mutex_lock (&am->vlib_rp->mutex);
899   oldheap = svm_push_data_heap (am->vlib_rp);
900
901   reply = (u8 *) (mp->reply_in_shmem);
902   vec_free (reply);
903
904   svm_pop_heap (oldheap);
905   pthread_mutex_unlock (&am->vlib_rp->mutex);
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 static void
915 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   i32 retval = ntohl (mp->retval);
919
920   vam->retval = retval;
921   vam->cmd_reply = mp->reply;
922   vam->result_ready = 1;
923 }
924
925 static void
926 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_string_copy (&node, "reply", mp->reply);
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_classify_add_del_table_reply_t_handler
943   (vl_api_classify_add_del_table_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947   if (vam->async_mode)
948     {
949       vam->async_errors += (retval < 0);
950     }
951   else
952     {
953       vam->retval = retval;
954       if (retval == 0 &&
955           ((mp->new_table_index != 0xFFFFFFFF) ||
956            (mp->skip_n_vectors != 0xFFFFFFFF) ||
957            (mp->match_n_vectors != 0xFFFFFFFF)))
958         /*
959          * Note: this is just barely thread-safe, depends on
960          * the main thread spinning waiting for an answer...
961          */
962         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
963                 ntohl (mp->new_table_index),
964                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
965       vam->result_ready = 1;
966     }
967 }
968
969 static void vl_api_classify_add_del_table_reply_t_handler_json
970   (vl_api_classify_add_del_table_reply_t * mp)
971 {
972   vat_main_t *vam = &vat_main;
973   vat_json_node_t node;
974
975   vat_json_init_object (&node);
976   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
977   vat_json_object_add_uint (&node, "new_table_index",
978                             ntohl (mp->new_table_index));
979   vat_json_object_add_uint (&node, "skip_n_vectors",
980                             ntohl (mp->skip_n_vectors));
981   vat_json_object_add_uint (&node, "match_n_vectors",
982                             ntohl (mp->match_n_vectors));
983
984   vat_json_print (vam->ofp, &node);
985   vat_json_free (&node);
986
987   vam->retval = ntohl (mp->retval);
988   vam->result_ready = 1;
989 }
990
991 static void vl_api_get_node_index_reply_t_handler
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   i32 retval = ntohl (mp->retval);
996   if (vam->async_mode)
997     {
998       vam->async_errors += (retval < 0);
999     }
1000   else
1001     {
1002       vam->retval = retval;
1003       if (retval == 0)
1004         errmsg ("node index %d\n", ntohl (mp->node_index));
1005       vam->result_ready = 1;
1006     }
1007 }
1008
1009 static void vl_api_get_node_index_reply_t_handler_json
1010   (vl_api_get_node_index_reply_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t node;
1014
1015   vat_json_init_object (&node);
1016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1017   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1018
1019   vat_json_print (vam->ofp, &node);
1020   vat_json_free (&node);
1021
1022   vam->retval = ntohl (mp->retval);
1023   vam->result_ready = 1;
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031   if (vam->async_mode)
1032     {
1033       vam->async_errors += (retval < 0);
1034     }
1035   else
1036     {
1037       vam->retval = retval;
1038       if (retval == 0)
1039         errmsg ("next node index %d\n", ntohl (mp->next_index));
1040       vam->result_ready = 1;
1041     }
1042 }
1043
1044 static void vl_api_get_next_index_reply_t_handler_json
1045   (vl_api_get_next_index_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049
1050   vat_json_init_object (&node);
1051   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1052   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1053
1054   vat_json_print (vam->ofp, &node);
1055   vat_json_free (&node);
1056
1057   vam->retval = ntohl (mp->retval);
1058   vam->result_ready = 1;
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   i32 retval = ntohl (mp->retval);
1066   if (vam->async_mode)
1067     {
1068       vam->async_errors += (retval < 0);
1069     }
1070   else
1071     {
1072       vam->retval = retval;
1073       if (retval == 0)
1074         errmsg ("next index %d\n", ntohl (mp->next_index));
1075       vam->result_ready = 1;
1076     }
1077 }
1078
1079 static void vl_api_add_node_next_reply_t_handler_json
1080   (vl_api_add_node_next_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   vat_json_node_t node;
1084
1085   vat_json_init_object (&node);
1086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1087   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1088
1089   vat_json_print (vam->ofp, &node);
1090   vat_json_free (&node);
1091
1092   vam->retval = ntohl (mp->retval);
1093   vam->result_ready = 1;
1094 }
1095
1096 static void vl_api_show_version_reply_t_handler
1097   (vl_api_show_version_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   i32 retval = ntohl (mp->retval);
1101
1102   if (retval >= 0)
1103     {
1104       errmsg ("        program: %s\n", mp->program);
1105       errmsg ("        version: %s\n", mp->version);
1106       errmsg ("     build date: %s\n", mp->build_date);
1107       errmsg ("build directory: %s\n", mp->build_directory);
1108     }
1109   vam->retval = retval;
1110   vam->result_ready = 1;
1111 }
1112
1113 static void vl_api_show_version_reply_t_handler_json
1114   (vl_api_show_version_reply_t * mp)
1115 {
1116   vat_main_t *vam = &vat_main;
1117   vat_json_node_t node;
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "program", mp->program);
1122   vat_json_object_add_string_copy (&node, "version", mp->version);
1123   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1124   vat_json_object_add_string_copy (&node, "build_directory",
1125                                    mp->build_directory);
1126
1127   vat_json_print (vam->ofp, &node);
1128   vat_json_free (&node);
1129
1130   vam->retval = ntohl (mp->retval);
1131   vam->result_ready = 1;
1132 }
1133
1134 static void
1135 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1136 {
1137   vat_main_t *vam = &vat_main;
1138   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1139           mp->mac_ip ? "mac/ip binding" : "address resolution",
1140           format_ip4_address, &mp->address,
1141           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1142 }
1143
1144 static void
1145 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1146 {
1147   /* JSON output not supported */
1148 }
1149
1150 static void
1151 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip6_address, mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 /*
1167  * Special-case: build the bridge domain table, maintain
1168  * the next bd id vbl.
1169  */
1170 static void vl_api_bridge_domain_details_t_handler
1171   (vl_api_bridge_domain_details_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1175
1176   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1177            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1178
1179   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1180            ntohl (mp->bd_id), mp->learn, mp->forward,
1181            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1182
1183   if (n_sw_ifs)
1184     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1185              "Interface Name");
1186 }
1187
1188 static void vl_api_bridge_domain_details_t_handler_json
1189   (vl_api_bridge_domain_details_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   vat_json_node_t *node, *array = NULL;
1193
1194   if (VAT_JSON_ARRAY != vam->json_tree.type)
1195     {
1196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1197       vat_json_init_array (&vam->json_tree);
1198     }
1199   node = vat_json_array_add (&vam->json_tree);
1200
1201   vat_json_init_object (node);
1202   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1203   vat_json_object_add_uint (node, "flood", mp->flood);
1204   vat_json_object_add_uint (node, "forward", mp->forward);
1205   vat_json_object_add_uint (node, "learn", mp->learn);
1206   vat_json_object_add_uint (node, "bvi_sw_if_index",
1207                             ntohl (mp->bvi_sw_if_index));
1208   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1209   array = vat_json_object_add (node, "sw_if");
1210   vat_json_init_array (array);
1211 }
1212
1213 /*
1214  * Special-case: build the bridge domain sw if table.
1215  */
1216 static void vl_api_bridge_domain_sw_if_details_t_handler
1217   (vl_api_bridge_domain_sw_if_details_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   hash_pair_t *p;
1221   u8 *sw_if_name = 0;
1222   u32 sw_if_index;
1223
1224   sw_if_index = ntohl (mp->sw_if_index);
1225   /* *INDENT-OFF* */
1226   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1227   ({
1228     if ((u32) p->value[0] == sw_if_index)
1229       {
1230         sw_if_name = (u8 *)(p->key);
1231         break;
1232       }
1233   }));
1234   /* *INDENT-ON* */
1235
1236   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1237            mp->shg, sw_if_name ? (char *) sw_if_name :
1238            "sw_if_index not found!");
1239 }
1240
1241 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1242   (vl_api_bridge_domain_sw_if_details_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t *node = NULL;
1246   uword last_index = 0;
1247
1248   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1249   ASSERT (vec_len (vam->json_tree.array) >= 1);
1250   last_index = vec_len (vam->json_tree.array) - 1;
1251   node = &vam->json_tree.array[last_index];
1252   node = vat_json_object_get_element (node, "sw_if");
1253   ASSERT (NULL != node);
1254   node = vat_json_array_add (node);
1255
1256   vat_json_init_object (node);
1257   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1258   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1259   vat_json_object_add_uint (node, "shg", mp->shg);
1260 }
1261
1262 static void vl_api_control_ping_reply_t_handler
1263   (vl_api_control_ping_reply_t * mp)
1264 {
1265   vat_main_t *vam = &vat_main;
1266   i32 retval = ntohl (mp->retval);
1267   if (vam->async_mode)
1268     {
1269       vam->async_errors += (retval < 0);
1270     }
1271   else
1272     {
1273       vam->retval = retval;
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler_json
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283
1284   if (VAT_JSON_NONE != vam->json_tree.type)
1285     {
1286       vat_json_print (vam->ofp, &vam->json_tree);
1287       vat_json_free (&vam->json_tree);
1288       vam->json_tree.type = VAT_JSON_NONE;
1289     }
1290   else
1291     {
1292       /* just print [] */
1293       vat_json_init_array (&vam->json_tree);
1294       vat_json_print (vam->ofp, &vam->json_tree);
1295       vam->json_tree.type = VAT_JSON_NONE;
1296     }
1297
1298   vam->retval = retval;
1299   vam->result_ready = 1;
1300 }
1301
1302 static void
1303 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   i32 retval = ntohl (mp->retval);
1307   if (vam->async_mode)
1308     {
1309       vam->async_errors += (retval < 0);
1310     }
1311   else
1312     {
1313       vam->retval = retval;
1314       vam->result_ready = 1;
1315     }
1316 }
1317
1318 static void vl_api_l2_flags_reply_t_handler_json
1319   (vl_api_l2_flags_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   vat_json_node_t node;
1323
1324   vat_json_init_object (&node);
1325   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1326   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1327                             ntohl (mp->resulting_feature_bitmap));
1328
1329   vat_json_print (vam->ofp, &node);
1330   vat_json_free (&node);
1331
1332   vam->retval = ntohl (mp->retval);
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_bridge_flags_reply_t_handler
1337   (vl_api_bridge_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   i32 retval = ntohl (mp->retval);
1341   if (vam->async_mode)
1342     {
1343       vam->async_errors += (retval < 0);
1344     }
1345   else
1346     {
1347       vam->retval = retval;
1348       vam->result_ready = 1;
1349     }
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler_json
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   vat_json_node_t node;
1357
1358   vat_json_init_object (&node);
1359   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1360   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1361                             ntohl (mp->resulting_feature_bitmap));
1362
1363   vat_json_print (vam->ofp, &node);
1364   vat_json_free (&node);
1365
1366   vam->retval = ntohl (mp->retval);
1367   vam->result_ready = 1;
1368 }
1369
1370 static void vl_api_tap_connect_reply_t_handler
1371   (vl_api_tap_connect_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   i32 retval = ntohl (mp->retval);
1375   if (vam->async_mode)
1376     {
1377       vam->async_errors += (retval < 0);
1378     }
1379   else
1380     {
1381       vam->retval = retval;
1382       vam->sw_if_index = ntohl (mp->sw_if_index);
1383       vam->result_ready = 1;
1384     }
1385
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler_json
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   vat_json_node_t node;
1393
1394   vat_json_init_object (&node);
1395   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1396   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1397
1398   vat_json_print (vam->ofp, &node);
1399   vat_json_free (&node);
1400
1401   vam->retval = ntohl (mp->retval);
1402   vam->result_ready = 1;
1403
1404 }
1405
1406 static void
1407 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   i32 retval = ntohl (mp->retval);
1411   if (vam->async_mode)
1412     {
1413       vam->async_errors += (retval < 0);
1414     }
1415   else
1416     {
1417       vam->retval = retval;
1418       vam->sw_if_index = ntohl (mp->sw_if_index);
1419       vam->result_ready = 1;
1420     }
1421 }
1422
1423 static void vl_api_tap_modify_reply_t_handler_json
1424   (vl_api_tap_modify_reply_t * mp)
1425 {
1426   vat_main_t *vam = &vat_main;
1427   vat_json_node_t node;
1428
1429   vat_json_init_object (&node);
1430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1431   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1432
1433   vat_json_print (vam->ofp, &node);
1434   vat_json_free (&node);
1435
1436   vam->retval = ntohl (mp->retval);
1437   vam->result_ready = 1;
1438 }
1439
1440 static void
1441 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   i32 retval = ntohl (mp->retval);
1445   if (vam->async_mode)
1446     {
1447       vam->async_errors += (retval < 0);
1448     }
1449   else
1450     {
1451       vam->retval = retval;
1452       vam->result_ready = 1;
1453     }
1454 }
1455
1456 static void vl_api_tap_delete_reply_t_handler_json
1457   (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   vat_json_node_t node;
1461
1462   vat_json_init_object (&node);
1463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1464
1465   vat_json_print (vam->ofp, &node);
1466   vat_json_free (&node);
1467
1468   vam->retval = ntohl (mp->retval);
1469   vam->result_ready = 1;
1470 }
1471
1472 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1473   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   i32 retval = ntohl (mp->retval);
1477   if (vam->async_mode)
1478     {
1479       vam->async_errors += (retval < 0);
1480     }
1481   else
1482     {
1483       vam->retval = retval;
1484       vam->result_ready = 1;
1485     }
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   vat_json_node_t node;
1493
1494   vat_json_init_object (&node);
1495   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1496   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1497                             ntohl (mp->tunnel_sw_if_index));
1498
1499   vat_json_print (vam->ofp, &node);
1500   vat_json_free (&node);
1501
1502   vam->retval = ntohl (mp->retval);
1503   vam->result_ready = 1;
1504 }
1505
1506 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1507   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   i32 retval = ntohl (mp->retval);
1511   if (vam->async_mode)
1512     {
1513       vam->async_errors += (retval < 0);
1514     }
1515   else
1516     {
1517       vam->retval = retval;
1518       vam->sw_if_index = ntohl (mp->sw_if_index);
1519       vam->result_ready = 1;
1520     }
1521 }
1522
1523 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1524   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1525 {
1526   vat_main_t *vam = &vat_main;
1527   vat_json_node_t node;
1528
1529   vat_json_init_object (&node);
1530   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1531   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540
1541 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1542   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   i32 retval = ntohl (mp->retval);
1546   if (vam->async_mode)
1547     {
1548       vam->async_errors += (retval < 0);
1549     }
1550   else
1551     {
1552       vam->retval = retval;
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   vat_json_node_t node;
1562
1563   vat_json_init_object (&node);
1564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1565   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1575   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->sw_if_index = ntohl (mp->sw_if_index);
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1592   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   vat_json_node_t node;
1596
1597   vat_json_init_object (&node);
1598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1599   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_gre_add_del_tunnel_reply_t_handler
1609   (vl_api_gre_add_del_tunnel_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623 }
1624
1625 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1626   (vl_api_gre_add_del_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   vat_json_node_t node;
1630
1631   vat_json_init_object (&node);
1632   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1633   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1634
1635   vat_json_print (vam->ofp, &node);
1636   vat_json_free (&node);
1637
1638   vam->retval = ntohl (mp->retval);
1639   vam->result_ready = 1;
1640 }
1641
1642 static void vl_api_create_vhost_user_if_reply_t_handler
1643   (vl_api_create_vhost_user_if_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   i32 retval = ntohl (mp->retval);
1647   if (vam->async_mode)
1648     {
1649       vam->async_errors += (retval < 0);
1650     }
1651   else
1652     {
1653       vam->retval = retval;
1654       vam->sw_if_index = ntohl (mp->sw_if_index);
1655       vam->result_ready = 1;
1656     }
1657 }
1658
1659 static void vl_api_create_vhost_user_if_reply_t_handler_json
1660   (vl_api_create_vhost_user_if_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   vat_json_node_t node;
1664
1665   vat_json_init_object (&node);
1666   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1667   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1668
1669   vat_json_print (vam->ofp, &node);
1670   vat_json_free (&node);
1671
1672   vam->retval = ntohl (mp->retval);
1673   vam->result_ready = 1;
1674 }
1675
1676 static void vl_api_ip_address_details_t_handler
1677   (vl_api_ip_address_details_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   static ip_address_details_t empty_ip_address_details = { {0} };
1681   ip_address_details_t *address = NULL;
1682   ip_details_t *current_ip_details = NULL;
1683   ip_details_t *details = NULL;
1684
1685   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1686
1687   if (!details || vam->current_sw_if_index >= vec_len (details)
1688       || !details[vam->current_sw_if_index].present)
1689     {
1690       errmsg ("ip address details arrived but not stored\n");
1691       errmsg ("ip_dump should be called first\n");
1692       return;
1693     }
1694
1695   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1696
1697 #define addresses (current_ip_details->addr)
1698
1699   vec_validate_init_empty (addresses, vec_len (addresses),
1700                            empty_ip_address_details);
1701
1702   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1703
1704   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1705   address->prefix_length = mp->prefix_length;
1706 #undef addresses
1707 }
1708
1709 static void vl_api_ip_address_details_t_handler_json
1710   (vl_api_ip_address_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   vat_json_node_t *node = NULL;
1714   struct in6_addr ip6;
1715   struct in_addr ip4;
1716
1717   if (VAT_JSON_ARRAY != vam->json_tree.type)
1718     {
1719       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1720       vat_json_init_array (&vam->json_tree);
1721     }
1722   node = vat_json_array_add (&vam->json_tree);
1723
1724   vat_json_init_object (node);
1725   if (vam->is_ipv6)
1726     {
1727       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1728       vat_json_object_add_ip6 (node, "ip", ip6);
1729     }
1730   else
1731     {
1732       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1733       vat_json_object_add_ip4 (node, "ip", ip4);
1734     }
1735   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1736 }
1737
1738 static void
1739 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   static ip_details_t empty_ip_details = { 0 };
1743   ip_details_t *ip = NULL;
1744   u32 sw_if_index = ~0;
1745
1746   sw_if_index = ntohl (mp->sw_if_index);
1747
1748   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1749                            sw_if_index, empty_ip_details);
1750
1751   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1752                          sw_if_index);
1753
1754   ip->present = 1;
1755 }
1756
1757 static void
1758 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1759 {
1760   vat_main_t *vam = &vat_main;
1761
1762   if (VAT_JSON_ARRAY != vam->json_tree.type)
1763     {
1764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1765       vat_json_init_array (&vam->json_tree);
1766     }
1767   vat_json_array_add_uint (&vam->json_tree,
1768                            clib_net_to_host_u32 (mp->sw_if_index));
1769 }
1770
1771 static void vl_api_map_domain_details_t_handler_json
1772   (vl_api_map_domain_details_t * mp)
1773 {
1774   vat_json_node_t *node = NULL;
1775   vat_main_t *vam = &vat_main;
1776   struct in6_addr ip6;
1777   struct in_addr ip4;
1778
1779   if (VAT_JSON_ARRAY != vam->json_tree.type)
1780     {
1781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1782       vat_json_init_array (&vam->json_tree);
1783     }
1784
1785   node = vat_json_array_add (&vam->json_tree);
1786   vat_json_init_object (node);
1787
1788   vat_json_object_add_uint (node, "domain_index",
1789                             clib_net_to_host_u32 (mp->domain_index));
1790   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1791   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1792   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1793   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1794   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1795   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1796   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1797   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1798   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1799   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1800   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1801   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1802   vat_json_object_add_uint (node, "flags", mp->flags);
1803   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1804   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1805 }
1806
1807 static void vl_api_map_domain_details_t_handler
1808   (vl_api_map_domain_details_t * mp)
1809 {
1810   vat_main_t *vam = &vat_main;
1811
1812   if (mp->is_translation)
1813     {
1814       fformat (vam->ofp,
1815                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1816                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1817                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1818                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1819                clib_net_to_host_u32 (mp->domain_index));
1820     }
1821   else
1822     {
1823       fformat (vam->ofp,
1824                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1825                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1826                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1827                format_ip6_address, mp->ip6_src,
1828                clib_net_to_host_u32 (mp->domain_index));
1829     }
1830   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1831            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1832            mp->is_translation ? "map-t" : "");
1833 }
1834
1835 static void vl_api_map_rule_details_t_handler_json
1836   (vl_api_map_rule_details_t * mp)
1837 {
1838   struct in6_addr ip6;
1839   vat_json_node_t *node = NULL;
1840   vat_main_t *vam = &vat_main;
1841
1842   if (VAT_JSON_ARRAY != vam->json_tree.type)
1843     {
1844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1845       vat_json_init_array (&vam->json_tree);
1846     }
1847
1848   node = vat_json_array_add (&vam->json_tree);
1849   vat_json_init_object (node);
1850
1851   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1852   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1853   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1854 }
1855
1856 static void
1857 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1861            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1862 }
1863
1864 static void
1865 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1869           "router_addr %U host_mac %U\n",
1870           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1871           format_ip4_address, &mp->host_address,
1872           format_ip4_address, &mp->router_address,
1873           format_ethernet_address, mp->host_mac);
1874 }
1875
1876 static void vl_api_dhcp_compl_event_t_handler_json
1877   (vl_api_dhcp_compl_event_t * mp)
1878 {
1879   /* JSON output not supported */
1880 }
1881
1882 static void
1883 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1884                               u32 counter)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   static u64 default_counter = 0;
1888
1889   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1890                            NULL);
1891   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1892                            sw_if_index, default_counter);
1893   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1894 }
1895
1896 static void
1897 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1898                                 interface_counter_t counter)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   static interface_counter_t default_counter = { 0, };
1902
1903   vec_validate_init_empty (vam->combined_interface_counters,
1904                            vnet_counter_type, NULL);
1905   vec_validate_init_empty (vam->combined_interface_counters
1906                            [vnet_counter_type], sw_if_index, default_counter);
1907   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1908 }
1909
1910 static void vl_api_vnet_interface_counters_t_handler
1911   (vl_api_vnet_interface_counters_t * mp)
1912 {
1913   /* not supported */
1914 }
1915
1916 static void vl_api_vnet_interface_counters_t_handler_json
1917   (vl_api_vnet_interface_counters_t * mp)
1918 {
1919   interface_counter_t counter;
1920   vlib_counter_t *v;
1921   u64 *v_packets;
1922   u64 packets;
1923   u32 count;
1924   u32 first_sw_if_index;
1925   int i;
1926
1927   count = ntohl (mp->count);
1928   first_sw_if_index = ntohl (mp->first_sw_if_index);
1929
1930   if (!mp->is_combined)
1931     {
1932       v_packets = (u64 *) & mp->data;
1933       for (i = 0; i < count; i++)
1934         {
1935           packets =
1936             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1937           set_simple_interface_counter (mp->vnet_counter_type,
1938                                         first_sw_if_index + i, packets);
1939           v_packets++;
1940         }
1941     }
1942   else
1943     {
1944       v = (vlib_counter_t *) & mp->data;
1945       for (i = 0; i < count; i++)
1946         {
1947           counter.packets =
1948             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1949           counter.bytes =
1950             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1951           set_combined_interface_counter (mp->vnet_counter_type,
1952                                           first_sw_if_index + i, counter);
1953           v++;
1954         }
1955     }
1956 }
1957
1958 static u32
1959 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   u32 i;
1963
1964   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1965     {
1966       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1967         {
1968           return i;
1969         }
1970     }
1971   return ~0;
1972 }
1973
1974 static u32
1975 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static void vl_api_vnet_ip4_fib_counters_t_handler
1991   (vl_api_vnet_ip4_fib_counters_t * mp)
1992 {
1993   /* not supported */
1994 }
1995
1996 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1997   (vl_api_vnet_ip4_fib_counters_t * mp)
1998 {
1999   vat_main_t *vam = &vat_main;
2000   vl_api_ip4_fib_counter_t *v;
2001   ip4_fib_counter_t *counter;
2002   struct in_addr ip4;
2003   u32 vrf_id;
2004   u32 vrf_index;
2005   u32 count;
2006   int i;
2007
2008   vrf_id = ntohl (mp->vrf_id);
2009   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2010   if (~0 == vrf_index)
2011     {
2012       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2013       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2014       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2015       vec_validate (vam->ip4_fib_counters, vrf_index);
2016       vam->ip4_fib_counters[vrf_index] = NULL;
2017     }
2018
2019   vec_free (vam->ip4_fib_counters[vrf_index]);
2020   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2021   count = ntohl (mp->count);
2022   for (i = 0; i < count; i++)
2023     {
2024       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2025       counter = &vam->ip4_fib_counters[vrf_index][i];
2026       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2027       counter->address = ip4;
2028       counter->address_length = v->address_length;
2029       counter->packets = clib_net_to_host_u64 (v->packets);
2030       counter->bytes = clib_net_to_host_u64 (v->bytes);
2031       v++;
2032     }
2033 }
2034
2035 static void vl_api_vnet_ip6_fib_counters_t_handler
2036   (vl_api_vnet_ip6_fib_counters_t * mp)
2037 {
2038   /* not supported */
2039 }
2040
2041 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2042   (vl_api_vnet_ip6_fib_counters_t * mp)
2043 {
2044   vat_main_t *vam = &vat_main;
2045   vl_api_ip6_fib_counter_t *v;
2046   ip6_fib_counter_t *counter;
2047   struct in6_addr ip6;
2048   u32 vrf_id;
2049   u32 vrf_index;
2050   u32 count;
2051   int i;
2052
2053   vrf_id = ntohl (mp->vrf_id);
2054   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2055   if (~0 == vrf_index)
2056     {
2057       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2058       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2059       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2060       vec_validate (vam->ip6_fib_counters, vrf_index);
2061       vam->ip6_fib_counters[vrf_index] = NULL;
2062     }
2063
2064   vec_free (vam->ip6_fib_counters[vrf_index]);
2065   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2066   count = ntohl (mp->count);
2067   for (i = 0; i < count; i++)
2068     {
2069       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2070       counter = &vam->ip6_fib_counters[vrf_index][i];
2071       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2072       counter->address = ip6;
2073       counter->address_length = v->address_length;
2074       counter->packets = clib_net_to_host_u64 (v->packets);
2075       counter->bytes = clib_net_to_host_u64 (v->bytes);
2076       v++;
2077     }
2078 }
2079
2080 static void vl_api_get_first_msg_id_reply_t_handler
2081   (vl_api_get_first_msg_id_reply_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   i32 retval = ntohl (mp->retval);
2085
2086   if (vam->async_mode)
2087     {
2088       vam->async_errors += (retval < 0);
2089     }
2090   else
2091     {
2092       vam->retval = retval;
2093       vam->result_ready = 1;
2094     }
2095   if (retval >= 0)
2096     {
2097       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2098     }
2099 }
2100
2101 static void vl_api_get_first_msg_id_reply_t_handler_json
2102   (vl_api_get_first_msg_id_reply_t * mp)
2103 {
2104   vat_main_t *vam = &vat_main;
2105   vat_json_node_t node;
2106
2107   vat_json_init_object (&node);
2108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2109   vat_json_object_add_uint (&node, "first_msg_id",
2110                             (uint) ntohs (mp->first_msg_id));
2111
2112   vat_json_print (vam->ofp, &node);
2113   vat_json_free (&node);
2114
2115   vam->retval = ntohl (mp->retval);
2116   vam->result_ready = 1;
2117 }
2118
2119 static void vl_api_get_node_graph_reply_t_handler
2120   (vl_api_get_node_graph_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   api_main_t *am = &api_main;
2124   i32 retval = ntohl (mp->retval);
2125   u8 *pvt_copy, *reply;
2126   void *oldheap;
2127   vlib_node_t *node;
2128   int i;
2129
2130   if (vam->async_mode)
2131     {
2132       vam->async_errors += (retval < 0);
2133     }
2134   else
2135     {
2136       vam->retval = retval;
2137       vam->result_ready = 1;
2138     }
2139
2140   /* "Should never happen..." */
2141   if (retval != 0)
2142     return;
2143
2144   reply = (u8 *) (mp->reply_in_shmem);
2145   pvt_copy = vec_dup (reply);
2146
2147   /* Toss the shared-memory original... */
2148   pthread_mutex_lock (&am->vlib_rp->mutex);
2149   oldheap = svm_push_data_heap (am->vlib_rp);
2150
2151   vec_free (reply);
2152
2153   svm_pop_heap (oldheap);
2154   pthread_mutex_unlock (&am->vlib_rp->mutex);
2155
2156   if (vam->graph_nodes)
2157     {
2158       hash_free (vam->graph_node_index_by_name);
2159
2160       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2161         {
2162           node = vam->graph_nodes[i];
2163           vec_free (node->name);
2164           vec_free (node->next_nodes);
2165           vec_free (node);
2166         }
2167       vec_free (vam->graph_nodes);
2168     }
2169
2170   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2171   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2172   vec_free (pvt_copy);
2173
2174   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2175     {
2176       node = vam->graph_nodes[i];
2177       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2178     }
2179 }
2180
2181 static void vl_api_get_node_graph_reply_t_handler_json
2182   (vl_api_get_node_graph_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   api_main_t *am = &api_main;
2186   void *oldheap;
2187   vat_json_node_t node;
2188   u8 *reply;
2189
2190   /* $$$$ make this real? */
2191   vat_json_init_object (&node);
2192   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2193   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2194
2195   reply = (u8 *) (mp->reply_in_shmem);
2196
2197   /* Toss the shared-memory original... */
2198   pthread_mutex_lock (&am->vlib_rp->mutex);
2199   oldheap = svm_push_data_heap (am->vlib_rp);
2200
2201   vec_free (reply);
2202
2203   svm_pop_heap (oldheap);
2204   pthread_mutex_unlock (&am->vlib_rp->mutex);
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void
2214 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   u8 *s = 0;
2218
2219   if (mp->local)
2220     {
2221       s = format (s, "%=16d%=16d%=16d\n",
2222                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2223     }
2224   else
2225     {
2226       s = format (s, "%=16U%=16d%=16d\n",
2227                   mp->is_ipv6 ? format_ip6_address :
2228                   format_ip4_address,
2229                   mp->ip_address, mp->priority, mp->weight);
2230     }
2231
2232   fformat (vam->ofp, "%v", s);
2233   vec_free (s);
2234 }
2235
2236 static void
2237 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2238                                             mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   vat_json_node_t *node = NULL;
2242   struct in6_addr ip6;
2243   struct in_addr ip4;
2244
2245   if (VAT_JSON_ARRAY != vam->json_tree.type)
2246     {
2247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2248       vat_json_init_array (&vam->json_tree);
2249     }
2250   node = vat_json_array_add (&vam->json_tree);
2251   vat_json_init_object (node);
2252
2253   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2254   vat_json_object_add_uint (node, "priority", mp->priority);
2255   vat_json_object_add_uint (node, "weight", mp->weight);
2256
2257   if (mp->local)
2258     vat_json_object_add_uint (node, "sw_if_index",
2259                               clib_net_to_host_u32 (mp->sw_if_index));
2260   else
2261     {
2262       if (mp->is_ipv6)
2263         {
2264           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2265           vat_json_object_add_ip6 (node, "address", ip6);
2266         }
2267       else
2268         {
2269           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2270           vat_json_object_add_ip4 (node, "address", ip4);
2271         }
2272     }
2273 }
2274
2275 static void
2276 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2277                                            mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   u8 *ls_name = 0;
2281
2282   ls_name = format (0, "%s", mp->ls_name);
2283
2284   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2285            ls_name);
2286   vec_free (ls_name);
2287 }
2288
2289 static void
2290   vl_api_lisp_locator_set_details_t_handler_json
2291   (vl_api_lisp_locator_set_details_t * mp)
2292 {
2293   vat_main_t *vam = &vat_main;
2294   vat_json_node_t *node = 0;
2295   u8 *ls_name = 0;
2296
2297   ls_name = format (0, "%s", mp->ls_name);
2298   vec_add1 (ls_name, 0);
2299
2300   if (VAT_JSON_ARRAY != vam->json_tree.type)
2301     {
2302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2303       vat_json_init_array (&vam->json_tree);
2304     }
2305   node = vat_json_array_add (&vam->json_tree);
2306
2307   vat_json_init_object (node);
2308   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2309   vat_json_object_add_uint (node, "ls_index",
2310                             clib_net_to_host_u32 (mp->ls_index));
2311   vec_free (ls_name);
2312 }
2313
2314 static u8 *
2315 format_lisp_flat_eid (u8 * s, va_list * args)
2316 {
2317   u32 type = va_arg (*args, u32);
2318   u8 *eid = va_arg (*args, u8 *);
2319   u32 eid_len = va_arg (*args, u32);
2320
2321   switch (type)
2322     {
2323     case 0:
2324       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2325     case 1:
2326       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2327     case 2:
2328       return format (s, "%U", format_ethernet_address, eid);
2329     }
2330   return 0;
2331 }
2332
2333 static u8 *
2334 format_lisp_eid_vat (u8 * s, va_list * args)
2335 {
2336   u32 type = va_arg (*args, u32);
2337   u8 *eid = va_arg (*args, u8 *);
2338   u32 eid_len = va_arg (*args, u32);
2339   u8 *seid = va_arg (*args, u8 *);
2340   u32 seid_len = va_arg (*args, u32);
2341   u32 is_src_dst = va_arg (*args, u32);
2342
2343   if (is_src_dst)
2344     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2345
2346   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2347
2348   return s;
2349 }
2350
2351 static void
2352 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   u8 *s = 0, *eid = 0;
2356
2357   if (~0 == mp->locator_set_index)
2358     s = format (0, "action: %d", mp->action);
2359   else
2360     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2361
2362   eid = format (0, "%U", format_lisp_eid_vat,
2363                 mp->eid_type,
2364                 mp->eid,
2365                 mp->eid_prefix_len,
2366                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2367   vec_add1 (eid, 0);
2368
2369   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2370            clib_net_to_host_u32 (mp->vni),
2371            eid,
2372            mp->is_local ? "local" : "remote",
2373            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2374   vec_free (s);
2375   vec_free (eid);
2376 }
2377
2378 static void
2379 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2380                                               * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   vat_json_node_t *node = 0;
2384   u8 *eid = 0;
2385
2386   if (VAT_JSON_ARRAY != vam->json_tree.type)
2387     {
2388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2389       vat_json_init_array (&vam->json_tree);
2390     }
2391   node = vat_json_array_add (&vam->json_tree);
2392
2393   vat_json_init_object (node);
2394   if (~0 == mp->locator_set_index)
2395     vat_json_object_add_uint (node, "action", mp->action);
2396   else
2397     vat_json_object_add_uint (node, "locator_set_index",
2398                               clib_net_to_host_u32 (mp->locator_set_index));
2399
2400   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2401   eid = format (0, "%U", format_lisp_eid_vat,
2402                 mp->eid_type,
2403                 mp->eid,
2404                 mp->eid_prefix_len,
2405                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2406   vec_add1 (eid, 0);
2407   vat_json_object_add_string_copy (node, "eid", eid);
2408   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2409   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2410   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2411   vec_free (eid);
2412 }
2413
2414 static void
2415   vl_api_lisp_eid_table_map_details_t_handler
2416   (vl_api_lisp_eid_table_map_details_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419
2420   u8 *line = format (0, "%=10d%=10d",
2421                      clib_net_to_host_u32 (mp->vni),
2422                      clib_net_to_host_u32 (mp->dp_table));
2423   fformat (vam->ofp, "%v\n", line);
2424   vec_free (line);
2425 }
2426
2427 static void
2428   vl_api_lisp_eid_table_map_details_t_handler_json
2429   (vl_api_lisp_eid_table_map_details_t * mp)
2430 {
2431   vat_main_t *vam = &vat_main;
2432   vat_json_node_t *node = NULL;
2433
2434   if (VAT_JSON_ARRAY != vam->json_tree.type)
2435     {
2436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2437       vat_json_init_array (&vam->json_tree);
2438     }
2439   node = vat_json_array_add (&vam->json_tree);
2440   vat_json_init_object (node);
2441   vat_json_object_add_uint (node, "dp_table",
2442                             clib_net_to_host_u32 (mp->dp_table));
2443   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2444 }
2445
2446 static void
2447   vl_api_lisp_eid_table_vni_details_t_handler
2448   (vl_api_lisp_eid_table_vni_details_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451
2452   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2453   fformat (vam->ofp, "%v\n", line);
2454   vec_free (line);
2455 }
2456
2457 static void
2458   vl_api_lisp_eid_table_vni_details_t_handler_json
2459   (vl_api_lisp_eid_table_vni_details_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   vat_json_node_t *node = NULL;
2463
2464   if (VAT_JSON_ARRAY != vam->json_tree.type)
2465     {
2466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2467       vat_json_init_array (&vam->json_tree);
2468     }
2469   node = vat_json_array_add (&vam->json_tree);
2470   vat_json_init_object (node);
2471   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2472 }
2473
2474 static u8 *
2475 format_decap_next (u8 * s, va_list * args)
2476 {
2477   u32 next_index = va_arg (*args, u32);
2478
2479   switch (next_index)
2480     {
2481     case LISP_GPE_INPUT_NEXT_DROP:
2482       return format (s, "drop");
2483     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2484       return format (s, "ip4");
2485     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2486       return format (s, "ip6");
2487     default:
2488       return format (s, "unknown %d", next_index);
2489     }
2490   return s;
2491 }
2492
2493 static void
2494 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2495                                           mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   u8 *iid_str;
2499   u8 *flag_str = NULL;
2500
2501   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2502
2503 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2504   foreach_lisp_gpe_flag_bit;
2505 #undef _
2506
2507   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2508            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2509            mp->tunnels,
2510            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2511            mp->source_ip,
2512            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2513            mp->destination_ip,
2514            ntohl (mp->encap_fib_id),
2515            ntohl (mp->decap_fib_id),
2516            format_decap_next, ntohl (mp->dcap_next),
2517            mp->ver_res >> 6,
2518            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2519
2520   vec_free (iid_str);
2521 }
2522
2523 static void
2524   vl_api_lisp_gpe_tunnel_details_t_handler_json
2525   (vl_api_lisp_gpe_tunnel_details_t * mp)
2526 {
2527   vat_main_t *vam = &vat_main;
2528   vat_json_node_t *node = NULL;
2529   struct in6_addr ip6;
2530   struct in_addr ip4;
2531   u8 *next_decap_str;
2532
2533   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2534
2535   if (VAT_JSON_ARRAY != vam->json_tree.type)
2536     {
2537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2538       vat_json_init_array (&vam->json_tree);
2539     }
2540   node = vat_json_array_add (&vam->json_tree);
2541
2542   vat_json_init_object (node);
2543   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2544   if (mp->is_ipv6)
2545     {
2546       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2547       vat_json_object_add_ip6 (node, "source address", ip6);
2548       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2549       vat_json_object_add_ip6 (node, "destination address", ip6);
2550     }
2551   else
2552     {
2553       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2554       vat_json_object_add_ip4 (node, "source address", ip4);
2555       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2556       vat_json_object_add_ip4 (node, "destination address", ip4);
2557     }
2558   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2559   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2560   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2561   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2562   vat_json_object_add_uint (node, "flags", mp->flags);
2563   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2564   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2565   vat_json_object_add_uint (node, "res", mp->res);
2566   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2567
2568   vec_free (next_decap_str);
2569 }
2570
2571 static void
2572   vl_api_lisp_adjacencies_get_reply_t_handler
2573   (vl_api_lisp_adjacencies_get_reply_t * mp)
2574 {
2575   vat_main_t *vam = &vat_main;
2576   u32 i, n;
2577   int retval = clib_net_to_host_u32 (mp->retval);
2578   vl_api_lisp_adjacency_t *a;
2579
2580   if (retval)
2581     goto end;
2582
2583   n = clib_net_to_host_u32 (mp->count);
2584
2585   for (i = 0; i < n; i++)
2586     {
2587       a = &mp->adjacencies[i];
2588       fformat (vam->ofp, "%U %40U\n",
2589                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2590                format_lisp_flat_eid, a->eid_type, a->reid,
2591                a->reid_prefix_len);
2592     }
2593
2594 end:
2595   vam->retval = retval;
2596   vam->result_ready = 1;
2597 }
2598
2599 static void
2600   vl_api_lisp_adjacencies_get_reply_t_handler_json
2601   (vl_api_lisp_adjacencies_get_reply_t * mp)
2602 {
2603   u8 *s = 0;
2604   vat_main_t *vam = &vat_main;
2605   vat_json_node_t *e = 0, root;
2606   u32 i, n;
2607   int retval = clib_net_to_host_u32 (mp->retval);
2608   vl_api_lisp_adjacency_t *a;
2609
2610   if (retval)
2611     goto end;
2612
2613   n = clib_net_to_host_u32 (mp->count);
2614   vat_json_init_array (&root);
2615
2616   for (i = 0; i < n; i++)
2617     {
2618       e = vat_json_array_add (&root);
2619       a = &mp->adjacencies[i];
2620
2621       vat_json_init_object (e);
2622       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2623                   a->leid_prefix_len);
2624       vec_add1 (s, 0);
2625       vat_json_object_add_string_copy (e, "leid", s);
2626       vec_free (s);
2627
2628       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2629                   a->reid_prefix_len);
2630       vec_add1 (s, 0);
2631       vat_json_object_add_string_copy (e, "reid", s);
2632       vec_free (s);
2633     }
2634
2635   vat_json_print (vam->ofp, &root);
2636   vat_json_free (&root);
2637
2638 end:
2639   vam->retval = retval;
2640   vam->result_ready = 1;
2641 }
2642
2643 static void
2644 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2645                                             * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648
2649   fformat (vam->ofp, "%=20U\n",
2650            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2651            mp->ip_address);
2652 }
2653
2654 static void
2655   vl_api_lisp_map_resolver_details_t_handler_json
2656   (vl_api_lisp_map_resolver_details_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   vat_json_node_t *node = NULL;
2660   struct in6_addr ip6;
2661   struct in_addr ip4;
2662
2663   if (VAT_JSON_ARRAY != vam->json_tree.type)
2664     {
2665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2666       vat_json_init_array (&vam->json_tree);
2667     }
2668   node = vat_json_array_add (&vam->json_tree);
2669
2670   vat_json_init_object (node);
2671   if (mp->is_ipv6)
2672     {
2673       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2674       vat_json_object_add_ip6 (node, "map resolver", ip6);
2675     }
2676   else
2677     {
2678       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2679       vat_json_object_add_ip4 (node, "map resolver", ip4);
2680     }
2681 }
2682
2683 static void
2684   vl_api_show_lisp_status_reply_t_handler
2685   (vl_api_show_lisp_status_reply_t * mp)
2686 {
2687   vat_main_t *vam = &vat_main;
2688   i32 retval = ntohl (mp->retval);
2689
2690   if (0 <= retval)
2691     {
2692       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2693                mp->feature_status ? "enabled" : "disabled",
2694                mp->gpe_status ? "enabled" : "disabled");
2695     }
2696
2697   vam->retval = retval;
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_show_lisp_status_reply_t_handler_json
2703   (vl_api_show_lisp_status_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   vat_json_node_t node;
2707   u8 *gpe_status = NULL;
2708   u8 *feature_status = NULL;
2709
2710   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2711   feature_status = format (0, "%s",
2712                            mp->feature_status ? "enabled" : "disabled");
2713   vec_add1 (gpe_status, 0);
2714   vec_add1 (feature_status, 0);
2715
2716   vat_json_init_object (&node);
2717   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2718   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2719
2720   vec_free (gpe_status);
2721   vec_free (feature_status);
2722
2723   vat_json_print (vam->ofp, &node);
2724   vat_json_free (&node);
2725
2726   vam->retval = ntohl (mp->retval);
2727   vam->result_ready = 1;
2728 }
2729
2730 static void
2731   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2732   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2733 {
2734   vat_main_t *vam = &vat_main;
2735   i32 retval = ntohl (mp->retval);
2736
2737   if (retval >= 0)
2738     {
2739       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2740     }
2741
2742   vam->retval = retval;
2743   vam->result_ready = 1;
2744 }
2745
2746 static void
2747   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2748   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2749 {
2750   vat_main_t *vam = &vat_main;
2751   vat_json_node_t *node = NULL;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2762
2763   vat_json_print (vam->ofp, node);
2764   vat_json_free (node);
2765
2766   vam->retval = ntohl (mp->retval);
2767   vam->result_ready = 1;
2768 }
2769
2770 static u8 *
2771 format_lisp_map_request_mode (u8 * s, va_list * args)
2772 {
2773   u32 mode = va_arg (*args, u32);
2774
2775   switch (mode)
2776     {
2777     case 0:
2778       return format (0, "dst-only");
2779     case 1:
2780       return format (0, "src-dst");
2781     }
2782   return 0;
2783 }
2784
2785 static void
2786   vl_api_show_lisp_map_request_mode_reply_t_handler
2787   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   i32 retval = ntohl (mp->retval);
2791
2792   if (0 <= retval)
2793     {
2794       u32 mode = mp->mode;
2795       fformat (vam->ofp, "map_request_mode: %U\n",
2796                format_lisp_map_request_mode, mode);
2797     }
2798
2799   vam->retval = retval;
2800   vam->result_ready = 1;
2801 }
2802
2803 static void
2804   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2805   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   vat_json_node_t node;
2809   u8 *s = 0;
2810   u32 mode;
2811
2812   mode = mp->mode;
2813   s = format (0, "%U", format_lisp_map_request_mode, mode);
2814   vec_add1 (s, 0);
2815
2816   vat_json_init_object (&node);
2817   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2818   vat_json_print (vam->ofp, &node);
2819   vat_json_free (&node);
2820
2821   vec_free (s);
2822   vam->retval = ntohl (mp->retval);
2823   vam->result_ready = 1;
2824 }
2825
2826 static void
2827 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   i32 retval = ntohl (mp->retval);
2831
2832   if (0 <= retval)
2833     {
2834       fformat (vam->ofp, "%-20s%-16s\n",
2835                mp->status ? "enabled" : "disabled",
2836                mp->status ? (char *) mp->locator_set_name : "");
2837     }
2838
2839   vam->retval = retval;
2840   vam->result_ready = 1;
2841 }
2842
2843 static void
2844 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2845                                             mp)
2846 {
2847   vat_main_t *vam = &vat_main;
2848   vat_json_node_t node;
2849   u8 *status = 0;
2850
2851   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2852   vec_add1 (status, 0);
2853
2854   vat_json_init_object (&node);
2855   vat_json_object_add_string_copy (&node, "status", status);
2856   if (mp->status)
2857     {
2858       vat_json_object_add_string_copy (&node, "locator_set",
2859                                        mp->locator_set_name);
2860     }
2861
2862   vec_free (status);
2863
2864   vat_json_print (vam->ofp, &node);
2865   vat_json_free (&node);
2866
2867   vam->retval = ntohl (mp->retval);
2868   vam->result_ready = 1;
2869 }
2870
2871 static u8 *
2872 format_policer_type (u8 * s, va_list * va)
2873 {
2874   u32 i = va_arg (*va, u32);
2875
2876   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2877     s = format (s, "1r2c");
2878   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2879     s = format (s, "1r3c");
2880   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2881     s = format (s, "2r3c-2698");
2882   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2883     s = format (s, "2r3c-4115");
2884   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2885     s = format (s, "2r3c-mef5cf1");
2886   else
2887     s = format (s, "ILLEGAL");
2888   return s;
2889 }
2890
2891 static u8 *
2892 format_policer_rate_type (u8 * s, va_list * va)
2893 {
2894   u32 i = va_arg (*va, u32);
2895
2896   if (i == SSE2_QOS_RATE_KBPS)
2897     s = format (s, "kbps");
2898   else if (i == SSE2_QOS_RATE_PPS)
2899     s = format (s, "pps");
2900   else
2901     s = format (s, "ILLEGAL");
2902   return s;
2903 }
2904
2905 static u8 *
2906 format_policer_round_type (u8 * s, va_list * va)
2907 {
2908   u32 i = va_arg (*va, u32);
2909
2910   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2911     s = format (s, "closest");
2912   else if (i == SSE2_QOS_ROUND_TO_UP)
2913     s = format (s, "up");
2914   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2915     s = format (s, "down");
2916   else
2917     s = format (s, "ILLEGAL");
2918   return s;
2919 }
2920
2921 static u8 *
2922 format_policer_action_type (u8 * s, va_list * va)
2923 {
2924   u32 i = va_arg (*va, u32);
2925
2926   if (i == SSE2_QOS_ACTION_DROP)
2927     s = format (s, "drop");
2928   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2929     s = format (s, "transmit");
2930   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2931     s = format (s, "mark-and-transmit");
2932   else
2933     s = format (s, "ILLEGAL");
2934   return s;
2935 }
2936
2937 static u8 *
2938 format_dscp (u8 * s, va_list * va)
2939 {
2940   u32 i = va_arg (*va, u32);
2941   char *t = 0;
2942
2943   switch (i)
2944     {
2945 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2946       foreach_vnet_dscp
2947 #undef _
2948     default:
2949       return format (s, "ILLEGAL");
2950     }
2951   s = format (s, "%s", t);
2952   return s;
2953 }
2954
2955 static void
2956 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2957 {
2958   vat_main_t *vam = &vat_main;
2959   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2960
2961   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2962     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2963   else
2964     conform_dscp_str = format (0, "");
2965
2966   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2967     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2968   else
2969     exceed_dscp_str = format (0, "");
2970
2971   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2972     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2973   else
2974     violate_dscp_str = format (0, "");
2975
2976   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2977            "rate type %U, round type %U, %s rate, %s color-aware, "
2978            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2979            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2980            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2981            mp->name,
2982            format_policer_type, mp->type,
2983            ntohl (mp->cir),
2984            ntohl (mp->eir),
2985            clib_net_to_host_u64 (mp->cb),
2986            clib_net_to_host_u64 (mp->eb),
2987            format_policer_rate_type, mp->rate_type,
2988            format_policer_round_type, mp->round_type,
2989            mp->single_rate ? "single" : "dual",
2990            mp->color_aware ? "is" : "not",
2991            ntohl (mp->cir_tokens_per_period),
2992            ntohl (mp->pir_tokens_per_period),
2993            ntohl (mp->scale),
2994            ntohl (mp->current_limit),
2995            ntohl (mp->current_bucket),
2996            ntohl (mp->extended_limit),
2997            ntohl (mp->extended_bucket),
2998            clib_net_to_host_u64 (mp->last_update_time),
2999            format_policer_action_type, mp->conform_action_type,
3000            conform_dscp_str,
3001            format_policer_action_type, mp->exceed_action_type,
3002            exceed_dscp_str,
3003            format_policer_action_type, mp->violate_action_type,
3004            violate_dscp_str);
3005
3006   vec_free (conform_dscp_str);
3007   vec_free (exceed_dscp_str);
3008   vec_free (violate_dscp_str);
3009 }
3010
3011 static void vl_api_policer_details_t_handler_json
3012   (vl_api_policer_details_t * mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   vat_json_node_t *node;
3016   u8 *rate_type_str, *round_type_str, *type_str;
3017   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3018
3019   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3020   round_type_str =
3021     format (0, "%U", format_policer_round_type, mp->round_type);
3022   type_str = format (0, "%U", format_policer_type, mp->type);
3023   conform_action_str = format (0, "%U", format_policer_action_type,
3024                                mp->conform_action_type);
3025   exceed_action_str = format (0, "%U", format_policer_action_type,
3026                               mp->exceed_action_type);
3027   violate_action_str = format (0, "%U", format_policer_action_type,
3028                                mp->violate_action_type);
3029
3030   if (VAT_JSON_ARRAY != vam->json_tree.type)
3031     {
3032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3033       vat_json_init_array (&vam->json_tree);
3034     }
3035   node = vat_json_array_add (&vam->json_tree);
3036
3037   vat_json_init_object (node);
3038   vat_json_object_add_string_copy (node, "name", mp->name);
3039   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3040   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3041   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3042   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3043   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3044   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3045   vat_json_object_add_string_copy (node, "type", type_str);
3046   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3047   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3048   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3049   vat_json_object_add_uint (node, "cir_tokens_per_period",
3050                             ntohl (mp->cir_tokens_per_period));
3051   vat_json_object_add_uint (node, "eir_tokens_per_period",
3052                             ntohl (mp->pir_tokens_per_period));
3053   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3054   vat_json_object_add_uint (node, "current_bucket",
3055                             ntohl (mp->current_bucket));
3056   vat_json_object_add_uint (node, "extended_limit",
3057                             ntohl (mp->extended_limit));
3058   vat_json_object_add_uint (node, "extended_bucket",
3059                             ntohl (mp->extended_bucket));
3060   vat_json_object_add_uint (node, "last_update_time",
3061                             ntohl (mp->last_update_time));
3062   vat_json_object_add_string_copy (node, "conform_action",
3063                                    conform_action_str);
3064   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3065     {
3066       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3067       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3068       vec_free (dscp_str);
3069     }
3070   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3071   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3072     {
3073       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3074       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3075       vec_free (dscp_str);
3076     }
3077   vat_json_object_add_string_copy (node, "violate_action",
3078                                    violate_action_str);
3079   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3080     {
3081       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3082       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3083       vec_free (dscp_str);
3084     }
3085
3086   vec_free (rate_type_str);
3087   vec_free (round_type_str);
3088   vec_free (type_str);
3089   vec_free (conform_action_str);
3090   vec_free (exceed_action_str);
3091   vec_free (violate_action_str);
3092 }
3093
3094 static void
3095 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3096                                            mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   int i, count = ntohl (mp->count);
3100
3101   if (count > 0)
3102     fformat (vam->ofp, "classify table ids (%d) : ", count);
3103   for (i = 0; i < count; i++)
3104     {
3105       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3106       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3107     }
3108   vam->retval = ntohl (mp->retval);
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_classify_table_ids_reply_t_handler_json
3114   (vl_api_classify_table_ids_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   int i, count = ntohl (mp->count);
3118
3119   if (count > 0)
3120     {
3121       vat_json_node_t node;
3122
3123       vat_json_init_object (&node);
3124       for (i = 0; i < count; i++)
3125         {
3126           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3127         }
3128       vat_json_print (vam->ofp, &node);
3129       vat_json_free (&node);
3130     }
3131   vam->retval = ntohl (mp->retval);
3132   vam->result_ready = 1;
3133 }
3134
3135 static void
3136   vl_api_classify_table_by_interface_reply_t_handler
3137   (vl_api_classify_table_by_interface_reply_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   u32 table_id;
3141
3142   table_id = ntohl (mp->l2_table_id);
3143   if (table_id != ~0)
3144     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3145   else
3146     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3147   table_id = ntohl (mp->ip4_table_id);
3148   if (table_id != ~0)
3149     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3150   else
3151     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3152   table_id = ntohl (mp->ip6_table_id);
3153   if (table_id != ~0)
3154     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3155   else
3156     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3157   vam->retval = ntohl (mp->retval);
3158   vam->result_ready = 1;
3159 }
3160
3161 static void
3162   vl_api_classify_table_by_interface_reply_t_handler_json
3163   (vl_api_classify_table_by_interface_reply_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   vat_json_node_t node;
3167
3168   vat_json_init_object (&node);
3169
3170   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3171   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3172   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3173
3174   vat_json_print (vam->ofp, &node);
3175   vat_json_free (&node);
3176
3177   vam->retval = ntohl (mp->retval);
3178   vam->result_ready = 1;
3179 }
3180
3181 static void vl_api_policer_add_del_reply_t_handler
3182   (vl_api_policer_add_del_reply_t * mp)
3183 {
3184   vat_main_t *vam = &vat_main;
3185   i32 retval = ntohl (mp->retval);
3186   if (vam->async_mode)
3187     {
3188       vam->async_errors += (retval < 0);
3189     }
3190   else
3191     {
3192       vam->retval = retval;
3193       vam->result_ready = 1;
3194       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3195         /*
3196          * Note: this is just barely thread-safe, depends on
3197          * the main thread spinning waiting for an answer...
3198          */
3199         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3200     }
3201 }
3202
3203 static void vl_api_policer_add_del_reply_t_handler_json
3204   (vl_api_policer_add_del_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t node;
3208
3209   vat_json_init_object (&node);
3210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3211   vat_json_object_add_uint (&node, "policer_index",
3212                             ntohl (mp->policer_index));
3213
3214   vat_json_print (vam->ofp, &node);
3215   vat_json_free (&node);
3216
3217   vam->retval = ntohl (mp->retval);
3218   vam->result_ready = 1;
3219 }
3220
3221 /* Format hex dump. */
3222 u8 *
3223 format_hex_bytes (u8 * s, va_list * va)
3224 {
3225   u8 *bytes = va_arg (*va, u8 *);
3226   int n_bytes = va_arg (*va, int);
3227   uword i;
3228
3229   /* Print short or long form depending on byte count. */
3230   uword short_form = n_bytes <= 32;
3231   uword indent = format_get_indent (s);
3232
3233   if (n_bytes == 0)
3234     return s;
3235
3236   for (i = 0; i < n_bytes; i++)
3237     {
3238       if (!short_form && (i % 32) == 0)
3239         s = format (s, "%08x: ", i);
3240       s = format (s, "%02x", bytes[i]);
3241       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3242         s = format (s, "\n%U", format_white_space, indent);
3243     }
3244
3245   return s;
3246 }
3247
3248 static void
3249 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3250                                             * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   i32 retval = ntohl (mp->retval);
3254   if (retval == 0)
3255     {
3256       fformat (vam->ofp, "classify table info :\n");
3257       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3258                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3259                ntohl (mp->miss_next_index));
3260       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3261                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3262                ntohl (mp->match_n_vectors));
3263       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3264                ntohl (mp->mask_length));
3265     }
3266   vam->retval = retval;
3267   vam->result_ready = 1;
3268 }
3269
3270 static void
3271   vl_api_classify_table_info_reply_t_handler_json
3272   (vl_api_classify_table_info_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   vat_json_node_t node;
3276
3277   i32 retval = ntohl (mp->retval);
3278   if (retval == 0)
3279     {
3280       vat_json_init_object (&node);
3281
3282       vat_json_object_add_int (&node, "sessions",
3283                                ntohl (mp->active_sessions));
3284       vat_json_object_add_int (&node, "nexttbl",
3285                                ntohl (mp->next_table_index));
3286       vat_json_object_add_int (&node, "nextnode",
3287                                ntohl (mp->miss_next_index));
3288       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3289       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3290       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3291       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3292                       ntohl (mp->mask_length), 0);
3293       vat_json_object_add_string_copy (&node, "mask", s);
3294
3295       vat_json_print (vam->ofp, &node);
3296       vat_json_free (&node);
3297     }
3298   vam->retval = ntohl (mp->retval);
3299   vam->result_ready = 1;
3300 }
3301
3302 static void
3303 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3304                                            mp)
3305 {
3306   vat_main_t *vam = &vat_main;
3307
3308   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3309            ntohl (mp->hit_next_index), ntohl (mp->advance),
3310            ntohl (mp->opaque_index));
3311   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3312            ntohl (mp->match_length));
3313 }
3314
3315 static void
3316   vl_api_classify_session_details_t_handler_json
3317   (vl_api_classify_session_details_t * mp)
3318 {
3319   vat_main_t *vam = &vat_main;
3320   vat_json_node_t *node = NULL;
3321
3322   if (VAT_JSON_ARRAY != vam->json_tree.type)
3323     {
3324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3325       vat_json_init_array (&vam->json_tree);
3326     }
3327   node = vat_json_array_add (&vam->json_tree);
3328
3329   vat_json_init_object (node);
3330   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3331   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3332   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3333   u8 *s =
3334     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3335             0);
3336   vat_json_object_add_string_copy (node, "match", s);
3337 }
3338
3339 static void vl_api_pg_create_interface_reply_t_handler
3340   (vl_api_pg_create_interface_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   vam->retval = ntohl (mp->retval);
3345   vam->result_ready = 1;
3346 }
3347
3348 static void vl_api_pg_create_interface_reply_t_handler_json
3349   (vl_api_pg_create_interface_reply_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t node;
3353
3354   i32 retval = ntohl (mp->retval);
3355   if (retval == 0)
3356     {
3357       vat_json_init_object (&node);
3358
3359       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3360
3361       vat_json_print (vam->ofp, &node);
3362       vat_json_free (&node);
3363     }
3364   vam->retval = ntohl (mp->retval);
3365   vam->result_ready = 1;
3366 }
3367
3368 static void vl_api_policer_classify_details_t_handler
3369   (vl_api_policer_classify_details_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372
3373   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3374            ntohl (mp->table_index));
3375 }
3376
3377 static void vl_api_policer_classify_details_t_handler_json
3378   (vl_api_policer_classify_details_t * mp)
3379 {
3380   vat_main_t *vam = &vat_main;
3381   vat_json_node_t *node;
3382
3383   if (VAT_JSON_ARRAY != vam->json_tree.type)
3384     {
3385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3386       vat_json_init_array (&vam->json_tree);
3387     }
3388   node = vat_json_array_add (&vam->json_tree);
3389
3390   vat_json_init_object (node);
3391   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3392   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3393 }
3394
3395 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3396   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399   i32 retval = ntohl (mp->retval);
3400   if (vam->async_mode)
3401     {
3402       vam->async_errors += (retval < 0);
3403     }
3404   else
3405     {
3406       vam->retval = retval;
3407       vam->sw_if_index = ntohl (mp->sw_if_index);
3408       vam->result_ready = 1;
3409     }
3410 }
3411
3412 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3413   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3414 {
3415   vat_main_t *vam = &vat_main;
3416   vat_json_node_t node;
3417
3418   vat_json_init_object (&node);
3419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3420   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3421
3422   vat_json_print (vam->ofp, &node);
3423   vat_json_free (&node);
3424
3425   vam->retval = ntohl (mp->retval);
3426   vam->result_ready = 1;
3427 }
3428
3429 static void vl_api_flow_classify_details_t_handler
3430   (vl_api_flow_classify_details_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3435            ntohl (mp->table_index));
3436 }
3437
3438 static void vl_api_flow_classify_details_t_handler_json
3439   (vl_api_flow_classify_details_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t *node;
3443
3444   if (VAT_JSON_ARRAY != vam->json_tree.type)
3445     {
3446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3447       vat_json_init_array (&vam->json_tree);
3448     }
3449   node = vat_json_array_add (&vam->json_tree);
3450
3451   vat_json_init_object (node);
3452   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3453   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3454 }
3455
3456
3457
3458 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3459 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3460 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3461 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3462 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3463 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3464
3465 /*
3466  * Generate boilerplate reply handlers, which
3467  * dig the return value out of the xxx_reply_t API message,
3468  * stick it into vam->retval, and set vam->result_ready
3469  *
3470  * Could also do this by pointing N message decode slots at
3471  * a single function, but that could break in subtle ways.
3472  */
3473
3474 #define foreach_standard_reply_retval_handler           \
3475 _(sw_interface_set_flags_reply)                         \
3476 _(sw_interface_add_del_address_reply)                   \
3477 _(sw_interface_set_table_reply)                         \
3478 _(sw_interface_set_mpls_enable_reply)                   \
3479 _(sw_interface_set_vpath_reply)                         \
3480 _(sw_interface_set_l2_bridge_reply)                     \
3481 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3482 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3483 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3484 _(bridge_domain_add_del_reply)                          \
3485 _(sw_interface_set_l2_xconnect_reply)                   \
3486 _(l2fib_add_del_reply)                                  \
3487 _(ip_add_del_route_reply)                               \
3488 _(mpls_route_add_del_reply)                             \
3489 _(mpls_ip_bind_unbind_reply)                            \
3490 _(proxy_arp_add_del_reply)                              \
3491 _(proxy_arp_intfc_enable_disable_reply)                 \
3492 _(mpls_add_del_encap_reply)                             \
3493 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3494 _(sw_interface_set_unnumbered_reply)                    \
3495 _(ip_neighbor_add_del_reply)                            \
3496 _(reset_vrf_reply)                                      \
3497 _(oam_add_del_reply)                                    \
3498 _(reset_fib_reply)                                      \
3499 _(dhcp_proxy_config_reply)                              \
3500 _(dhcp_proxy_config_2_reply)                            \
3501 _(dhcp_proxy_set_vss_reply)                             \
3502 _(dhcp_client_config_reply)                             \
3503 _(set_ip_flow_hash_reply)                               \
3504 _(sw_interface_ip6_enable_disable_reply)                \
3505 _(sw_interface_ip6_set_link_local_address_reply)        \
3506 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3507 _(sw_interface_ip6nd_ra_config_reply)                   \
3508 _(set_arp_neighbor_limit_reply)                         \
3509 _(l2_patch_add_del_reply)                               \
3510 _(sr_tunnel_add_del_reply)                              \
3511 _(sr_policy_add_del_reply)                              \
3512 _(sr_multicast_map_add_del_reply)                       \
3513 _(classify_add_del_session_reply)                       \
3514 _(classify_set_interface_ip_table_reply)                \
3515 _(classify_set_interface_l2_tables_reply)               \
3516 _(l2tpv3_set_tunnel_cookies_reply)                      \
3517 _(l2tpv3_interface_enable_disable_reply)                \
3518 _(l2tpv3_set_lookup_key_reply)                          \
3519 _(l2_fib_clear_table_reply)                             \
3520 _(l2_interface_efp_filter_reply)                        \
3521 _(l2_interface_vlan_tag_rewrite_reply)                  \
3522 _(modify_vhost_user_if_reply)                           \
3523 _(delete_vhost_user_if_reply)                           \
3524 _(want_ip4_arp_events_reply)                            \
3525 _(want_ip6_nd_events_reply)                             \
3526 _(input_acl_set_interface_reply)                        \
3527 _(ipsec_spd_add_del_reply)                              \
3528 _(ipsec_interface_add_del_spd_reply)                    \
3529 _(ipsec_spd_add_del_entry_reply)                        \
3530 _(ipsec_sad_add_del_entry_reply)                        \
3531 _(ipsec_sa_set_key_reply)                               \
3532 _(ikev2_profile_add_del_reply)                          \
3533 _(ikev2_profile_set_auth_reply)                         \
3534 _(ikev2_profile_set_id_reply)                           \
3535 _(ikev2_profile_set_ts_reply)                           \
3536 _(ikev2_set_local_key_reply)                            \
3537 _(delete_loopback_reply)                                \
3538 _(bd_ip_mac_add_del_reply)                              \
3539 _(map_del_domain_reply)                                 \
3540 _(map_add_del_rule_reply)                               \
3541 _(want_interface_events_reply)                          \
3542 _(want_stats_reply)                                     \
3543 _(cop_interface_enable_disable_reply)                   \
3544 _(cop_whitelist_enable_disable_reply)                   \
3545 _(sw_interface_clear_stats_reply)                       \
3546 _(ioam_enable_reply)                              \
3547 _(ioam_disable_reply)                              \
3548 _(lisp_add_del_locator_reply)                           \
3549 _(lisp_add_del_local_eid_reply)                         \
3550 _(lisp_add_del_remote_mapping_reply)                    \
3551 _(lisp_add_del_adjacency_reply)                         \
3552 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3553 _(lisp_add_del_map_resolver_reply)                      \
3554 _(lisp_gpe_enable_disable_reply)                        \
3555 _(lisp_gpe_add_del_iface_reply)                         \
3556 _(lisp_enable_disable_reply)                            \
3557 _(lisp_pitr_set_locator_set_reply)                      \
3558 _(lisp_map_request_mode_reply)                          \
3559 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3560 _(lisp_eid_table_add_del_map_reply)                     \
3561 _(vxlan_gpe_add_del_tunnel_reply)                       \
3562 _(af_packet_delete_reply)                               \
3563 _(policer_classify_set_interface_reply)                 \
3564 _(netmap_create_reply)                                  \
3565 _(netmap_delete_reply)                                  \
3566 _(set_ipfix_exporter_reply)                             \
3567 _(set_ipfix_classify_stream_reply)                      \
3568 _(ipfix_classify_table_add_del_reply)                   \
3569 _(flow_classify_set_interface_reply)                    \
3570 _(pg_capture_reply)                                     \
3571 _(pg_enable_disable_reply)                              \
3572 _(ip_source_and_port_range_check_add_del_reply)         \
3573 _(ip_source_and_port_range_check_interface_add_del_reply)\
3574 _(delete_subif_reply)                                   \
3575 _(l2_interface_pbb_tag_rewrite_reply)                   \
3576 _(punt_reply)
3577
3578 #define _(n)                                    \
3579     static void vl_api_##n##_t_handler          \
3580     (vl_api_##n##_t * mp)                       \
3581     {                                           \
3582         vat_main_t * vam = &vat_main;           \
3583         i32 retval = ntohl(mp->retval);         \
3584         if (vam->async_mode) {                  \
3585             vam->async_errors += (retval < 0);  \
3586         } else {                                \
3587             vam->retval = retval;               \
3588             vam->result_ready = 1;              \
3589         }                                       \
3590     }
3591 foreach_standard_reply_retval_handler;
3592 #undef _
3593
3594 #define _(n)                                    \
3595     static void vl_api_##n##_t_handler_json     \
3596     (vl_api_##n##_t * mp)                       \
3597     {                                           \
3598         vat_main_t * vam = &vat_main;           \
3599         vat_json_node_t node;                   \
3600         vat_json_init_object(&node);            \
3601         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3602         vat_json_print(vam->ofp, &node);        \
3603         vam->retval = ntohl(mp->retval);        \
3604         vam->result_ready = 1;                  \
3605     }
3606 foreach_standard_reply_retval_handler;
3607 #undef _
3608
3609 /*
3610  * Table of message reply handlers, must include boilerplate handlers
3611  * we just generated
3612  */
3613
3614 #define foreach_vpe_api_reply_msg                                       \
3615 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3616 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3617 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3618 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3619 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3620 _(CLI_REPLY, cli_reply)                                                 \
3621 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3622 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3623   sw_interface_add_del_address_reply)                                   \
3624 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3625 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3626 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3627 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3628   sw_interface_set_l2_xconnect_reply)                                   \
3629 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3630   sw_interface_set_l2_bridge_reply)                                     \
3631 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3632   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3633 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3634   sw_interface_set_dpdk_hqos_subport_reply)                             \
3635 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3636   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3637 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3638 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3639 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3640 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3641 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3642 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3643 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3644 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3645 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3646 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3647 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3648 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3649 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3650 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3651 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3652   proxy_arp_intfc_enable_disable_reply)                                 \
3653 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3654 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3655   mpls_ethernet_add_del_tunnel_reply)                                   \
3656 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3657   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3658 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3659   sw_interface_set_unnumbered_reply)                                    \
3660 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3661 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3662 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3663 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3664 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3665 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3666 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3667 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3668 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3669 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3670 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3671 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3672   sw_interface_ip6_enable_disable_reply)                                \
3673 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3674   sw_interface_ip6_set_link_local_address_reply)                        \
3675 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3676   sw_interface_ip6nd_ra_prefix_reply)                                   \
3677 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3678   sw_interface_ip6nd_ra_config_reply)                                   \
3679 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3680 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3681 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3682 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3683 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3684 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3685 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3686 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3687 classify_set_interface_ip_table_reply)                                  \
3688 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3689   classify_set_interface_l2_tables_reply)                               \
3690 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3691 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3692 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3693 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3694 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3695   l2tpv3_interface_enable_disable_reply)                                \
3696 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3697 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3698 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3699 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3700 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3701 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3702 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3703 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3704 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3705 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3706 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3707 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3708 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3709 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3710 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3711 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3712 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3713 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3714 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3715 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3716 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3717 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3718 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3719 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3720 _(IP_DETAILS, ip_details)                                               \
3721 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3722 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3723 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3724 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3725 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3726 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3727 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3728 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3729 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3730 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3731 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3732 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3733 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3734 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3735 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3736 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3737 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3738 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3739 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3740 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3741 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3742 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3743 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3744 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3745 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3746 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3747 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3748 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3749 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3750 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3751 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3752 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3753 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3754 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3755 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3756 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3757 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3758 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3759 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3760 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3761 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3762 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3763 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3764 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3765 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3766 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3767 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3768 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3769 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3770 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3771 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3772 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3773 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3774   lisp_add_del_map_request_itr_rlocs_reply)                             \
3775 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3776   lisp_get_map_request_itr_rlocs_reply)                                 \
3777 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3778 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3779 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3780 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3781 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3782 _(POLICER_DETAILS, policer_details)                                     \
3783 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3784 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3785 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3786 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3787 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3788 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3789 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3790 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3791 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3792 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3793 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3794 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3795 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3796 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3797 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3798 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3799 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3800 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3801 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3802 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3803 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3804 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3805 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3806 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3807  ip_source_and_port_range_check_add_del_reply)                          \
3808 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3809  ip_source_and_port_range_check_interface_add_del_reply)                \
3810 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3811 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3812 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3813 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3814 _(PUNT_REPLY, punt_reply)
3815
3816 /* M: construct, but don't yet send a message */
3817
3818 #define M(T,t)                                  \
3819 do {                                            \
3820     vam->result_ready = 0;                      \
3821     mp = vl_msg_api_alloc(sizeof(*mp));         \
3822     memset (mp, 0, sizeof (*mp));               \
3823     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3824     mp->client_index = vam->my_client_index;    \
3825 } while(0);
3826
3827 #define M2(T,t,n)                               \
3828 do {                                            \
3829     vam->result_ready = 0;                      \
3830     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3831     memset (mp, 0, sizeof (*mp));               \
3832     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3833     mp->client_index = vam->my_client_index;    \
3834 } while(0);
3835
3836
3837 /* S: send a message */
3838 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3839
3840 /* W: wait for results, with timeout */
3841 #define W                                       \
3842 do {                                            \
3843     timeout = vat_time_now (vam) + 1.0;         \
3844                                                 \
3845     while (vat_time_now (vam) < timeout) {      \
3846         if (vam->result_ready == 1) {           \
3847             return (vam->retval);               \
3848         }                                       \
3849     }                                           \
3850     return -99;                                 \
3851 } while(0);
3852
3853 /* W2: wait for results, with timeout */
3854 #define W2(body)                                \
3855 do {                                            \
3856     timeout = vat_time_now (vam) + 1.0;         \
3857                                                 \
3858     while (vat_time_now (vam) < timeout) {      \
3859         if (vam->result_ready == 1) {           \
3860           (body);                               \
3861           return (vam->retval);                 \
3862         }                                       \
3863     }                                           \
3864     return -99;                                 \
3865 } while(0);
3866
3867 typedef struct
3868 {
3869   u8 *name;
3870   u32 value;
3871 } name_sort_t;
3872
3873
3874 #define STR_VTR_OP_CASE(op)     \
3875     case L2_VTR_ ## op:         \
3876         return "" # op;
3877
3878 static const char *
3879 str_vtr_op (u32 vtr_op)
3880 {
3881   switch (vtr_op)
3882     {
3883       STR_VTR_OP_CASE (DISABLED);
3884       STR_VTR_OP_CASE (PUSH_1);
3885       STR_VTR_OP_CASE (PUSH_2);
3886       STR_VTR_OP_CASE (POP_1);
3887       STR_VTR_OP_CASE (POP_2);
3888       STR_VTR_OP_CASE (TRANSLATE_1_1);
3889       STR_VTR_OP_CASE (TRANSLATE_1_2);
3890       STR_VTR_OP_CASE (TRANSLATE_2_1);
3891       STR_VTR_OP_CASE (TRANSLATE_2_2);
3892     }
3893
3894   return "UNKNOWN";
3895 }
3896
3897 static int
3898 dump_sub_interface_table (vat_main_t * vam)
3899 {
3900   const sw_interface_subif_t *sub = NULL;
3901
3902   if (vam->json_output)
3903     {
3904       clib_warning
3905         ("JSON output supported only for VPE API calls and dump_stats_table");
3906       return -99;
3907     }
3908
3909   fformat (vam->ofp,
3910            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3911            "Interface", "sw_if_index",
3912            "sub id", "dot1ad", "tags", "outer id",
3913            "inner id", "exact", "default", "outer any", "inner any");
3914
3915   vec_foreach (sub, vam->sw_if_subif_table)
3916   {
3917     fformat (vam->ofp,
3918              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3919              sub->interface_name,
3920              sub->sw_if_index,
3921              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3922              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3923              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3924              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3925     if (sub->vtr_op != L2_VTR_DISABLED)
3926       {
3927         fformat (vam->ofp,
3928                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3929                  "tag1: %d tag2: %d ]\n",
3930                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3931                  sub->vtr_tag1, sub->vtr_tag2);
3932       }
3933   }
3934
3935   return 0;
3936 }
3937
3938 static int
3939 name_sort_cmp (void *a1, void *a2)
3940 {
3941   name_sort_t *n1 = a1;
3942   name_sort_t *n2 = a2;
3943
3944   return strcmp ((char *) n1->name, (char *) n2->name);
3945 }
3946
3947 static int
3948 dump_interface_table (vat_main_t * vam)
3949 {
3950   hash_pair_t *p;
3951   name_sort_t *nses = 0, *ns;
3952
3953   if (vam->json_output)
3954     {
3955       clib_warning
3956         ("JSON output supported only for VPE API calls and dump_stats_table");
3957       return -99;
3958     }
3959
3960   /* *INDENT-OFF* */
3961   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3962   ({
3963     vec_add2 (nses, ns, 1);
3964     ns->name = (u8 *)(p->key);
3965     ns->value = (u32) p->value[0];
3966   }));
3967   /* *INDENT-ON* */
3968
3969   vec_sort_with_function (nses, name_sort_cmp);
3970
3971   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3972   vec_foreach (ns, nses)
3973   {
3974     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3975   }
3976   vec_free (nses);
3977   return 0;
3978 }
3979
3980 static int
3981 dump_ip_table (vat_main_t * vam, int is_ipv6)
3982 {
3983   const ip_details_t *det = NULL;
3984   const ip_address_details_t *address = NULL;
3985   u32 i = ~0;
3986
3987   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3988
3989   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3990   {
3991     i++;
3992     if (!det->present)
3993       {
3994         continue;
3995       }
3996     fformat (vam->ofp, "%-12d\n", i);
3997     fformat (vam->ofp,
3998              "            %-30s%-13s\n", "Address", "Prefix length");
3999     if (!det->addr)
4000       {
4001         continue;
4002       }
4003     vec_foreach (address, det->addr)
4004     {
4005       fformat (vam->ofp,
4006                "            %-30U%-13d\n",
4007                is_ipv6 ? format_ip6_address : format_ip4_address,
4008                address->ip, address->prefix_length);
4009     }
4010   }
4011
4012   return 0;
4013 }
4014
4015 static int
4016 dump_ipv4_table (vat_main_t * vam)
4017 {
4018   if (vam->json_output)
4019     {
4020       clib_warning
4021         ("JSON output supported only for VPE API calls and dump_stats_table");
4022       return -99;
4023     }
4024
4025   return dump_ip_table (vam, 0);
4026 }
4027
4028 static int
4029 dump_ipv6_table (vat_main_t * vam)
4030 {
4031   if (vam->json_output)
4032     {
4033       clib_warning
4034         ("JSON output supported only for VPE API calls and dump_stats_table");
4035       return -99;
4036     }
4037
4038   return dump_ip_table (vam, 1);
4039 }
4040
4041 static char *
4042 counter_type_to_str (u8 counter_type, u8 is_combined)
4043 {
4044   if (!is_combined)
4045     {
4046       switch (counter_type)
4047         {
4048         case VNET_INTERFACE_COUNTER_DROP:
4049           return "drop";
4050         case VNET_INTERFACE_COUNTER_PUNT:
4051           return "punt";
4052         case VNET_INTERFACE_COUNTER_IP4:
4053           return "ip4";
4054         case VNET_INTERFACE_COUNTER_IP6:
4055           return "ip6";
4056         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4057           return "rx-no-buf";
4058         case VNET_INTERFACE_COUNTER_RX_MISS:
4059           return "rx-miss";
4060         case VNET_INTERFACE_COUNTER_RX_ERROR:
4061           return "rx-error";
4062         case VNET_INTERFACE_COUNTER_TX_ERROR:
4063           return "tx-error";
4064         default:
4065           return "INVALID-COUNTER-TYPE";
4066         }
4067     }
4068   else
4069     {
4070       switch (counter_type)
4071         {
4072         case VNET_INTERFACE_COUNTER_RX:
4073           return "rx";
4074         case VNET_INTERFACE_COUNTER_TX:
4075           return "tx";
4076         default:
4077           return "INVALID-COUNTER-TYPE";
4078         }
4079     }
4080 }
4081
4082 static int
4083 dump_stats_table (vat_main_t * vam)
4084 {
4085   vat_json_node_t node;
4086   vat_json_node_t *msg_array;
4087   vat_json_node_t *msg;
4088   vat_json_node_t *counter_array;
4089   vat_json_node_t *counter;
4090   interface_counter_t c;
4091   u64 packets;
4092   ip4_fib_counter_t *c4;
4093   ip6_fib_counter_t *c6;
4094   int i, j;
4095
4096   if (!vam->json_output)
4097     {
4098       clib_warning ("dump_stats_table supported only in JSON format");
4099       return -99;
4100     }
4101
4102   vat_json_init_object (&node);
4103
4104   /* interface counters */
4105   msg_array = vat_json_object_add (&node, "interface_counters");
4106   vat_json_init_array (msg_array);
4107   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4108     {
4109       msg = vat_json_array_add (msg_array);
4110       vat_json_init_object (msg);
4111       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4112                                        (u8 *) counter_type_to_str (i, 0));
4113       vat_json_object_add_int (msg, "is_combined", 0);
4114       counter_array = vat_json_object_add (msg, "data");
4115       vat_json_init_array (counter_array);
4116       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4117         {
4118           packets = vam->simple_interface_counters[i][j];
4119           vat_json_array_add_uint (counter_array, packets);
4120         }
4121     }
4122   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4123     {
4124       msg = vat_json_array_add (msg_array);
4125       vat_json_init_object (msg);
4126       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4127                                        (u8 *) counter_type_to_str (i, 1));
4128       vat_json_object_add_int (msg, "is_combined", 1);
4129       counter_array = vat_json_object_add (msg, "data");
4130       vat_json_init_array (counter_array);
4131       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4132         {
4133           c = vam->combined_interface_counters[i][j];
4134           counter = vat_json_array_add (counter_array);
4135           vat_json_init_object (counter);
4136           vat_json_object_add_uint (counter, "packets", c.packets);
4137           vat_json_object_add_uint (counter, "bytes", c.bytes);
4138         }
4139     }
4140
4141   /* ip4 fib counters */
4142   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4143   vat_json_init_array (msg_array);
4144   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4145     {
4146       msg = vat_json_array_add (msg_array);
4147       vat_json_init_object (msg);
4148       vat_json_object_add_uint (msg, "vrf_id",
4149                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4150       counter_array = vat_json_object_add (msg, "c");
4151       vat_json_init_array (counter_array);
4152       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4153         {
4154           counter = vat_json_array_add (counter_array);
4155           vat_json_init_object (counter);
4156           c4 = &vam->ip4_fib_counters[i][j];
4157           vat_json_object_add_ip4 (counter, "address", c4->address);
4158           vat_json_object_add_uint (counter, "address_length",
4159                                     c4->address_length);
4160           vat_json_object_add_uint (counter, "packets", c4->packets);
4161           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4162         }
4163     }
4164
4165   /* ip6 fib counters */
4166   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4167   vat_json_init_array (msg_array);
4168   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4169     {
4170       msg = vat_json_array_add (msg_array);
4171       vat_json_init_object (msg);
4172       vat_json_object_add_uint (msg, "vrf_id",
4173                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4174       counter_array = vat_json_object_add (msg, "c");
4175       vat_json_init_array (counter_array);
4176       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4177         {
4178           counter = vat_json_array_add (counter_array);
4179           vat_json_init_object (counter);
4180           c6 = &vam->ip6_fib_counters[i][j];
4181           vat_json_object_add_ip6 (counter, "address", c6->address);
4182           vat_json_object_add_uint (counter, "address_length",
4183                                     c6->address_length);
4184           vat_json_object_add_uint (counter, "packets", c6->packets);
4185           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4186         }
4187     }
4188
4189   vat_json_print (vam->ofp, &node);
4190   vat_json_free (&node);
4191
4192   return 0;
4193 }
4194
4195 int
4196 exec (vat_main_t * vam)
4197 {
4198   api_main_t *am = &api_main;
4199   vl_api_cli_request_t *mp;
4200   f64 timeout;
4201   void *oldheap;
4202   u8 *cmd = 0;
4203   unformat_input_t *i = vam->input;
4204
4205   if (vec_len (i->buffer) == 0)
4206     return -1;
4207
4208   if (vam->exec_mode == 0 && unformat (i, "mode"))
4209     {
4210       vam->exec_mode = 1;
4211       return 0;
4212     }
4213   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4214     {
4215       vam->exec_mode = 0;
4216       return 0;
4217     }
4218
4219
4220   M (CLI_REQUEST, cli_request);
4221
4222   /*
4223    * Copy cmd into shared memory.
4224    * In order for the CLI command to work, it
4225    * must be a vector ending in \n, not a C-string ending
4226    * in \n\0.
4227    */
4228   pthread_mutex_lock (&am->vlib_rp->mutex);
4229   oldheap = svm_push_data_heap (am->vlib_rp);
4230
4231   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4232   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4233
4234   svm_pop_heap (oldheap);
4235   pthread_mutex_unlock (&am->vlib_rp->mutex);
4236
4237   mp->cmd_in_shmem = (u64) cmd;
4238   S;
4239   timeout = vat_time_now (vam) + 10.0;
4240
4241   while (vat_time_now (vam) < timeout)
4242     {
4243       if (vam->result_ready == 1)
4244         {
4245           u8 *free_me;
4246           if (vam->shmem_result != NULL)
4247             fformat (vam->ofp, "%s", vam->shmem_result);
4248           pthread_mutex_lock (&am->vlib_rp->mutex);
4249           oldheap = svm_push_data_heap (am->vlib_rp);
4250
4251           free_me = (u8 *) vam->shmem_result;
4252           vec_free (free_me);
4253
4254           svm_pop_heap (oldheap);
4255           pthread_mutex_unlock (&am->vlib_rp->mutex);
4256           return 0;
4257         }
4258     }
4259   return -99;
4260 }
4261
4262 /*
4263  * Future replacement of exec() that passes CLI buffers directly in
4264  * the API messages instead of an additional shared memory area.
4265  */
4266 static int
4267 exec_inband (vat_main_t * vam)
4268 {
4269   vl_api_cli_inband_t *mp;
4270   f64 timeout;
4271   unformat_input_t *i = vam->input;
4272
4273   if (vec_len (i->buffer) == 0)
4274     return -1;
4275
4276   if (vam->exec_mode == 0 && unformat (i, "mode"))
4277     {
4278       vam->exec_mode = 1;
4279       return 0;
4280     }
4281   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4282     {
4283       vam->exec_mode = 0;
4284       return 0;
4285     }
4286
4287   /*
4288    * In order for the CLI command to work, it
4289    * must be a vector ending in \n, not a C-string ending
4290    * in \n\0.
4291    */
4292   u32 len = vec_len (vam->input->buffer);
4293   M2 (CLI_INBAND, cli_inband, len);
4294   clib_memcpy (mp->cmd, vam->input->buffer, len);
4295   mp->length = htonl (len);
4296
4297   S;
4298   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4299 }
4300
4301 static int
4302 api_create_loopback (vat_main_t * vam)
4303 {
4304   unformat_input_t *i = vam->input;
4305   vl_api_create_loopback_t *mp;
4306   f64 timeout;
4307   u8 mac_address[6];
4308   u8 mac_set = 0;
4309
4310   memset (mac_address, 0, sizeof (mac_address));
4311
4312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4313     {
4314       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4315         mac_set = 1;
4316       else
4317         break;
4318     }
4319
4320   /* Construct the API message */
4321   M (CREATE_LOOPBACK, create_loopback);
4322   if (mac_set)
4323     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4324
4325   S;
4326   W;
4327 }
4328
4329 static int
4330 api_delete_loopback (vat_main_t * vam)
4331 {
4332   unformat_input_t *i = vam->input;
4333   vl_api_delete_loopback_t *mp;
4334   f64 timeout;
4335   u32 sw_if_index = ~0;
4336
4337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4338     {
4339       if (unformat (i, "sw_if_index %d", &sw_if_index))
4340         ;
4341       else
4342         break;
4343     }
4344
4345   if (sw_if_index == ~0)
4346     {
4347       errmsg ("missing sw_if_index\n");
4348       return -99;
4349     }
4350
4351   /* Construct the API message */
4352   M (DELETE_LOOPBACK, delete_loopback);
4353   mp->sw_if_index = ntohl (sw_if_index);
4354
4355   S;
4356   W;
4357 }
4358
4359 static int
4360 api_want_stats (vat_main_t * vam)
4361 {
4362   unformat_input_t *i = vam->input;
4363   vl_api_want_stats_t *mp;
4364   f64 timeout;
4365   int enable = -1;
4366
4367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4368     {
4369       if (unformat (i, "enable"))
4370         enable = 1;
4371       else if (unformat (i, "disable"))
4372         enable = 0;
4373       else
4374         break;
4375     }
4376
4377   if (enable == -1)
4378     {
4379       errmsg ("missing enable|disable\n");
4380       return -99;
4381     }
4382
4383   M (WANT_STATS, want_stats);
4384   mp->enable_disable = enable;
4385
4386   S;
4387   W;
4388 }
4389
4390 static int
4391 api_want_interface_events (vat_main_t * vam)
4392 {
4393   unformat_input_t *i = vam->input;
4394   vl_api_want_interface_events_t *mp;
4395   f64 timeout;
4396   int enable = -1;
4397
4398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4399     {
4400       if (unformat (i, "enable"))
4401         enable = 1;
4402       else if (unformat (i, "disable"))
4403         enable = 0;
4404       else
4405         break;
4406     }
4407
4408   if (enable == -1)
4409     {
4410       errmsg ("missing enable|disable\n");
4411       return -99;
4412     }
4413
4414   M (WANT_INTERFACE_EVENTS, want_interface_events);
4415   mp->enable_disable = enable;
4416
4417   vam->interface_event_display = enable;
4418
4419   S;
4420   W;
4421 }
4422
4423
4424 /* Note: non-static, called once to set up the initial intfc table */
4425 int
4426 api_sw_interface_dump (vat_main_t * vam)
4427 {
4428   vl_api_sw_interface_dump_t *mp;
4429   f64 timeout;
4430   hash_pair_t *p;
4431   name_sort_t *nses = 0, *ns;
4432   sw_interface_subif_t *sub = NULL;
4433
4434   /* Toss the old name table */
4435   /* *INDENT-OFF* */
4436   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4437   ({
4438     vec_add2 (nses, ns, 1);
4439     ns->name = (u8 *)(p->key);
4440     ns->value = (u32) p->value[0];
4441   }));
4442   /* *INDENT-ON* */
4443
4444   hash_free (vam->sw_if_index_by_interface_name);
4445
4446   vec_foreach (ns, nses) vec_free (ns->name);
4447
4448   vec_free (nses);
4449
4450   vec_foreach (sub, vam->sw_if_subif_table)
4451   {
4452     vec_free (sub->interface_name);
4453   }
4454   vec_free (vam->sw_if_subif_table);
4455
4456   /* recreate the interface name hash table */
4457   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4458
4459   /* Get list of ethernets */
4460   M (SW_INTERFACE_DUMP, sw_interface_dump);
4461   mp->name_filter_valid = 1;
4462   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4463   S;
4464
4465   /* and local / loopback interfaces */
4466   M (SW_INTERFACE_DUMP, sw_interface_dump);
4467   mp->name_filter_valid = 1;
4468   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4469   S;
4470
4471   /* and packet-generator interfaces */
4472   M (SW_INTERFACE_DUMP, sw_interface_dump);
4473   mp->name_filter_valid = 1;
4474   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4475   S;
4476
4477   /* and vxlan-gpe tunnel interfaces */
4478   M (SW_INTERFACE_DUMP, sw_interface_dump);
4479   mp->name_filter_valid = 1;
4480   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4481            sizeof (mp->name_filter) - 1);
4482   S;
4483
4484   /* and vxlan tunnel interfaces */
4485   M (SW_INTERFACE_DUMP, sw_interface_dump);
4486   mp->name_filter_valid = 1;
4487   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4488   S;
4489
4490   /* and host (af_packet) interfaces */
4491   M (SW_INTERFACE_DUMP, sw_interface_dump);
4492   mp->name_filter_valid = 1;
4493   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4494   S;
4495
4496   /* and l2tpv3 tunnel interfaces */
4497   M (SW_INTERFACE_DUMP, sw_interface_dump);
4498   mp->name_filter_valid = 1;
4499   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4500            sizeof (mp->name_filter) - 1);
4501   S;
4502
4503   /* and GRE tunnel interfaces */
4504   M (SW_INTERFACE_DUMP, sw_interface_dump);
4505   mp->name_filter_valid = 1;
4506   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4507   S;
4508
4509   /* and LISP-GPE interfaces */
4510   M (SW_INTERFACE_DUMP, sw_interface_dump);
4511   mp->name_filter_valid = 1;
4512   strncpy ((char *) mp->name_filter, "lisp_gpe",
4513            sizeof (mp->name_filter) - 1);
4514   S;
4515
4516   /* and IPSEC tunnel interfaces */
4517   M (SW_INTERFACE_DUMP, sw_interface_dump);
4518   mp->name_filter_valid = 1;
4519   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4520   S;
4521
4522   /* Use a control ping for synchronization */
4523   {
4524     vl_api_control_ping_t *mp;
4525     M (CONTROL_PING, control_ping);
4526     S;
4527   }
4528   W;
4529 }
4530
4531 static int
4532 api_sw_interface_set_flags (vat_main_t * vam)
4533 {
4534   unformat_input_t *i = vam->input;
4535   vl_api_sw_interface_set_flags_t *mp;
4536   f64 timeout;
4537   u32 sw_if_index;
4538   u8 sw_if_index_set = 0;
4539   u8 admin_up = 0, link_up = 0;
4540
4541   /* Parse args required to build the message */
4542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4543     {
4544       if (unformat (i, "admin-up"))
4545         admin_up = 1;
4546       else if (unformat (i, "admin-down"))
4547         admin_up = 0;
4548       else if (unformat (i, "link-up"))
4549         link_up = 1;
4550       else if (unformat (i, "link-down"))
4551         link_up = 0;
4552       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4553         sw_if_index_set = 1;
4554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4555         sw_if_index_set = 1;
4556       else
4557         break;
4558     }
4559
4560   if (sw_if_index_set == 0)
4561     {
4562       errmsg ("missing interface name or sw_if_index\n");
4563       return -99;
4564     }
4565
4566   /* Construct the API message */
4567   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4568   mp->sw_if_index = ntohl (sw_if_index);
4569   mp->admin_up_down = admin_up;
4570   mp->link_up_down = link_up;
4571
4572   /* send it... */
4573   S;
4574
4575   /* Wait for a reply, return the good/bad news... */
4576   W;
4577 }
4578
4579 static int
4580 api_sw_interface_clear_stats (vat_main_t * vam)
4581 {
4582   unformat_input_t *i = vam->input;
4583   vl_api_sw_interface_clear_stats_t *mp;
4584   f64 timeout;
4585   u32 sw_if_index;
4586   u8 sw_if_index_set = 0;
4587
4588   /* Parse args required to build the message */
4589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4590     {
4591       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4592         sw_if_index_set = 1;
4593       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4594         sw_if_index_set = 1;
4595       else
4596         break;
4597     }
4598
4599   /* Construct the API message */
4600   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4601
4602   if (sw_if_index_set == 1)
4603     mp->sw_if_index = ntohl (sw_if_index);
4604   else
4605     mp->sw_if_index = ~0;
4606
4607   /* send it... */
4608   S;
4609
4610   /* Wait for a reply, return the good/bad news... */
4611   W;
4612 }
4613
4614 static int
4615 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4616 {
4617   unformat_input_t *i = vam->input;
4618   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4619   f64 timeout;
4620   u32 sw_if_index;
4621   u8 sw_if_index_set = 0;
4622   u32 subport;
4623   u8 subport_set = 0;
4624   u32 pipe;
4625   u8 pipe_set = 0;
4626   u32 profile;
4627   u8 profile_set = 0;
4628
4629   /* Parse args required to build the message */
4630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4631     {
4632       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4633         sw_if_index_set = 1;
4634       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4635         sw_if_index_set = 1;
4636       else if (unformat (i, "subport %u", &subport))
4637         subport_set = 1;
4638       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4639         sw_if_index_set = 1;
4640       else if (unformat (i, "pipe %u", &pipe))
4641         pipe_set = 1;
4642       else if (unformat (i, "profile %u", &profile))
4643         profile_set = 1;
4644       else
4645         break;
4646     }
4647
4648   if (sw_if_index_set == 0)
4649     {
4650       errmsg ("missing interface name or sw_if_index\n");
4651       return -99;
4652     }
4653
4654   if (subport_set == 0)
4655     {
4656       errmsg ("missing subport \n");
4657       return -99;
4658     }
4659
4660   if (pipe_set == 0)
4661     {
4662       errmsg ("missing pipe\n");
4663       return -99;
4664     }
4665
4666   if (profile_set == 0)
4667     {
4668       errmsg ("missing profile\n");
4669       return -99;
4670     }
4671
4672   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4673
4674   mp->sw_if_index = ntohl (sw_if_index);
4675   mp->subport = ntohl (subport);
4676   mp->pipe = ntohl (pipe);
4677   mp->profile = ntohl (profile);
4678
4679
4680   S;
4681   W;
4682   /* NOTREACHED */
4683   return 0;
4684 }
4685
4686 static int
4687 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4688 {
4689   unformat_input_t *i = vam->input;
4690   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4691   f64 timeout;
4692   u32 sw_if_index;
4693   u8 sw_if_index_set = 0;
4694   u32 subport;
4695   u8 subport_set = 0;
4696   u32 tb_rate = 1250000000;     /* 10GbE */
4697   u32 tb_size = 1000000;
4698   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4699   u32 tc_period = 10;
4700
4701   /* Parse args required to build the message */
4702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4703     {
4704       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4705         sw_if_index_set = 1;
4706       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4707         sw_if_index_set = 1;
4708       else if (unformat (i, "subport %u", &subport))
4709         subport_set = 1;
4710       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4711         sw_if_index_set = 1;
4712       else if (unformat (i, "rate %u", &tb_rate))
4713         {
4714           u32 tc_id;
4715
4716           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4717                tc_id++)
4718             tc_rate[tc_id] = tb_rate;
4719         }
4720       else if (unformat (i, "bktsize %u", &tb_size))
4721         ;
4722       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4723         ;
4724       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4725         ;
4726       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4727         ;
4728       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4729         ;
4730       else if (unformat (i, "period %u", &tc_period))
4731         ;
4732       else
4733         break;
4734     }
4735
4736   if (sw_if_index_set == 0)
4737     {
4738       errmsg ("missing interface name or sw_if_index\n");
4739       return -99;
4740     }
4741
4742   if (subport_set == 0)
4743     {
4744       errmsg ("missing subport \n");
4745       return -99;
4746     }
4747
4748   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4749
4750   mp->sw_if_index = ntohl (sw_if_index);
4751   mp->subport = ntohl (subport);
4752   mp->tb_rate = ntohl (tb_rate);
4753   mp->tb_size = ntohl (tb_size);
4754   mp->tc_rate[0] = ntohl (tc_rate[0]);
4755   mp->tc_rate[1] = ntohl (tc_rate[1]);
4756   mp->tc_rate[2] = ntohl (tc_rate[2]);
4757   mp->tc_rate[3] = ntohl (tc_rate[3]);
4758   mp->tc_period = ntohl (tc_period);
4759
4760   S;
4761   W;
4762   /* NOTREACHED */
4763   return 0;
4764 }
4765
4766 static int
4767 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4768 {
4769   unformat_input_t *i = vam->input;
4770   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4771   f64 timeout;
4772   u32 sw_if_index;
4773   u8 sw_if_index_set = 0;
4774   u8 entry_set = 0;
4775   u8 tc_set = 0;
4776   u8 queue_set = 0;
4777   u32 entry, tc, queue;
4778
4779   /* Parse args required to build the message */
4780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4781     {
4782       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4783         sw_if_index_set = 1;
4784       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4785         sw_if_index_set = 1;
4786       else if (unformat (i, "entry %d", &entry))
4787         entry_set = 1;
4788       else if (unformat (i, "tc %d", &tc))
4789         tc_set = 1;
4790       else if (unformat (i, "queue %d", &queue))
4791         queue_set = 1;
4792       else
4793         break;
4794     }
4795
4796   if (sw_if_index_set == 0)
4797     {
4798       errmsg ("missing interface name or sw_if_index\n");
4799       return -99;
4800     }
4801
4802   if (entry_set == 0)
4803     {
4804       errmsg ("missing entry \n");
4805       return -99;
4806     }
4807
4808   if (tc_set == 0)
4809     {
4810       errmsg ("missing traffic class \n");
4811       return -99;
4812     }
4813
4814   if (queue_set == 0)
4815     {
4816       errmsg ("missing queue \n");
4817       return -99;
4818     }
4819
4820   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4821
4822   mp->sw_if_index = ntohl (sw_if_index);
4823   mp->entry = ntohl (entry);
4824   mp->tc = ntohl (tc);
4825   mp->queue = ntohl (queue);
4826
4827   S;
4828   W;
4829   /* NOTREACHED */
4830   return 0;
4831 }
4832
4833 static int
4834 api_sw_interface_add_del_address (vat_main_t * vam)
4835 {
4836   unformat_input_t *i = vam->input;
4837   vl_api_sw_interface_add_del_address_t *mp;
4838   f64 timeout;
4839   u32 sw_if_index;
4840   u8 sw_if_index_set = 0;
4841   u8 is_add = 1, del_all = 0;
4842   u32 address_length = 0;
4843   u8 v4_address_set = 0;
4844   u8 v6_address_set = 0;
4845   ip4_address_t v4address;
4846   ip6_address_t v6address;
4847
4848   /* Parse args required to build the message */
4849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4850     {
4851       if (unformat (i, "del-all"))
4852         del_all = 1;
4853       else if (unformat (i, "del"))
4854         is_add = 0;
4855       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4856         sw_if_index_set = 1;
4857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4858         sw_if_index_set = 1;
4859       else if (unformat (i, "%U/%d",
4860                          unformat_ip4_address, &v4address, &address_length))
4861         v4_address_set = 1;
4862       else if (unformat (i, "%U/%d",
4863                          unformat_ip6_address, &v6address, &address_length))
4864         v6_address_set = 1;
4865       else
4866         break;
4867     }
4868
4869   if (sw_if_index_set == 0)
4870     {
4871       errmsg ("missing interface name or sw_if_index\n");
4872       return -99;
4873     }
4874   if (v4_address_set && v6_address_set)
4875     {
4876       errmsg ("both v4 and v6 addresses set\n");
4877       return -99;
4878     }
4879   if (!v4_address_set && !v6_address_set && !del_all)
4880     {
4881       errmsg ("no addresses set\n");
4882       return -99;
4883     }
4884
4885   /* Construct the API message */
4886   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4887
4888   mp->sw_if_index = ntohl (sw_if_index);
4889   mp->is_add = is_add;
4890   mp->del_all = del_all;
4891   if (v6_address_set)
4892     {
4893       mp->is_ipv6 = 1;
4894       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4895     }
4896   else
4897     {
4898       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4899     }
4900   mp->address_length = address_length;
4901
4902   /* send it... */
4903   S;
4904
4905   /* Wait for a reply, return good/bad news  */
4906   W;
4907 }
4908
4909 static int
4910 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4911 {
4912   unformat_input_t *i = vam->input;
4913   vl_api_sw_interface_set_mpls_enable_t *mp;
4914   f64 timeout;
4915   u32 sw_if_index;
4916   u8 sw_if_index_set = 0;
4917   u8 enable = 1;
4918
4919   /* Parse args required to build the message */
4920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4921     {
4922       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4923         sw_if_index_set = 1;
4924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4925         sw_if_index_set = 1;
4926       else if (unformat (i, "disable"))
4927         enable = 0;
4928       else if (unformat (i, "dis"))
4929         enable = 0;
4930       else
4931         break;
4932     }
4933
4934   if (sw_if_index_set == 0)
4935     {
4936       errmsg ("missing interface name or sw_if_index\n");
4937       return -99;
4938     }
4939
4940   /* Construct the API message */
4941   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4942
4943   mp->sw_if_index = ntohl (sw_if_index);
4944   mp->enable = enable;
4945
4946   /* send it... */
4947   S;
4948
4949   /* Wait for a reply... */
4950   W;
4951 }
4952
4953 static int
4954 api_sw_interface_set_table (vat_main_t * vam)
4955 {
4956   unformat_input_t *i = vam->input;
4957   vl_api_sw_interface_set_table_t *mp;
4958   f64 timeout;
4959   u32 sw_if_index, vrf_id = 0;
4960   u8 sw_if_index_set = 0;
4961   u8 is_ipv6 = 0;
4962
4963   /* Parse args required to build the message */
4964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4965     {
4966       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4967         sw_if_index_set = 1;
4968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4969         sw_if_index_set = 1;
4970       else if (unformat (i, "vrf %d", &vrf_id))
4971         ;
4972       else if (unformat (i, "ipv6"))
4973         is_ipv6 = 1;
4974       else
4975         break;
4976     }
4977
4978   if (sw_if_index_set == 0)
4979     {
4980       errmsg ("missing interface name or sw_if_index\n");
4981       return -99;
4982     }
4983
4984   /* Construct the API message */
4985   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4986
4987   mp->sw_if_index = ntohl (sw_if_index);
4988   mp->is_ipv6 = is_ipv6;
4989   mp->vrf_id = ntohl (vrf_id);
4990
4991   /* send it... */
4992   S;
4993
4994   /* Wait for a reply... */
4995   W;
4996 }
4997
4998 static int
4999 api_sw_interface_set_vpath (vat_main_t * vam)
5000 {
5001   unformat_input_t *i = vam->input;
5002   vl_api_sw_interface_set_vpath_t *mp;
5003   f64 timeout;
5004   u32 sw_if_index = 0;
5005   u8 sw_if_index_set = 0;
5006   u8 is_enable = 0;
5007
5008   /* Parse args required to build the message */
5009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5010     {
5011       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5012         sw_if_index_set = 1;
5013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5014         sw_if_index_set = 1;
5015       else if (unformat (i, "enable"))
5016         is_enable = 1;
5017       else if (unformat (i, "disable"))
5018         is_enable = 0;
5019       else
5020         break;
5021     }
5022
5023   if (sw_if_index_set == 0)
5024     {
5025       errmsg ("missing interface name or sw_if_index\n");
5026       return -99;
5027     }
5028
5029   /* Construct the API message */
5030   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5031
5032   mp->sw_if_index = ntohl (sw_if_index);
5033   mp->enable = is_enable;
5034
5035   /* send it... */
5036   S;
5037
5038   /* Wait for a reply... */
5039   W;
5040 }
5041
5042 static int
5043 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5044 {
5045   unformat_input_t *i = vam->input;
5046   vl_api_sw_interface_set_l2_xconnect_t *mp;
5047   f64 timeout;
5048   u32 rx_sw_if_index;
5049   u8 rx_sw_if_index_set = 0;
5050   u32 tx_sw_if_index;
5051   u8 tx_sw_if_index_set = 0;
5052   u8 enable = 1;
5053
5054   /* Parse args required to build the message */
5055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5056     {
5057       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5058         rx_sw_if_index_set = 1;
5059       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5060         tx_sw_if_index_set = 1;
5061       else if (unformat (i, "rx"))
5062         {
5063           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5064             {
5065               if (unformat (i, "%U", unformat_sw_if_index, vam,
5066                             &rx_sw_if_index))
5067                 rx_sw_if_index_set = 1;
5068             }
5069           else
5070             break;
5071         }
5072       else if (unformat (i, "tx"))
5073         {
5074           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5075             {
5076               if (unformat (i, "%U", unformat_sw_if_index, vam,
5077                             &tx_sw_if_index))
5078                 tx_sw_if_index_set = 1;
5079             }
5080           else
5081             break;
5082         }
5083       else if (unformat (i, "enable"))
5084         enable = 1;
5085       else if (unformat (i, "disable"))
5086         enable = 0;
5087       else
5088         break;
5089     }
5090
5091   if (rx_sw_if_index_set == 0)
5092     {
5093       errmsg ("missing rx interface name or rx_sw_if_index\n");
5094       return -99;
5095     }
5096
5097   if (enable && (tx_sw_if_index_set == 0))
5098     {
5099       errmsg ("missing tx interface name or tx_sw_if_index\n");
5100       return -99;
5101     }
5102
5103   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5104
5105   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5106   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5107   mp->enable = enable;
5108
5109   S;
5110   W;
5111   /* NOTREACHED */
5112   return 0;
5113 }
5114
5115 static int
5116 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5117 {
5118   unformat_input_t *i = vam->input;
5119   vl_api_sw_interface_set_l2_bridge_t *mp;
5120   f64 timeout;
5121   u32 rx_sw_if_index;
5122   u8 rx_sw_if_index_set = 0;
5123   u32 bd_id;
5124   u8 bd_id_set = 0;
5125   u8 bvi = 0;
5126   u32 shg = 0;
5127   u8 enable = 1;
5128
5129   /* Parse args required to build the message */
5130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5131     {
5132       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5133         rx_sw_if_index_set = 1;
5134       else if (unformat (i, "bd_id %d", &bd_id))
5135         bd_id_set = 1;
5136       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5137         rx_sw_if_index_set = 1;
5138       else if (unformat (i, "shg %d", &shg))
5139         ;
5140       else if (unformat (i, "bvi"))
5141         bvi = 1;
5142       else if (unformat (i, "enable"))
5143         enable = 1;
5144       else if (unformat (i, "disable"))
5145         enable = 0;
5146       else
5147         break;
5148     }
5149
5150   if (rx_sw_if_index_set == 0)
5151     {
5152       errmsg ("missing rx interface name or sw_if_index\n");
5153       return -99;
5154     }
5155
5156   if (enable && (bd_id_set == 0))
5157     {
5158       errmsg ("missing bridge domain\n");
5159       return -99;
5160     }
5161
5162   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5163
5164   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5165   mp->bd_id = ntohl (bd_id);
5166   mp->shg = (u8) shg;
5167   mp->bvi = bvi;
5168   mp->enable = enable;
5169
5170   S;
5171   W;
5172   /* NOTREACHED */
5173   return 0;
5174 }
5175
5176 static int
5177 api_bridge_domain_dump (vat_main_t * vam)
5178 {
5179   unformat_input_t *i = vam->input;
5180   vl_api_bridge_domain_dump_t *mp;
5181   f64 timeout;
5182   u32 bd_id = ~0;
5183
5184   /* Parse args required to build the message */
5185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5186     {
5187       if (unformat (i, "bd_id %d", &bd_id))
5188         ;
5189       else
5190         break;
5191     }
5192
5193   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5194   mp->bd_id = ntohl (bd_id);
5195   S;
5196
5197   /* Use a control ping for synchronization */
5198   {
5199     vl_api_control_ping_t *mp;
5200     M (CONTROL_PING, control_ping);
5201     S;
5202   }
5203
5204   W;
5205   /* NOTREACHED */
5206   return 0;
5207 }
5208
5209 static int
5210 api_bridge_domain_add_del (vat_main_t * vam)
5211 {
5212   unformat_input_t *i = vam->input;
5213   vl_api_bridge_domain_add_del_t *mp;
5214   f64 timeout;
5215   u32 bd_id = ~0;
5216   u8 is_add = 1;
5217   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5218
5219   /* Parse args required to build the message */
5220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5221     {
5222       if (unformat (i, "bd_id %d", &bd_id))
5223         ;
5224       else if (unformat (i, "flood %d", &flood))
5225         ;
5226       else if (unformat (i, "uu-flood %d", &uu_flood))
5227         ;
5228       else if (unformat (i, "forward %d", &forward))
5229         ;
5230       else if (unformat (i, "learn %d", &learn))
5231         ;
5232       else if (unformat (i, "arp-term %d", &arp_term))
5233         ;
5234       else if (unformat (i, "del"))
5235         {
5236           is_add = 0;
5237           flood = uu_flood = forward = learn = 0;
5238         }
5239       else
5240         break;
5241     }
5242
5243   if (bd_id == ~0)
5244     {
5245       errmsg ("missing bridge domain\n");
5246       return -99;
5247     }
5248
5249   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5250
5251   mp->bd_id = ntohl (bd_id);
5252   mp->flood = flood;
5253   mp->uu_flood = uu_flood;
5254   mp->forward = forward;
5255   mp->learn = learn;
5256   mp->arp_term = arp_term;
5257   mp->is_add = is_add;
5258
5259   S;
5260   W;
5261   /* NOTREACHED */
5262   return 0;
5263 }
5264
5265 static int
5266 api_l2fib_add_del (vat_main_t * vam)
5267 {
5268   unformat_input_t *i = vam->input;
5269   vl_api_l2fib_add_del_t *mp;
5270   f64 timeout;
5271   u64 mac = 0;
5272   u8 mac_set = 0;
5273   u32 bd_id;
5274   u8 bd_id_set = 0;
5275   u32 sw_if_index;
5276   u8 sw_if_index_set = 0;
5277   u8 is_add = 1;
5278   u8 static_mac = 0;
5279   u8 filter_mac = 0;
5280   u8 bvi_mac = 0;
5281   int count = 1;
5282   f64 before = 0;
5283   int j;
5284
5285   /* Parse args required to build the message */
5286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5287     {
5288       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5289         mac_set = 1;
5290       else if (unformat (i, "bd_id %d", &bd_id))
5291         bd_id_set = 1;
5292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5293         sw_if_index_set = 1;
5294       else if (unformat (i, "sw_if"))
5295         {
5296           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5297             {
5298               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5299                 sw_if_index_set = 1;
5300             }
5301           else
5302             break;
5303         }
5304       else if (unformat (i, "static"))
5305         static_mac = 1;
5306       else if (unformat (i, "filter"))
5307         {
5308           filter_mac = 1;
5309           static_mac = 1;
5310         }
5311       else if (unformat (i, "bvi"))
5312         {
5313           bvi_mac = 1;
5314           static_mac = 1;
5315         }
5316       else if (unformat (i, "del"))
5317         is_add = 0;
5318       else if (unformat (i, "count %d", &count))
5319         ;
5320       else
5321         break;
5322     }
5323
5324   if (mac_set == 0)
5325     {
5326       errmsg ("missing mac address\n");
5327       return -99;
5328     }
5329
5330   if (bd_id_set == 0)
5331     {
5332       errmsg ("missing bridge domain\n");
5333       return -99;
5334     }
5335
5336   if (is_add && (sw_if_index_set == 0))
5337     {
5338       errmsg ("missing interface name or sw_if_index\n");
5339       return -99;
5340     }
5341
5342   if (count > 1)
5343     {
5344       /* Turn on async mode */
5345       vam->async_mode = 1;
5346       vam->async_errors = 0;
5347       before = vat_time_now (vam);
5348     }
5349
5350   for (j = 0; j < count; j++)
5351     {
5352       M (L2FIB_ADD_DEL, l2fib_add_del);
5353
5354       mp->mac = mac;
5355       mp->bd_id = ntohl (bd_id);
5356       mp->is_add = is_add;
5357
5358       if (is_add)
5359         {
5360           mp->sw_if_index = ntohl (sw_if_index);
5361           mp->static_mac = static_mac;
5362           mp->filter_mac = filter_mac;
5363           mp->bvi_mac = bvi_mac;
5364         }
5365       increment_mac_address (&mac);
5366       /* send it... */
5367       S;
5368     }
5369
5370   if (count > 1)
5371     {
5372       vl_api_control_ping_t *mp;
5373       f64 after;
5374
5375       /* Shut off async mode */
5376       vam->async_mode = 0;
5377
5378       M (CONTROL_PING, control_ping);
5379       S;
5380
5381       timeout = vat_time_now (vam) + 1.0;
5382       while (vat_time_now (vam) < timeout)
5383         if (vam->result_ready == 1)
5384           goto out;
5385       vam->retval = -99;
5386
5387     out:
5388       if (vam->retval == -99)
5389         errmsg ("timeout\n");
5390
5391       if (vam->async_errors > 0)
5392         {
5393           errmsg ("%d asynchronous errors\n", vam->async_errors);
5394           vam->retval = -98;
5395         }
5396       vam->async_errors = 0;
5397       after = vat_time_now (vam);
5398
5399       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5400                count, after - before, count / (after - before));
5401     }
5402   else
5403     {
5404       /* Wait for a reply... */
5405       W;
5406     }
5407   /* Return the good/bad news */
5408   return (vam->retval);
5409 }
5410
5411 static int
5412 api_l2_flags (vat_main_t * vam)
5413 {
5414   unformat_input_t *i = vam->input;
5415   vl_api_l2_flags_t *mp;
5416   f64 timeout;
5417   u32 sw_if_index;
5418   u32 feature_bitmap = 0;
5419   u8 sw_if_index_set = 0;
5420
5421   /* Parse args required to build the message */
5422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5423     {
5424       if (unformat (i, "sw_if_index %d", &sw_if_index))
5425         sw_if_index_set = 1;
5426       else if (unformat (i, "sw_if"))
5427         {
5428           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5429             {
5430               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5431                 sw_if_index_set = 1;
5432             }
5433           else
5434             break;
5435         }
5436       else if (unformat (i, "learn"))
5437         feature_bitmap |= L2INPUT_FEAT_LEARN;
5438       else if (unformat (i, "forward"))
5439         feature_bitmap |= L2INPUT_FEAT_FWD;
5440       else if (unformat (i, "flood"))
5441         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5442       else if (unformat (i, "uu-flood"))
5443         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5444       else
5445         break;
5446     }
5447
5448   if (sw_if_index_set == 0)
5449     {
5450       errmsg ("missing interface name or sw_if_index\n");
5451       return -99;
5452     }
5453
5454   M (L2_FLAGS, l2_flags);
5455
5456   mp->sw_if_index = ntohl (sw_if_index);
5457   mp->feature_bitmap = ntohl (feature_bitmap);
5458
5459   S;
5460   W;
5461   /* NOTREACHED */
5462   return 0;
5463 }
5464
5465 static int
5466 api_bridge_flags (vat_main_t * vam)
5467 {
5468   unformat_input_t *i = vam->input;
5469   vl_api_bridge_flags_t *mp;
5470   f64 timeout;
5471   u32 bd_id;
5472   u8 bd_id_set = 0;
5473   u8 is_set = 1;
5474   u32 flags = 0;
5475
5476   /* Parse args required to build the message */
5477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5478     {
5479       if (unformat (i, "bd_id %d", &bd_id))
5480         bd_id_set = 1;
5481       else if (unformat (i, "learn"))
5482         flags |= L2_LEARN;
5483       else if (unformat (i, "forward"))
5484         flags |= L2_FWD;
5485       else if (unformat (i, "flood"))
5486         flags |= L2_FLOOD;
5487       else if (unformat (i, "uu-flood"))
5488         flags |= L2_UU_FLOOD;
5489       else if (unformat (i, "arp-term"))
5490         flags |= L2_ARP_TERM;
5491       else if (unformat (i, "off"))
5492         is_set = 0;
5493       else if (unformat (i, "disable"))
5494         is_set = 0;
5495       else
5496         break;
5497     }
5498
5499   if (bd_id_set == 0)
5500     {
5501       errmsg ("missing bridge domain\n");
5502       return -99;
5503     }
5504
5505   M (BRIDGE_FLAGS, bridge_flags);
5506
5507   mp->bd_id = ntohl (bd_id);
5508   mp->feature_bitmap = ntohl (flags);
5509   mp->is_set = is_set;
5510
5511   S;
5512   W;
5513   /* NOTREACHED */
5514   return 0;
5515 }
5516
5517 static int
5518 api_bd_ip_mac_add_del (vat_main_t * vam)
5519 {
5520   unformat_input_t *i = vam->input;
5521   vl_api_bd_ip_mac_add_del_t *mp;
5522   f64 timeout;
5523   u32 bd_id;
5524   u8 is_ipv6 = 0;
5525   u8 is_add = 1;
5526   u8 bd_id_set = 0;
5527   u8 ip_set = 0;
5528   u8 mac_set = 0;
5529   ip4_address_t v4addr;
5530   ip6_address_t v6addr;
5531   u8 macaddr[6];
5532
5533
5534   /* Parse args required to build the message */
5535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5536     {
5537       if (unformat (i, "bd_id %d", &bd_id))
5538         {
5539           bd_id_set++;
5540         }
5541       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5542         {
5543           ip_set++;
5544         }
5545       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5546         {
5547           ip_set++;
5548           is_ipv6++;
5549         }
5550       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5551         {
5552           mac_set++;
5553         }
5554       else if (unformat (i, "del"))
5555         is_add = 0;
5556       else
5557         break;
5558     }
5559
5560   if (bd_id_set == 0)
5561     {
5562       errmsg ("missing bridge domain\n");
5563       return -99;
5564     }
5565   else if (ip_set == 0)
5566     {
5567       errmsg ("missing IP address\n");
5568       return -99;
5569     }
5570   else if (mac_set == 0)
5571     {
5572       errmsg ("missing MAC address\n");
5573       return -99;
5574     }
5575
5576   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5577
5578   mp->bd_id = ntohl (bd_id);
5579   mp->is_ipv6 = is_ipv6;
5580   mp->is_add = is_add;
5581   if (is_ipv6)
5582     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5583   else
5584     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5585   clib_memcpy (mp->mac_address, macaddr, 6);
5586   S;
5587   W;
5588   /* NOTREACHED */
5589   return 0;
5590 }
5591
5592 static int
5593 api_tap_connect (vat_main_t * vam)
5594 {
5595   unformat_input_t *i = vam->input;
5596   vl_api_tap_connect_t *mp;
5597   f64 timeout;
5598   u8 mac_address[6];
5599   u8 random_mac = 1;
5600   u8 name_set = 0;
5601   u8 *tap_name;
5602
5603   memset (mac_address, 0, sizeof (mac_address));
5604
5605   /* Parse args required to build the message */
5606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5607     {
5608       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5609         {
5610           random_mac = 0;
5611         }
5612       else if (unformat (i, "random-mac"))
5613         random_mac = 1;
5614       else if (unformat (i, "tapname %s", &tap_name))
5615         name_set = 1;
5616       else
5617         break;
5618     }
5619
5620   if (name_set == 0)
5621     {
5622       errmsg ("missing tap name\n");
5623       return -99;
5624     }
5625   if (vec_len (tap_name) > 63)
5626     {
5627       errmsg ("tap name too long\n");
5628     }
5629   vec_add1 (tap_name, 0);
5630
5631   /* Construct the API message */
5632   M (TAP_CONNECT, tap_connect);
5633
5634   mp->use_random_mac = random_mac;
5635   clib_memcpy (mp->mac_address, mac_address, 6);
5636   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5637   vec_free (tap_name);
5638
5639   /* send it... */
5640   S;
5641
5642   /* Wait for a reply... */
5643   W;
5644 }
5645
5646 static int
5647 api_tap_modify (vat_main_t * vam)
5648 {
5649   unformat_input_t *i = vam->input;
5650   vl_api_tap_modify_t *mp;
5651   f64 timeout;
5652   u8 mac_address[6];
5653   u8 random_mac = 1;
5654   u8 name_set = 0;
5655   u8 *tap_name;
5656   u32 sw_if_index = ~0;
5657   u8 sw_if_index_set = 0;
5658
5659   memset (mac_address, 0, sizeof (mac_address));
5660
5661   /* Parse args required to build the message */
5662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5663     {
5664       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5665         sw_if_index_set = 1;
5666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5667         sw_if_index_set = 1;
5668       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5669         {
5670           random_mac = 0;
5671         }
5672       else if (unformat (i, "random-mac"))
5673         random_mac = 1;
5674       else if (unformat (i, "tapname %s", &tap_name))
5675         name_set = 1;
5676       else
5677         break;
5678     }
5679
5680   if (sw_if_index_set == 0)
5681     {
5682       errmsg ("missing vpp interface name");
5683       return -99;
5684     }
5685   if (name_set == 0)
5686     {
5687       errmsg ("missing tap name\n");
5688       return -99;
5689     }
5690   if (vec_len (tap_name) > 63)
5691     {
5692       errmsg ("tap name too long\n");
5693     }
5694   vec_add1 (tap_name, 0);
5695
5696   /* Construct the API message */
5697   M (TAP_MODIFY, tap_modify);
5698
5699   mp->use_random_mac = random_mac;
5700   mp->sw_if_index = ntohl (sw_if_index);
5701   clib_memcpy (mp->mac_address, mac_address, 6);
5702   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5703   vec_free (tap_name);
5704
5705   /* send it... */
5706   S;
5707
5708   /* Wait for a reply... */
5709   W;
5710 }
5711
5712 static int
5713 api_tap_delete (vat_main_t * vam)
5714 {
5715   unformat_input_t *i = vam->input;
5716   vl_api_tap_delete_t *mp;
5717   f64 timeout;
5718   u32 sw_if_index = ~0;
5719   u8 sw_if_index_set = 0;
5720
5721   /* Parse args required to build the message */
5722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723     {
5724       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5725         sw_if_index_set = 1;
5726       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5727         sw_if_index_set = 1;
5728       else
5729         break;
5730     }
5731
5732   if (sw_if_index_set == 0)
5733     {
5734       errmsg ("missing vpp interface name");
5735       return -99;
5736     }
5737
5738   /* Construct the API message */
5739   M (TAP_DELETE, tap_delete);
5740
5741   mp->sw_if_index = ntohl (sw_if_index);
5742
5743   /* send it... */
5744   S;
5745
5746   /* Wait for a reply... */
5747   W;
5748 }
5749
5750 static int
5751 api_ip_add_del_route (vat_main_t * vam)
5752 {
5753   unformat_input_t *i = vam->input;
5754   vl_api_ip_add_del_route_t *mp;
5755   f64 timeout;
5756   u32 sw_if_index = ~0, vrf_id = 0;
5757   u8 sw_if_index_set = 0;
5758   u8 is_ipv6 = 0;
5759   u8 is_local = 0, is_drop = 0;
5760   u8 is_unreach = 0, is_prohibit = 0;
5761   u8 create_vrf_if_needed = 0;
5762   u8 is_add = 1;
5763   u8 next_hop_weight = 1;
5764   u8 not_last = 0;
5765   u8 is_multipath = 0;
5766   u8 address_set = 0;
5767   u8 address_length_set = 0;
5768   u32 next_hop_table_id = 0;
5769   u32 resolve_attempts = 0;
5770   u32 dst_address_length = 0;
5771   u8 next_hop_set = 0;
5772   ip4_address_t v4_dst_address, v4_next_hop_address;
5773   ip6_address_t v6_dst_address, v6_next_hop_address;
5774   int count = 1;
5775   int j;
5776   f64 before = 0;
5777   u32 random_add_del = 0;
5778   u32 *random_vector = 0;
5779   uword *random_hash;
5780   u32 random_seed = 0xdeaddabe;
5781   u32 classify_table_index = ~0;
5782   u8 is_classify = 0;
5783   u8 resolve_host = 0, resolve_attached = 0;
5784   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5785
5786   /* Parse args required to build the message */
5787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5788     {
5789       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5790         sw_if_index_set = 1;
5791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5792         sw_if_index_set = 1;
5793       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5794         {
5795           address_set = 1;
5796           is_ipv6 = 0;
5797         }
5798       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5799         {
5800           address_set = 1;
5801           is_ipv6 = 1;
5802         }
5803       else if (unformat (i, "/%d", &dst_address_length))
5804         {
5805           address_length_set = 1;
5806         }
5807
5808       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5809                                          &v4_next_hop_address))
5810         {
5811           next_hop_set = 1;
5812         }
5813       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5814                                          &v6_next_hop_address))
5815         {
5816           next_hop_set = 1;
5817         }
5818       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5819         ;
5820       else if (unformat (i, "weight %d", &next_hop_weight))
5821         ;
5822       else if (unformat (i, "drop"))
5823         {
5824           is_drop = 1;
5825         }
5826       else if (unformat (i, "null-send-unreach"))
5827         {
5828           is_unreach = 1;
5829         }
5830       else if (unformat (i, "null-send-prohibit"))
5831         {
5832           is_prohibit = 1;
5833         }
5834       else if (unformat (i, "local"))
5835         {
5836           is_local = 1;
5837         }
5838       else if (unformat (i, "classify %d", &classify_table_index))
5839         {
5840           is_classify = 1;
5841         }
5842       else if (unformat (i, "del"))
5843         is_add = 0;
5844       else if (unformat (i, "add"))
5845         is_add = 1;
5846       else if (unformat (i, "not-last"))
5847         not_last = 1;
5848       else if (unformat (i, "resolve-via-host"))
5849         resolve_host = 1;
5850       else if (unformat (i, "resolve-via-attached"))
5851         resolve_attached = 1;
5852       else if (unformat (i, "multipath"))
5853         is_multipath = 1;
5854       else if (unformat (i, "vrf %d", &vrf_id))
5855         ;
5856       else if (unformat (i, "create-vrf"))
5857         create_vrf_if_needed = 1;
5858       else if (unformat (i, "count %d", &count))
5859         ;
5860       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5861         ;
5862       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5863         ;
5864       else if (unformat (i, "out-label %d", &next_hop_out_label))
5865         ;
5866       else if (unformat (i, "random"))
5867         random_add_del = 1;
5868       else if (unformat (i, "seed %d", &random_seed))
5869         ;
5870       else
5871         {
5872           clib_warning ("parse error '%U'", format_unformat_error, i);
5873           return -99;
5874         }
5875     }
5876
5877   if (resolve_attempts > 0 && sw_if_index_set == 0)
5878     {
5879       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5880       return -99;
5881     }
5882
5883   if (!next_hop_set && !is_drop && !is_local &&
5884       !is_classify && !is_unreach && !is_prohibit)
5885     {
5886       errmsg
5887         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5888       return -99;
5889     }
5890
5891   if (address_set == 0)
5892     {
5893       errmsg ("missing addresses\n");
5894       return -99;
5895     }
5896
5897   if (address_length_set == 0)
5898     {
5899       errmsg ("missing address length\n");
5900       return -99;
5901     }
5902
5903   /* Generate a pile of unique, random routes */
5904   if (random_add_del)
5905     {
5906       u32 this_random_address;
5907       random_hash = hash_create (count, sizeof (uword));
5908
5909       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5910       for (j = 0; j <= count; j++)
5911         {
5912           do
5913             {
5914               this_random_address = random_u32 (&random_seed);
5915               this_random_address =
5916                 clib_host_to_net_u32 (this_random_address);
5917             }
5918           while (hash_get (random_hash, this_random_address));
5919           vec_add1 (random_vector, this_random_address);
5920           hash_set (random_hash, this_random_address, 1);
5921         }
5922       hash_free (random_hash);
5923       v4_dst_address.as_u32 = random_vector[0];
5924     }
5925
5926   if (count > 1)
5927     {
5928       /* Turn on async mode */
5929       vam->async_mode = 1;
5930       vam->async_errors = 0;
5931       before = vat_time_now (vam);
5932     }
5933
5934   for (j = 0; j < count; j++)
5935     {
5936       /* Construct the API message */
5937       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5938
5939       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5940       mp->table_id = ntohl (vrf_id);
5941       if (resolve_attempts > 0)
5942         {
5943           mp->resolve_attempts = ntohl (resolve_attempts);
5944           mp->resolve_if_needed = 1;
5945         }
5946       mp->create_vrf_if_needed = create_vrf_if_needed;
5947
5948       mp->is_add = is_add;
5949       mp->is_drop = is_drop;
5950       mp->is_unreach = is_unreach;
5951       mp->is_prohibit = is_prohibit;
5952       mp->is_ipv6 = is_ipv6;
5953       mp->is_local = is_local;
5954       mp->is_classify = is_classify;
5955       mp->is_multipath = is_multipath;
5956       mp->is_resolve_host = resolve_host;
5957       mp->is_resolve_attached = resolve_attached;
5958       mp->not_last = not_last;
5959       mp->next_hop_weight = next_hop_weight;
5960       mp->dst_address_length = dst_address_length;
5961       mp->next_hop_table_id = ntohl (next_hop_table_id);
5962       mp->classify_table_index = ntohl (classify_table_index);
5963       mp->next_hop_out_label = ntohl (next_hop_out_label);
5964
5965       if (is_ipv6)
5966         {
5967           clib_memcpy (mp->dst_address, &v6_dst_address,
5968                        sizeof (v6_dst_address));
5969           if (next_hop_set)
5970             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5971                          sizeof (v6_next_hop_address));
5972           increment_v6_address (&v6_dst_address);
5973         }
5974       else
5975         {
5976           clib_memcpy (mp->dst_address, &v4_dst_address,
5977                        sizeof (v4_dst_address));
5978           if (next_hop_set)
5979             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5980                          sizeof (v4_next_hop_address));
5981           if (random_add_del)
5982             v4_dst_address.as_u32 = random_vector[j + 1];
5983           else
5984             increment_v4_address (&v4_dst_address);
5985         }
5986       /* send it... */
5987       S;
5988       /* If we receive SIGTERM, stop now... */
5989       if (vam->do_exit)
5990         break;
5991     }
5992
5993   /* When testing multiple add/del ops, use a control-ping to sync */
5994   if (count > 1)
5995     {
5996       vl_api_control_ping_t *mp;
5997       f64 after;
5998
5999       /* Shut off async mode */
6000       vam->async_mode = 0;
6001
6002       M (CONTROL_PING, control_ping);
6003       S;
6004
6005       timeout = vat_time_now (vam) + 1.0;
6006       while (vat_time_now (vam) < timeout)
6007         if (vam->result_ready == 1)
6008           goto out;
6009       vam->retval = -99;
6010
6011     out:
6012       if (vam->retval == -99)
6013         errmsg ("timeout\n");
6014
6015       if (vam->async_errors > 0)
6016         {
6017           errmsg ("%d asynchronous errors\n", vam->async_errors);
6018           vam->retval = -98;
6019         }
6020       vam->async_errors = 0;
6021       after = vat_time_now (vam);
6022
6023       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6024       if (j > 0)
6025         count = j;
6026
6027       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6028                count, after - before, count / (after - before));
6029     }
6030   else
6031     {
6032       /* Wait for a reply... */
6033       W;
6034     }
6035
6036   /* Return the good/bad news */
6037   return (vam->retval);
6038 }
6039
6040 static int
6041 api_mpls_route_add_del (vat_main_t * vam)
6042 {
6043   unformat_input_t *i = vam->input;
6044   vl_api_mpls_route_add_del_t *mp;
6045   f64 timeout;
6046   u32 sw_if_index = ~0, table_id = 0;
6047   u8 create_table_if_needed = 0;
6048   u8 is_add = 1;
6049   u8 next_hop_weight = 1;
6050   u8 is_multipath = 0;
6051   u32 next_hop_table_id = 0;
6052   u8 next_hop_set = 0;
6053   ip4_address_t v4_next_hop_address = {
6054     .as_u32 = 0,
6055   };
6056   ip6_address_t v6_next_hop_address = { {0} };
6057   int count = 1;
6058   int j;
6059   f64 before = 0;
6060   u32 classify_table_index = ~0;
6061   u8 is_classify = 0;
6062   u8 resolve_host = 0, resolve_attached = 0;
6063   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6064   mpls_label_t local_label = MPLS_LABEL_INVALID;
6065   u8 is_eos = 1;
6066   u8 next_hop_proto_is_ip4 = 1;
6067
6068   /* Parse args required to build the message */
6069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6070     {
6071       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6072         ;
6073       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6074         ;
6075       else if (unformat (i, "%d", &local_label))
6076         ;
6077       else if (unformat (i, "eos"))
6078         is_eos = 1;
6079       else if (unformat (i, "non-eos"))
6080         is_eos = 0;
6081       else if (unformat (i, "via %U", unformat_ip4_address,
6082                          &v4_next_hop_address))
6083         {
6084           next_hop_set = 1;
6085           next_hop_proto_is_ip4 = 1;
6086         }
6087       else if (unformat (i, "via %U", unformat_ip6_address,
6088                          &v6_next_hop_address))
6089         {
6090           next_hop_set = 1;
6091           next_hop_proto_is_ip4 = 0;
6092         }
6093       else if (unformat (i, "weight %d", &next_hop_weight))
6094         ;
6095       else if (unformat (i, "create-table"))
6096         create_table_if_needed = 1;
6097       else if (unformat (i, "classify %d", &classify_table_index))
6098         {
6099           is_classify = 1;
6100         }
6101       else if (unformat (i, "del"))
6102         is_add = 0;
6103       else if (unformat (i, "add"))
6104         is_add = 1;
6105       else if (unformat (i, "resolve-via-host"))
6106         resolve_host = 1;
6107       else if (unformat (i, "resolve-via-attached"))
6108         resolve_attached = 1;
6109       else if (unformat (i, "multipath"))
6110         is_multipath = 1;
6111       else if (unformat (i, "count %d", &count))
6112         ;
6113       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6114         {
6115           next_hop_set = 1;
6116           next_hop_proto_is_ip4 = 1;
6117         }
6118       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6119         {
6120           next_hop_set = 1;
6121           next_hop_proto_is_ip4 = 0;
6122         }
6123       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6124         ;
6125       else if (unformat (i, "out-label %d", &next_hop_out_label))
6126         ;
6127       else
6128         {
6129           clib_warning ("parse error '%U'", format_unformat_error, i);
6130           return -99;
6131         }
6132     }
6133
6134   if (!next_hop_set && !is_classify)
6135     {
6136       errmsg ("next hop / classify not set\n");
6137       return -99;
6138     }
6139
6140   if (MPLS_LABEL_INVALID == local_label)
6141     {
6142       errmsg ("missing label\n");
6143       return -99;
6144     }
6145
6146   if (count > 1)
6147     {
6148       /* Turn on async mode */
6149       vam->async_mode = 1;
6150       vam->async_errors = 0;
6151       before = vat_time_now (vam);
6152     }
6153
6154   for (j = 0; j < count; j++)
6155     {
6156       /* Construct the API message */
6157       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6158
6159       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6160       mp->mr_table_id = ntohl (table_id);
6161       mp->mr_create_table_if_needed = create_table_if_needed;
6162
6163       mp->mr_is_add = is_add;
6164       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6165       mp->mr_is_classify = is_classify;
6166       mp->mr_is_multipath = is_multipath;
6167       mp->mr_is_resolve_host = resolve_host;
6168       mp->mr_is_resolve_attached = resolve_attached;
6169       mp->mr_next_hop_weight = next_hop_weight;
6170       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6171       mp->mr_classify_table_index = ntohl (classify_table_index);
6172       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6173       mp->mr_label = ntohl (local_label);
6174       mp->mr_eos = is_eos;
6175
6176       if (next_hop_set)
6177         {
6178           if (next_hop_proto_is_ip4)
6179             {
6180               clib_memcpy (mp->mr_next_hop,
6181                            &v4_next_hop_address,
6182                            sizeof (v4_next_hop_address));
6183             }
6184           else
6185             {
6186               clib_memcpy (mp->mr_next_hop,
6187                            &v6_next_hop_address,
6188                            sizeof (v6_next_hop_address));
6189             }
6190         }
6191       local_label++;
6192
6193       /* send it... */
6194       S;
6195       /* If we receive SIGTERM, stop now... */
6196       if (vam->do_exit)
6197         break;
6198     }
6199
6200   /* When testing multiple add/del ops, use a control-ping to sync */
6201   if (count > 1)
6202     {
6203       vl_api_control_ping_t *mp;
6204       f64 after;
6205
6206       /* Shut off async mode */
6207       vam->async_mode = 0;
6208
6209       M (CONTROL_PING, control_ping);
6210       S;
6211
6212       timeout = vat_time_now (vam) + 1.0;
6213       while (vat_time_now (vam) < timeout)
6214         if (vam->result_ready == 1)
6215           goto out;
6216       vam->retval = -99;
6217
6218     out:
6219       if (vam->retval == -99)
6220         errmsg ("timeout\n");
6221
6222       if (vam->async_errors > 0)
6223         {
6224           errmsg ("%d asynchronous errors\n", vam->async_errors);
6225           vam->retval = -98;
6226         }
6227       vam->async_errors = 0;
6228       after = vat_time_now (vam);
6229
6230       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6231       if (j > 0)
6232         count = j;
6233
6234       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6235                count, after - before, count / (after - before));
6236     }
6237   else
6238     {
6239       /* Wait for a reply... */
6240       W;
6241     }
6242
6243   /* Return the good/bad news */
6244   return (vam->retval);
6245 }
6246
6247 static int
6248 api_mpls_ip_bind_unbind (vat_main_t * vam)
6249 {
6250   unformat_input_t *i = vam->input;
6251   vl_api_mpls_ip_bind_unbind_t *mp;
6252   f64 timeout;
6253   u32 ip_table_id = 0;
6254   u8 create_table_if_needed = 0;
6255   u8 is_bind = 1;
6256   u8 is_ip4 = 1;
6257   ip4_address_t v4_address;
6258   ip6_address_t v6_address;
6259   u32 address_length;
6260   u8 address_set = 0;
6261   mpls_label_t local_label = MPLS_LABEL_INVALID;
6262
6263   /* Parse args required to build the message */
6264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6265     {
6266       if (unformat (i, "%U/%d", unformat_ip4_address,
6267                     &v4_address, &address_length))
6268         {
6269           is_ip4 = 1;
6270           address_set = 1;
6271         }
6272       else if (unformat (i, "%U/%d", unformat_ip6_address,
6273                          &v6_address, &address_length))
6274         {
6275           is_ip4 = 0;
6276           address_set = 1;
6277         }
6278       else if (unformat (i, "%d", &local_label))
6279         ;
6280       else if (unformat (i, "create-table"))
6281         create_table_if_needed = 1;
6282       else if (unformat (i, "table-id %d", &ip_table_id))
6283         ;
6284       else if (unformat (i, "unbind"))
6285         is_bind = 0;
6286       else if (unformat (i, "bind"))
6287         is_bind = 1;
6288       else
6289         {
6290           clib_warning ("parse error '%U'", format_unformat_error, i);
6291           return -99;
6292         }
6293     }
6294
6295   if (!address_set)
6296     {
6297       errmsg ("IP addres not set\n");
6298       return -99;
6299     }
6300
6301   if (MPLS_LABEL_INVALID == local_label)
6302     {
6303       errmsg ("missing label\n");
6304       return -99;
6305     }
6306
6307   /* Construct the API message */
6308   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6309
6310   mp->mb_create_table_if_needed = create_table_if_needed;
6311   mp->mb_is_bind = is_bind;
6312   mp->mb_is_ip4 = is_ip4;
6313   mp->mb_ip_table_id = ntohl (ip_table_id);
6314   mp->mb_mpls_table_id = 0;
6315   mp->mb_label = ntohl (local_label);
6316   mp->mb_address_length = address_length;
6317
6318   if (is_ip4)
6319     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6320   else
6321     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6322
6323   /* send it... */
6324   S;
6325
6326   /* Wait for a reply... */
6327   W;
6328
6329   /* Return the good/bad news */
6330   return (vam->retval);
6331 }
6332
6333 static int
6334 api_proxy_arp_add_del (vat_main_t * vam)
6335 {
6336   unformat_input_t *i = vam->input;
6337   vl_api_proxy_arp_add_del_t *mp;
6338   f64 timeout;
6339   u32 vrf_id = 0;
6340   u8 is_add = 1;
6341   ip4_address_t lo, hi;
6342   u8 range_set = 0;
6343
6344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6345     {
6346       if (unformat (i, "vrf %d", &vrf_id))
6347         ;
6348       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6349                          unformat_ip4_address, &hi))
6350         range_set = 1;
6351       else if (unformat (i, "del"))
6352         is_add = 0;
6353       else
6354         {
6355           clib_warning ("parse error '%U'", format_unformat_error, i);
6356           return -99;
6357         }
6358     }
6359
6360   if (range_set == 0)
6361     {
6362       errmsg ("address range not set\n");
6363       return -99;
6364     }
6365
6366   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6367
6368   mp->vrf_id = ntohl (vrf_id);
6369   mp->is_add = is_add;
6370   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6371   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6372
6373   S;
6374   W;
6375   /* NOTREACHED */
6376   return 0;
6377 }
6378
6379 static int
6380 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6381 {
6382   unformat_input_t *i = vam->input;
6383   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6384   f64 timeout;
6385   u32 sw_if_index;
6386   u8 enable = 1;
6387   u8 sw_if_index_set = 0;
6388
6389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6390     {
6391       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6392         sw_if_index_set = 1;
6393       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6394         sw_if_index_set = 1;
6395       else if (unformat (i, "enable"))
6396         enable = 1;
6397       else if (unformat (i, "disable"))
6398         enable = 0;
6399       else
6400         {
6401           clib_warning ("parse error '%U'", format_unformat_error, i);
6402           return -99;
6403         }
6404     }
6405
6406   if (sw_if_index_set == 0)
6407     {
6408       errmsg ("missing interface name or sw_if_index\n");
6409       return -99;
6410     }
6411
6412   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6413
6414   mp->sw_if_index = ntohl (sw_if_index);
6415   mp->enable_disable = enable;
6416
6417   S;
6418   W;
6419   /* NOTREACHED */
6420   return 0;
6421 }
6422
6423 static int
6424 api_mpls_add_del_encap (vat_main_t * vam)
6425 {
6426   unformat_input_t *i = vam->input;
6427   vl_api_mpls_add_del_encap_t *mp;
6428   f64 timeout;
6429   u32 vrf_id = 0;
6430   u32 *labels = 0;
6431   u32 label;
6432   ip4_address_t dst_address;
6433   u8 is_add = 1;
6434
6435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6436     {
6437       if (unformat (i, "vrf %d", &vrf_id))
6438         ;
6439       else if (unformat (i, "label %d", &label))
6440         vec_add1 (labels, ntohl (label));
6441       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6442         ;
6443       else if (unformat (i, "del"))
6444         is_add = 0;
6445       else
6446         {
6447           clib_warning ("parse error '%U'", format_unformat_error, i);
6448           return -99;
6449         }
6450     }
6451
6452   if (vec_len (labels) == 0)
6453     {
6454       errmsg ("missing encap label stack\n");
6455       return -99;
6456     }
6457
6458   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6459       sizeof (u32) * vec_len (labels));
6460
6461   mp->vrf_id = ntohl (vrf_id);
6462   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6463   mp->is_add = is_add;
6464   mp->nlabels = vec_len (labels);
6465   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6466
6467   vec_free (labels);
6468
6469   S;
6470   W;
6471   /* NOTREACHED */
6472   return 0;
6473 }
6474
6475 static int
6476 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6477 {
6478   unformat_input_t *i = vam->input;
6479   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6480   f64 timeout;
6481   u32 inner_vrf_id = 0;
6482   ip4_address_t intfc_address;
6483   u8 dst_mac_address[6];
6484   int dst_set = 1;
6485   u32 tmp;
6486   u8 intfc_address_length = 0;
6487   u8 is_add = 1;
6488   u8 l2_only = 0;
6489   u32 tx_sw_if_index;
6490   int tx_sw_if_index_set = 0;
6491
6492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6493     {
6494       if (unformat (i, "vrf %d", &inner_vrf_id))
6495         ;
6496       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6497                          &intfc_address, &tmp))
6498         intfc_address_length = tmp;
6499       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6500         tx_sw_if_index_set = 1;
6501       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6502         tx_sw_if_index_set = 1;
6503       else if (unformat (i, "dst %U", unformat_ethernet_address,
6504                          dst_mac_address))
6505         dst_set = 1;
6506       else if (unformat (i, "l2-only"))
6507         l2_only = 1;
6508       else if (unformat (i, "del"))
6509         is_add = 0;
6510       else
6511         {
6512           clib_warning ("parse error '%U'", format_unformat_error, i);
6513           return -99;
6514         }
6515     }
6516
6517   if (!dst_set)
6518     {
6519       errmsg ("dst (mac address) not set\n");
6520       return -99;
6521     }
6522   if (!tx_sw_if_index_set)
6523     {
6524       errmsg ("tx-intfc not set\n");
6525       return -99;
6526     }
6527
6528   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6529
6530   mp->vrf_id = ntohl (inner_vrf_id);
6531   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6532   mp->adj_address_length = intfc_address_length;
6533   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6534                sizeof (dst_mac_address));
6535   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6536   mp->l2_only = l2_only;
6537   mp->is_add = is_add;
6538
6539   S;
6540   W;
6541   /* NOTREACHED */
6542   return 0;
6543 }
6544
6545 static int
6546 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6547 {
6548   unformat_input_t *i = vam->input;
6549   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6550   f64 timeout;
6551   u32 inner_vrf_id = 0;
6552   u32 outer_vrf_id = 0;
6553   ip4_address_t adj_address;
6554   int adj_address_set = 0;
6555   ip4_address_t next_hop_address;
6556   int next_hop_address_set = 0;
6557   u32 tmp;
6558   u8 adj_address_length = 0;
6559   u8 l2_only = 0;
6560   u8 is_add = 1;
6561   u32 resolve_attempts = 5;
6562   u8 resolve_if_needed = 1;
6563
6564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6565     {
6566       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6567         ;
6568       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6569         ;
6570       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6571                          &adj_address, &tmp))
6572         {
6573           adj_address_length = tmp;
6574           adj_address_set = 1;
6575         }
6576       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6577                          &next_hop_address))
6578         next_hop_address_set = 1;
6579       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6580         ;
6581       else if (unformat (i, "resolve-if-needed %d", &tmp))
6582         resolve_if_needed = tmp;
6583       else if (unformat (i, "l2-only"))
6584         l2_only = 1;
6585       else if (unformat (i, "del"))
6586         is_add = 0;
6587       else
6588         {
6589           clib_warning ("parse error '%U'", format_unformat_error, i);
6590           return -99;
6591         }
6592     }
6593
6594   if (!adj_address_set)
6595     {
6596       errmsg ("adjacency address/mask not set\n");
6597       return -99;
6598     }
6599   if (!next_hop_address_set)
6600     {
6601       errmsg ("ip4 next hop address (in outer fib) not set\n");
6602       return -99;
6603     }
6604
6605   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6606
6607   mp->inner_vrf_id = ntohl (inner_vrf_id);
6608   mp->outer_vrf_id = ntohl (outer_vrf_id);
6609   mp->resolve_attempts = ntohl (resolve_attempts);
6610   mp->resolve_if_needed = resolve_if_needed;
6611   mp->is_add = is_add;
6612   mp->l2_only = l2_only;
6613   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6614   mp->adj_address_length = adj_address_length;
6615   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6616                sizeof (next_hop_address));
6617
6618   S;
6619   W;
6620   /* NOTREACHED */
6621   return 0;
6622 }
6623
6624 static int
6625 api_sw_interface_set_unnumbered (vat_main_t * vam)
6626 {
6627   unformat_input_t *i = vam->input;
6628   vl_api_sw_interface_set_unnumbered_t *mp;
6629   f64 timeout;
6630   u32 sw_if_index;
6631   u32 unnum_sw_index = ~0;
6632   u8 is_add = 1;
6633   u8 sw_if_index_set = 0;
6634
6635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6636     {
6637       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6638         sw_if_index_set = 1;
6639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6640         sw_if_index_set = 1;
6641       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6642         ;
6643       else if (unformat (i, "del"))
6644         is_add = 0;
6645       else
6646         {
6647           clib_warning ("parse error '%U'", format_unformat_error, i);
6648           return -99;
6649         }
6650     }
6651
6652   if (sw_if_index_set == 0)
6653     {
6654       errmsg ("missing interface name or sw_if_index\n");
6655       return -99;
6656     }
6657
6658   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6659
6660   mp->sw_if_index = ntohl (sw_if_index);
6661   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6662   mp->is_add = is_add;
6663
6664   S;
6665   W;
6666   /* NOTREACHED */
6667   return 0;
6668 }
6669
6670 static int
6671 api_ip_neighbor_add_del (vat_main_t * vam)
6672 {
6673   unformat_input_t *i = vam->input;
6674   vl_api_ip_neighbor_add_del_t *mp;
6675   f64 timeout;
6676   u32 sw_if_index;
6677   u8 sw_if_index_set = 0;
6678   u32 vrf_id = 0;
6679   u8 is_add = 1;
6680   u8 is_static = 0;
6681   u8 mac_address[6];
6682   u8 mac_set = 0;
6683   u8 v4_address_set = 0;
6684   u8 v6_address_set = 0;
6685   ip4_address_t v4address;
6686   ip6_address_t v6address;
6687
6688   memset (mac_address, 0, sizeof (mac_address));
6689
6690   /* Parse args required to build the message */
6691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6692     {
6693       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6694         {
6695           mac_set = 1;
6696         }
6697       else if (unformat (i, "del"))
6698         is_add = 0;
6699       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6700         sw_if_index_set = 1;
6701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6702         sw_if_index_set = 1;
6703       else if (unformat (i, "is_static"))
6704         is_static = 1;
6705       else if (unformat (i, "vrf %d", &vrf_id))
6706         ;
6707       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6708         v4_address_set = 1;
6709       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6710         v6_address_set = 1;
6711       else
6712         {
6713           clib_warning ("parse error '%U'", format_unformat_error, i);
6714           return -99;
6715         }
6716     }
6717
6718   if (sw_if_index_set == 0)
6719     {
6720       errmsg ("missing interface name or sw_if_index\n");
6721       return -99;
6722     }
6723   if (v4_address_set && v6_address_set)
6724     {
6725       errmsg ("both v4 and v6 addresses set\n");
6726       return -99;
6727     }
6728   if (!v4_address_set && !v6_address_set)
6729     {
6730       errmsg ("no address set\n");
6731       return -99;
6732     }
6733
6734   /* Construct the API message */
6735   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6736
6737   mp->sw_if_index = ntohl (sw_if_index);
6738   mp->is_add = is_add;
6739   mp->vrf_id = ntohl (vrf_id);
6740   mp->is_static = is_static;
6741   if (mac_set)
6742     clib_memcpy (mp->mac_address, mac_address, 6);
6743   if (v6_address_set)
6744     {
6745       mp->is_ipv6 = 1;
6746       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6747     }
6748   else
6749     {
6750       /* mp->is_ipv6 = 0; via memset in M macro above */
6751       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6752     }
6753
6754   /* send it... */
6755   S;
6756
6757   /* Wait for a reply, return good/bad news  */
6758   W;
6759
6760   /* NOTREACHED */
6761   return 0;
6762 }
6763
6764 static int
6765 api_reset_vrf (vat_main_t * vam)
6766 {
6767   unformat_input_t *i = vam->input;
6768   vl_api_reset_vrf_t *mp;
6769   f64 timeout;
6770   u32 vrf_id = 0;
6771   u8 is_ipv6 = 0;
6772   u8 vrf_id_set = 0;
6773
6774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6775     {
6776       if (unformat (i, "vrf %d", &vrf_id))
6777         vrf_id_set = 1;
6778       else if (unformat (i, "ipv6"))
6779         is_ipv6 = 1;
6780       else
6781         {
6782           clib_warning ("parse error '%U'", format_unformat_error, i);
6783           return -99;
6784         }
6785     }
6786
6787   if (vrf_id_set == 0)
6788     {
6789       errmsg ("missing vrf id\n");
6790       return -99;
6791     }
6792
6793   M (RESET_VRF, reset_vrf);
6794
6795   mp->vrf_id = ntohl (vrf_id);
6796   mp->is_ipv6 = is_ipv6;
6797
6798   S;
6799   W;
6800   /* NOTREACHED */
6801   return 0;
6802 }
6803
6804 static int
6805 api_create_vlan_subif (vat_main_t * vam)
6806 {
6807   unformat_input_t *i = vam->input;
6808   vl_api_create_vlan_subif_t *mp;
6809   f64 timeout;
6810   u32 sw_if_index;
6811   u8 sw_if_index_set = 0;
6812   u32 vlan_id;
6813   u8 vlan_id_set = 0;
6814
6815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6816     {
6817       if (unformat (i, "sw_if_index %d", &sw_if_index))
6818         sw_if_index_set = 1;
6819       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6820         sw_if_index_set = 1;
6821       else if (unformat (i, "vlan %d", &vlan_id))
6822         vlan_id_set = 1;
6823       else
6824         {
6825           clib_warning ("parse error '%U'", format_unformat_error, i);
6826           return -99;
6827         }
6828     }
6829
6830   if (sw_if_index_set == 0)
6831     {
6832       errmsg ("missing interface name or sw_if_index\n");
6833       return -99;
6834     }
6835
6836   if (vlan_id_set == 0)
6837     {
6838       errmsg ("missing vlan_id\n");
6839       return -99;
6840     }
6841   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6842
6843   mp->sw_if_index = ntohl (sw_if_index);
6844   mp->vlan_id = ntohl (vlan_id);
6845
6846   S;
6847   W;
6848   /* NOTREACHED */
6849   return 0;
6850 }
6851
6852 #define foreach_create_subif_bit                \
6853 _(no_tags)                                      \
6854 _(one_tag)                                      \
6855 _(two_tags)                                     \
6856 _(dot1ad)                                       \
6857 _(exact_match)                                  \
6858 _(default_sub)                                  \
6859 _(outer_vlan_id_any)                            \
6860 _(inner_vlan_id_any)
6861
6862 static int
6863 api_create_subif (vat_main_t * vam)
6864 {
6865   unformat_input_t *i = vam->input;
6866   vl_api_create_subif_t *mp;
6867   f64 timeout;
6868   u32 sw_if_index;
6869   u8 sw_if_index_set = 0;
6870   u32 sub_id;
6871   u8 sub_id_set = 0;
6872   u32 no_tags = 0;
6873   u32 one_tag = 0;
6874   u32 two_tags = 0;
6875   u32 dot1ad = 0;
6876   u32 exact_match = 0;
6877   u32 default_sub = 0;
6878   u32 outer_vlan_id_any = 0;
6879   u32 inner_vlan_id_any = 0;
6880   u32 tmp;
6881   u16 outer_vlan_id = 0;
6882   u16 inner_vlan_id = 0;
6883
6884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6885     {
6886       if (unformat (i, "sw_if_index %d", &sw_if_index))
6887         sw_if_index_set = 1;
6888       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6889         sw_if_index_set = 1;
6890       else if (unformat (i, "sub_id %d", &sub_id))
6891         sub_id_set = 1;
6892       else if (unformat (i, "outer_vlan_id %d", &tmp))
6893         outer_vlan_id = tmp;
6894       else if (unformat (i, "inner_vlan_id %d", &tmp))
6895         inner_vlan_id = tmp;
6896
6897 #define _(a) else if (unformat (i, #a)) a = 1 ;
6898       foreach_create_subif_bit
6899 #undef _
6900         else
6901         {
6902           clib_warning ("parse error '%U'", format_unformat_error, i);
6903           return -99;
6904         }
6905     }
6906
6907   if (sw_if_index_set == 0)
6908     {
6909       errmsg ("missing interface name or sw_if_index\n");
6910       return -99;
6911     }
6912
6913   if (sub_id_set == 0)
6914     {
6915       errmsg ("missing sub_id\n");
6916       return -99;
6917     }
6918   M (CREATE_SUBIF, create_subif);
6919
6920   mp->sw_if_index = ntohl (sw_if_index);
6921   mp->sub_id = ntohl (sub_id);
6922
6923 #define _(a) mp->a = a;
6924   foreach_create_subif_bit;
6925 #undef _
6926
6927   mp->outer_vlan_id = ntohs (outer_vlan_id);
6928   mp->inner_vlan_id = ntohs (inner_vlan_id);
6929
6930   S;
6931   W;
6932   /* NOTREACHED */
6933   return 0;
6934 }
6935
6936 static int
6937 api_oam_add_del (vat_main_t * vam)
6938 {
6939   unformat_input_t *i = vam->input;
6940   vl_api_oam_add_del_t *mp;
6941   f64 timeout;
6942   u32 vrf_id = 0;
6943   u8 is_add = 1;
6944   ip4_address_t src, dst;
6945   u8 src_set = 0;
6946   u8 dst_set = 0;
6947
6948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6949     {
6950       if (unformat (i, "vrf %d", &vrf_id))
6951         ;
6952       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6953         src_set = 1;
6954       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6955         dst_set = 1;
6956       else if (unformat (i, "del"))
6957         is_add = 0;
6958       else
6959         {
6960           clib_warning ("parse error '%U'", format_unformat_error, i);
6961           return -99;
6962         }
6963     }
6964
6965   if (src_set == 0)
6966     {
6967       errmsg ("missing src addr\n");
6968       return -99;
6969     }
6970
6971   if (dst_set == 0)
6972     {
6973       errmsg ("missing dst addr\n");
6974       return -99;
6975     }
6976
6977   M (OAM_ADD_DEL, oam_add_del);
6978
6979   mp->vrf_id = ntohl (vrf_id);
6980   mp->is_add = is_add;
6981   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6982   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6983
6984   S;
6985   W;
6986   /* NOTREACHED */
6987   return 0;
6988 }
6989
6990 static int
6991 api_reset_fib (vat_main_t * vam)
6992 {
6993   unformat_input_t *i = vam->input;
6994   vl_api_reset_fib_t *mp;
6995   f64 timeout;
6996   u32 vrf_id = 0;
6997   u8 is_ipv6 = 0;
6998   u8 vrf_id_set = 0;
6999
7000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7001     {
7002       if (unformat (i, "vrf %d", &vrf_id))
7003         vrf_id_set = 1;
7004       else if (unformat (i, "ipv6"))
7005         is_ipv6 = 1;
7006       else
7007         {
7008           clib_warning ("parse error '%U'", format_unformat_error, i);
7009           return -99;
7010         }
7011     }
7012
7013   if (vrf_id_set == 0)
7014     {
7015       errmsg ("missing vrf id\n");
7016       return -99;
7017     }
7018
7019   M (RESET_FIB, reset_fib);
7020
7021   mp->vrf_id = ntohl (vrf_id);
7022   mp->is_ipv6 = is_ipv6;
7023
7024   S;
7025   W;
7026   /* NOTREACHED */
7027   return 0;
7028 }
7029
7030 static int
7031 api_dhcp_proxy_config (vat_main_t * vam)
7032 {
7033   unformat_input_t *i = vam->input;
7034   vl_api_dhcp_proxy_config_t *mp;
7035   f64 timeout;
7036   u32 vrf_id = 0;
7037   u8 is_add = 1;
7038   u8 insert_cid = 1;
7039   u8 v4_address_set = 0;
7040   u8 v6_address_set = 0;
7041   ip4_address_t v4address;
7042   ip6_address_t v6address;
7043   u8 v4_src_address_set = 0;
7044   u8 v6_src_address_set = 0;
7045   ip4_address_t v4srcaddress;
7046   ip6_address_t v6srcaddress;
7047
7048   /* Parse args required to build the message */
7049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7050     {
7051       if (unformat (i, "del"))
7052         is_add = 0;
7053       else if (unformat (i, "vrf %d", &vrf_id))
7054         ;
7055       else if (unformat (i, "insert-cid %d", &insert_cid))
7056         ;
7057       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7058         v4_address_set = 1;
7059       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7060         v6_address_set = 1;
7061       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7062         v4_src_address_set = 1;
7063       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7064         v6_src_address_set = 1;
7065       else
7066         break;
7067     }
7068
7069   if (v4_address_set && v6_address_set)
7070     {
7071       errmsg ("both v4 and v6 server addresses set\n");
7072       return -99;
7073     }
7074   if (!v4_address_set && !v6_address_set)
7075     {
7076       errmsg ("no server addresses set\n");
7077       return -99;
7078     }
7079
7080   if (v4_src_address_set && v6_src_address_set)
7081     {
7082       errmsg ("both v4 and v6  src addresses set\n");
7083       return -99;
7084     }
7085   if (!v4_src_address_set && !v6_src_address_set)
7086     {
7087       errmsg ("no src addresses set\n");
7088       return -99;
7089     }
7090
7091   if (!(v4_src_address_set && v4_address_set) &&
7092       !(v6_src_address_set && v6_address_set))
7093     {
7094       errmsg ("no matching server and src addresses set\n");
7095       return -99;
7096     }
7097
7098   /* Construct the API message */
7099   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7100
7101   mp->insert_circuit_id = insert_cid;
7102   mp->is_add = is_add;
7103   mp->vrf_id = ntohl (vrf_id);
7104   if (v6_address_set)
7105     {
7106       mp->is_ipv6 = 1;
7107       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7108       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7109     }
7110   else
7111     {
7112       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7113       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7114     }
7115
7116   /* send it... */
7117   S;
7118
7119   /* Wait for a reply, return good/bad news  */
7120   W;
7121   /* NOTREACHED */
7122   return 0;
7123 }
7124
7125 static int
7126 api_dhcp_proxy_config_2 (vat_main_t * vam)
7127 {
7128   unformat_input_t *i = vam->input;
7129   vl_api_dhcp_proxy_config_2_t *mp;
7130   f64 timeout;
7131   u32 rx_vrf_id = 0;
7132   u32 server_vrf_id = 0;
7133   u8 is_add = 1;
7134   u8 insert_cid = 1;
7135   u8 v4_address_set = 0;
7136   u8 v6_address_set = 0;
7137   ip4_address_t v4address;
7138   ip6_address_t v6address;
7139   u8 v4_src_address_set = 0;
7140   u8 v6_src_address_set = 0;
7141   ip4_address_t v4srcaddress;
7142   ip6_address_t v6srcaddress;
7143
7144   /* Parse args required to build the message */
7145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7146     {
7147       if (unformat (i, "del"))
7148         is_add = 0;
7149       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7150         ;
7151       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7152         ;
7153       else if (unformat (i, "insert-cid %d", &insert_cid))
7154         ;
7155       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7156         v4_address_set = 1;
7157       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7158         v6_address_set = 1;
7159       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7160         v4_src_address_set = 1;
7161       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7162         v6_src_address_set = 1;
7163       else
7164         break;
7165     }
7166
7167   if (v4_address_set && v6_address_set)
7168     {
7169       errmsg ("both v4 and v6 server addresses set\n");
7170       return -99;
7171     }
7172   if (!v4_address_set && !v6_address_set)
7173     {
7174       errmsg ("no server addresses set\n");
7175       return -99;
7176     }
7177
7178   if (v4_src_address_set && v6_src_address_set)
7179     {
7180       errmsg ("both v4 and v6  src addresses set\n");
7181       return -99;
7182     }
7183   if (!v4_src_address_set && !v6_src_address_set)
7184     {
7185       errmsg ("no src addresses set\n");
7186       return -99;
7187     }
7188
7189   if (!(v4_src_address_set && v4_address_set) &&
7190       !(v6_src_address_set && v6_address_set))
7191     {
7192       errmsg ("no matching server and src addresses set\n");
7193       return -99;
7194     }
7195
7196   /* Construct the API message */
7197   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7198
7199   mp->insert_circuit_id = insert_cid;
7200   mp->is_add = is_add;
7201   mp->rx_vrf_id = ntohl (rx_vrf_id);
7202   mp->server_vrf_id = ntohl (server_vrf_id);
7203   if (v6_address_set)
7204     {
7205       mp->is_ipv6 = 1;
7206       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7207       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7208     }
7209   else
7210     {
7211       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7212       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7213     }
7214
7215   /* send it... */
7216   S;
7217
7218   /* Wait for a reply, return good/bad news  */
7219   W;
7220   /* NOTREACHED */
7221   return 0;
7222 }
7223
7224 static int
7225 api_dhcp_proxy_set_vss (vat_main_t * vam)
7226 {
7227   unformat_input_t *i = vam->input;
7228   vl_api_dhcp_proxy_set_vss_t *mp;
7229   f64 timeout;
7230   u8 is_ipv6 = 0;
7231   u8 is_add = 1;
7232   u32 tbl_id;
7233   u8 tbl_id_set = 0;
7234   u32 oui;
7235   u8 oui_set = 0;
7236   u32 fib_id;
7237   u8 fib_id_set = 0;
7238
7239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7240     {
7241       if (unformat (i, "tbl_id %d", &tbl_id))
7242         tbl_id_set = 1;
7243       if (unformat (i, "fib_id %d", &fib_id))
7244         fib_id_set = 1;
7245       if (unformat (i, "oui %d", &oui))
7246         oui_set = 1;
7247       else if (unformat (i, "ipv6"))
7248         is_ipv6 = 1;
7249       else if (unformat (i, "del"))
7250         is_add = 0;
7251       else
7252         {
7253           clib_warning ("parse error '%U'", format_unformat_error, i);
7254           return -99;
7255         }
7256     }
7257
7258   if (tbl_id_set == 0)
7259     {
7260       errmsg ("missing tbl id\n");
7261       return -99;
7262     }
7263
7264   if (fib_id_set == 0)
7265     {
7266       errmsg ("missing fib id\n");
7267       return -99;
7268     }
7269   if (oui_set == 0)
7270     {
7271       errmsg ("missing oui\n");
7272       return -99;
7273     }
7274
7275   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7276   mp->tbl_id = ntohl (tbl_id);
7277   mp->fib_id = ntohl (fib_id);
7278   mp->oui = ntohl (oui);
7279   mp->is_ipv6 = is_ipv6;
7280   mp->is_add = is_add;
7281
7282   S;
7283   W;
7284   /* NOTREACHED */
7285   return 0;
7286 }
7287
7288 static int
7289 api_dhcp_client_config (vat_main_t * vam)
7290 {
7291   unformat_input_t *i = vam->input;
7292   vl_api_dhcp_client_config_t *mp;
7293   f64 timeout;
7294   u32 sw_if_index;
7295   u8 sw_if_index_set = 0;
7296   u8 is_add = 1;
7297   u8 *hostname = 0;
7298   u8 disable_event = 0;
7299
7300   /* Parse args required to build the message */
7301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7302     {
7303       if (unformat (i, "del"))
7304         is_add = 0;
7305       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7306         sw_if_index_set = 1;
7307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7308         sw_if_index_set = 1;
7309       else if (unformat (i, "hostname %s", &hostname))
7310         ;
7311       else if (unformat (i, "disable_event"))
7312         disable_event = 1;
7313       else
7314         break;
7315     }
7316
7317   if (sw_if_index_set == 0)
7318     {
7319       errmsg ("missing interface name or sw_if_index\n");
7320       return -99;
7321     }
7322
7323   if (vec_len (hostname) > 63)
7324     {
7325       errmsg ("hostname too long\n");
7326     }
7327   vec_add1 (hostname, 0);
7328
7329   /* Construct the API message */
7330   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7331
7332   mp->sw_if_index = ntohl (sw_if_index);
7333   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7334   vec_free (hostname);
7335   mp->is_add = is_add;
7336   mp->want_dhcp_event = disable_event ? 0 : 1;
7337   mp->pid = getpid ();
7338
7339   /* send it... */
7340   S;
7341
7342   /* Wait for a reply, return good/bad news  */
7343   W;
7344   /* NOTREACHED */
7345   return 0;
7346 }
7347
7348 static int
7349 api_set_ip_flow_hash (vat_main_t * vam)
7350 {
7351   unformat_input_t *i = vam->input;
7352   vl_api_set_ip_flow_hash_t *mp;
7353   f64 timeout;
7354   u32 vrf_id = 0;
7355   u8 is_ipv6 = 0;
7356   u8 vrf_id_set = 0;
7357   u8 src = 0;
7358   u8 dst = 0;
7359   u8 sport = 0;
7360   u8 dport = 0;
7361   u8 proto = 0;
7362   u8 reverse = 0;
7363
7364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7365     {
7366       if (unformat (i, "vrf %d", &vrf_id))
7367         vrf_id_set = 1;
7368       else if (unformat (i, "ipv6"))
7369         is_ipv6 = 1;
7370       else if (unformat (i, "src"))
7371         src = 1;
7372       else if (unformat (i, "dst"))
7373         dst = 1;
7374       else if (unformat (i, "sport"))
7375         sport = 1;
7376       else if (unformat (i, "dport"))
7377         dport = 1;
7378       else if (unformat (i, "proto"))
7379         proto = 1;
7380       else if (unformat (i, "reverse"))
7381         reverse = 1;
7382
7383       else
7384         {
7385           clib_warning ("parse error '%U'", format_unformat_error, i);
7386           return -99;
7387         }
7388     }
7389
7390   if (vrf_id_set == 0)
7391     {
7392       errmsg ("missing vrf id\n");
7393       return -99;
7394     }
7395
7396   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7397   mp->src = src;
7398   mp->dst = dst;
7399   mp->sport = sport;
7400   mp->dport = dport;
7401   mp->proto = proto;
7402   mp->reverse = reverse;
7403   mp->vrf_id = ntohl (vrf_id);
7404   mp->is_ipv6 = is_ipv6;
7405
7406   S;
7407   W;
7408   /* NOTREACHED */
7409   return 0;
7410 }
7411
7412 static int
7413 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7414 {
7415   unformat_input_t *i = vam->input;
7416   vl_api_sw_interface_ip6_enable_disable_t *mp;
7417   f64 timeout;
7418   u32 sw_if_index;
7419   u8 sw_if_index_set = 0;
7420   u8 enable = 0;
7421
7422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7423     {
7424       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7425         sw_if_index_set = 1;
7426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7427         sw_if_index_set = 1;
7428       else if (unformat (i, "enable"))
7429         enable = 1;
7430       else if (unformat (i, "disable"))
7431         enable = 0;
7432       else
7433         {
7434           clib_warning ("parse error '%U'", format_unformat_error, i);
7435           return -99;
7436         }
7437     }
7438
7439   if (sw_if_index_set == 0)
7440     {
7441       errmsg ("missing interface name or sw_if_index\n");
7442       return -99;
7443     }
7444
7445   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7446
7447   mp->sw_if_index = ntohl (sw_if_index);
7448   mp->enable = enable;
7449
7450   S;
7451   W;
7452   /* NOTREACHED */
7453   return 0;
7454 }
7455
7456 static int
7457 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7458 {
7459   unformat_input_t *i = vam->input;
7460   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7461   f64 timeout;
7462   u32 sw_if_index;
7463   u8 sw_if_index_set = 0;
7464   u32 address_length = 0;
7465   u8 v6_address_set = 0;
7466   ip6_address_t v6address;
7467
7468   /* Parse args required to build the message */
7469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7470     {
7471       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7472         sw_if_index_set = 1;
7473       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7474         sw_if_index_set = 1;
7475       else if (unformat (i, "%U/%d",
7476                          unformat_ip6_address, &v6address, &address_length))
7477         v6_address_set = 1;
7478       else
7479         break;
7480     }
7481
7482   if (sw_if_index_set == 0)
7483     {
7484       errmsg ("missing interface name or sw_if_index\n");
7485       return -99;
7486     }
7487   if (!v6_address_set)
7488     {
7489       errmsg ("no address set\n");
7490       return -99;
7491     }
7492
7493   /* Construct the API message */
7494   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7495      sw_interface_ip6_set_link_local_address);
7496
7497   mp->sw_if_index = ntohl (sw_if_index);
7498   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7499   mp->address_length = address_length;
7500
7501   /* send it... */
7502   S;
7503
7504   /* Wait for a reply, return good/bad news  */
7505   W;
7506
7507   /* NOTREACHED */
7508   return 0;
7509 }
7510
7511
7512 static int
7513 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7514 {
7515   unformat_input_t *i = vam->input;
7516   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7517   f64 timeout;
7518   u32 sw_if_index;
7519   u8 sw_if_index_set = 0;
7520   u32 address_length = 0;
7521   u8 v6_address_set = 0;
7522   ip6_address_t v6address;
7523   u8 use_default = 0;
7524   u8 no_advertise = 0;
7525   u8 off_link = 0;
7526   u8 no_autoconfig = 0;
7527   u8 no_onlink = 0;
7528   u8 is_no = 0;
7529   u32 val_lifetime = 0;
7530   u32 pref_lifetime = 0;
7531
7532   /* Parse args required to build the message */
7533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7534     {
7535       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7536         sw_if_index_set = 1;
7537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7538         sw_if_index_set = 1;
7539       else if (unformat (i, "%U/%d",
7540                          unformat_ip6_address, &v6address, &address_length))
7541         v6_address_set = 1;
7542       else if (unformat (i, "val_life %d", &val_lifetime))
7543         ;
7544       else if (unformat (i, "pref_life %d", &pref_lifetime))
7545         ;
7546       else if (unformat (i, "def"))
7547         use_default = 1;
7548       else if (unformat (i, "noadv"))
7549         no_advertise = 1;
7550       else if (unformat (i, "offl"))
7551         off_link = 1;
7552       else if (unformat (i, "noauto"))
7553         no_autoconfig = 1;
7554       else if (unformat (i, "nolink"))
7555         no_onlink = 1;
7556       else if (unformat (i, "isno"))
7557         is_no = 1;
7558       else
7559         {
7560           clib_warning ("parse error '%U'", format_unformat_error, i);
7561           return -99;
7562         }
7563     }
7564
7565   if (sw_if_index_set == 0)
7566     {
7567       errmsg ("missing interface name or sw_if_index\n");
7568       return -99;
7569     }
7570   if (!v6_address_set)
7571     {
7572       errmsg ("no address set\n");
7573       return -99;
7574     }
7575
7576   /* Construct the API message */
7577   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7578
7579   mp->sw_if_index = ntohl (sw_if_index);
7580   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7581   mp->address_length = address_length;
7582   mp->use_default = use_default;
7583   mp->no_advertise = no_advertise;
7584   mp->off_link = off_link;
7585   mp->no_autoconfig = no_autoconfig;
7586   mp->no_onlink = no_onlink;
7587   mp->is_no = is_no;
7588   mp->val_lifetime = ntohl (val_lifetime);
7589   mp->pref_lifetime = ntohl (pref_lifetime);
7590
7591   /* send it... */
7592   S;
7593
7594   /* Wait for a reply, return good/bad news  */
7595   W;
7596
7597   /* NOTREACHED */
7598   return 0;
7599 }
7600
7601 static int
7602 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7603 {
7604   unformat_input_t *i = vam->input;
7605   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7606   f64 timeout;
7607   u32 sw_if_index;
7608   u8 sw_if_index_set = 0;
7609   u8 suppress = 0;
7610   u8 managed = 0;
7611   u8 other = 0;
7612   u8 ll_option = 0;
7613   u8 send_unicast = 0;
7614   u8 cease = 0;
7615   u8 is_no = 0;
7616   u8 default_router = 0;
7617   u32 max_interval = 0;
7618   u32 min_interval = 0;
7619   u32 lifetime = 0;
7620   u32 initial_count = 0;
7621   u32 initial_interval = 0;
7622
7623
7624   /* Parse args required to build the message */
7625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7626     {
7627       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7628         sw_if_index_set = 1;
7629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7630         sw_if_index_set = 1;
7631       else if (unformat (i, "maxint %d", &max_interval))
7632         ;
7633       else if (unformat (i, "minint %d", &min_interval))
7634         ;
7635       else if (unformat (i, "life %d", &lifetime))
7636         ;
7637       else if (unformat (i, "count %d", &initial_count))
7638         ;
7639       else if (unformat (i, "interval %d", &initial_interval))
7640         ;
7641       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7642         suppress = 1;
7643       else if (unformat (i, "managed"))
7644         managed = 1;
7645       else if (unformat (i, "other"))
7646         other = 1;
7647       else if (unformat (i, "ll"))
7648         ll_option = 1;
7649       else if (unformat (i, "send"))
7650         send_unicast = 1;
7651       else if (unformat (i, "cease"))
7652         cease = 1;
7653       else if (unformat (i, "isno"))
7654         is_no = 1;
7655       else if (unformat (i, "def"))
7656         default_router = 1;
7657       else
7658         {
7659           clib_warning ("parse error '%U'", format_unformat_error, i);
7660           return -99;
7661         }
7662     }
7663
7664   if (sw_if_index_set == 0)
7665     {
7666       errmsg ("missing interface name or sw_if_index\n");
7667       return -99;
7668     }
7669
7670   /* Construct the API message */
7671   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7672
7673   mp->sw_if_index = ntohl (sw_if_index);
7674   mp->max_interval = ntohl (max_interval);
7675   mp->min_interval = ntohl (min_interval);
7676   mp->lifetime = ntohl (lifetime);
7677   mp->initial_count = ntohl (initial_count);
7678   mp->initial_interval = ntohl (initial_interval);
7679   mp->suppress = suppress;
7680   mp->managed = managed;
7681   mp->other = other;
7682   mp->ll_option = ll_option;
7683   mp->send_unicast = send_unicast;
7684   mp->cease = cease;
7685   mp->is_no = is_no;
7686   mp->default_router = default_router;
7687
7688   /* send it... */
7689   S;
7690
7691   /* Wait for a reply, return good/bad news  */
7692   W;
7693
7694   /* NOTREACHED */
7695   return 0;
7696 }
7697
7698 static int
7699 api_set_arp_neighbor_limit (vat_main_t * vam)
7700 {
7701   unformat_input_t *i = vam->input;
7702   vl_api_set_arp_neighbor_limit_t *mp;
7703   f64 timeout;
7704   u32 arp_nbr_limit;
7705   u8 limit_set = 0;
7706   u8 is_ipv6 = 0;
7707
7708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7709     {
7710       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7711         limit_set = 1;
7712       else if (unformat (i, "ipv6"))
7713         is_ipv6 = 1;
7714       else
7715         {
7716           clib_warning ("parse error '%U'", format_unformat_error, i);
7717           return -99;
7718         }
7719     }
7720
7721   if (limit_set == 0)
7722     {
7723       errmsg ("missing limit value\n");
7724       return -99;
7725     }
7726
7727   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7728
7729   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7730   mp->is_ipv6 = is_ipv6;
7731
7732   S;
7733   W;
7734   /* NOTREACHED */
7735   return 0;
7736 }
7737
7738 static int
7739 api_l2_patch_add_del (vat_main_t * vam)
7740 {
7741   unformat_input_t *i = vam->input;
7742   vl_api_l2_patch_add_del_t *mp;
7743   f64 timeout;
7744   u32 rx_sw_if_index;
7745   u8 rx_sw_if_index_set = 0;
7746   u32 tx_sw_if_index;
7747   u8 tx_sw_if_index_set = 0;
7748   u8 is_add = 1;
7749
7750   /* Parse args required to build the message */
7751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7752     {
7753       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7754         rx_sw_if_index_set = 1;
7755       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7756         tx_sw_if_index_set = 1;
7757       else if (unformat (i, "rx"))
7758         {
7759           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7760             {
7761               if (unformat (i, "%U", unformat_sw_if_index, vam,
7762                             &rx_sw_if_index))
7763                 rx_sw_if_index_set = 1;
7764             }
7765           else
7766             break;
7767         }
7768       else if (unformat (i, "tx"))
7769         {
7770           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7771             {
7772               if (unformat (i, "%U", unformat_sw_if_index, vam,
7773                             &tx_sw_if_index))
7774                 tx_sw_if_index_set = 1;
7775             }
7776           else
7777             break;
7778         }
7779       else if (unformat (i, "del"))
7780         is_add = 0;
7781       else
7782         break;
7783     }
7784
7785   if (rx_sw_if_index_set == 0)
7786     {
7787       errmsg ("missing rx interface name or rx_sw_if_index\n");
7788       return -99;
7789     }
7790
7791   if (tx_sw_if_index_set == 0)
7792     {
7793       errmsg ("missing tx interface name or tx_sw_if_index\n");
7794       return -99;
7795     }
7796
7797   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7798
7799   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7800   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7801   mp->is_add = is_add;
7802
7803   S;
7804   W;
7805   /* NOTREACHED */
7806   return 0;
7807 }
7808
7809 static int
7810 api_ioam_enable (vat_main_t * vam)
7811 {
7812   unformat_input_t *input = vam->input;
7813   vl_api_ioam_enable_t *mp;
7814   f64 timeout;
7815   u32 id = 0;
7816   int has_trace_option = 0;
7817   int has_pow_option = 0;
7818   int has_ppc_option = 0;
7819
7820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7821     {
7822       if (unformat (input, "trace"))
7823         has_trace_option = 1;
7824       else if (unformat (input, "pow"))
7825         has_pow_option = 1;
7826       else if (unformat (input, "ppc encap"))
7827         has_ppc_option = PPC_ENCAP;
7828       else if (unformat (input, "ppc decap"))
7829         has_ppc_option = PPC_DECAP;
7830       else if (unformat (input, "ppc none"))
7831         has_ppc_option = PPC_NONE;
7832       else
7833         break;
7834     }
7835   M (IOAM_ENABLE, ioam_enable);
7836   mp->id = htons (id);
7837   mp->trace_ppc = has_ppc_option;
7838   mp->pow_enable = has_pow_option;
7839   mp->trace_enable = has_trace_option;
7840
7841   S;
7842   W;
7843
7844   return (0);
7845
7846 }
7847
7848
7849 static int
7850 api_ioam_disable (vat_main_t * vam)
7851 {
7852   vl_api_ioam_disable_t *mp;
7853   f64 timeout;
7854
7855   M (IOAM_DISABLE, ioam_disable);
7856   S;
7857   W;
7858   return 0;
7859 }
7860
7861 static int
7862 api_sr_tunnel_add_del (vat_main_t * vam)
7863 {
7864   unformat_input_t *i = vam->input;
7865   vl_api_sr_tunnel_add_del_t *mp;
7866   f64 timeout;
7867   int is_del = 0;
7868   int pl_index;
7869   ip6_address_t src_address;
7870   int src_address_set = 0;
7871   ip6_address_t dst_address;
7872   u32 dst_mask_width;
7873   int dst_address_set = 0;
7874   u16 flags = 0;
7875   u32 rx_table_id = 0;
7876   u32 tx_table_id = 0;
7877   ip6_address_t *segments = 0;
7878   ip6_address_t *this_seg;
7879   ip6_address_t *tags = 0;
7880   ip6_address_t *this_tag;
7881   ip6_address_t next_address, tag;
7882   u8 *name = 0;
7883   u8 *policy_name = 0;
7884
7885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7886     {
7887       if (unformat (i, "del"))
7888         is_del = 1;
7889       else if (unformat (i, "name %s", &name))
7890         ;
7891       else if (unformat (i, "policy %s", &policy_name))
7892         ;
7893       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7894         ;
7895       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7896         ;
7897       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7898         src_address_set = 1;
7899       else if (unformat (i, "dst %U/%d",
7900                          unformat_ip6_address, &dst_address, &dst_mask_width))
7901         dst_address_set = 1;
7902       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7903         {
7904           vec_add2 (segments, this_seg, 1);
7905           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7906                        sizeof (*this_seg));
7907         }
7908       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7909         {
7910           vec_add2 (tags, this_tag, 1);
7911           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7912         }
7913       else if (unformat (i, "clean"))
7914         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7915       else if (unformat (i, "protected"))
7916         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7917       else if (unformat (i, "InPE %d", &pl_index))
7918         {
7919           if (pl_index <= 0 || pl_index > 4)
7920             {
7921             pl_index_range_error:
7922               errmsg ("pl index %d out of range\n", pl_index);
7923               return -99;
7924             }
7925           flags |=
7926             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7927         }
7928       else if (unformat (i, "EgPE %d", &pl_index))
7929         {
7930           if (pl_index <= 0 || pl_index > 4)
7931             goto pl_index_range_error;
7932           flags |=
7933             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7934         }
7935       else if (unformat (i, "OrgSrc %d", &pl_index))
7936         {
7937           if (pl_index <= 0 || pl_index > 4)
7938             goto pl_index_range_error;
7939           flags |=
7940             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7941         }
7942       else
7943         break;
7944     }
7945
7946   if (!src_address_set)
7947     {
7948       errmsg ("src address required\n");
7949       return -99;
7950     }
7951
7952   if (!dst_address_set)
7953     {
7954       errmsg ("dst address required\n");
7955       return -99;
7956     }
7957
7958   if (!segments)
7959     {
7960       errmsg ("at least one sr segment required\n");
7961       return -99;
7962     }
7963
7964   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7965       vec_len (segments) * sizeof (ip6_address_t)
7966       + vec_len (tags) * sizeof (ip6_address_t));
7967
7968   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7969   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7970   mp->dst_mask_width = dst_mask_width;
7971   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7972   mp->n_segments = vec_len (segments);
7973   mp->n_tags = vec_len (tags);
7974   mp->is_add = is_del == 0;
7975   clib_memcpy (mp->segs_and_tags, segments,
7976                vec_len (segments) * sizeof (ip6_address_t));
7977   clib_memcpy (mp->segs_and_tags +
7978                vec_len (segments) * sizeof (ip6_address_t), tags,
7979                vec_len (tags) * sizeof (ip6_address_t));
7980
7981   mp->outer_vrf_id = ntohl (rx_table_id);
7982   mp->inner_vrf_id = ntohl (tx_table_id);
7983   memcpy (mp->name, name, vec_len (name));
7984   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7985
7986   vec_free (segments);
7987   vec_free (tags);
7988
7989   S;
7990   W;
7991   /* NOTREACHED */
7992 }
7993
7994 static int
7995 api_sr_policy_add_del (vat_main_t * vam)
7996 {
7997   unformat_input_t *input = vam->input;
7998   vl_api_sr_policy_add_del_t *mp;
7999   f64 timeout;
8000   int is_del = 0;
8001   u8 *name = 0;
8002   u8 *tunnel_name = 0;
8003   u8 **tunnel_names = 0;
8004
8005   int name_set = 0;
8006   int tunnel_set = 0;
8007   int j = 0;
8008   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8009   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8010
8011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8012     {
8013       if (unformat (input, "del"))
8014         is_del = 1;
8015       else if (unformat (input, "name %s", &name))
8016         name_set = 1;
8017       else if (unformat (input, "tunnel %s", &tunnel_name))
8018         {
8019           if (tunnel_name)
8020             {
8021               vec_add1 (tunnel_names, tunnel_name);
8022               /* For serializer:
8023                  - length = #bytes to store in serial vector
8024                  - +1 = byte to store that length
8025                */
8026               tunnel_names_length += (vec_len (tunnel_name) + 1);
8027               tunnel_set = 1;
8028               tunnel_name = 0;
8029             }
8030         }
8031       else
8032         break;
8033     }
8034
8035   if (!name_set)
8036     {
8037       errmsg ("policy name required\n");
8038       return -99;
8039     }
8040
8041   if ((!tunnel_set) && (!is_del))
8042     {
8043       errmsg ("tunnel name required\n");
8044       return -99;
8045     }
8046
8047   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8048
8049
8050
8051   mp->is_add = !is_del;
8052
8053   memcpy (mp->name, name, vec_len (name));
8054   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8055   u8 *serial_orig = 0;
8056   vec_validate (serial_orig, tunnel_names_length);
8057   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8058   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8059
8060   for (j = 0; j < vec_len (tunnel_names); j++)
8061     {
8062       tun_name_len = vec_len (tunnel_names[j]);
8063       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8064       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8065       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8066       serial_orig += tun_name_len;      // Advance past the copy
8067     }
8068   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8069
8070   vec_free (tunnel_names);
8071   vec_free (tunnel_name);
8072
8073   S;
8074   W;
8075   /* NOTREACHED */
8076 }
8077
8078 static int
8079 api_sr_multicast_map_add_del (vat_main_t * vam)
8080 {
8081   unformat_input_t *input = vam->input;
8082   vl_api_sr_multicast_map_add_del_t *mp;
8083   f64 timeout;
8084   int is_del = 0;
8085   ip6_address_t multicast_address;
8086   u8 *policy_name = 0;
8087   int multicast_address_set = 0;
8088
8089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8090     {
8091       if (unformat (input, "del"))
8092         is_del = 1;
8093       else
8094         if (unformat
8095             (input, "address %U", unformat_ip6_address, &multicast_address))
8096         multicast_address_set = 1;
8097       else if (unformat (input, "sr-policy %s", &policy_name))
8098         ;
8099       else
8100         break;
8101     }
8102
8103   if (!is_del && !policy_name)
8104     {
8105       errmsg ("sr-policy name required\n");
8106       return -99;
8107     }
8108
8109
8110   if (!multicast_address_set)
8111     {
8112       errmsg ("address required\n");
8113       return -99;
8114     }
8115
8116   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8117
8118   mp->is_add = !is_del;
8119   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8120   clib_memcpy (mp->multicast_address, &multicast_address,
8121                sizeof (mp->multicast_address));
8122
8123
8124   vec_free (policy_name);
8125
8126   S;
8127   W;
8128   /* NOTREACHED */
8129 }
8130
8131
8132 #define foreach_tcp_proto_field                 \
8133 _(src_port)                                     \
8134 _(dst_port)
8135
8136 #define foreach_udp_proto_field                 \
8137 _(src_port)                                     \
8138 _(dst_port)
8139
8140 #define foreach_ip4_proto_field                 \
8141 _(src_address)                                  \
8142 _(dst_address)                                  \
8143 _(tos)                                          \
8144 _(length)                                       \
8145 _(fragment_id)                                  \
8146 _(ttl)                                          \
8147 _(protocol)                                     \
8148 _(checksum)
8149
8150 uword
8151 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8152 {
8153   u8 **maskp = va_arg (*args, u8 **);
8154   u8 *mask = 0;
8155   u8 found_something = 0;
8156   tcp_header_t *tcp;
8157
8158 #define _(a) u8 a=0;
8159   foreach_tcp_proto_field;
8160 #undef _
8161
8162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8163     {
8164       if (0);
8165 #define _(a) else if (unformat (input, #a)) a=1;
8166       foreach_tcp_proto_field
8167 #undef _
8168         else
8169         break;
8170     }
8171
8172 #define _(a) found_something += a;
8173   foreach_tcp_proto_field;
8174 #undef _
8175
8176   if (found_something == 0)
8177     return 0;
8178
8179   vec_validate (mask, sizeof (*tcp) - 1);
8180
8181   tcp = (tcp_header_t *) mask;
8182
8183 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8184   foreach_tcp_proto_field;
8185 #undef _
8186
8187   *maskp = mask;
8188   return 1;
8189 }
8190
8191 uword
8192 unformat_udp_mask (unformat_input_t * input, va_list * args)
8193 {
8194   u8 **maskp = va_arg (*args, u8 **);
8195   u8 *mask = 0;
8196   u8 found_something = 0;
8197   udp_header_t *udp;
8198
8199 #define _(a) u8 a=0;
8200   foreach_udp_proto_field;
8201 #undef _
8202
8203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8204     {
8205       if (0);
8206 #define _(a) else if (unformat (input, #a)) a=1;
8207       foreach_udp_proto_field
8208 #undef _
8209         else
8210         break;
8211     }
8212
8213 #define _(a) found_something += a;
8214   foreach_udp_proto_field;
8215 #undef _
8216
8217   if (found_something == 0)
8218     return 0;
8219
8220   vec_validate (mask, sizeof (*udp) - 1);
8221
8222   udp = (udp_header_t *) mask;
8223
8224 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8225   foreach_udp_proto_field;
8226 #undef _
8227
8228   *maskp = mask;
8229   return 1;
8230 }
8231
8232 typedef struct
8233 {
8234   u16 src_port, dst_port;
8235 } tcpudp_header_t;
8236
8237 uword
8238 unformat_l4_mask (unformat_input_t * input, va_list * args)
8239 {
8240   u8 **maskp = va_arg (*args, u8 **);
8241   u16 src_port = 0, dst_port = 0;
8242   tcpudp_header_t *tcpudp;
8243
8244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8245     {
8246       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8247         return 1;
8248       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8249         return 1;
8250       else if (unformat (input, "src_port"))
8251         src_port = 0xFFFF;
8252       else if (unformat (input, "dst_port"))
8253         dst_port = 0xFFFF;
8254       else
8255         return 0;
8256     }
8257
8258   if (!src_port && !dst_port)
8259     return 0;
8260
8261   u8 *mask = 0;
8262   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8263
8264   tcpudp = (tcpudp_header_t *) mask;
8265   tcpudp->src_port = src_port;
8266   tcpudp->dst_port = dst_port;
8267
8268   *maskp = mask;
8269
8270   return 1;
8271 }
8272
8273 uword
8274 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8275 {
8276   u8 **maskp = va_arg (*args, u8 **);
8277   u8 *mask = 0;
8278   u8 found_something = 0;
8279   ip4_header_t *ip;
8280
8281 #define _(a) u8 a=0;
8282   foreach_ip4_proto_field;
8283 #undef _
8284   u8 version = 0;
8285   u8 hdr_length = 0;
8286
8287
8288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8289     {
8290       if (unformat (input, "version"))
8291         version = 1;
8292       else if (unformat (input, "hdr_length"))
8293         hdr_length = 1;
8294       else if (unformat (input, "src"))
8295         src_address = 1;
8296       else if (unformat (input, "dst"))
8297         dst_address = 1;
8298       else if (unformat (input, "proto"))
8299         protocol = 1;
8300
8301 #define _(a) else if (unformat (input, #a)) a=1;
8302       foreach_ip4_proto_field
8303 #undef _
8304         else
8305         break;
8306     }
8307
8308 #define _(a) found_something += a;
8309   foreach_ip4_proto_field;
8310 #undef _
8311
8312   if (found_something == 0)
8313     return 0;
8314
8315   vec_validate (mask, sizeof (*ip) - 1);
8316
8317   ip = (ip4_header_t *) mask;
8318
8319 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8320   foreach_ip4_proto_field;
8321 #undef _
8322
8323   ip->ip_version_and_header_length = 0;
8324
8325   if (version)
8326     ip->ip_version_and_header_length |= 0xF0;
8327
8328   if (hdr_length)
8329     ip->ip_version_and_header_length |= 0x0F;
8330
8331   *maskp = mask;
8332   return 1;
8333 }
8334
8335 #define foreach_ip6_proto_field                 \
8336 _(src_address)                                  \
8337 _(dst_address)                                  \
8338 _(payload_length)                               \
8339 _(hop_limit)                                    \
8340 _(protocol)
8341
8342 uword
8343 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8344 {
8345   u8 **maskp = va_arg (*args, u8 **);
8346   u8 *mask = 0;
8347   u8 found_something = 0;
8348   ip6_header_t *ip;
8349   u32 ip_version_traffic_class_and_flow_label;
8350
8351 #define _(a) u8 a=0;
8352   foreach_ip6_proto_field;
8353 #undef _
8354   u8 version = 0;
8355   u8 traffic_class = 0;
8356   u8 flow_label = 0;
8357
8358   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8359     {
8360       if (unformat (input, "version"))
8361         version = 1;
8362       else if (unformat (input, "traffic-class"))
8363         traffic_class = 1;
8364       else if (unformat (input, "flow-label"))
8365         flow_label = 1;
8366       else if (unformat (input, "src"))
8367         src_address = 1;
8368       else if (unformat (input, "dst"))
8369         dst_address = 1;
8370       else if (unformat (input, "proto"))
8371         protocol = 1;
8372
8373 #define _(a) else if (unformat (input, #a)) a=1;
8374       foreach_ip6_proto_field
8375 #undef _
8376         else
8377         break;
8378     }
8379
8380 #define _(a) found_something += a;
8381   foreach_ip6_proto_field;
8382 #undef _
8383
8384   if (found_something == 0)
8385     return 0;
8386
8387   vec_validate (mask, sizeof (*ip) - 1);
8388
8389   ip = (ip6_header_t *) mask;
8390
8391 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8392   foreach_ip6_proto_field;
8393 #undef _
8394
8395   ip_version_traffic_class_and_flow_label = 0;
8396
8397   if (version)
8398     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8399
8400   if (traffic_class)
8401     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8402
8403   if (flow_label)
8404     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8405
8406   ip->ip_version_traffic_class_and_flow_label =
8407     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8408
8409   *maskp = mask;
8410   return 1;
8411 }
8412
8413 uword
8414 unformat_l3_mask (unformat_input_t * input, va_list * args)
8415 {
8416   u8 **maskp = va_arg (*args, u8 **);
8417
8418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8419     {
8420       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8421         return 1;
8422       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8423         return 1;
8424       else
8425         break;
8426     }
8427   return 0;
8428 }
8429
8430 uword
8431 unformat_l2_mask (unformat_input_t * input, va_list * args)
8432 {
8433   u8 **maskp = va_arg (*args, u8 **);
8434   u8 *mask = 0;
8435   u8 src = 0;
8436   u8 dst = 0;
8437   u8 proto = 0;
8438   u8 tag1 = 0;
8439   u8 tag2 = 0;
8440   u8 ignore_tag1 = 0;
8441   u8 ignore_tag2 = 0;
8442   u8 cos1 = 0;
8443   u8 cos2 = 0;
8444   u8 dot1q = 0;
8445   u8 dot1ad = 0;
8446   int len = 14;
8447
8448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8449     {
8450       if (unformat (input, "src"))
8451         src = 1;
8452       else if (unformat (input, "dst"))
8453         dst = 1;
8454       else if (unformat (input, "proto"))
8455         proto = 1;
8456       else if (unformat (input, "tag1"))
8457         tag1 = 1;
8458       else if (unformat (input, "tag2"))
8459         tag2 = 1;
8460       else if (unformat (input, "ignore-tag1"))
8461         ignore_tag1 = 1;
8462       else if (unformat (input, "ignore-tag2"))
8463         ignore_tag2 = 1;
8464       else if (unformat (input, "cos1"))
8465         cos1 = 1;
8466       else if (unformat (input, "cos2"))
8467         cos2 = 1;
8468       else if (unformat (input, "dot1q"))
8469         dot1q = 1;
8470       else if (unformat (input, "dot1ad"))
8471         dot1ad = 1;
8472       else
8473         break;
8474     }
8475   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8476        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8477     return 0;
8478
8479   if (tag1 || ignore_tag1 || cos1 || dot1q)
8480     len = 18;
8481   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8482     len = 22;
8483
8484   vec_validate (mask, len - 1);
8485
8486   if (dst)
8487     memset (mask, 0xff, 6);
8488
8489   if (src)
8490     memset (mask + 6, 0xff, 6);
8491
8492   if (tag2 || dot1ad)
8493     {
8494       /* inner vlan tag */
8495       if (tag2)
8496         {
8497           mask[19] = 0xff;
8498           mask[18] = 0x0f;
8499         }
8500       if (cos2)
8501         mask[18] |= 0xe0;
8502       if (proto)
8503         mask[21] = mask[20] = 0xff;
8504       if (tag1)
8505         {
8506           mask[15] = 0xff;
8507           mask[14] = 0x0f;
8508         }
8509       if (cos1)
8510         mask[14] |= 0xe0;
8511       *maskp = mask;
8512       return 1;
8513     }
8514   if (tag1 | dot1q)
8515     {
8516       if (tag1)
8517         {
8518           mask[15] = 0xff;
8519           mask[14] = 0x0f;
8520         }
8521       if (cos1)
8522         mask[14] |= 0xe0;
8523       if (proto)
8524         mask[16] = mask[17] = 0xff;
8525
8526       *maskp = mask;
8527       return 1;
8528     }
8529   if (cos2)
8530     mask[18] |= 0xe0;
8531   if (cos1)
8532     mask[14] |= 0xe0;
8533   if (proto)
8534     mask[12] = mask[13] = 0xff;
8535
8536   *maskp = mask;
8537   return 1;
8538 }
8539
8540 uword
8541 unformat_classify_mask (unformat_input_t * input, va_list * args)
8542 {
8543   u8 **maskp = va_arg (*args, u8 **);
8544   u32 *skipp = va_arg (*args, u32 *);
8545   u32 *matchp = va_arg (*args, u32 *);
8546   u32 match;
8547   u8 *mask = 0;
8548   u8 *l2 = 0;
8549   u8 *l3 = 0;
8550   u8 *l4 = 0;
8551   int i;
8552
8553   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8554     {
8555       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8556         ;
8557       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8558         ;
8559       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8560         ;
8561       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8562         ;
8563       else
8564         break;
8565     }
8566
8567   if (l4 && !l3)
8568     {
8569       vec_free (mask);
8570       vec_free (l2);
8571       vec_free (l4);
8572       return 0;
8573     }
8574
8575   if (mask || l2 || l3 || l4)
8576     {
8577       if (l2 || l3 || l4)
8578         {
8579           /* "With a free Ethernet header in every package" */
8580           if (l2 == 0)
8581             vec_validate (l2, 13);
8582           mask = l2;
8583           if (vec_len (l3))
8584             {
8585               vec_append (mask, l3);
8586               vec_free (l3);
8587             }
8588           if (vec_len (l4))
8589             {
8590               vec_append (mask, l4);
8591               vec_free (l4);
8592             }
8593         }
8594
8595       /* Scan forward looking for the first significant mask octet */
8596       for (i = 0; i < vec_len (mask); i++)
8597         if (mask[i])
8598           break;
8599
8600       /* compute (skip, match) params */
8601       *skipp = i / sizeof (u32x4);
8602       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8603
8604       /* Pad mask to an even multiple of the vector size */
8605       while (vec_len (mask) % sizeof (u32x4))
8606         vec_add1 (mask, 0);
8607
8608       match = vec_len (mask) / sizeof (u32x4);
8609
8610       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8611         {
8612           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8613           if (*tmp || *(tmp + 1))
8614             break;
8615           match--;
8616         }
8617       if (match == 0)
8618         clib_warning ("BUG: match 0");
8619
8620       _vec_len (mask) = match * sizeof (u32x4);
8621
8622       *matchp = match;
8623       *maskp = mask;
8624
8625       return 1;
8626     }
8627
8628   return 0;
8629 }
8630
8631 #define foreach_l2_next                         \
8632 _(drop, DROP)                                   \
8633 _(ethernet, ETHERNET_INPUT)                     \
8634 _(ip4, IP4_INPUT)                               \
8635 _(ip6, IP6_INPUT)
8636
8637 uword
8638 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8639 {
8640   u32 *miss_next_indexp = va_arg (*args, u32 *);
8641   u32 next_index = 0;
8642   u32 tmp;
8643
8644 #define _(n,N) \
8645   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8646   foreach_l2_next;
8647 #undef _
8648
8649   if (unformat (input, "%d", &tmp))
8650     {
8651       next_index = tmp;
8652       goto out;
8653     }
8654
8655   return 0;
8656
8657 out:
8658   *miss_next_indexp = next_index;
8659   return 1;
8660 }
8661
8662 #define foreach_ip_next                         \
8663 _(drop, DROP)                                   \
8664 _(local, LOCAL)                                 \
8665 _(rewrite, REWRITE)
8666
8667 uword
8668 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8669 {
8670   u32 *miss_next_indexp = va_arg (*args, u32 *);
8671   u32 next_index = 0;
8672   u32 tmp;
8673
8674 #define _(n,N) \
8675   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8676   foreach_ip_next;
8677 #undef _
8678
8679   if (unformat (input, "%d", &tmp))
8680     {
8681       next_index = tmp;
8682       goto out;
8683     }
8684
8685   return 0;
8686
8687 out:
8688   *miss_next_indexp = next_index;
8689   return 1;
8690 }
8691
8692 #define foreach_acl_next                        \
8693 _(deny, DENY)
8694
8695 uword
8696 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8697 {
8698   u32 *miss_next_indexp = va_arg (*args, u32 *);
8699   u32 next_index = 0;
8700   u32 tmp;
8701
8702 #define _(n,N) \
8703   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8704   foreach_acl_next;
8705 #undef _
8706
8707   if (unformat (input, "permit"))
8708     {
8709       next_index = ~0;
8710       goto out;
8711     }
8712   else if (unformat (input, "%d", &tmp))
8713     {
8714       next_index = tmp;
8715       goto out;
8716     }
8717
8718   return 0;
8719
8720 out:
8721   *miss_next_indexp = next_index;
8722   return 1;
8723 }
8724
8725 uword
8726 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8727 {
8728   u32 *r = va_arg (*args, u32 *);
8729
8730   if (unformat (input, "conform-color"))
8731     *r = POLICE_CONFORM;
8732   else if (unformat (input, "exceed-color"))
8733     *r = POLICE_EXCEED;
8734   else
8735     return 0;
8736
8737   return 1;
8738 }
8739
8740 static int
8741 api_classify_add_del_table (vat_main_t * vam)
8742 {
8743   unformat_input_t *i = vam->input;
8744   vl_api_classify_add_del_table_t *mp;
8745
8746   u32 nbuckets = 2;
8747   u32 skip = ~0;
8748   u32 match = ~0;
8749   int is_add = 1;
8750   u32 table_index = ~0;
8751   u32 next_table_index = ~0;
8752   u32 miss_next_index = ~0;
8753   u32 memory_size = 32 << 20;
8754   u8 *mask = 0;
8755   f64 timeout;
8756
8757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8758     {
8759       if (unformat (i, "del"))
8760         is_add = 0;
8761       else if (unformat (i, "buckets %d", &nbuckets))
8762         ;
8763       else if (unformat (i, "memory_size %d", &memory_size))
8764         ;
8765       else if (unformat (i, "skip %d", &skip))
8766         ;
8767       else if (unformat (i, "match %d", &match))
8768         ;
8769       else if (unformat (i, "table %d", &table_index))
8770         ;
8771       else if (unformat (i, "mask %U", unformat_classify_mask,
8772                          &mask, &skip, &match))
8773         ;
8774       else if (unformat (i, "next-table %d", &next_table_index))
8775         ;
8776       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8777                          &miss_next_index))
8778         ;
8779       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8780                          &miss_next_index))
8781         ;
8782       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8783                          &miss_next_index))
8784         ;
8785       else
8786         break;
8787     }
8788
8789   if (is_add && mask == 0)
8790     {
8791       errmsg ("Mask required\n");
8792       return -99;
8793     }
8794
8795   if (is_add && skip == ~0)
8796     {
8797       errmsg ("skip count required\n");
8798       return -99;
8799     }
8800
8801   if (is_add && match == ~0)
8802     {
8803       errmsg ("match count required\n");
8804       return -99;
8805     }
8806
8807   if (!is_add && table_index == ~0)
8808     {
8809       errmsg ("table index required for delete\n");
8810       return -99;
8811     }
8812
8813   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8814
8815   mp->is_add = is_add;
8816   mp->table_index = ntohl (table_index);
8817   mp->nbuckets = ntohl (nbuckets);
8818   mp->memory_size = ntohl (memory_size);
8819   mp->skip_n_vectors = ntohl (skip);
8820   mp->match_n_vectors = ntohl (match);
8821   mp->next_table_index = ntohl (next_table_index);
8822   mp->miss_next_index = ntohl (miss_next_index);
8823   clib_memcpy (mp->mask, mask, vec_len (mask));
8824
8825   vec_free (mask);
8826
8827   S;
8828   W;
8829   /* NOTREACHED */
8830 }
8831
8832 uword
8833 unformat_l4_match (unformat_input_t * input, va_list * args)
8834 {
8835   u8 **matchp = va_arg (*args, u8 **);
8836
8837   u8 *proto_header = 0;
8838   int src_port = 0;
8839   int dst_port = 0;
8840
8841   tcpudp_header_t h;
8842
8843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8844     {
8845       if (unformat (input, "src_port %d", &src_port))
8846         ;
8847       else if (unformat (input, "dst_port %d", &dst_port))
8848         ;
8849       else
8850         return 0;
8851     }
8852
8853   h.src_port = clib_host_to_net_u16 (src_port);
8854   h.dst_port = clib_host_to_net_u16 (dst_port);
8855   vec_validate (proto_header, sizeof (h) - 1);
8856   memcpy (proto_header, &h, sizeof (h));
8857
8858   *matchp = proto_header;
8859
8860   return 1;
8861 }
8862
8863 uword
8864 unformat_ip4_match (unformat_input_t * input, va_list * args)
8865 {
8866   u8 **matchp = va_arg (*args, u8 **);
8867   u8 *match = 0;
8868   ip4_header_t *ip;
8869   int version = 0;
8870   u32 version_val;
8871   int hdr_length = 0;
8872   u32 hdr_length_val;
8873   int src = 0, dst = 0;
8874   ip4_address_t src_val, dst_val;
8875   int proto = 0;
8876   u32 proto_val;
8877   int tos = 0;
8878   u32 tos_val;
8879   int length = 0;
8880   u32 length_val;
8881   int fragment_id = 0;
8882   u32 fragment_id_val;
8883   int ttl = 0;
8884   int ttl_val;
8885   int checksum = 0;
8886   u32 checksum_val;
8887
8888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8889     {
8890       if (unformat (input, "version %d", &version_val))
8891         version = 1;
8892       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8893         hdr_length = 1;
8894       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8895         src = 1;
8896       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8897         dst = 1;
8898       else if (unformat (input, "proto %d", &proto_val))
8899         proto = 1;
8900       else if (unformat (input, "tos %d", &tos_val))
8901         tos = 1;
8902       else if (unformat (input, "length %d", &length_val))
8903         length = 1;
8904       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8905         fragment_id = 1;
8906       else if (unformat (input, "ttl %d", &ttl_val))
8907         ttl = 1;
8908       else if (unformat (input, "checksum %d", &checksum_val))
8909         checksum = 1;
8910       else
8911         break;
8912     }
8913
8914   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8915       + ttl + checksum == 0)
8916     return 0;
8917
8918   /*
8919    * Aligned because we use the real comparison functions
8920    */
8921   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8922
8923   ip = (ip4_header_t *) match;
8924
8925   /* These are realistically matched in practice */
8926   if (src)
8927     ip->src_address.as_u32 = src_val.as_u32;
8928
8929   if (dst)
8930     ip->dst_address.as_u32 = dst_val.as_u32;
8931
8932   if (proto)
8933     ip->protocol = proto_val;
8934
8935
8936   /* These are not, but they're included for completeness */
8937   if (version)
8938     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8939
8940   if (hdr_length)
8941     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8942
8943   if (tos)
8944     ip->tos = tos_val;
8945
8946   if (length)
8947     ip->length = clib_host_to_net_u16 (length_val);
8948
8949   if (ttl)
8950     ip->ttl = ttl_val;
8951
8952   if (checksum)
8953     ip->checksum = clib_host_to_net_u16 (checksum_val);
8954
8955   *matchp = match;
8956   return 1;
8957 }
8958
8959 uword
8960 unformat_ip6_match (unformat_input_t * input, va_list * args)
8961 {
8962   u8 **matchp = va_arg (*args, u8 **);
8963   u8 *match = 0;
8964   ip6_header_t *ip;
8965   int version = 0;
8966   u32 version_val;
8967   u8 traffic_class = 0;
8968   u32 traffic_class_val = 0;
8969   u8 flow_label = 0;
8970   u8 flow_label_val;
8971   int src = 0, dst = 0;
8972   ip6_address_t src_val, dst_val;
8973   int proto = 0;
8974   u32 proto_val;
8975   int payload_length = 0;
8976   u32 payload_length_val;
8977   int hop_limit = 0;
8978   int hop_limit_val;
8979   u32 ip_version_traffic_class_and_flow_label;
8980
8981   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8982     {
8983       if (unformat (input, "version %d", &version_val))
8984         version = 1;
8985       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8986         traffic_class = 1;
8987       else if (unformat (input, "flow_label %d", &flow_label_val))
8988         flow_label = 1;
8989       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8990         src = 1;
8991       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8992         dst = 1;
8993       else if (unformat (input, "proto %d", &proto_val))
8994         proto = 1;
8995       else if (unformat (input, "payload_length %d", &payload_length_val))
8996         payload_length = 1;
8997       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8998         hop_limit = 1;
8999       else
9000         break;
9001     }
9002
9003   if (version + traffic_class + flow_label + src + dst + proto +
9004       payload_length + hop_limit == 0)
9005     return 0;
9006
9007   /*
9008    * Aligned because we use the real comparison functions
9009    */
9010   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9011
9012   ip = (ip6_header_t *) match;
9013
9014   if (src)
9015     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9016
9017   if (dst)
9018     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9019
9020   if (proto)
9021     ip->protocol = proto_val;
9022
9023   ip_version_traffic_class_and_flow_label = 0;
9024
9025   if (version)
9026     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9027
9028   if (traffic_class)
9029     ip_version_traffic_class_and_flow_label |=
9030       (traffic_class_val & 0xFF) << 20;
9031
9032   if (flow_label)
9033     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9034
9035   ip->ip_version_traffic_class_and_flow_label =
9036     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9037
9038   if (payload_length)
9039     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9040
9041   if (hop_limit)
9042     ip->hop_limit = hop_limit_val;
9043
9044   *matchp = match;
9045   return 1;
9046 }
9047
9048 uword
9049 unformat_l3_match (unformat_input_t * input, va_list * args)
9050 {
9051   u8 **matchp = va_arg (*args, u8 **);
9052
9053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9054     {
9055       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9056         return 1;
9057       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9058         return 1;
9059       else
9060         break;
9061     }
9062   return 0;
9063 }
9064
9065 uword
9066 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9067 {
9068   u8 *tagp = va_arg (*args, u8 *);
9069   u32 tag;
9070
9071   if (unformat (input, "%d", &tag))
9072     {
9073       tagp[0] = (tag >> 8) & 0x0F;
9074       tagp[1] = tag & 0xFF;
9075       return 1;
9076     }
9077
9078   return 0;
9079 }
9080
9081 uword
9082 unformat_l2_match (unformat_input_t * input, va_list * args)
9083 {
9084   u8 **matchp = va_arg (*args, u8 **);
9085   u8 *match = 0;
9086   u8 src = 0;
9087   u8 src_val[6];
9088   u8 dst = 0;
9089   u8 dst_val[6];
9090   u8 proto = 0;
9091   u16 proto_val;
9092   u8 tag1 = 0;
9093   u8 tag1_val[2];
9094   u8 tag2 = 0;
9095   u8 tag2_val[2];
9096   int len = 14;
9097   u8 ignore_tag1 = 0;
9098   u8 ignore_tag2 = 0;
9099   u8 cos1 = 0;
9100   u8 cos2 = 0;
9101   u32 cos1_val = 0;
9102   u32 cos2_val = 0;
9103
9104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9105     {
9106       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9107         src = 1;
9108       else
9109         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9110         dst = 1;
9111       else if (unformat (input, "proto %U",
9112                          unformat_ethernet_type_host_byte_order, &proto_val))
9113         proto = 1;
9114       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9115         tag1 = 1;
9116       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9117         tag2 = 1;
9118       else if (unformat (input, "ignore-tag1"))
9119         ignore_tag1 = 1;
9120       else if (unformat (input, "ignore-tag2"))
9121         ignore_tag2 = 1;
9122       else if (unformat (input, "cos1 %d", &cos1_val))
9123         cos1 = 1;
9124       else if (unformat (input, "cos2 %d", &cos2_val))
9125         cos2 = 1;
9126       else
9127         break;
9128     }
9129   if ((src + dst + proto + tag1 + tag2 +
9130        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9131     return 0;
9132
9133   if (tag1 || ignore_tag1 || cos1)
9134     len = 18;
9135   if (tag2 || ignore_tag2 || cos2)
9136     len = 22;
9137
9138   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9139
9140   if (dst)
9141     clib_memcpy (match, dst_val, 6);
9142
9143   if (src)
9144     clib_memcpy (match + 6, src_val, 6);
9145
9146   if (tag2)
9147     {
9148       /* inner vlan tag */
9149       match[19] = tag2_val[1];
9150       match[18] = tag2_val[0];
9151       if (cos2)
9152         match[18] |= (cos2_val & 0x7) << 5;
9153       if (proto)
9154         {
9155           match[21] = proto_val & 0xff;
9156           match[20] = proto_val >> 8;
9157         }
9158       if (tag1)
9159         {
9160           match[15] = tag1_val[1];
9161           match[14] = tag1_val[0];
9162         }
9163       if (cos1)
9164         match[14] |= (cos1_val & 0x7) << 5;
9165       *matchp = match;
9166       return 1;
9167     }
9168   if (tag1)
9169     {
9170       match[15] = tag1_val[1];
9171       match[14] = tag1_val[0];
9172       if (proto)
9173         {
9174           match[17] = proto_val & 0xff;
9175           match[16] = proto_val >> 8;
9176         }
9177       if (cos1)
9178         match[14] |= (cos1_val & 0x7) << 5;
9179
9180       *matchp = match;
9181       return 1;
9182     }
9183   if (cos2)
9184     match[18] |= (cos2_val & 0x7) << 5;
9185   if (cos1)
9186     match[14] |= (cos1_val & 0x7) << 5;
9187   if (proto)
9188     {
9189       match[13] = proto_val & 0xff;
9190       match[12] = proto_val >> 8;
9191     }
9192
9193   *matchp = match;
9194   return 1;
9195 }
9196
9197
9198 uword
9199 unformat_classify_match (unformat_input_t * input, va_list * args)
9200 {
9201   u8 **matchp = va_arg (*args, u8 **);
9202   u32 skip_n_vectors = va_arg (*args, u32);
9203   u32 match_n_vectors = va_arg (*args, u32);
9204
9205   u8 *match = 0;
9206   u8 *l2 = 0;
9207   u8 *l3 = 0;
9208   u8 *l4 = 0;
9209
9210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9211     {
9212       if (unformat (input, "hex %U", unformat_hex_string, &match))
9213         ;
9214       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9215         ;
9216       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9217         ;
9218       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9219         ;
9220       else
9221         break;
9222     }
9223
9224   if (l4 && !l3)
9225     {
9226       vec_free (match);
9227       vec_free (l2);
9228       vec_free (l4);
9229       return 0;
9230     }
9231
9232   if (match || l2 || l3 || l4)
9233     {
9234       if (l2 || l3 || l4)
9235         {
9236           /* "Win a free Ethernet header in every packet" */
9237           if (l2 == 0)
9238             vec_validate_aligned (l2, 13, sizeof (u32x4));
9239           match = l2;
9240           if (vec_len (l3))
9241             {
9242               vec_append_aligned (match, l3, sizeof (u32x4));
9243               vec_free (l3);
9244             }
9245           if (vec_len (l4))
9246             {
9247               vec_append_aligned (match, l4, sizeof (u32x4));
9248               vec_free (l4);
9249             }
9250         }
9251
9252       /* Make sure the vector is big enough even if key is all 0's */
9253       vec_validate_aligned
9254         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9255          sizeof (u32x4));
9256
9257       /* Set size, include skipped vectors */
9258       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9259
9260       *matchp = match;
9261
9262       return 1;
9263     }
9264
9265   return 0;
9266 }
9267
9268 static int
9269 api_classify_add_del_session (vat_main_t * vam)
9270 {
9271   unformat_input_t *i = vam->input;
9272   vl_api_classify_add_del_session_t *mp;
9273   int is_add = 1;
9274   u32 table_index = ~0;
9275   u32 hit_next_index = ~0;
9276   u32 opaque_index = ~0;
9277   u8 *match = 0;
9278   i32 advance = 0;
9279   f64 timeout;
9280   u32 skip_n_vectors = 0;
9281   u32 match_n_vectors = 0;
9282
9283   /*
9284    * Warning: you have to supply skip_n and match_n
9285    * because the API client cant simply look at the classify
9286    * table object.
9287    */
9288
9289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9290     {
9291       if (unformat (i, "del"))
9292         is_add = 0;
9293       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9294                          &hit_next_index))
9295         ;
9296       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9297                          &hit_next_index))
9298         ;
9299       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9300                          &hit_next_index))
9301         ;
9302       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9303         ;
9304       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9305         ;
9306       else if (unformat (i, "opaque-index %d", &opaque_index))
9307         ;
9308       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9309         ;
9310       else if (unformat (i, "match_n %d", &match_n_vectors))
9311         ;
9312       else if (unformat (i, "match %U", unformat_classify_match,
9313                          &match, skip_n_vectors, match_n_vectors))
9314         ;
9315       else if (unformat (i, "advance %d", &advance))
9316         ;
9317       else if (unformat (i, "table-index %d", &table_index))
9318         ;
9319       else
9320         break;
9321     }
9322
9323   if (table_index == ~0)
9324     {
9325       errmsg ("Table index required\n");
9326       return -99;
9327     }
9328
9329   if (is_add && match == 0)
9330     {
9331       errmsg ("Match value required\n");
9332       return -99;
9333     }
9334
9335   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9336
9337   mp->is_add = is_add;
9338   mp->table_index = ntohl (table_index);
9339   mp->hit_next_index = ntohl (hit_next_index);
9340   mp->opaque_index = ntohl (opaque_index);
9341   mp->advance = ntohl (advance);
9342   clib_memcpy (mp->match, match, vec_len (match));
9343   vec_free (match);
9344
9345   S;
9346   W;
9347   /* NOTREACHED */
9348 }
9349
9350 static int
9351 api_classify_set_interface_ip_table (vat_main_t * vam)
9352 {
9353   unformat_input_t *i = vam->input;
9354   vl_api_classify_set_interface_ip_table_t *mp;
9355   f64 timeout;
9356   u32 sw_if_index;
9357   int sw_if_index_set;
9358   u32 table_index = ~0;
9359   u8 is_ipv6 = 0;
9360
9361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9362     {
9363       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9364         sw_if_index_set = 1;
9365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9366         sw_if_index_set = 1;
9367       else if (unformat (i, "table %d", &table_index))
9368         ;
9369       else
9370         {
9371           clib_warning ("parse error '%U'", format_unformat_error, i);
9372           return -99;
9373         }
9374     }
9375
9376   if (sw_if_index_set == 0)
9377     {
9378       errmsg ("missing interface name or sw_if_index\n");
9379       return -99;
9380     }
9381
9382
9383   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9384
9385   mp->sw_if_index = ntohl (sw_if_index);
9386   mp->table_index = ntohl (table_index);
9387   mp->is_ipv6 = is_ipv6;
9388
9389   S;
9390   W;
9391   /* NOTREACHED */
9392   return 0;
9393 }
9394
9395 static int
9396 api_classify_set_interface_l2_tables (vat_main_t * vam)
9397 {
9398   unformat_input_t *i = vam->input;
9399   vl_api_classify_set_interface_l2_tables_t *mp;
9400   f64 timeout;
9401   u32 sw_if_index;
9402   int sw_if_index_set;
9403   u32 ip4_table_index = ~0;
9404   u32 ip6_table_index = ~0;
9405   u32 other_table_index = ~0;
9406   u32 is_input = 1;
9407
9408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9409     {
9410       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9411         sw_if_index_set = 1;
9412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9413         sw_if_index_set = 1;
9414       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9415         ;
9416       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9417         ;
9418       else if (unformat (i, "other-table %d", &other_table_index))
9419         ;
9420       else if (unformat (i, "is-input %d", &is_input))
9421         ;
9422       else
9423         {
9424           clib_warning ("parse error '%U'", format_unformat_error, i);
9425           return -99;
9426         }
9427     }
9428
9429   if (sw_if_index_set == 0)
9430     {
9431       errmsg ("missing interface name or sw_if_index\n");
9432       return -99;
9433     }
9434
9435
9436   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9437
9438   mp->sw_if_index = ntohl (sw_if_index);
9439   mp->ip4_table_index = ntohl (ip4_table_index);
9440   mp->ip6_table_index = ntohl (ip6_table_index);
9441   mp->other_table_index = ntohl (other_table_index);
9442   mp->is_input = (u8) is_input;
9443
9444   S;
9445   W;
9446   /* NOTREACHED */
9447   return 0;
9448 }
9449
9450 static int
9451 api_set_ipfix_exporter (vat_main_t * vam)
9452 {
9453   unformat_input_t *i = vam->input;
9454   vl_api_set_ipfix_exporter_t *mp;
9455   ip4_address_t collector_address;
9456   u8 collector_address_set = 0;
9457   u32 collector_port = ~0;
9458   ip4_address_t src_address;
9459   u8 src_address_set = 0;
9460   u32 vrf_id = ~0;
9461   u32 path_mtu = ~0;
9462   u32 template_interval = ~0;
9463   u8 udp_checksum = 0;
9464   f64 timeout;
9465
9466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9467     {
9468       if (unformat (i, "collector_address %U", unformat_ip4_address,
9469                     &collector_address))
9470         collector_address_set = 1;
9471       else if (unformat (i, "collector_port %d", &collector_port))
9472         ;
9473       else if (unformat (i, "src_address %U", unformat_ip4_address,
9474                          &src_address))
9475         src_address_set = 1;
9476       else if (unformat (i, "vrf_id %d", &vrf_id))
9477         ;
9478       else if (unformat (i, "path_mtu %d", &path_mtu))
9479         ;
9480       else if (unformat (i, "template_interval %d", &template_interval))
9481         ;
9482       else if (unformat (i, "udp_checksum"))
9483         udp_checksum = 1;
9484       else
9485         break;
9486     }
9487
9488   if (collector_address_set == 0)
9489     {
9490       errmsg ("collector_address required\n");
9491       return -99;
9492     }
9493
9494   if (src_address_set == 0)
9495     {
9496       errmsg ("src_address required\n");
9497       return -99;
9498     }
9499
9500   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9501
9502   memcpy (mp->collector_address, collector_address.data,
9503           sizeof (collector_address.data));
9504   mp->collector_port = htons ((u16) collector_port);
9505   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9506   mp->vrf_id = htonl (vrf_id);
9507   mp->path_mtu = htonl (path_mtu);
9508   mp->template_interval = htonl (template_interval);
9509   mp->udp_checksum = udp_checksum;
9510
9511   S;
9512   W;
9513   /* NOTREACHED */
9514 }
9515
9516 static int
9517 api_set_ipfix_classify_stream (vat_main_t * vam)
9518 {
9519   unformat_input_t *i = vam->input;
9520   vl_api_set_ipfix_classify_stream_t *mp;
9521   u32 domain_id = 0;
9522   u32 src_port = UDP_DST_PORT_ipfix;
9523   f64 timeout;
9524
9525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9526     {
9527       if (unformat (i, "domain %d", &domain_id))
9528         ;
9529       else if (unformat (i, "src_port %d", &src_port))
9530         ;
9531       else
9532         {
9533           errmsg ("unknown input `%U'", format_unformat_error, i);
9534           return -99;
9535         }
9536     }
9537
9538   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9539
9540   mp->domain_id = htonl (domain_id);
9541   mp->src_port = htons ((u16) src_port);
9542
9543   S;
9544   W;
9545   /* NOTREACHED */
9546 }
9547
9548 static int
9549 api_ipfix_classify_table_add_del (vat_main_t * vam)
9550 {
9551   unformat_input_t *i = vam->input;
9552   vl_api_ipfix_classify_table_add_del_t *mp;
9553   int is_add = -1;
9554   u32 classify_table_index = ~0;
9555   u8 ip_version = 0;
9556   u8 transport_protocol = 255;
9557   f64 timeout;
9558
9559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9560     {
9561       if (unformat (i, "add"))
9562         is_add = 1;
9563       else if (unformat (i, "del"))
9564         is_add = 0;
9565       else if (unformat (i, "table %d", &classify_table_index))
9566         ;
9567       else if (unformat (i, "ip4"))
9568         ip_version = 4;
9569       else if (unformat (i, "ip6"))
9570         ip_version = 6;
9571       else if (unformat (i, "tcp"))
9572         transport_protocol = 6;
9573       else if (unformat (i, "udp"))
9574         transport_protocol = 17;
9575       else
9576         {
9577           errmsg ("unknown input `%U'", format_unformat_error, i);
9578           return -99;
9579         }
9580     }
9581
9582   if (is_add == -1)
9583     {
9584       errmsg ("expecting: add|del");
9585       return -99;
9586     }
9587   if (classify_table_index == ~0)
9588     {
9589       errmsg ("classifier table not specified");
9590       return -99;
9591     }
9592   if (ip_version == 0)
9593     {
9594       errmsg ("IP version not specified");
9595       return -99;
9596     }
9597
9598   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9599
9600   mp->is_add = is_add;
9601   mp->table_id = htonl (classify_table_index);
9602   mp->ip_version = ip_version;
9603   mp->transport_protocol = transport_protocol;
9604
9605   S;
9606   W;
9607   /* NOTREACHED */
9608 }
9609
9610 static int
9611 api_get_node_index (vat_main_t * vam)
9612 {
9613   unformat_input_t *i = vam->input;
9614   vl_api_get_node_index_t *mp;
9615   f64 timeout;
9616   u8 *name = 0;
9617
9618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9619     {
9620       if (unformat (i, "node %s", &name))
9621         ;
9622       else
9623         break;
9624     }
9625   if (name == 0)
9626     {
9627       errmsg ("node name required\n");
9628       return -99;
9629     }
9630   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9631     {
9632       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9633       return -99;
9634     }
9635
9636   M (GET_NODE_INDEX, get_node_index);
9637   clib_memcpy (mp->node_name, name, vec_len (name));
9638   vec_free (name);
9639
9640   S;
9641   W;
9642   /* NOTREACHED */
9643   return 0;
9644 }
9645
9646 static int
9647 api_get_next_index (vat_main_t * vam)
9648 {
9649   unformat_input_t *i = vam->input;
9650   vl_api_get_next_index_t *mp;
9651   f64 timeout;
9652   u8 *node_name = 0, *next_node_name = 0;
9653
9654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9655     {
9656       if (unformat (i, "node-name %s", &node_name))
9657         ;
9658       else if (unformat (i, "next-node-name %s", &next_node_name))
9659         break;
9660     }
9661
9662   if (node_name == 0)
9663     {
9664       errmsg ("node name required\n");
9665       return -99;
9666     }
9667   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9668     {
9669       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9670       return -99;
9671     }
9672
9673   if (next_node_name == 0)
9674     {
9675       errmsg ("next node name required\n");
9676       return -99;
9677     }
9678   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9679     {
9680       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9681       return -99;
9682     }
9683
9684   M (GET_NEXT_INDEX, get_next_index);
9685   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9686   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9687   vec_free (node_name);
9688   vec_free (next_node_name);
9689
9690   S;
9691   W;
9692   /* NOTREACHED */
9693   return 0;
9694 }
9695
9696 static int
9697 api_add_node_next (vat_main_t * vam)
9698 {
9699   unformat_input_t *i = vam->input;
9700   vl_api_add_node_next_t *mp;
9701   f64 timeout;
9702   u8 *name = 0;
9703   u8 *next = 0;
9704
9705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9706     {
9707       if (unformat (i, "node %s", &name))
9708         ;
9709       else if (unformat (i, "next %s", &next))
9710         ;
9711       else
9712         break;
9713     }
9714   if (name == 0)
9715     {
9716       errmsg ("node name required\n");
9717       return -99;
9718     }
9719   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9720     {
9721       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9722       return -99;
9723     }
9724   if (next == 0)
9725     {
9726       errmsg ("next node required\n");
9727       return -99;
9728     }
9729   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9730     {
9731       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9732       return -99;
9733     }
9734
9735   M (ADD_NODE_NEXT, add_node_next);
9736   clib_memcpy (mp->node_name, name, vec_len (name));
9737   clib_memcpy (mp->next_name, next, vec_len (next));
9738   vec_free (name);
9739   vec_free (next);
9740
9741   S;
9742   W;
9743   /* NOTREACHED */
9744   return 0;
9745 }
9746
9747 static int
9748 api_l2tpv3_create_tunnel (vat_main_t * vam)
9749 {
9750   unformat_input_t *i = vam->input;
9751   ip6_address_t client_address, our_address;
9752   int client_address_set = 0;
9753   int our_address_set = 0;
9754   u32 local_session_id = 0;
9755   u32 remote_session_id = 0;
9756   u64 local_cookie = 0;
9757   u64 remote_cookie = 0;
9758   u8 l2_sublayer_present = 0;
9759   vl_api_l2tpv3_create_tunnel_t *mp;
9760   f64 timeout;
9761
9762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9763     {
9764       if (unformat (i, "client_address %U", unformat_ip6_address,
9765                     &client_address))
9766         client_address_set = 1;
9767       else if (unformat (i, "our_address %U", unformat_ip6_address,
9768                          &our_address))
9769         our_address_set = 1;
9770       else if (unformat (i, "local_session_id %d", &local_session_id))
9771         ;
9772       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9773         ;
9774       else if (unformat (i, "local_cookie %lld", &local_cookie))
9775         ;
9776       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9777         ;
9778       else if (unformat (i, "l2-sublayer-present"))
9779         l2_sublayer_present = 1;
9780       else
9781         break;
9782     }
9783
9784   if (client_address_set == 0)
9785     {
9786       errmsg ("client_address required\n");
9787       return -99;
9788     }
9789
9790   if (our_address_set == 0)
9791     {
9792       errmsg ("our_address required\n");
9793       return -99;
9794     }
9795
9796   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9797
9798   clib_memcpy (mp->client_address, client_address.as_u8,
9799                sizeof (mp->client_address));
9800
9801   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9802
9803   mp->local_session_id = ntohl (local_session_id);
9804   mp->remote_session_id = ntohl (remote_session_id);
9805   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9806   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9807   mp->l2_sublayer_present = l2_sublayer_present;
9808   mp->is_ipv6 = 1;
9809
9810   S;
9811   W;
9812   /* NOTREACHED */
9813   return 0;
9814 }
9815
9816 static int
9817 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9818 {
9819   unformat_input_t *i = vam->input;
9820   u32 sw_if_index;
9821   u8 sw_if_index_set = 0;
9822   u64 new_local_cookie = 0;
9823   u64 new_remote_cookie = 0;
9824   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9825   f64 timeout;
9826
9827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9828     {
9829       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9830         sw_if_index_set = 1;
9831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9832         sw_if_index_set = 1;
9833       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9834         ;
9835       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9836         ;
9837       else
9838         break;
9839     }
9840
9841   if (sw_if_index_set == 0)
9842     {
9843       errmsg ("missing interface name or sw_if_index\n");
9844       return -99;
9845     }
9846
9847   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9848
9849   mp->sw_if_index = ntohl (sw_if_index);
9850   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9851   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9852
9853   S;
9854   W;
9855   /* NOTREACHED */
9856   return 0;
9857 }
9858
9859 static int
9860 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9861 {
9862   unformat_input_t *i = vam->input;
9863   vl_api_l2tpv3_interface_enable_disable_t *mp;
9864   f64 timeout;
9865   u32 sw_if_index;
9866   u8 sw_if_index_set = 0;
9867   u8 enable_disable = 1;
9868
9869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9870     {
9871       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9874         sw_if_index_set = 1;
9875       else if (unformat (i, "enable"))
9876         enable_disable = 1;
9877       else if (unformat (i, "disable"))
9878         enable_disable = 0;
9879       else
9880         break;
9881     }
9882
9883   if (sw_if_index_set == 0)
9884     {
9885       errmsg ("missing interface name or sw_if_index\n");
9886       return -99;
9887     }
9888
9889   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9890
9891   mp->sw_if_index = ntohl (sw_if_index);
9892   mp->enable_disable = enable_disable;
9893
9894   S;
9895   W;
9896   /* NOTREACHED */
9897   return 0;
9898 }
9899
9900 static int
9901 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9902 {
9903   unformat_input_t *i = vam->input;
9904   vl_api_l2tpv3_set_lookup_key_t *mp;
9905   f64 timeout;
9906   u8 key = ~0;
9907
9908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9909     {
9910       if (unformat (i, "lookup_v6_src"))
9911         key = L2T_LOOKUP_SRC_ADDRESS;
9912       else if (unformat (i, "lookup_v6_dst"))
9913         key = L2T_LOOKUP_DST_ADDRESS;
9914       else if (unformat (i, "lookup_session_id"))
9915         key = L2T_LOOKUP_SESSION_ID;
9916       else
9917         break;
9918     }
9919
9920   if (key == (u8) ~ 0)
9921     {
9922       errmsg ("l2tp session lookup key unset\n");
9923       return -99;
9924     }
9925
9926   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9927
9928   mp->key = key;
9929
9930   S;
9931   W;
9932   /* NOTREACHED */
9933   return 0;
9934 }
9935
9936 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9937   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9938 {
9939   vat_main_t *vam = &vat_main;
9940
9941   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9942            format_ip6_address, mp->our_address,
9943            format_ip6_address, mp->client_address,
9944            clib_net_to_host_u32 (mp->sw_if_index));
9945
9946   fformat (vam->ofp,
9947            "   local cookies %016llx %016llx remote cookie %016llx\n",
9948            clib_net_to_host_u64 (mp->local_cookie[0]),
9949            clib_net_to_host_u64 (mp->local_cookie[1]),
9950            clib_net_to_host_u64 (mp->remote_cookie));
9951
9952   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9953            clib_net_to_host_u32 (mp->local_session_id),
9954            clib_net_to_host_u32 (mp->remote_session_id));
9955
9956   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9957            mp->l2_sublayer_present ? "preset" : "absent");
9958
9959 }
9960
9961 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9962   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9963 {
9964   vat_main_t *vam = &vat_main;
9965   vat_json_node_t *node = NULL;
9966   struct in6_addr addr;
9967
9968   if (VAT_JSON_ARRAY != vam->json_tree.type)
9969     {
9970       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9971       vat_json_init_array (&vam->json_tree);
9972     }
9973   node = vat_json_array_add (&vam->json_tree);
9974
9975   vat_json_init_object (node);
9976
9977   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9978   vat_json_object_add_ip6 (node, "our_address", addr);
9979   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9980   vat_json_object_add_ip6 (node, "client_address", addr);
9981
9982   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9983   vat_json_init_array (lc);
9984   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9985   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9986   vat_json_object_add_uint (node, "remote_cookie",
9987                             clib_net_to_host_u64 (mp->remote_cookie));
9988
9989   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9990   vat_json_object_add_uint (node, "local_session_id",
9991                             clib_net_to_host_u32 (mp->local_session_id));
9992   vat_json_object_add_uint (node, "remote_session_id",
9993                             clib_net_to_host_u32 (mp->remote_session_id));
9994   vat_json_object_add_string_copy (node, "l2_sublayer",
9995                                    mp->l2_sublayer_present ? (u8 *) "present"
9996                                    : (u8 *) "absent");
9997 }
9998
9999 static int
10000 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10001 {
10002   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10003   f64 timeout;
10004
10005   /* Get list of l2tpv3-tunnel interfaces */
10006   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10007   S;
10008
10009   /* Use a control ping for synchronization */
10010   {
10011     vl_api_control_ping_t *mp;
10012     M (CONTROL_PING, control_ping);
10013     S;
10014   }
10015   W;
10016 }
10017
10018
10019 static void vl_api_sw_interface_tap_details_t_handler
10020   (vl_api_sw_interface_tap_details_t * mp)
10021 {
10022   vat_main_t *vam = &vat_main;
10023
10024   fformat (vam->ofp, "%-16s %d\n",
10025            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10026 }
10027
10028 static void vl_api_sw_interface_tap_details_t_handler_json
10029   (vl_api_sw_interface_tap_details_t * mp)
10030 {
10031   vat_main_t *vam = &vat_main;
10032   vat_json_node_t *node = NULL;
10033
10034   if (VAT_JSON_ARRAY != vam->json_tree.type)
10035     {
10036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10037       vat_json_init_array (&vam->json_tree);
10038     }
10039   node = vat_json_array_add (&vam->json_tree);
10040
10041   vat_json_init_object (node);
10042   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10043   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10044 }
10045
10046 static int
10047 api_sw_interface_tap_dump (vat_main_t * vam)
10048 {
10049   vl_api_sw_interface_tap_dump_t *mp;
10050   f64 timeout;
10051
10052   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10053   /* Get list of tap interfaces */
10054   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10055   S;
10056
10057   /* Use a control ping for synchronization */
10058   {
10059     vl_api_control_ping_t *mp;
10060     M (CONTROL_PING, control_ping);
10061     S;
10062   }
10063   W;
10064 }
10065
10066 static uword unformat_vxlan_decap_next
10067   (unformat_input_t * input, va_list * args)
10068 {
10069   u32 *result = va_arg (*args, u32 *);
10070   u32 tmp;
10071
10072   if (unformat (input, "drop"))
10073     *result = VXLAN_INPUT_NEXT_DROP;
10074   else if (unformat (input, "ip4"))
10075     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
10076   else if (unformat (input, "ip6"))
10077     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
10078   else if (unformat (input, "l2"))
10079     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10080   else if (unformat (input, "%d", &tmp))
10081     *result = tmp;
10082   else
10083     return 0;
10084   return 1;
10085 }
10086
10087 static int
10088 api_vxlan_add_del_tunnel (vat_main_t * vam)
10089 {
10090   unformat_input_t *line_input = vam->input;
10091   vl_api_vxlan_add_del_tunnel_t *mp;
10092   f64 timeout;
10093   ip4_address_t src4, dst4;
10094   ip6_address_t src6, dst6;
10095   u8 is_add = 1;
10096   u8 ipv4_set = 0, ipv6_set = 0;
10097   u8 src_set = 0;
10098   u8 dst_set = 0;
10099   u32 encap_vrf_id = 0;
10100   u32 decap_next_index = ~0;
10101   u32 vni = 0;
10102
10103   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10104     {
10105       if (unformat (line_input, "del"))
10106         is_add = 0;
10107       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10108         {
10109           ipv4_set = 1;
10110           src_set = 1;
10111         }
10112       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10113         {
10114           ipv4_set = 1;
10115           dst_set = 1;
10116         }
10117       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10118         {
10119           ipv6_set = 1;
10120           src_set = 1;
10121         }
10122       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10123         {
10124           ipv6_set = 1;
10125           dst_set = 1;
10126         }
10127       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10128         ;
10129       else if (unformat (line_input, "decap-next %U",
10130                          unformat_vxlan_decap_next, &decap_next_index))
10131         ;
10132       else if (unformat (line_input, "vni %d", &vni))
10133         ;
10134       else
10135         {
10136           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10137           return -99;
10138         }
10139     }
10140
10141   if (src_set == 0)
10142     {
10143       errmsg ("tunnel src address not specified\n");
10144       return -99;
10145     }
10146   if (dst_set == 0)
10147     {
10148       errmsg ("tunnel dst address not specified\n");
10149       return -99;
10150     }
10151
10152   if (ipv4_set && ipv6_set)
10153     {
10154       errmsg ("both IPv4 and IPv6 addresses specified");
10155       return -99;
10156     }
10157
10158   if ((vni == 0) || (vni >> 24))
10159     {
10160       errmsg ("vni not specified or out of range\n");
10161       return -99;
10162     }
10163
10164   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10165
10166   if (ipv6_set)
10167     {
10168       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10169       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10170     }
10171   else
10172     {
10173       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10174       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10175     }
10176   mp->encap_vrf_id = ntohl (encap_vrf_id);
10177   mp->decap_next_index = ntohl (decap_next_index);
10178   mp->vni = ntohl (vni);
10179   mp->is_add = is_add;
10180   mp->is_ipv6 = ipv6_set;
10181
10182   S;
10183   W;
10184   /* NOTREACHED */
10185   return 0;
10186 }
10187
10188 static void vl_api_vxlan_tunnel_details_t_handler
10189   (vl_api_vxlan_tunnel_details_t * mp)
10190 {
10191   vat_main_t *vam = &vat_main;
10192
10193   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10194            ntohl (mp->sw_if_index),
10195            format_ip46_address, &(mp->src_address[0]),
10196            IP46_TYPE_ANY,
10197            format_ip46_address, &(mp->dst_address[0]),
10198            IP46_TYPE_ANY,
10199            ntohl (mp->encap_vrf_id),
10200            ntohl (mp->decap_next_index), ntohl (mp->vni));
10201 }
10202
10203 static void vl_api_vxlan_tunnel_details_t_handler_json
10204   (vl_api_vxlan_tunnel_details_t * mp)
10205 {
10206   vat_main_t *vam = &vat_main;
10207   vat_json_node_t *node = NULL;
10208   struct in_addr ip4;
10209   struct in6_addr ip6;
10210
10211   if (VAT_JSON_ARRAY != vam->json_tree.type)
10212     {
10213       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10214       vat_json_init_array (&vam->json_tree);
10215     }
10216   node = vat_json_array_add (&vam->json_tree);
10217
10218   vat_json_init_object (node);
10219   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10220   if (mp->is_ipv6)
10221     {
10222       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10223       vat_json_object_add_ip6 (node, "src_address", ip6);
10224       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10225       vat_json_object_add_ip6 (node, "dst_address", ip6);
10226     }
10227   else
10228     {
10229       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10230       vat_json_object_add_ip4 (node, "src_address", ip4);
10231       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10232       vat_json_object_add_ip4 (node, "dst_address", ip4);
10233     }
10234   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10235   vat_json_object_add_uint (node, "decap_next_index",
10236                             ntohl (mp->decap_next_index));
10237   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10238   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10239 }
10240
10241 static int
10242 api_vxlan_tunnel_dump (vat_main_t * vam)
10243 {
10244   unformat_input_t *i = vam->input;
10245   vl_api_vxlan_tunnel_dump_t *mp;
10246   f64 timeout;
10247   u32 sw_if_index;
10248   u8 sw_if_index_set = 0;
10249
10250   /* Parse args required to build the message */
10251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10252     {
10253       if (unformat (i, "sw_if_index %d", &sw_if_index))
10254         sw_if_index_set = 1;
10255       else
10256         break;
10257     }
10258
10259   if (sw_if_index_set == 0)
10260     {
10261       sw_if_index = ~0;
10262     }
10263
10264   if (!vam->json_output)
10265     {
10266       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10267                "sw_if_index", "src_address", "dst_address",
10268                "encap_vrf_id", "decap_next_index", "vni");
10269     }
10270
10271   /* Get list of vxlan-tunnel interfaces */
10272   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10273
10274   mp->sw_if_index = htonl (sw_if_index);
10275
10276   S;
10277
10278   /* Use a control ping for synchronization */
10279   {
10280     vl_api_control_ping_t *mp;
10281     M (CONTROL_PING, control_ping);
10282     S;
10283   }
10284   W;
10285 }
10286
10287 static int
10288 api_gre_add_del_tunnel (vat_main_t * vam)
10289 {
10290   unformat_input_t *line_input = vam->input;
10291   vl_api_gre_add_del_tunnel_t *mp;
10292   f64 timeout;
10293   ip4_address_t src4, dst4;
10294   u8 is_add = 1;
10295   u8 teb = 0;
10296   u8 src_set = 0;
10297   u8 dst_set = 0;
10298   u32 outer_fib_id = 0;
10299
10300   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10301     {
10302       if (unformat (line_input, "del"))
10303         is_add = 0;
10304       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10305         src_set = 1;
10306       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10307         dst_set = 1;
10308       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10309         ;
10310       else if (unformat (line_input, "teb"))
10311         teb = 1;
10312       else
10313         {
10314           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10315           return -99;
10316         }
10317     }
10318
10319   if (src_set == 0)
10320     {
10321       errmsg ("tunnel src address not specified\n");
10322       return -99;
10323     }
10324   if (dst_set == 0)
10325     {
10326       errmsg ("tunnel dst address not specified\n");
10327       return -99;
10328     }
10329
10330
10331   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10332
10333   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10334   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10335   mp->outer_fib_id = ntohl (outer_fib_id);
10336   mp->is_add = is_add;
10337   mp->teb = teb;
10338
10339   S;
10340   W;
10341   /* NOTREACHED */
10342   return 0;
10343 }
10344
10345 static void vl_api_gre_tunnel_details_t_handler
10346   (vl_api_gre_tunnel_details_t * mp)
10347 {
10348   vat_main_t *vam = &vat_main;
10349
10350   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10351            ntohl (mp->sw_if_index),
10352            format_ip4_address, &mp->src_address,
10353            format_ip4_address, &mp->dst_address,
10354            mp->teb, ntohl (mp->outer_fib_id));
10355 }
10356
10357 static void vl_api_gre_tunnel_details_t_handler_json
10358   (vl_api_gre_tunnel_details_t * mp)
10359 {
10360   vat_main_t *vam = &vat_main;
10361   vat_json_node_t *node = NULL;
10362   struct in_addr ip4;
10363
10364   if (VAT_JSON_ARRAY != vam->json_tree.type)
10365     {
10366       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10367       vat_json_init_array (&vam->json_tree);
10368     }
10369   node = vat_json_array_add (&vam->json_tree);
10370
10371   vat_json_init_object (node);
10372   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10373   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10374   vat_json_object_add_ip4 (node, "src_address", ip4);
10375   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10376   vat_json_object_add_ip4 (node, "dst_address", ip4);
10377   vat_json_object_add_uint (node, "teb", mp->teb);
10378   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10379 }
10380
10381 static int
10382 api_gre_tunnel_dump (vat_main_t * vam)
10383 {
10384   unformat_input_t *i = vam->input;
10385   vl_api_gre_tunnel_dump_t *mp;
10386   f64 timeout;
10387   u32 sw_if_index;
10388   u8 sw_if_index_set = 0;
10389
10390   /* Parse args required to build the message */
10391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10392     {
10393       if (unformat (i, "sw_if_index %d", &sw_if_index))
10394         sw_if_index_set = 1;
10395       else
10396         break;
10397     }
10398
10399   if (sw_if_index_set == 0)
10400     {
10401       sw_if_index = ~0;
10402     }
10403
10404   if (!vam->json_output)
10405     {
10406       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10407                "sw_if_index", "src_address", "dst_address", "teb",
10408                "outer_fib_id");
10409     }
10410
10411   /* Get list of gre-tunnel interfaces */
10412   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10413
10414   mp->sw_if_index = htonl (sw_if_index);
10415
10416   S;
10417
10418   /* Use a control ping for synchronization */
10419   {
10420     vl_api_control_ping_t *mp;
10421     M (CONTROL_PING, control_ping);
10422     S;
10423   }
10424   W;
10425 }
10426
10427 static int
10428 api_l2_fib_clear_table (vat_main_t * vam)
10429 {
10430 //  unformat_input_t * i = vam->input;
10431   vl_api_l2_fib_clear_table_t *mp;
10432   f64 timeout;
10433
10434   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10435
10436   S;
10437   W;
10438   /* NOTREACHED */
10439   return 0;
10440 }
10441
10442 static int
10443 api_l2_interface_efp_filter (vat_main_t * vam)
10444 {
10445   unformat_input_t *i = vam->input;
10446   vl_api_l2_interface_efp_filter_t *mp;
10447   f64 timeout;
10448   u32 sw_if_index;
10449   u8 enable = 1;
10450   u8 sw_if_index_set = 0;
10451
10452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10453     {
10454       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10455         sw_if_index_set = 1;
10456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10457         sw_if_index_set = 1;
10458       else if (unformat (i, "enable"))
10459         enable = 1;
10460       else if (unformat (i, "disable"))
10461         enable = 0;
10462       else
10463         {
10464           clib_warning ("parse error '%U'", format_unformat_error, i);
10465           return -99;
10466         }
10467     }
10468
10469   if (sw_if_index_set == 0)
10470     {
10471       errmsg ("missing sw_if_index\n");
10472       return -99;
10473     }
10474
10475   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10476
10477   mp->sw_if_index = ntohl (sw_if_index);
10478   mp->enable_disable = enable;
10479
10480   S;
10481   W;
10482   /* NOTREACHED */
10483   return 0;
10484 }
10485
10486 #define foreach_vtr_op                          \
10487 _("disable",  L2_VTR_DISABLED)                  \
10488 _("push-1",  L2_VTR_PUSH_1)                     \
10489 _("push-2",  L2_VTR_PUSH_2)                     \
10490 _("pop-1",  L2_VTR_POP_1)                       \
10491 _("pop-2",  L2_VTR_POP_2)                       \
10492 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10493 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10494 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10495 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10496
10497 static int
10498 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10499 {
10500   unformat_input_t *i = vam->input;
10501   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10502   f64 timeout;
10503   u32 sw_if_index;
10504   u8 sw_if_index_set = 0;
10505   u8 vtr_op_set = 0;
10506   u32 vtr_op = 0;
10507   u32 push_dot1q = 1;
10508   u32 tag1 = ~0;
10509   u32 tag2 = ~0;
10510
10511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10512     {
10513       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10514         sw_if_index_set = 1;
10515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10516         sw_if_index_set = 1;
10517       else if (unformat (i, "vtr_op %d", &vtr_op))
10518         vtr_op_set = 1;
10519 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10520       foreach_vtr_op
10521 #undef _
10522         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10523         ;
10524       else if (unformat (i, "tag1 %d", &tag1))
10525         ;
10526       else if (unformat (i, "tag2 %d", &tag2))
10527         ;
10528       else
10529         {
10530           clib_warning ("parse error '%U'", format_unformat_error, i);
10531           return -99;
10532         }
10533     }
10534
10535   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10536     {
10537       errmsg ("missing vtr operation or sw_if_index\n");
10538       return -99;
10539     }
10540
10541   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10542     mp->sw_if_index = ntohl (sw_if_index);
10543   mp->vtr_op = ntohl (vtr_op);
10544   mp->push_dot1q = ntohl (push_dot1q);
10545   mp->tag1 = ntohl (tag1);
10546   mp->tag2 = ntohl (tag2);
10547
10548   S;
10549   W;
10550   /* NOTREACHED */
10551   return 0;
10552 }
10553
10554 static int
10555 api_create_vhost_user_if (vat_main_t * vam)
10556 {
10557   unformat_input_t *i = vam->input;
10558   vl_api_create_vhost_user_if_t *mp;
10559   f64 timeout;
10560   u8 *file_name;
10561   u8 is_server = 0;
10562   u8 file_name_set = 0;
10563   u32 custom_dev_instance = ~0;
10564   u8 hwaddr[6];
10565   u8 use_custom_mac = 0;
10566
10567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10568     {
10569       if (unformat (i, "socket %s", &file_name))
10570         {
10571           file_name_set = 1;
10572         }
10573       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10574         ;
10575       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10576         use_custom_mac = 1;
10577       else if (unformat (i, "server"))
10578         is_server = 1;
10579       else
10580         break;
10581     }
10582
10583   if (file_name_set == 0)
10584     {
10585       errmsg ("missing socket file name\n");
10586       return -99;
10587     }
10588
10589   if (vec_len (file_name) > 255)
10590     {
10591       errmsg ("socket file name too long\n");
10592       return -99;
10593     }
10594   vec_add1 (file_name, 0);
10595
10596   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10597
10598   mp->is_server = is_server;
10599   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10600   vec_free (file_name);
10601   if (custom_dev_instance != ~0)
10602     {
10603       mp->renumber = 1;
10604       mp->custom_dev_instance = ntohl (custom_dev_instance);
10605     }
10606   mp->use_custom_mac = use_custom_mac;
10607   clib_memcpy (mp->mac_address, hwaddr, 6);
10608
10609   S;
10610   W;
10611   /* NOTREACHED */
10612   return 0;
10613 }
10614
10615 static int
10616 api_modify_vhost_user_if (vat_main_t * vam)
10617 {
10618   unformat_input_t *i = vam->input;
10619   vl_api_modify_vhost_user_if_t *mp;
10620   f64 timeout;
10621   u8 *file_name;
10622   u8 is_server = 0;
10623   u8 file_name_set = 0;
10624   u32 custom_dev_instance = ~0;
10625   u8 sw_if_index_set = 0;
10626   u32 sw_if_index = (u32) ~ 0;
10627
10628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10629     {
10630       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10631         sw_if_index_set = 1;
10632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10633         sw_if_index_set = 1;
10634       else if (unformat (i, "socket %s", &file_name))
10635         {
10636           file_name_set = 1;
10637         }
10638       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10639         ;
10640       else if (unformat (i, "server"))
10641         is_server = 1;
10642       else
10643         break;
10644     }
10645
10646   if (sw_if_index_set == 0)
10647     {
10648       errmsg ("missing sw_if_index or interface name\n");
10649       return -99;
10650     }
10651
10652   if (file_name_set == 0)
10653     {
10654       errmsg ("missing socket file name\n");
10655       return -99;
10656     }
10657
10658   if (vec_len (file_name) > 255)
10659     {
10660       errmsg ("socket file name too long\n");
10661       return -99;
10662     }
10663   vec_add1 (file_name, 0);
10664
10665   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10666
10667   mp->sw_if_index = ntohl (sw_if_index);
10668   mp->is_server = is_server;
10669   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10670   vec_free (file_name);
10671   if (custom_dev_instance != ~0)
10672     {
10673       mp->renumber = 1;
10674       mp->custom_dev_instance = ntohl (custom_dev_instance);
10675     }
10676
10677   S;
10678   W;
10679   /* NOTREACHED */
10680   return 0;
10681 }
10682
10683 static int
10684 api_delete_vhost_user_if (vat_main_t * vam)
10685 {
10686   unformat_input_t *i = vam->input;
10687   vl_api_delete_vhost_user_if_t *mp;
10688   f64 timeout;
10689   u32 sw_if_index = ~0;
10690   u8 sw_if_index_set = 0;
10691
10692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10693     {
10694       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10695         sw_if_index_set = 1;
10696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10697         sw_if_index_set = 1;
10698       else
10699         break;
10700     }
10701
10702   if (sw_if_index_set == 0)
10703     {
10704       errmsg ("missing sw_if_index or interface name\n");
10705       return -99;
10706     }
10707
10708
10709   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10710
10711   mp->sw_if_index = ntohl (sw_if_index);
10712
10713   S;
10714   W;
10715   /* NOTREACHED */
10716   return 0;
10717 }
10718
10719 static void vl_api_sw_interface_vhost_user_details_t_handler
10720   (vl_api_sw_interface_vhost_user_details_t * mp)
10721 {
10722   vat_main_t *vam = &vat_main;
10723
10724   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10725            (char *) mp->interface_name,
10726            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10727            clib_net_to_host_u64 (mp->features), mp->is_server,
10728            ntohl (mp->num_regions), (char *) mp->sock_filename);
10729   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10730 }
10731
10732 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10733   (vl_api_sw_interface_vhost_user_details_t * mp)
10734 {
10735   vat_main_t *vam = &vat_main;
10736   vat_json_node_t *node = NULL;
10737
10738   if (VAT_JSON_ARRAY != vam->json_tree.type)
10739     {
10740       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10741       vat_json_init_array (&vam->json_tree);
10742     }
10743   node = vat_json_array_add (&vam->json_tree);
10744
10745   vat_json_init_object (node);
10746   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10747   vat_json_object_add_string_copy (node, "interface_name",
10748                                    mp->interface_name);
10749   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10750                             ntohl (mp->virtio_net_hdr_sz));
10751   vat_json_object_add_uint (node, "features",
10752                             clib_net_to_host_u64 (mp->features));
10753   vat_json_object_add_uint (node, "is_server", mp->is_server);
10754   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10755   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10756   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10757 }
10758
10759 static int
10760 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10761 {
10762   vl_api_sw_interface_vhost_user_dump_t *mp;
10763   f64 timeout;
10764   fformat (vam->ofp,
10765            "Interface name           idx hdr_sz features server regions filename\n");
10766
10767   /* Get list of vhost-user interfaces */
10768   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10769   S;
10770
10771   /* Use a control ping for synchronization */
10772   {
10773     vl_api_control_ping_t *mp;
10774     M (CONTROL_PING, control_ping);
10775     S;
10776   }
10777   W;
10778 }
10779
10780 static int
10781 api_show_version (vat_main_t * vam)
10782 {
10783   vl_api_show_version_t *mp;
10784   f64 timeout;
10785
10786   M (SHOW_VERSION, show_version);
10787
10788   S;
10789   W;
10790   /* NOTREACHED */
10791   return 0;
10792 }
10793
10794
10795 static int
10796 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10797 {
10798   unformat_input_t *line_input = vam->input;
10799   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10800   f64 timeout;
10801   ip4_address_t local4, remote4;
10802   ip6_address_t local6, remote6;
10803   u8 is_add = 1;
10804   u8 ipv4_set = 0, ipv6_set = 0;
10805   u8 local_set = 0;
10806   u8 remote_set = 0;
10807   u32 encap_vrf_id = 0;
10808   u32 decap_vrf_id = 0;
10809   u8 protocol = ~0;
10810   u32 vni;
10811   u8 vni_set = 0;
10812
10813   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10814     {
10815       if (unformat (line_input, "del"))
10816         is_add = 0;
10817       else if (unformat (line_input, "local %U",
10818                          unformat_ip4_address, &local4))
10819         {
10820           local_set = 1;
10821           ipv4_set = 1;
10822         }
10823       else if (unformat (line_input, "remote %U",
10824                          unformat_ip4_address, &remote4))
10825         {
10826           remote_set = 1;
10827           ipv4_set = 1;
10828         }
10829       else if (unformat (line_input, "local %U",
10830                          unformat_ip6_address, &local6))
10831         {
10832           local_set = 1;
10833           ipv6_set = 1;
10834         }
10835       else if (unformat (line_input, "remote %U",
10836                          unformat_ip6_address, &remote6))
10837         {
10838           remote_set = 1;
10839           ipv6_set = 1;
10840         }
10841       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10842         ;
10843       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10844         ;
10845       else if (unformat (line_input, "vni %d", &vni))
10846         vni_set = 1;
10847       else if (unformat (line_input, "next-ip4"))
10848         protocol = 1;
10849       else if (unformat (line_input, "next-ip6"))
10850         protocol = 2;
10851       else if (unformat (line_input, "next-ethernet"))
10852         protocol = 3;
10853       else if (unformat (line_input, "next-nsh"))
10854         protocol = 4;
10855       else
10856         {
10857           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10858           return -99;
10859         }
10860     }
10861
10862   if (local_set == 0)
10863     {
10864       errmsg ("tunnel local address not specified\n");
10865       return -99;
10866     }
10867   if (remote_set == 0)
10868     {
10869       errmsg ("tunnel remote address not specified\n");
10870       return -99;
10871     }
10872   if (ipv4_set && ipv6_set)
10873     {
10874       errmsg ("both IPv4 and IPv6 addresses specified");
10875       return -99;
10876     }
10877
10878   if (vni_set == 0)
10879     {
10880       errmsg ("vni not specified\n");
10881       return -99;
10882     }
10883
10884   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10885
10886
10887   if (ipv6_set)
10888     {
10889       clib_memcpy (&mp->local, &local6, sizeof (local6));
10890       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10891     }
10892   else
10893     {
10894       clib_memcpy (&mp->local, &local4, sizeof (local4));
10895       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10896     }
10897
10898   mp->encap_vrf_id = ntohl (encap_vrf_id);
10899   mp->decap_vrf_id = ntohl (decap_vrf_id);
10900   mp->protocol = ntohl (protocol);
10901   mp->vni = ntohl (vni);
10902   mp->is_add = is_add;
10903   mp->is_ipv6 = ipv6_set;
10904
10905   S;
10906   W;
10907   /* NOTREACHED */
10908   return 0;
10909 }
10910
10911 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10912   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10913 {
10914   vat_main_t *vam = &vat_main;
10915
10916   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10917            ntohl (mp->sw_if_index),
10918            format_ip46_address, &(mp->local[0]),
10919            format_ip46_address, &(mp->remote[0]),
10920            ntohl (mp->vni),
10921            ntohl (mp->protocol),
10922            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10923 }
10924
10925 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10926   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10927 {
10928   vat_main_t *vam = &vat_main;
10929   vat_json_node_t *node = NULL;
10930   struct in_addr ip4;
10931   struct in6_addr ip6;
10932
10933   if (VAT_JSON_ARRAY != vam->json_tree.type)
10934     {
10935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10936       vat_json_init_array (&vam->json_tree);
10937     }
10938   node = vat_json_array_add (&vam->json_tree);
10939
10940   vat_json_init_object (node);
10941   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10942   if (mp->is_ipv6)
10943     {
10944       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10945       vat_json_object_add_ip6 (node, "local", ip6);
10946       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10947       vat_json_object_add_ip6 (node, "remote", ip6);
10948     }
10949   else
10950     {
10951       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10952       vat_json_object_add_ip4 (node, "local", ip4);
10953       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10954       vat_json_object_add_ip4 (node, "remote", ip4);
10955     }
10956   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10957   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10958   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10959   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10960   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10961 }
10962
10963 static int
10964 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10965 {
10966   unformat_input_t *i = vam->input;
10967   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10968   f64 timeout;
10969   u32 sw_if_index;
10970   u8 sw_if_index_set = 0;
10971
10972   /* Parse args required to build the message */
10973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10974     {
10975       if (unformat (i, "sw_if_index %d", &sw_if_index))
10976         sw_if_index_set = 1;
10977       else
10978         break;
10979     }
10980
10981   if (sw_if_index_set == 0)
10982     {
10983       sw_if_index = ~0;
10984     }
10985
10986   if (!vam->json_output)
10987     {
10988       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10989                "sw_if_index", "local", "remote", "vni",
10990                "protocol", "encap_vrf_id", "decap_vrf_id");
10991     }
10992
10993   /* Get list of vxlan-tunnel interfaces */
10994   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10995
10996   mp->sw_if_index = htonl (sw_if_index);
10997
10998   S;
10999
11000   /* Use a control ping for synchronization */
11001   {
11002     vl_api_control_ping_t *mp;
11003     M (CONTROL_PING, control_ping);
11004     S;
11005   }
11006   W;
11007 }
11008
11009 u8 *
11010 format_l2_fib_mac_address (u8 * s, va_list * args)
11011 {
11012   u8 *a = va_arg (*args, u8 *);
11013
11014   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11015                  a[2], a[3], a[4], a[5], a[6], a[7]);
11016 }
11017
11018 static void vl_api_l2_fib_table_entry_t_handler
11019   (vl_api_l2_fib_table_entry_t * mp)
11020 {
11021   vat_main_t *vam = &vat_main;
11022
11023   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11024            "       %d       %d     %d\n",
11025            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11026            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11027            mp->bvi_mac);
11028 }
11029
11030 static void vl_api_l2_fib_table_entry_t_handler_json
11031   (vl_api_l2_fib_table_entry_t * mp)
11032 {
11033   vat_main_t *vam = &vat_main;
11034   vat_json_node_t *node = NULL;
11035
11036   if (VAT_JSON_ARRAY != vam->json_tree.type)
11037     {
11038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11039       vat_json_init_array (&vam->json_tree);
11040     }
11041   node = vat_json_array_add (&vam->json_tree);
11042
11043   vat_json_init_object (node);
11044   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11045   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11046   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11047   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11048   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11049   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11050 }
11051
11052 static int
11053 api_l2_fib_table_dump (vat_main_t * vam)
11054 {
11055   unformat_input_t *i = vam->input;
11056   vl_api_l2_fib_table_dump_t *mp;
11057   f64 timeout;
11058   u32 bd_id;
11059   u8 bd_id_set = 0;
11060
11061   /* Parse args required to build the message */
11062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11063     {
11064       if (unformat (i, "bd_id %d", &bd_id))
11065         bd_id_set = 1;
11066       else
11067         break;
11068     }
11069
11070   if (bd_id_set == 0)
11071     {
11072       errmsg ("missing bridge domain\n");
11073       return -99;
11074     }
11075
11076   fformat (vam->ofp,
11077            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11078
11079   /* Get list of l2 fib entries */
11080   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11081
11082   mp->bd_id = ntohl (bd_id);
11083   S;
11084
11085   /* Use a control ping for synchronization */
11086   {
11087     vl_api_control_ping_t *mp;
11088     M (CONTROL_PING, control_ping);
11089     S;
11090   }
11091   W;
11092 }
11093
11094
11095 static int
11096 api_interface_name_renumber (vat_main_t * vam)
11097 {
11098   unformat_input_t *line_input = vam->input;
11099   vl_api_interface_name_renumber_t *mp;
11100   u32 sw_if_index = ~0;
11101   f64 timeout;
11102   u32 new_show_dev_instance = ~0;
11103
11104   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11105     {
11106       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11107                     &sw_if_index))
11108         ;
11109       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11110         ;
11111       else if (unformat (line_input, "new_show_dev_instance %d",
11112                          &new_show_dev_instance))
11113         ;
11114       else
11115         break;
11116     }
11117
11118   if (sw_if_index == ~0)
11119     {
11120       errmsg ("missing interface name or sw_if_index\n");
11121       return -99;
11122     }
11123
11124   if (new_show_dev_instance == ~0)
11125     {
11126       errmsg ("missing new_show_dev_instance\n");
11127       return -99;
11128     }
11129
11130   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11131
11132   mp->sw_if_index = ntohl (sw_if_index);
11133   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11134
11135   S;
11136   W;
11137 }
11138
11139 static int
11140 api_want_ip4_arp_events (vat_main_t * vam)
11141 {
11142   unformat_input_t *line_input = vam->input;
11143   vl_api_want_ip4_arp_events_t *mp;
11144   f64 timeout;
11145   ip4_address_t address;
11146   int address_set = 0;
11147   u32 enable_disable = 1;
11148
11149   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11150     {
11151       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11152         address_set = 1;
11153       else if (unformat (line_input, "del"))
11154         enable_disable = 0;
11155       else
11156         break;
11157     }
11158
11159   if (address_set == 0)
11160     {
11161       errmsg ("missing addresses\n");
11162       return -99;
11163     }
11164
11165   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11166   mp->enable_disable = enable_disable;
11167   mp->pid = getpid ();
11168   mp->address = address.as_u32;
11169
11170   S;
11171   W;
11172 }
11173
11174 static int
11175 api_want_ip6_nd_events (vat_main_t * vam)
11176 {
11177   unformat_input_t *line_input = vam->input;
11178   vl_api_want_ip6_nd_events_t *mp;
11179   f64 timeout;
11180   ip6_address_t address;
11181   int address_set = 0;
11182   u32 enable_disable = 1;
11183
11184   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11185     {
11186       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11187         address_set = 1;
11188       else if (unformat (line_input, "del"))
11189         enable_disable = 0;
11190       else
11191         break;
11192     }
11193
11194   if (address_set == 0)
11195     {
11196       errmsg ("missing addresses\n");
11197       return -99;
11198     }
11199
11200   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11201   mp->enable_disable = enable_disable;
11202   mp->pid = getpid ();
11203   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11204
11205   S;
11206   W;
11207 }
11208
11209 static int
11210 api_input_acl_set_interface (vat_main_t * vam)
11211 {
11212   unformat_input_t *i = vam->input;
11213   vl_api_input_acl_set_interface_t *mp;
11214   f64 timeout;
11215   u32 sw_if_index;
11216   int sw_if_index_set;
11217   u32 ip4_table_index = ~0;
11218   u32 ip6_table_index = ~0;
11219   u32 l2_table_index = ~0;
11220   u8 is_add = 1;
11221
11222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11223     {
11224       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11225         sw_if_index_set = 1;
11226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11227         sw_if_index_set = 1;
11228       else if (unformat (i, "del"))
11229         is_add = 0;
11230       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11231         ;
11232       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11233         ;
11234       else if (unformat (i, "l2-table %d", &l2_table_index))
11235         ;
11236       else
11237         {
11238           clib_warning ("parse error '%U'", format_unformat_error, i);
11239           return -99;
11240         }
11241     }
11242
11243   if (sw_if_index_set == 0)
11244     {
11245       errmsg ("missing interface name or sw_if_index\n");
11246       return -99;
11247     }
11248
11249   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11250
11251   mp->sw_if_index = ntohl (sw_if_index);
11252   mp->ip4_table_index = ntohl (ip4_table_index);
11253   mp->ip6_table_index = ntohl (ip6_table_index);
11254   mp->l2_table_index = ntohl (l2_table_index);
11255   mp->is_add = is_add;
11256
11257   S;
11258   W;
11259   /* NOTREACHED */
11260   return 0;
11261 }
11262
11263 static int
11264 api_ip_address_dump (vat_main_t * vam)
11265 {
11266   unformat_input_t *i = vam->input;
11267   vl_api_ip_address_dump_t *mp;
11268   u32 sw_if_index = ~0;
11269   u8 sw_if_index_set = 0;
11270   u8 ipv4_set = 0;
11271   u8 ipv6_set = 0;
11272   f64 timeout;
11273
11274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11275     {
11276       if (unformat (i, "sw_if_index %d", &sw_if_index))
11277         sw_if_index_set = 1;
11278       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11279         sw_if_index_set = 1;
11280       else if (unformat (i, "ipv4"))
11281         ipv4_set = 1;
11282       else if (unformat (i, "ipv6"))
11283         ipv6_set = 1;
11284       else
11285         break;
11286     }
11287
11288   if (ipv4_set && ipv6_set)
11289     {
11290       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11291       return -99;
11292     }
11293
11294   if ((!ipv4_set) && (!ipv6_set))
11295     {
11296       errmsg ("no ipv4 nor ipv6 flag set\n");
11297       return -99;
11298     }
11299
11300   if (sw_if_index_set == 0)
11301     {
11302       errmsg ("missing interface name or sw_if_index\n");
11303       return -99;
11304     }
11305
11306   vam->current_sw_if_index = sw_if_index;
11307   vam->is_ipv6 = ipv6_set;
11308
11309   M (IP_ADDRESS_DUMP, ip_address_dump);
11310   mp->sw_if_index = ntohl (sw_if_index);
11311   mp->is_ipv6 = ipv6_set;
11312   S;
11313
11314   /* Use a control ping for synchronization */
11315   {
11316     vl_api_control_ping_t *mp;
11317     M (CONTROL_PING, control_ping);
11318     S;
11319   }
11320   W;
11321 }
11322
11323 static int
11324 api_ip_dump (vat_main_t * vam)
11325 {
11326   vl_api_ip_dump_t *mp;
11327   unformat_input_t *in = vam->input;
11328   int ipv4_set = 0;
11329   int ipv6_set = 0;
11330   int is_ipv6;
11331   f64 timeout;
11332   int i;
11333
11334   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11335     {
11336       if (unformat (in, "ipv4"))
11337         ipv4_set = 1;
11338       else if (unformat (in, "ipv6"))
11339         ipv6_set = 1;
11340       else
11341         break;
11342     }
11343
11344   if (ipv4_set && ipv6_set)
11345     {
11346       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11347       return -99;
11348     }
11349
11350   if ((!ipv4_set) && (!ipv6_set))
11351     {
11352       errmsg ("no ipv4 nor ipv6 flag set\n");
11353       return -99;
11354     }
11355
11356   is_ipv6 = ipv6_set;
11357   vam->is_ipv6 = is_ipv6;
11358
11359   /* free old data */
11360   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11361     {
11362       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11363     }
11364   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11365
11366   M (IP_DUMP, ip_dump);
11367   mp->is_ipv6 = ipv6_set;
11368   S;
11369
11370   /* Use a control ping for synchronization */
11371   {
11372     vl_api_control_ping_t *mp;
11373     M (CONTROL_PING, control_ping);
11374     S;
11375   }
11376   W;
11377 }
11378
11379 static int
11380 api_ipsec_spd_add_del (vat_main_t * vam)
11381 {
11382 #if DPDK > 0
11383   unformat_input_t *i = vam->input;
11384   vl_api_ipsec_spd_add_del_t *mp;
11385   f64 timeout;
11386   u32 spd_id = ~0;
11387   u8 is_add = 1;
11388
11389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11390     {
11391       if (unformat (i, "spd_id %d", &spd_id))
11392         ;
11393       else if (unformat (i, "del"))
11394         is_add = 0;
11395       else
11396         {
11397           clib_warning ("parse error '%U'", format_unformat_error, i);
11398           return -99;
11399         }
11400     }
11401   if (spd_id == ~0)
11402     {
11403       errmsg ("spd_id must be set\n");
11404       return -99;
11405     }
11406
11407   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11408
11409   mp->spd_id = ntohl (spd_id);
11410   mp->is_add = is_add;
11411
11412   S;
11413   W;
11414   /* NOTREACHED */
11415   return 0;
11416 #else
11417   clib_warning ("unsupported (no dpdk)");
11418   return -99;
11419 #endif
11420 }
11421
11422 static int
11423 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11424 {
11425 #if DPDK > 0
11426   unformat_input_t *i = vam->input;
11427   vl_api_ipsec_interface_add_del_spd_t *mp;
11428   f64 timeout;
11429   u32 sw_if_index;
11430   u8 sw_if_index_set = 0;
11431   u32 spd_id = (u32) ~ 0;
11432   u8 is_add = 1;
11433
11434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11435     {
11436       if (unformat (i, "del"))
11437         is_add = 0;
11438       else if (unformat (i, "spd_id %d", &spd_id))
11439         ;
11440       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11441         sw_if_index_set = 1;
11442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11443         sw_if_index_set = 1;
11444       else
11445         {
11446           clib_warning ("parse error '%U'", format_unformat_error, i);
11447           return -99;
11448         }
11449
11450     }
11451
11452   if (spd_id == (u32) ~ 0)
11453     {
11454       errmsg ("spd_id must be set\n");
11455       return -99;
11456     }
11457
11458   if (sw_if_index_set == 0)
11459     {
11460       errmsg ("missing interface name or sw_if_index\n");
11461       return -99;
11462     }
11463
11464   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11465
11466   mp->spd_id = ntohl (spd_id);
11467   mp->sw_if_index = ntohl (sw_if_index);
11468   mp->is_add = is_add;
11469
11470   S;
11471   W;
11472   /* NOTREACHED */
11473   return 0;
11474 #else
11475   clib_warning ("unsupported (no dpdk)");
11476   return -99;
11477 #endif
11478 }
11479
11480 static int
11481 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11482 {
11483 #if DPDK > 0
11484   unformat_input_t *i = vam->input;
11485   vl_api_ipsec_spd_add_del_entry_t *mp;
11486   f64 timeout;
11487   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11488   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11489   i32 priority = 0;
11490   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11491   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11492   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11493   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11494
11495   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11496   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11497   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11498   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11499   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11500   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11501
11502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11503     {
11504       if (unformat (i, "del"))
11505         is_add = 0;
11506       if (unformat (i, "outbound"))
11507         is_outbound = 1;
11508       if (unformat (i, "inbound"))
11509         is_outbound = 0;
11510       else if (unformat (i, "spd_id %d", &spd_id))
11511         ;
11512       else if (unformat (i, "sa_id %d", &sa_id))
11513         ;
11514       else if (unformat (i, "priority %d", &priority))
11515         ;
11516       else if (unformat (i, "protocol %d", &protocol))
11517         ;
11518       else if (unformat (i, "lport_start %d", &lport_start))
11519         ;
11520       else if (unformat (i, "lport_stop %d", &lport_stop))
11521         ;
11522       else if (unformat (i, "rport_start %d", &rport_start))
11523         ;
11524       else if (unformat (i, "rport_stop %d", &rport_stop))
11525         ;
11526       else
11527         if (unformat
11528             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11529         {
11530           is_ipv6 = 0;
11531           is_ip_any = 0;
11532         }
11533       else
11534         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11535         {
11536           is_ipv6 = 0;
11537           is_ip_any = 0;
11538         }
11539       else
11540         if (unformat
11541             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11542         {
11543           is_ipv6 = 0;
11544           is_ip_any = 0;
11545         }
11546       else
11547         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11548         {
11549           is_ipv6 = 0;
11550           is_ip_any = 0;
11551         }
11552       else
11553         if (unformat
11554             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11555         {
11556           is_ipv6 = 1;
11557           is_ip_any = 0;
11558         }
11559       else
11560         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11561         {
11562           is_ipv6 = 1;
11563           is_ip_any = 0;
11564         }
11565       else
11566         if (unformat
11567             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11568         {
11569           is_ipv6 = 1;
11570           is_ip_any = 0;
11571         }
11572       else
11573         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11574         {
11575           is_ipv6 = 1;
11576           is_ip_any = 0;
11577         }
11578       else
11579         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11580         {
11581           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11582             {
11583               clib_warning ("unsupported action: 'resolve'");
11584               return -99;
11585             }
11586         }
11587       else
11588         {
11589           clib_warning ("parse error '%U'", format_unformat_error, i);
11590           return -99;
11591         }
11592
11593     }
11594
11595   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11596
11597   mp->spd_id = ntohl (spd_id);
11598   mp->priority = ntohl (priority);
11599   mp->is_outbound = is_outbound;
11600
11601   mp->is_ipv6 = is_ipv6;
11602   if (is_ipv6 || is_ip_any)
11603     {
11604       clib_memcpy (mp->remote_address_start, &raddr6_start,
11605                    sizeof (ip6_address_t));
11606       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11607                    sizeof (ip6_address_t));
11608       clib_memcpy (mp->local_address_start, &laddr6_start,
11609                    sizeof (ip6_address_t));
11610       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11611                    sizeof (ip6_address_t));
11612     }
11613   else
11614     {
11615       clib_memcpy (mp->remote_address_start, &raddr4_start,
11616                    sizeof (ip4_address_t));
11617       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11618                    sizeof (ip4_address_t));
11619       clib_memcpy (mp->local_address_start, &laddr4_start,
11620                    sizeof (ip4_address_t));
11621       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11622                    sizeof (ip4_address_t));
11623     }
11624   mp->protocol = (u8) protocol;
11625   mp->local_port_start = ntohs ((u16) lport_start);
11626   mp->local_port_stop = ntohs ((u16) lport_stop);
11627   mp->remote_port_start = ntohs ((u16) rport_start);
11628   mp->remote_port_stop = ntohs ((u16) rport_stop);
11629   mp->policy = (u8) policy;
11630   mp->sa_id = ntohl (sa_id);
11631   mp->is_add = is_add;
11632   mp->is_ip_any = is_ip_any;
11633   S;
11634   W;
11635   /* NOTREACHED */
11636   return 0;
11637 #else
11638   clib_warning ("unsupported (no dpdk)");
11639   return -99;
11640 #endif
11641 }
11642
11643 static int
11644 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11645 {
11646 #if DPDK > 0
11647   unformat_input_t *i = vam->input;
11648   vl_api_ipsec_sad_add_del_entry_t *mp;
11649   f64 timeout;
11650   u32 sad_id = 0, spi = 0;
11651   u8 *ck = 0, *ik = 0;
11652   u8 is_add = 1;
11653
11654   u8 protocol = IPSEC_PROTOCOL_AH;
11655   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11656   u32 crypto_alg = 0, integ_alg = 0;
11657   ip4_address_t tun_src4;
11658   ip4_address_t tun_dst4;
11659   ip6_address_t tun_src6;
11660   ip6_address_t tun_dst6;
11661
11662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11663     {
11664       if (unformat (i, "del"))
11665         is_add = 0;
11666       else if (unformat (i, "sad_id %d", &sad_id))
11667         ;
11668       else if (unformat (i, "spi %d", &spi))
11669         ;
11670       else if (unformat (i, "esp"))
11671         protocol = IPSEC_PROTOCOL_ESP;
11672       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11673         {
11674           is_tunnel = 1;
11675           is_tunnel_ipv6 = 0;
11676         }
11677       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11678         {
11679           is_tunnel = 1;
11680           is_tunnel_ipv6 = 0;
11681         }
11682       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11683         {
11684           is_tunnel = 1;
11685           is_tunnel_ipv6 = 1;
11686         }
11687       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11688         {
11689           is_tunnel = 1;
11690           is_tunnel_ipv6 = 1;
11691         }
11692       else
11693         if (unformat
11694             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11695         {
11696           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11697               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11698             {
11699               clib_warning ("unsupported crypto-alg: '%U'",
11700                             format_ipsec_crypto_alg, crypto_alg);
11701               return -99;
11702             }
11703         }
11704       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11705         ;
11706       else
11707         if (unformat
11708             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11709         {
11710           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11711               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11712             {
11713               clib_warning ("unsupported integ-alg: '%U'",
11714                             format_ipsec_integ_alg, integ_alg);
11715               return -99;
11716             }
11717         }
11718       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11719         ;
11720       else
11721         {
11722           clib_warning ("parse error '%U'", format_unformat_error, i);
11723           return -99;
11724         }
11725
11726     }
11727
11728   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11729
11730   mp->sad_id = ntohl (sad_id);
11731   mp->is_add = is_add;
11732   mp->protocol = protocol;
11733   mp->spi = ntohl (spi);
11734   mp->is_tunnel = is_tunnel;
11735   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11736   mp->crypto_algorithm = crypto_alg;
11737   mp->integrity_algorithm = integ_alg;
11738   mp->crypto_key_length = vec_len (ck);
11739   mp->integrity_key_length = vec_len (ik);
11740
11741   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11742     mp->crypto_key_length = sizeof (mp->crypto_key);
11743
11744   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11745     mp->integrity_key_length = sizeof (mp->integrity_key);
11746
11747   if (ck)
11748     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11749   if (ik)
11750     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11751
11752   if (is_tunnel)
11753     {
11754       if (is_tunnel_ipv6)
11755         {
11756           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11757                        sizeof (ip6_address_t));
11758           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11759                        sizeof (ip6_address_t));
11760         }
11761       else
11762         {
11763           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11764                        sizeof (ip4_address_t));
11765           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11766                        sizeof (ip4_address_t));
11767         }
11768     }
11769
11770   S;
11771   W;
11772   /* NOTREACHED */
11773   return 0;
11774 #else
11775   clib_warning ("unsupported (no dpdk)");
11776   return -99;
11777 #endif
11778 }
11779
11780 static int
11781 api_ipsec_sa_set_key (vat_main_t * vam)
11782 {
11783 #if DPDK > 0
11784   unformat_input_t *i = vam->input;
11785   vl_api_ipsec_sa_set_key_t *mp;
11786   f64 timeout;
11787   u32 sa_id;
11788   u8 *ck = 0, *ik = 0;
11789
11790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11791     {
11792       if (unformat (i, "sa_id %d", &sa_id))
11793         ;
11794       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11795         ;
11796       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11797         ;
11798       else
11799         {
11800           clib_warning ("parse error '%U'", format_unformat_error, i);
11801           return -99;
11802         }
11803     }
11804
11805   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11806
11807   mp->sa_id = ntohl (sa_id);
11808   mp->crypto_key_length = vec_len (ck);
11809   mp->integrity_key_length = vec_len (ik);
11810
11811   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11812     mp->crypto_key_length = sizeof (mp->crypto_key);
11813
11814   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11815     mp->integrity_key_length = sizeof (mp->integrity_key);
11816
11817   if (ck)
11818     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11819   if (ik)
11820     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11821
11822   S;
11823   W;
11824   /* NOTREACHED */
11825   return 0;
11826 #else
11827   clib_warning ("unsupported (no dpdk)");
11828   return -99;
11829 #endif
11830 }
11831
11832 static int
11833 api_ikev2_profile_add_del (vat_main_t * vam)
11834 {
11835 #if DPDK > 0
11836   unformat_input_t *i = vam->input;
11837   vl_api_ikev2_profile_add_del_t *mp;
11838   f64 timeout;
11839   u8 is_add = 1;
11840   u8 *name = 0;
11841
11842   const char *valid_chars = "a-zA-Z0-9_";
11843
11844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11845     {
11846       if (unformat (i, "del"))
11847         is_add = 0;
11848       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11849         vec_add1 (name, 0);
11850       else
11851         {
11852           errmsg ("parse error '%U'", format_unformat_error, i);
11853           return -99;
11854         }
11855     }
11856
11857   if (!vec_len (name))
11858     {
11859       errmsg ("profile name must be specified");
11860       return -99;
11861     }
11862
11863   if (vec_len (name) > 64)
11864     {
11865       errmsg ("profile name too long");
11866       return -99;
11867     }
11868
11869   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11870
11871   clib_memcpy (mp->name, name, vec_len (name));
11872   mp->is_add = is_add;
11873   vec_free (name);
11874
11875   S;
11876   W;
11877   /* NOTREACHED */
11878   return 0;
11879 #else
11880   clib_warning ("unsupported (no dpdk)");
11881   return -99;
11882 #endif
11883 }
11884
11885 static int
11886 api_ikev2_profile_set_auth (vat_main_t * vam)
11887 {
11888 #if DPDK > 0
11889   unformat_input_t *i = vam->input;
11890   vl_api_ikev2_profile_set_auth_t *mp;
11891   f64 timeout;
11892   u8 *name = 0;
11893   u8 *data = 0;
11894   u32 auth_method = 0;
11895   u8 is_hex = 0;
11896
11897   const char *valid_chars = "a-zA-Z0-9_";
11898
11899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11900     {
11901       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11902         vec_add1 (name, 0);
11903       else if (unformat (i, "auth_method %U",
11904                          unformat_ikev2_auth_method, &auth_method))
11905         ;
11906       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11907         is_hex = 1;
11908       else if (unformat (i, "auth_data %v", &data))
11909         ;
11910       else
11911         {
11912           errmsg ("parse error '%U'", format_unformat_error, i);
11913           return -99;
11914         }
11915     }
11916
11917   if (!vec_len (name))
11918     {
11919       errmsg ("profile name must be specified");
11920       return -99;
11921     }
11922
11923   if (vec_len (name) > 64)
11924     {
11925       errmsg ("profile name too long");
11926       return -99;
11927     }
11928
11929   if (!vec_len (data))
11930     {
11931       errmsg ("auth_data must be specified");
11932       return -99;
11933     }
11934
11935   if (!auth_method)
11936     {
11937       errmsg ("auth_method must be specified");
11938       return -99;
11939     }
11940
11941   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11942
11943   mp->is_hex = is_hex;
11944   mp->auth_method = (u8) auth_method;
11945   mp->data_len = vec_len (data);
11946   clib_memcpy (mp->name, name, vec_len (name));
11947   clib_memcpy (mp->data, data, vec_len (data));
11948   vec_free (name);
11949   vec_free (data);
11950
11951   S;
11952   W;
11953   /* NOTREACHED */
11954   return 0;
11955 #else
11956   clib_warning ("unsupported (no dpdk)");
11957   return -99;
11958 #endif
11959 }
11960
11961 static int
11962 api_ikev2_profile_set_id (vat_main_t * vam)
11963 {
11964 #if DPDK > 0
11965   unformat_input_t *i = vam->input;
11966   vl_api_ikev2_profile_set_id_t *mp;
11967   f64 timeout;
11968   u8 *name = 0;
11969   u8 *data = 0;
11970   u8 is_local = 0;
11971   u32 id_type = 0;
11972   ip4_address_t ip4;
11973
11974   const char *valid_chars = "a-zA-Z0-9_";
11975
11976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11977     {
11978       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11979         vec_add1 (name, 0);
11980       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11981         ;
11982       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11983         {
11984           data = vec_new (u8, 4);
11985           clib_memcpy (data, ip4.as_u8, 4);
11986         }
11987       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11988         ;
11989       else if (unformat (i, "id_data %v", &data))
11990         ;
11991       else if (unformat (i, "local"))
11992         is_local = 1;
11993       else if (unformat (i, "remote"))
11994         is_local = 0;
11995       else
11996         {
11997           errmsg ("parse error '%U'", format_unformat_error, i);
11998           return -99;
11999         }
12000     }
12001
12002   if (!vec_len (name))
12003     {
12004       errmsg ("profile name must be specified");
12005       return -99;
12006     }
12007
12008   if (vec_len (name) > 64)
12009     {
12010       errmsg ("profile name too long");
12011       return -99;
12012     }
12013
12014   if (!vec_len (data))
12015     {
12016       errmsg ("id_data must be specified");
12017       return -99;
12018     }
12019
12020   if (!id_type)
12021     {
12022       errmsg ("id_type must be specified");
12023       return -99;
12024     }
12025
12026   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12027
12028   mp->is_local = is_local;
12029   mp->id_type = (u8) id_type;
12030   mp->data_len = vec_len (data);
12031   clib_memcpy (mp->name, name, vec_len (name));
12032   clib_memcpy (mp->data, data, vec_len (data));
12033   vec_free (name);
12034   vec_free (data);
12035
12036   S;
12037   W;
12038   /* NOTREACHED */
12039   return 0;
12040 #else
12041   clib_warning ("unsupported (no dpdk)");
12042   return -99;
12043 #endif
12044 }
12045
12046 static int
12047 api_ikev2_profile_set_ts (vat_main_t * vam)
12048 {
12049 #if DPDK > 0
12050   unformat_input_t *i = vam->input;
12051   vl_api_ikev2_profile_set_ts_t *mp;
12052   f64 timeout;
12053   u8 *name = 0;
12054   u8 is_local = 0;
12055   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12056   ip4_address_t start_addr, end_addr;
12057
12058   const char *valid_chars = "a-zA-Z0-9_";
12059
12060   start_addr.as_u32 = 0;
12061   end_addr.as_u32 = (u32) ~ 0;
12062
12063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12064     {
12065       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12066         vec_add1 (name, 0);
12067       else if (unformat (i, "protocol %d", &proto))
12068         ;
12069       else if (unformat (i, "start_port %d", &start_port))
12070         ;
12071       else if (unformat (i, "end_port %d", &end_port))
12072         ;
12073       else
12074         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12075         ;
12076       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12077         ;
12078       else if (unformat (i, "local"))
12079         is_local = 1;
12080       else if (unformat (i, "remote"))
12081         is_local = 0;
12082       else
12083         {
12084           errmsg ("parse error '%U'", format_unformat_error, i);
12085           return -99;
12086         }
12087     }
12088
12089   if (!vec_len (name))
12090     {
12091       errmsg ("profile name must be specified");
12092       return -99;
12093     }
12094
12095   if (vec_len (name) > 64)
12096     {
12097       errmsg ("profile name too long");
12098       return -99;
12099     }
12100
12101   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12102
12103   mp->is_local = is_local;
12104   mp->proto = (u8) proto;
12105   mp->start_port = (u16) start_port;
12106   mp->end_port = (u16) end_port;
12107   mp->start_addr = start_addr.as_u32;
12108   mp->end_addr = end_addr.as_u32;
12109   clib_memcpy (mp->name, name, vec_len (name));
12110   vec_free (name);
12111
12112   S;
12113   W;
12114   /* NOTREACHED */
12115   return 0;
12116 #else
12117   clib_warning ("unsupported (no dpdk)");
12118   return -99;
12119 #endif
12120 }
12121
12122 static int
12123 api_ikev2_set_local_key (vat_main_t * vam)
12124 {
12125 #if DPDK > 0
12126   unformat_input_t *i = vam->input;
12127   vl_api_ikev2_set_local_key_t *mp;
12128   f64 timeout;
12129   u8 *file = 0;
12130
12131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12132     {
12133       if (unformat (i, "file %v", &file))
12134         vec_add1 (file, 0);
12135       else
12136         {
12137           errmsg ("parse error '%U'", format_unformat_error, i);
12138           return -99;
12139         }
12140     }
12141
12142   if (!vec_len (file))
12143     {
12144       errmsg ("RSA key file must be specified");
12145       return -99;
12146     }
12147
12148   if (vec_len (file) > 256)
12149     {
12150       errmsg ("file name too long");
12151       return -99;
12152     }
12153
12154   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12155
12156   clib_memcpy (mp->key_file, file, vec_len (file));
12157   vec_free (file);
12158
12159   S;
12160   W;
12161   /* NOTREACHED */
12162   return 0;
12163 #else
12164   clib_warning ("unsupported (no dpdk)");
12165   return -99;
12166 #endif
12167 }
12168
12169 /*
12170  * MAP
12171  */
12172 static int
12173 api_map_add_domain (vat_main_t * vam)
12174 {
12175   unformat_input_t *i = vam->input;
12176   vl_api_map_add_domain_t *mp;
12177   f64 timeout;
12178
12179   ip4_address_t ip4_prefix;
12180   ip6_address_t ip6_prefix;
12181   ip6_address_t ip6_src;
12182   u32 num_m_args = 0;
12183   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12184     0, psid_length = 0;
12185   u8 is_translation = 0;
12186   u32 mtu = 0;
12187   u32 ip6_src_len = 128;
12188
12189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12190     {
12191       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12192                     &ip4_prefix, &ip4_prefix_len))
12193         num_m_args++;
12194       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12195                          &ip6_prefix, &ip6_prefix_len))
12196         num_m_args++;
12197       else
12198         if (unformat
12199             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12200              &ip6_src_len))
12201         num_m_args++;
12202       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12203         num_m_args++;
12204       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12205         num_m_args++;
12206       else if (unformat (i, "psid-offset %d", &psid_offset))
12207         num_m_args++;
12208       else if (unformat (i, "psid-len %d", &psid_length))
12209         num_m_args++;
12210       else if (unformat (i, "mtu %d", &mtu))
12211         num_m_args++;
12212       else if (unformat (i, "map-t"))
12213         is_translation = 1;
12214       else
12215         {
12216           clib_warning ("parse error '%U'", format_unformat_error, i);
12217           return -99;
12218         }
12219     }
12220
12221   if (num_m_args < 3)
12222     {
12223       errmsg ("mandatory argument(s) missing\n");
12224       return -99;
12225     }
12226
12227   /* Construct the API message */
12228   M (MAP_ADD_DOMAIN, map_add_domain);
12229
12230   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12231   mp->ip4_prefix_len = ip4_prefix_len;
12232
12233   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12234   mp->ip6_prefix_len = ip6_prefix_len;
12235
12236   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12237   mp->ip6_src_prefix_len = ip6_src_len;
12238
12239   mp->ea_bits_len = ea_bits_len;
12240   mp->psid_offset = psid_offset;
12241   mp->psid_length = psid_length;
12242   mp->is_translation = is_translation;
12243   mp->mtu = htons (mtu);
12244
12245   /* send it... */
12246   S;
12247
12248   /* Wait for a reply, return good/bad news  */
12249   W;
12250 }
12251
12252 static int
12253 api_map_del_domain (vat_main_t * vam)
12254 {
12255   unformat_input_t *i = vam->input;
12256   vl_api_map_del_domain_t *mp;
12257   f64 timeout;
12258
12259   u32 num_m_args = 0;
12260   u32 index;
12261
12262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12263     {
12264       if (unformat (i, "index %d", &index))
12265         num_m_args++;
12266       else
12267         {
12268           clib_warning ("parse error '%U'", format_unformat_error, i);
12269           return -99;
12270         }
12271     }
12272
12273   if (num_m_args != 1)
12274     {
12275       errmsg ("mandatory argument(s) missing\n");
12276       return -99;
12277     }
12278
12279   /* Construct the API message */
12280   M (MAP_DEL_DOMAIN, map_del_domain);
12281
12282   mp->index = ntohl (index);
12283
12284   /* send it... */
12285   S;
12286
12287   /* Wait for a reply, return good/bad news  */
12288   W;
12289 }
12290
12291 static int
12292 api_map_add_del_rule (vat_main_t * vam)
12293 {
12294   unformat_input_t *i = vam->input;
12295   vl_api_map_add_del_rule_t *mp;
12296   f64 timeout;
12297   u8 is_add = 1;
12298   ip6_address_t ip6_dst;
12299   u32 num_m_args = 0, index, psid = 0;
12300
12301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12302     {
12303       if (unformat (i, "index %d", &index))
12304         num_m_args++;
12305       else if (unformat (i, "psid %d", &psid))
12306         num_m_args++;
12307       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12308         num_m_args++;
12309       else if (unformat (i, "del"))
12310         {
12311           is_add = 0;
12312         }
12313       else
12314         {
12315           clib_warning ("parse error '%U'", format_unformat_error, i);
12316           return -99;
12317         }
12318     }
12319
12320   /* Construct the API message */
12321   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12322
12323   mp->index = ntohl (index);
12324   mp->is_add = is_add;
12325   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12326   mp->psid = ntohs (psid);
12327
12328   /* send it... */
12329   S;
12330
12331   /* Wait for a reply, return good/bad news  */
12332   W;
12333 }
12334
12335 static int
12336 api_map_domain_dump (vat_main_t * vam)
12337 {
12338   vl_api_map_domain_dump_t *mp;
12339   f64 timeout;
12340
12341   /* Construct the API message */
12342   M (MAP_DOMAIN_DUMP, map_domain_dump);
12343
12344   /* send it... */
12345   S;
12346
12347   /* Use a control ping for synchronization */
12348   {
12349     vl_api_control_ping_t *mp;
12350     M (CONTROL_PING, control_ping);
12351     S;
12352   }
12353   W;
12354 }
12355
12356 static int
12357 api_map_rule_dump (vat_main_t * vam)
12358 {
12359   unformat_input_t *i = vam->input;
12360   vl_api_map_rule_dump_t *mp;
12361   f64 timeout;
12362   u32 domain_index = ~0;
12363
12364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12365     {
12366       if (unformat (i, "index %u", &domain_index))
12367         ;
12368       else
12369         break;
12370     }
12371
12372   if (domain_index == ~0)
12373     {
12374       clib_warning ("parse error: domain index expected");
12375       return -99;
12376     }
12377
12378   /* Construct the API message */
12379   M (MAP_RULE_DUMP, map_rule_dump);
12380
12381   mp->domain_index = htonl (domain_index);
12382
12383   /* send it... */
12384   S;
12385
12386   /* Use a control ping for synchronization */
12387   {
12388     vl_api_control_ping_t *mp;
12389     M (CONTROL_PING, control_ping);
12390     S;
12391   }
12392   W;
12393 }
12394
12395 static void vl_api_map_add_domain_reply_t_handler
12396   (vl_api_map_add_domain_reply_t * mp)
12397 {
12398   vat_main_t *vam = &vat_main;
12399   i32 retval = ntohl (mp->retval);
12400
12401   if (vam->async_mode)
12402     {
12403       vam->async_errors += (retval < 0);
12404     }
12405   else
12406     {
12407       vam->retval = retval;
12408       vam->result_ready = 1;
12409     }
12410 }
12411
12412 static void vl_api_map_add_domain_reply_t_handler_json
12413   (vl_api_map_add_domain_reply_t * mp)
12414 {
12415   vat_main_t *vam = &vat_main;
12416   vat_json_node_t node;
12417
12418   vat_json_init_object (&node);
12419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12420   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12421
12422   vat_json_print (vam->ofp, &node);
12423   vat_json_free (&node);
12424
12425   vam->retval = ntohl (mp->retval);
12426   vam->result_ready = 1;
12427 }
12428
12429 static int
12430 api_get_first_msg_id (vat_main_t * vam)
12431 {
12432   vl_api_get_first_msg_id_t *mp;
12433   f64 timeout;
12434   unformat_input_t *i = vam->input;
12435   u8 *name;
12436   u8 name_set = 0;
12437
12438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12439     {
12440       if (unformat (i, "client %s", &name))
12441         name_set = 1;
12442       else
12443         break;
12444     }
12445
12446   if (name_set == 0)
12447     {
12448       errmsg ("missing client name\n");
12449       return -99;
12450     }
12451   vec_add1 (name, 0);
12452
12453   if (vec_len (name) > 63)
12454     {
12455       errmsg ("client name too long\n");
12456       return -99;
12457     }
12458
12459   M (GET_FIRST_MSG_ID, get_first_msg_id);
12460   clib_memcpy (mp->name, name, vec_len (name));
12461   S;
12462   W;
12463   /* NOTREACHED */
12464   return 0;
12465 }
12466
12467 static int
12468 api_cop_interface_enable_disable (vat_main_t * vam)
12469 {
12470   unformat_input_t *line_input = vam->input;
12471   vl_api_cop_interface_enable_disable_t *mp;
12472   f64 timeout;
12473   u32 sw_if_index = ~0;
12474   u8 enable_disable = 1;
12475
12476   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12477     {
12478       if (unformat (line_input, "disable"))
12479         enable_disable = 0;
12480       if (unformat (line_input, "enable"))
12481         enable_disable = 1;
12482       else if (unformat (line_input, "%U", unformat_sw_if_index,
12483                          vam, &sw_if_index))
12484         ;
12485       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12486         ;
12487       else
12488         break;
12489     }
12490
12491   if (sw_if_index == ~0)
12492     {
12493       errmsg ("missing interface name or sw_if_index\n");
12494       return -99;
12495     }
12496
12497   /* Construct the API message */
12498   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12499   mp->sw_if_index = ntohl (sw_if_index);
12500   mp->enable_disable = enable_disable;
12501
12502   /* send it... */
12503   S;
12504   /* Wait for the reply */
12505   W;
12506 }
12507
12508 static int
12509 api_cop_whitelist_enable_disable (vat_main_t * vam)
12510 {
12511   unformat_input_t *line_input = vam->input;
12512   vl_api_cop_whitelist_enable_disable_t *mp;
12513   f64 timeout;
12514   u32 sw_if_index = ~0;
12515   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12516   u32 fib_id = 0;
12517
12518   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12519     {
12520       if (unformat (line_input, "ip4"))
12521         ip4 = 1;
12522       else if (unformat (line_input, "ip6"))
12523         ip6 = 1;
12524       else if (unformat (line_input, "default"))
12525         default_cop = 1;
12526       else if (unformat (line_input, "%U", unformat_sw_if_index,
12527                          vam, &sw_if_index))
12528         ;
12529       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12530         ;
12531       else if (unformat (line_input, "fib-id %d", &fib_id))
12532         ;
12533       else
12534         break;
12535     }
12536
12537   if (sw_if_index == ~0)
12538     {
12539       errmsg ("missing interface name or sw_if_index\n");
12540       return -99;
12541     }
12542
12543   /* Construct the API message */
12544   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12545   mp->sw_if_index = ntohl (sw_if_index);
12546   mp->fib_id = ntohl (fib_id);
12547   mp->ip4 = ip4;
12548   mp->ip6 = ip6;
12549   mp->default_cop = default_cop;
12550
12551   /* send it... */
12552   S;
12553   /* Wait for the reply */
12554   W;
12555 }
12556
12557 static int
12558 api_get_node_graph (vat_main_t * vam)
12559 {
12560   vl_api_get_node_graph_t *mp;
12561   f64 timeout;
12562
12563   M (GET_NODE_GRAPH, get_node_graph);
12564
12565   /* send it... */
12566   S;
12567   /* Wait for the reply */
12568   W;
12569 }
12570
12571 /* *INDENT-OFF* */
12572 /** Used for parsing LISP eids */
12573 typedef CLIB_PACKED(struct{
12574   u8 addr[16];   /**< eid address */
12575   u32 len;       /**< prefix length if IP */
12576   u8 type;      /**< type of eid */
12577 }) lisp_eid_vat_t;
12578 /* *INDENT-ON* */
12579
12580 static uword
12581 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12582 {
12583   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12584
12585   memset (a, 0, sizeof (a[0]));
12586
12587   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12588     {
12589       a->type = 0;              /* ipv4 type */
12590     }
12591   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12592     {
12593       a->type = 1;              /* ipv6 type */
12594     }
12595   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12596     {
12597       a->type = 2;              /* mac type */
12598     }
12599   else
12600     {
12601       return 0;
12602     }
12603
12604   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12605     {
12606       return 0;
12607     }
12608
12609   return 1;
12610 }
12611
12612 static int
12613 lisp_eid_size_vat (u8 type)
12614 {
12615   switch (type)
12616     {
12617     case 0:
12618       return 4;
12619     case 1:
12620       return 16;
12621     case 2:
12622       return 6;
12623     }
12624   return 0;
12625 }
12626
12627 static void
12628 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12629 {
12630   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12631 }
12632
12633 /* *INDENT-OFF* */
12634 /** Used for transferring locators via VPP API */
12635 typedef CLIB_PACKED(struct
12636 {
12637   u32 sw_if_index; /**< locator sw_if_index */
12638   u8 priority; /**< locator priority */
12639   u8 weight;   /**< locator weight */
12640 }) ls_locator_t;
12641 /* *INDENT-ON* */
12642
12643 static int
12644 api_lisp_add_del_locator_set (vat_main_t * vam)
12645 {
12646   unformat_input_t *input = vam->input;
12647   vl_api_lisp_add_del_locator_set_t *mp;
12648   f64 timeout = ~0;
12649   u8 is_add = 1;
12650   u8 *locator_set_name = NULL;
12651   u8 locator_set_name_set = 0;
12652   ls_locator_t locator, *locators = 0;
12653   u32 sw_if_index, priority, weight;
12654   u32 data_len = 0;
12655
12656   /* Parse args required to build the message */
12657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12658     {
12659       if (unformat (input, "del"))
12660         {
12661           is_add = 0;
12662         }
12663       else if (unformat (input, "locator-set %s", &locator_set_name))
12664         {
12665           locator_set_name_set = 1;
12666         }
12667       else if (unformat (input, "sw_if_index %u p %u w %u",
12668                          &sw_if_index, &priority, &weight))
12669         {
12670           locator.sw_if_index = htonl (sw_if_index);
12671           locator.priority = priority;
12672           locator.weight = weight;
12673           vec_add1 (locators, locator);
12674         }
12675       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12676                          vam, &sw_if_index, &priority, &weight))
12677         {
12678           locator.sw_if_index = htonl (sw_if_index);
12679           locator.priority = priority;
12680           locator.weight = weight;
12681           vec_add1 (locators, locator);
12682         }
12683       else
12684         break;
12685     }
12686
12687   if (locator_set_name_set == 0)
12688     {
12689       errmsg ("missing locator-set name");
12690       vec_free (locators);
12691       return -99;
12692     }
12693
12694   if (vec_len (locator_set_name) > 64)
12695     {
12696       errmsg ("locator-set name too long\n");
12697       vec_free (locator_set_name);
12698       vec_free (locators);
12699       return -99;
12700     }
12701   vec_add1 (locator_set_name, 0);
12702
12703   data_len = sizeof (ls_locator_t) * vec_len (locators);
12704
12705   /* Construct the API message */
12706   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12707
12708   mp->is_add = is_add;
12709   clib_memcpy (mp->locator_set_name, locator_set_name,
12710                vec_len (locator_set_name));
12711   vec_free (locator_set_name);
12712
12713   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12714   if (locators)
12715     clib_memcpy (mp->locators, locators, data_len);
12716   vec_free (locators);
12717
12718   /* send it... */
12719   S;
12720
12721   /* Wait for a reply... */
12722   W;
12723
12724   /* NOTREACHED */
12725   return 0;
12726 }
12727
12728 static int
12729 api_lisp_add_del_locator (vat_main_t * vam)
12730 {
12731   unformat_input_t *input = vam->input;
12732   vl_api_lisp_add_del_locator_t *mp;
12733   f64 timeout = ~0;
12734   u32 tmp_if_index = ~0;
12735   u32 sw_if_index = ~0;
12736   u8 sw_if_index_set = 0;
12737   u8 sw_if_index_if_name_set = 0;
12738   u32 priority = ~0;
12739   u8 priority_set = 0;
12740   u32 weight = ~0;
12741   u8 weight_set = 0;
12742   u8 is_add = 1;
12743   u8 *locator_set_name = NULL;
12744   u8 locator_set_name_set = 0;
12745
12746   /* Parse args required to build the message */
12747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12748     {
12749       if (unformat (input, "del"))
12750         {
12751           is_add = 0;
12752         }
12753       else if (unformat (input, "locator-set %s", &locator_set_name))
12754         {
12755           locator_set_name_set = 1;
12756         }
12757       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12758                          &tmp_if_index))
12759         {
12760           sw_if_index_if_name_set = 1;
12761           sw_if_index = tmp_if_index;
12762         }
12763       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12764         {
12765           sw_if_index_set = 1;
12766           sw_if_index = tmp_if_index;
12767         }
12768       else if (unformat (input, "p %d", &priority))
12769         {
12770           priority_set = 1;
12771         }
12772       else if (unformat (input, "w %d", &weight))
12773         {
12774           weight_set = 1;
12775         }
12776       else
12777         break;
12778     }
12779
12780   if (locator_set_name_set == 0)
12781     {
12782       errmsg ("missing locator-set name");
12783       return -99;
12784     }
12785
12786   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12787     {
12788       errmsg ("missing sw_if_index");
12789       vec_free (locator_set_name);
12790       return -99;
12791     }
12792
12793   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12794     {
12795       errmsg ("cannot use both params interface name and sw_if_index");
12796       vec_free (locator_set_name);
12797       return -99;
12798     }
12799
12800   if (priority_set == 0)
12801     {
12802       errmsg ("missing locator-set priority\n");
12803       vec_free (locator_set_name);
12804       return -99;
12805     }
12806
12807   if (weight_set == 0)
12808     {
12809       errmsg ("missing locator-set weight\n");
12810       vec_free (locator_set_name);
12811       return -99;
12812     }
12813
12814   if (vec_len (locator_set_name) > 64)
12815     {
12816       errmsg ("locator-set name too long\n");
12817       vec_free (locator_set_name);
12818       return -99;
12819     }
12820   vec_add1 (locator_set_name, 0);
12821
12822   /* Construct the API message */
12823   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12824
12825   mp->is_add = is_add;
12826   mp->sw_if_index = ntohl (sw_if_index);
12827   mp->priority = priority;
12828   mp->weight = weight;
12829   clib_memcpy (mp->locator_set_name, locator_set_name,
12830                vec_len (locator_set_name));
12831   vec_free (locator_set_name);
12832
12833   /* send it... */
12834   S;
12835
12836   /* Wait for a reply... */
12837   W;
12838
12839   /* NOTREACHED */
12840   return 0;
12841 }
12842
12843 static int
12844 api_lisp_add_del_local_eid (vat_main_t * vam)
12845 {
12846   unformat_input_t *input = vam->input;
12847   vl_api_lisp_add_del_local_eid_t *mp;
12848   f64 timeout = ~0;
12849   u8 is_add = 1;
12850   u8 eid_set = 0;
12851   lisp_eid_vat_t _eid, *eid = &_eid;
12852   u8 *locator_set_name = 0;
12853   u8 locator_set_name_set = 0;
12854   u32 vni = 0;
12855
12856   /* Parse args required to build the message */
12857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12858     {
12859       if (unformat (input, "del"))
12860         {
12861           is_add = 0;
12862         }
12863       else if (unformat (input, "vni %d", &vni))
12864         {
12865           ;
12866         }
12867       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12868         {
12869           eid_set = 1;
12870         }
12871       else if (unformat (input, "locator-set %s", &locator_set_name))
12872         {
12873           locator_set_name_set = 1;
12874         }
12875       else
12876         break;
12877     }
12878
12879   if (locator_set_name_set == 0)
12880     {
12881       errmsg ("missing locator-set name\n");
12882       return -99;
12883     }
12884
12885   if (0 == eid_set)
12886     {
12887       errmsg ("EID address not set!");
12888       vec_free (locator_set_name);
12889       return -99;
12890     }
12891
12892   if (vec_len (locator_set_name) > 64)
12893     {
12894       errmsg ("locator-set name too long\n");
12895       vec_free (locator_set_name);
12896       return -99;
12897     }
12898   vec_add1 (locator_set_name, 0);
12899
12900   /* Construct the API message */
12901   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12902
12903   mp->is_add = is_add;
12904   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12905   mp->eid_type = eid->type;
12906   mp->prefix_len = eid->len;
12907   mp->vni = clib_host_to_net_u32 (vni);
12908   clib_memcpy (mp->locator_set_name, locator_set_name,
12909                vec_len (locator_set_name));
12910
12911   vec_free (locator_set_name);
12912
12913   /* send it... */
12914   S;
12915
12916   /* Wait for a reply... */
12917   W;
12918
12919   /* NOTREACHED */
12920   return 0;
12921 }
12922
12923 /* *INDENT-OFF* */
12924 /** Used for transferring locators via VPP API */
12925 typedef CLIB_PACKED(struct
12926 {
12927   u8 is_ip4; /**< is locator an IPv4 address? */
12928   u8 priority; /**< locator priority */
12929   u8 weight;   /**< locator weight */
12930   u8 addr[16]; /**< IPv4/IPv6 address */
12931 }) rloc_t;
12932 /* *INDENT-ON* */
12933
12934 static int
12935 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12936 {
12937   unformat_input_t *input = vam->input;
12938   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12939   f64 timeout = ~0;
12940   u8 is_add = 1;
12941   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12942   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12943   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12944   u32 action = ~0, p, w;
12945   ip4_address_t rmt_rloc4, lcl_rloc4;
12946   ip6_address_t rmt_rloc6, lcl_rloc6;
12947   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12948
12949   memset (&rloc, 0, sizeof (rloc));
12950
12951   /* Parse args required to build the message */
12952   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12953     {
12954       if (unformat (input, "del"))
12955         {
12956           is_add = 0;
12957         }
12958       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12959         {
12960           rmt_eid_set = 1;
12961         }
12962       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12963         {
12964           lcl_eid_set = 1;
12965         }
12966       else if (unformat (input, "p %d w %d", &p, &w))
12967         {
12968           if (!curr_rloc)
12969             {
12970               errmsg ("No RLOC configured for setting priority/weight!");
12971               return -99;
12972             }
12973           curr_rloc->priority = p;
12974           curr_rloc->weight = w;
12975         }
12976       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12977                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12978         {
12979           rloc.is_ip4 = 1;
12980
12981           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12982           rloc.priority = rloc.weight = 0;
12983           vec_add1 (lcl_locs, rloc);
12984
12985           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12986           vec_add1 (rmt_locs, rloc);
12987           /* priority and weight saved in rmt loc */
12988           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12989         }
12990       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12991                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12992         {
12993           rloc.is_ip4 = 0;
12994           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12995           rloc.priority = rloc.weight = 0;
12996           vec_add1 (lcl_locs, rloc);
12997
12998           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12999           vec_add1 (rmt_locs, rloc);
13000           /* priority and weight saved in rmt loc */
13001           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13002         }
13003       else if (unformat (input, "action %d", &action))
13004         {
13005           ;
13006         }
13007       else
13008         {
13009           clib_warning ("parse error '%U'", format_unformat_error, input);
13010           return -99;
13011         }
13012     }
13013
13014   if (!rmt_eid_set)
13015     {
13016       errmsg ("remote eid addresses not set\n");
13017       return -99;
13018     }
13019
13020   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13021     {
13022       errmsg ("eid types don't match\n");
13023       return -99;
13024     }
13025
13026   if (0 == rmt_locs && (u32) ~ 0 == action)
13027     {
13028       errmsg ("action not set for negative mapping\n");
13029       return -99;
13030     }
13031
13032   /* Construct the API message */
13033   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13034
13035   mp->is_add = is_add;
13036   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13037   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13038   mp->eid_type = rmt_eid->type;
13039   mp->rmt_len = rmt_eid->len;
13040   mp->lcl_len = lcl_eid->len;
13041   mp->action = action;
13042
13043   if (0 != rmt_locs && 0 != lcl_locs)
13044     {
13045       mp->loc_num = vec_len (rmt_locs);
13046       clib_memcpy (mp->lcl_locs, lcl_locs,
13047                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13048       clib_memcpy (mp->rmt_locs, rmt_locs,
13049                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13050     }
13051   vec_free (lcl_locs);
13052   vec_free (rmt_locs);
13053
13054   /* send it... */
13055   S;
13056
13057   /* Wait for a reply... */
13058   W;
13059
13060   /* NOTREACHED */
13061   return 0;
13062 }
13063
13064 static int
13065 api_lisp_add_del_map_resolver (vat_main_t * vam)
13066 {
13067   unformat_input_t *input = vam->input;
13068   vl_api_lisp_add_del_map_resolver_t *mp;
13069   f64 timeout = ~0;
13070   u8 is_add = 1;
13071   u8 ipv4_set = 0;
13072   u8 ipv6_set = 0;
13073   ip4_address_t ipv4;
13074   ip6_address_t ipv6;
13075
13076   /* Parse args required to build the message */
13077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13078     {
13079       if (unformat (input, "del"))
13080         {
13081           is_add = 0;
13082         }
13083       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13084         {
13085           ipv4_set = 1;
13086         }
13087       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13088         {
13089           ipv6_set = 1;
13090         }
13091       else
13092         break;
13093     }
13094
13095   if (ipv4_set && ipv6_set)
13096     {
13097       errmsg ("both eid v4 and v6 addresses set\n");
13098       return -99;
13099     }
13100
13101   if (!ipv4_set && !ipv6_set)
13102     {
13103       errmsg ("eid addresses not set\n");
13104       return -99;
13105     }
13106
13107   /* Construct the API message */
13108   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13109
13110   mp->is_add = is_add;
13111   if (ipv6_set)
13112     {
13113       mp->is_ipv6 = 1;
13114       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13115     }
13116   else
13117     {
13118       mp->is_ipv6 = 0;
13119       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13120     }
13121
13122   /* send it... */
13123   S;
13124
13125   /* Wait for a reply... */
13126   W;
13127
13128   /* NOTREACHED */
13129   return 0;
13130 }
13131
13132 static int
13133 api_lisp_gpe_enable_disable (vat_main_t * vam)
13134 {
13135   unformat_input_t *input = vam->input;
13136   vl_api_lisp_gpe_enable_disable_t *mp;
13137   f64 timeout = ~0;
13138   u8 is_set = 0;
13139   u8 is_en = 1;
13140
13141   /* Parse args required to build the message */
13142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13143     {
13144       if (unformat (input, "enable"))
13145         {
13146           is_set = 1;
13147           is_en = 1;
13148         }
13149       else if (unformat (input, "disable"))
13150         {
13151           is_set = 1;
13152           is_en = 0;
13153         }
13154       else
13155         break;
13156     }
13157
13158   if (is_set == 0)
13159     {
13160       errmsg ("Value not set\n");
13161       return -99;
13162     }
13163
13164   /* Construct the API message */
13165   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13166
13167   mp->is_en = is_en;
13168
13169   /* send it... */
13170   S;
13171
13172   /* Wait for a reply... */
13173   W;
13174
13175   /* NOTREACHED */
13176   return 0;
13177 }
13178
13179 static int
13180 api_lisp_enable_disable (vat_main_t * vam)
13181 {
13182   unformat_input_t *input = vam->input;
13183   vl_api_lisp_enable_disable_t *mp;
13184   f64 timeout = ~0;
13185   u8 is_set = 0;
13186   u8 is_en = 0;
13187
13188   /* Parse args required to build the message */
13189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13190     {
13191       if (unformat (input, "enable"))
13192         {
13193           is_set = 1;
13194           is_en = 1;
13195         }
13196       else if (unformat (input, "disable"))
13197         {
13198           is_set = 1;
13199         }
13200       else
13201         break;
13202     }
13203
13204   if (!is_set)
13205     {
13206       errmsg ("Value not set\n");
13207       return -99;
13208     }
13209
13210   /* Construct the API message */
13211   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13212
13213   mp->is_en = is_en;
13214
13215   /* send it... */
13216   S;
13217
13218   /* Wait for a reply... */
13219   W;
13220
13221   /* NOTREACHED */
13222   return 0;
13223 }
13224
13225 static int
13226 api_show_lisp_map_request_mode (vat_main_t * vam)
13227 {
13228   f64 timeout = ~0;
13229   vl_api_show_lisp_map_request_mode_t *mp;
13230
13231   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13232
13233   /* send */
13234   S;
13235
13236   /* wait for reply */
13237   W;
13238
13239   return 0;
13240 }
13241
13242 static int
13243 api_lisp_map_request_mode (vat_main_t * vam)
13244 {
13245   f64 timeout = ~0;
13246   unformat_input_t *input = vam->input;
13247   vl_api_lisp_map_request_mode_t *mp;
13248   u8 mode = 0;
13249
13250   /* Parse args required to build the message */
13251   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13252     {
13253       if (unformat (input, "dst-only"))
13254         mode = 0;
13255       else if (unformat (input, "src-dst"))
13256         mode = 1;
13257       else
13258         {
13259           errmsg ("parse error '%U'", format_unformat_error, input);
13260           return -99;
13261         }
13262     }
13263
13264   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13265
13266   mp->mode = mode;
13267
13268   /* send */
13269   S;
13270
13271   /* wait for reply */
13272   W;
13273
13274   /* notreached */
13275   return 0;
13276 }
13277
13278 /**
13279  * Enable/disable LISP proxy ITR.
13280  *
13281  * @param vam vpp API test context
13282  * @return return code
13283  */
13284 static int
13285 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13286 {
13287   f64 timeout = ~0;
13288   u8 ls_name_set = 0;
13289   unformat_input_t *input = vam->input;
13290   vl_api_lisp_pitr_set_locator_set_t *mp;
13291   u8 is_add = 1;
13292   u8 *ls_name = 0;
13293
13294   /* Parse args required to build the message */
13295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13296     {
13297       if (unformat (input, "del"))
13298         is_add = 0;
13299       else if (unformat (input, "locator-set %s", &ls_name))
13300         ls_name_set = 1;
13301       else
13302         {
13303           errmsg ("parse error '%U'", format_unformat_error, input);
13304           return -99;
13305         }
13306     }
13307
13308   if (!ls_name_set)
13309     {
13310       errmsg ("locator-set name not set!");
13311       return -99;
13312     }
13313
13314   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13315
13316   mp->is_add = is_add;
13317   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13318   vec_free (ls_name);
13319
13320   /* send */
13321   S;
13322
13323   /* wait for reply */
13324   W;
13325
13326   /* notreached */
13327   return 0;
13328 }
13329
13330 static int
13331 api_show_lisp_pitr (vat_main_t * vam)
13332 {
13333   vl_api_show_lisp_pitr_t *mp;
13334   f64 timeout = ~0;
13335
13336   if (!vam->json_output)
13337     {
13338       fformat (vam->ofp, "%=20s\n", "lisp status:");
13339     }
13340
13341   M (SHOW_LISP_PITR, show_lisp_pitr);
13342   /* send it... */
13343   S;
13344
13345   /* Wait for a reply... */
13346   W;
13347
13348   /* NOTREACHED */
13349   return 0;
13350 }
13351
13352 /**
13353  * Add/delete mapping between vni and vrf
13354  */
13355 static int
13356 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13357 {
13358   f64 timeout = ~0;
13359   unformat_input_t *input = vam->input;
13360   vl_api_lisp_eid_table_add_del_map_t *mp;
13361   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13362   u32 vni, vrf, bd_index;
13363
13364   /* Parse args required to build the message */
13365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13366     {
13367       if (unformat (input, "del"))
13368         is_add = 0;
13369       else if (unformat (input, "vrf %d", &vrf))
13370         vrf_set = 1;
13371       else if (unformat (input, "bd_index %d", &bd_index))
13372         bd_index_set = 1;
13373       else if (unformat (input, "vni %d", &vni))
13374         vni_set = 1;
13375       else
13376         break;
13377     }
13378
13379   if (!vni_set || (!vrf_set && !bd_index_set))
13380     {
13381       errmsg ("missing arguments!");
13382       return -99;
13383     }
13384
13385   if (vrf_set && bd_index_set)
13386     {
13387       errmsg ("error: both vrf and bd entered!");
13388       return -99;
13389     }
13390
13391   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13392
13393   mp->is_add = is_add;
13394   mp->vni = htonl (vni);
13395   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13396   mp->is_l2 = bd_index_set;
13397
13398   /* send */
13399   S;
13400
13401   /* wait for reply */
13402   W;
13403
13404   /* notreached */
13405   return 0;
13406 }
13407
13408 uword
13409 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13410 {
13411   u32 *action = va_arg (*args, u32 *);
13412   u8 *s = 0;
13413
13414   if (unformat (input, "%s", &s))
13415     {
13416       if (!strcmp ((char *) s, "no-action"))
13417         action[0] = 0;
13418       else if (!strcmp ((char *) s, "natively-forward"))
13419         action[0] = 1;
13420       else if (!strcmp ((char *) s, "send-map-request"))
13421         action[0] = 2;
13422       else if (!strcmp ((char *) s, "drop"))
13423         action[0] = 3;
13424       else
13425         {
13426           clib_warning ("invalid action: '%s'", s);
13427           action[0] = 3;
13428         }
13429     }
13430   else
13431     return 0;
13432
13433   vec_free (s);
13434   return 1;
13435 }
13436
13437 /**
13438  * Add/del remote mapping to/from LISP control plane
13439  *
13440  * @param vam vpp API test context
13441  * @return return code
13442  */
13443 static int
13444 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13445 {
13446   unformat_input_t *input = vam->input;
13447   vl_api_lisp_add_del_remote_mapping_t *mp;
13448   f64 timeout = ~0;
13449   u32 vni = 0;
13450   lisp_eid_vat_t _eid, *eid = &_eid;
13451   lisp_eid_vat_t _seid, *seid = &_seid;
13452   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13453   u32 action = ~0, p, w, data_len;
13454   ip4_address_t rloc4;
13455   ip6_address_t rloc6;
13456   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13457
13458   memset (&rloc, 0, sizeof (rloc));
13459
13460   /* Parse args required to build the message */
13461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13462     {
13463       if (unformat (input, "del-all"))
13464         {
13465           del_all = 1;
13466         }
13467       else if (unformat (input, "del"))
13468         {
13469           is_add = 0;
13470         }
13471       else if (unformat (input, "add"))
13472         {
13473           is_add = 1;
13474         }
13475       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13476         {
13477           eid_set = 1;
13478         }
13479       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13480         {
13481           seid_set = 1;
13482         }
13483       else if (unformat (input, "vni %d", &vni))
13484         {
13485           ;
13486         }
13487       else if (unformat (input, "p %d w %d", &p, &w))
13488         {
13489           if (!curr_rloc)
13490             {
13491               errmsg ("No RLOC configured for setting priority/weight!");
13492               return -99;
13493             }
13494           curr_rloc->priority = p;
13495           curr_rloc->weight = w;
13496         }
13497       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13498         {
13499           rloc.is_ip4 = 1;
13500           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13501           vec_add1 (rlocs, rloc);
13502           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13503         }
13504       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13505         {
13506           rloc.is_ip4 = 0;
13507           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13508           vec_add1 (rlocs, rloc);
13509           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13510         }
13511       else if (unformat (input, "action %U",
13512                          unformat_negative_mapping_action, &action))
13513         {
13514           ;
13515         }
13516       else
13517         {
13518           clib_warning ("parse error '%U'", format_unformat_error, input);
13519           return -99;
13520         }
13521     }
13522
13523   if (0 == eid_set)
13524     {
13525       errmsg ("missing params!");
13526       return -99;
13527     }
13528
13529   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13530     {
13531       errmsg ("no action set for negative map-reply!");
13532       return -99;
13533     }
13534
13535   data_len = vec_len (rlocs) * sizeof (rloc_t);
13536
13537   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13538   mp->is_add = is_add;
13539   mp->vni = htonl (vni);
13540   mp->action = (u8) action;
13541   mp->is_src_dst = seid_set;
13542   mp->eid_len = eid->len;
13543   mp->seid_len = seid->len;
13544   mp->del_all = del_all;
13545   mp->eid_type = eid->type;
13546   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13547   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13548
13549   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13550   clib_memcpy (mp->rlocs, rlocs, data_len);
13551   vec_free (rlocs);
13552
13553   /* send it... */
13554   S;
13555
13556   /* Wait for a reply... */
13557   W;
13558
13559   /* NOTREACHED */
13560   return 0;
13561 }
13562
13563 /**
13564  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13565  * forwarding entries in data-plane accordingly.
13566  *
13567  * @param vam vpp API test context
13568  * @return return code
13569  */
13570 static int
13571 api_lisp_add_del_adjacency (vat_main_t * vam)
13572 {
13573   unformat_input_t *input = vam->input;
13574   vl_api_lisp_add_del_adjacency_t *mp;
13575   f64 timeout = ~0;
13576   u32 vni = 0;
13577   ip4_address_t leid4, reid4;
13578   ip6_address_t leid6, reid6;
13579   u8 reid_mac[6] = { 0 };
13580   u8 leid_mac[6] = { 0 };
13581   u8 reid_type, leid_type;
13582   u32 leid_len = 0, reid_len = 0, len;
13583   u8 is_add = 1;
13584
13585   leid_type = reid_type = (u8) ~ 0;
13586
13587   /* Parse args required to build the message */
13588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13589     {
13590       if (unformat (input, "del"))
13591         {
13592           is_add = 0;
13593         }
13594       else if (unformat (input, "add"))
13595         {
13596           is_add = 1;
13597         }
13598       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13599                          &reid4, &len))
13600         {
13601           reid_type = 0;        /* ipv4 */
13602           reid_len = len;
13603         }
13604       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13605                          &reid6, &len))
13606         {
13607           reid_type = 1;        /* ipv6 */
13608           reid_len = len;
13609         }
13610       else if (unformat (input, "reid %U", unformat_ethernet_address,
13611                          reid_mac))
13612         {
13613           reid_type = 2;        /* mac */
13614         }
13615       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13616                          &leid4, &len))
13617         {
13618           leid_type = 0;        /* ipv4 */
13619           leid_len = len;
13620         }
13621       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13622                          &leid6, &len))
13623         {
13624           leid_type = 1;        /* ipv6 */
13625           leid_len = len;
13626         }
13627       else if (unformat (input, "leid %U", unformat_ethernet_address,
13628                          leid_mac))
13629         {
13630           leid_type = 2;        /* mac */
13631         }
13632       else if (unformat (input, "vni %d", &vni))
13633         {
13634           ;
13635         }
13636       else
13637         {
13638           errmsg ("parse error '%U'", format_unformat_error, input);
13639           return -99;
13640         }
13641     }
13642
13643   if ((u8) ~ 0 == reid_type)
13644     {
13645       errmsg ("missing params!");
13646       return -99;
13647     }
13648
13649   if (leid_type != reid_type)
13650     {
13651       errmsg ("remote and local EIDs are of different types!");
13652       return -99;
13653     }
13654
13655   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13656   mp->is_add = is_add;
13657   mp->vni = htonl (vni);
13658   mp->leid_len = leid_len;
13659   mp->reid_len = reid_len;
13660   mp->eid_type = reid_type;
13661
13662   switch (mp->eid_type)
13663     {
13664     case 0:
13665       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13666       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13667       break;
13668     case 1:
13669       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13670       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13671       break;
13672     case 2:
13673       clib_memcpy (mp->leid, leid_mac, 6);
13674       clib_memcpy (mp->reid, reid_mac, 6);
13675       break;
13676     default:
13677       errmsg ("unknown EID type %d!", mp->eid_type);
13678       return 0;
13679     }
13680
13681   /* send it... */
13682   S;
13683
13684   /* Wait for a reply... */
13685   W;
13686
13687   /* NOTREACHED */
13688   return 0;
13689 }
13690
13691 static int
13692 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13693 {
13694   unformat_input_t *input = vam->input;
13695   vl_api_lisp_gpe_add_del_iface_t *mp;
13696   f64 timeout = ~0;
13697   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13698   u32 dp_table = 0, vni = 0;
13699
13700   /* Parse args required to build the message */
13701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13702     {
13703       if (unformat (input, "up"))
13704         {
13705           action_set = 1;
13706           is_add = 1;
13707         }
13708       else if (unformat (input, "down"))
13709         {
13710           action_set = 1;
13711           is_add = 0;
13712         }
13713       else if (unformat (input, "table_id %d", &dp_table))
13714         {
13715           dp_table_set = 1;
13716         }
13717       else if (unformat (input, "bd_id %d", &dp_table))
13718         {
13719           dp_table_set = 1;
13720           is_l2 = 1;
13721         }
13722       else if (unformat (input, "vni %d", &vni))
13723         {
13724           vni_set = 1;
13725         }
13726       else
13727         break;
13728     }
13729
13730   if (action_set == 0)
13731     {
13732       errmsg ("Action not set\n");
13733       return -99;
13734     }
13735   if (dp_table_set == 0 || vni_set == 0)
13736     {
13737       errmsg ("vni and dp_table must be set\n");
13738       return -99;
13739     }
13740
13741   /* Construct the API message */
13742   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13743
13744   mp->is_add = is_add;
13745   mp->dp_table = dp_table;
13746   mp->is_l2 = is_l2;
13747   mp->vni = vni;
13748
13749   /* send it... */
13750   S;
13751
13752   /* Wait for a reply... */
13753   W;
13754
13755   /* NOTREACHED */
13756   return 0;
13757 }
13758
13759 /**
13760  * Add/del map request itr rlocs from LISP control plane and updates
13761  *
13762  * @param vam vpp API test context
13763  * @return return code
13764  */
13765 static int
13766 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13767 {
13768   unformat_input_t *input = vam->input;
13769   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13770   f64 timeout = ~0;
13771   u8 *locator_set_name = 0;
13772   u8 locator_set_name_set = 0;
13773   u8 is_add = 1;
13774
13775   /* Parse args required to build the message */
13776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13777     {
13778       if (unformat (input, "del"))
13779         {
13780           is_add = 0;
13781         }
13782       else if (unformat (input, "%_%v%_", &locator_set_name))
13783         {
13784           locator_set_name_set = 1;
13785         }
13786       else
13787         {
13788           clib_warning ("parse error '%U'", format_unformat_error, input);
13789           return -99;
13790         }
13791     }
13792
13793   if (is_add && !locator_set_name_set)
13794     {
13795       errmsg ("itr-rloc is not set!");
13796       return -99;
13797     }
13798
13799   if (is_add && vec_len (locator_set_name) > 64)
13800     {
13801       errmsg ("itr-rloc locator-set name too long\n");
13802       vec_free (locator_set_name);
13803       return -99;
13804     }
13805
13806   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13807   mp->is_add = is_add;
13808   if (is_add)
13809     {
13810       clib_memcpy (mp->locator_set_name, locator_set_name,
13811                    vec_len (locator_set_name));
13812     }
13813   else
13814     {
13815       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13816     }
13817   vec_free (locator_set_name);
13818
13819   /* send it... */
13820   S;
13821
13822   /* Wait for a reply... */
13823   W;
13824
13825   /* NOTREACHED */
13826   return 0;
13827 }
13828
13829 static int
13830 api_lisp_locator_dump (vat_main_t * vam)
13831 {
13832   unformat_input_t *input = vam->input;
13833   vl_api_lisp_locator_dump_t *mp;
13834   f64 timeout = ~0;
13835   u8 is_index_set = 0, is_name_set = 0;
13836   u8 *ls_name = 0;
13837   u32 ls_index = ~0;
13838
13839   /* Parse args required to build the message */
13840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13841     {
13842       if (unformat (input, "ls_name %_%v%_", &ls_name))
13843         {
13844           is_name_set = 1;
13845         }
13846       else if (unformat (input, "ls_index %d", &ls_index))
13847         {
13848           is_index_set = 1;
13849         }
13850       else
13851         {
13852           errmsg ("parse error '%U'", format_unformat_error, input);
13853           return -99;
13854         }
13855     }
13856
13857   if (!is_index_set && !is_name_set)
13858     {
13859       errmsg ("error: expected one of index or name!\n");
13860       return -99;
13861     }
13862
13863   if (is_index_set && is_name_set)
13864     {
13865       errmsg ("error: only one param expected!\n");
13866       return -99;
13867     }
13868
13869   if (vec_len (ls_name) > 62)
13870     {
13871       errmsg ("error: locator set name too long!");
13872       return -99;
13873     }
13874
13875   if (!vam->json_output)
13876     {
13877       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13878                "weight");
13879     }
13880
13881   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13882   mp->is_index_set = is_index_set;
13883
13884   if (is_index_set)
13885     mp->ls_index = clib_host_to_net_u32 (ls_index);
13886   else
13887     {
13888       vec_add1 (ls_name, 0);
13889       strncpy ((char *) mp->ls_name, (char *) ls_name,
13890                sizeof (mp->ls_name) - 1);
13891     }
13892
13893   /* send it... */
13894   S;
13895
13896   /* Use a control ping for synchronization */
13897   {
13898     vl_api_control_ping_t *mp;
13899     M (CONTROL_PING, control_ping);
13900     S;
13901   }
13902   /* Wait for a reply... */
13903   W;
13904
13905   /* NOTREACHED */
13906   return 0;
13907 }
13908
13909 static int
13910 api_lisp_locator_set_dump (vat_main_t * vam)
13911 {
13912   vl_api_lisp_locator_set_dump_t *mp;
13913   unformat_input_t *input = vam->input;
13914   f64 timeout = ~0;
13915   u8 filter = 0;
13916
13917   /* Parse args required to build the message */
13918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13919     {
13920       if (unformat (input, "local"))
13921         {
13922           filter = 1;
13923         }
13924       else if (unformat (input, "remote"))
13925         {
13926           filter = 2;
13927         }
13928       else
13929         {
13930           errmsg ("parse error '%U'", format_unformat_error, input);
13931           return -99;
13932         }
13933     }
13934
13935   if (!vam->json_output)
13936     {
13937       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13938     }
13939
13940   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13941
13942   mp->filter = filter;
13943
13944   /* send it... */
13945   S;
13946
13947   /* Use a control ping for synchronization */
13948   {
13949     vl_api_control_ping_t *mp;
13950     M (CONTROL_PING, control_ping);
13951     S;
13952   }
13953   /* Wait for a reply... */
13954   W;
13955
13956   /* NOTREACHED */
13957   return 0;
13958 }
13959
13960 static int
13961 api_lisp_eid_table_map_dump (vat_main_t * vam)
13962 {
13963   u8 is_l2 = 0;
13964   u8 mode_set = 0;
13965   unformat_input_t *input = vam->input;
13966   vl_api_lisp_eid_table_map_dump_t *mp;
13967   f64 timeout = ~0;
13968
13969   /* Parse args required to build the message */
13970   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13971     {
13972       if (unformat (input, "l2"))
13973         {
13974           is_l2 = 1;
13975           mode_set = 1;
13976         }
13977       else if (unformat (input, "l3"))
13978         {
13979           is_l2 = 0;
13980           mode_set = 1;
13981         }
13982       else
13983         {
13984           errmsg ("parse error '%U'", format_unformat_error, input);
13985           return -99;
13986         }
13987     }
13988
13989   if (!mode_set)
13990     {
13991       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13992       return -99;
13993     }
13994
13995   if (!vam->json_output)
13996     {
13997       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13998     }
13999
14000   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14001   mp->is_l2 = is_l2;
14002
14003   /* send it... */
14004   S;
14005
14006   /* Use a control ping for synchronization */
14007   {
14008     vl_api_control_ping_t *mp;
14009     M (CONTROL_PING, control_ping);
14010     S;
14011   }
14012   /* Wait for a reply... */
14013   W;
14014
14015   /* NOTREACHED */
14016   return 0;
14017 }
14018
14019 static int
14020 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14021 {
14022   vl_api_lisp_eid_table_vni_dump_t *mp;
14023   f64 timeout = ~0;
14024
14025   if (!vam->json_output)
14026     {
14027       fformat (vam->ofp, "VNI\n");
14028     }
14029
14030   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14031
14032   /* send it... */
14033   S;
14034
14035   /* Use a control ping for synchronization */
14036   {
14037     vl_api_control_ping_t *mp;
14038     M (CONTROL_PING, control_ping);
14039     S;
14040   }
14041   /* Wait for a reply... */
14042   W;
14043
14044   /* NOTREACHED */
14045   return 0;
14046 }
14047
14048 static int
14049 api_lisp_eid_table_dump (vat_main_t * vam)
14050 {
14051   unformat_input_t *i = vam->input;
14052   vl_api_lisp_eid_table_dump_t *mp;
14053   f64 timeout = ~0;
14054   struct in_addr ip4;
14055   struct in6_addr ip6;
14056   u8 mac[6];
14057   u8 eid_type = ~0, eid_set = 0;
14058   u32 prefix_length = ~0, t, vni = 0;
14059   u8 filter = 0;
14060
14061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14062     {
14063       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14064         {
14065           eid_set = 1;
14066           eid_type = 0;
14067           prefix_length = t;
14068         }
14069       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14070         {
14071           eid_set = 1;
14072           eid_type = 1;
14073           prefix_length = t;
14074         }
14075       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14076         {
14077           eid_set = 1;
14078           eid_type = 2;
14079         }
14080       else if (unformat (i, "vni %d", &t))
14081         {
14082           vni = t;
14083         }
14084       else if (unformat (i, "local"))
14085         {
14086           filter = 1;
14087         }
14088       else if (unformat (i, "remote"))
14089         {
14090           filter = 2;
14091         }
14092       else
14093         {
14094           errmsg ("parse error '%U'", format_unformat_error, i);
14095           return -99;
14096         }
14097     }
14098
14099   if (!vam->json_output)
14100     {
14101       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14102                "ls_index", "ttl", "authoritative");
14103     }
14104
14105   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14106
14107   mp->filter = filter;
14108   if (eid_set)
14109     {
14110       mp->eid_set = 1;
14111       mp->vni = htonl (vni);
14112       mp->eid_type = eid_type;
14113       switch (eid_type)
14114         {
14115         case 0:
14116           mp->prefix_length = prefix_length;
14117           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14118           break;
14119         case 1:
14120           mp->prefix_length = prefix_length;
14121           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14122           break;
14123         case 2:
14124           clib_memcpy (mp->eid, mac, sizeof (mac));
14125           break;
14126         default:
14127           errmsg ("unknown EID type %d!", eid_type);
14128           return -99;
14129         }
14130     }
14131
14132   /* send it... */
14133   S;
14134
14135   /* Use a control ping for synchronization */
14136   {
14137     vl_api_control_ping_t *mp;
14138     M (CONTROL_PING, control_ping);
14139     S;
14140   }
14141
14142   /* Wait for a reply... */
14143   W;
14144
14145   /* NOTREACHED */
14146   return 0;
14147 }
14148
14149 static int
14150 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14151 {
14152   vl_api_lisp_gpe_tunnel_dump_t *mp;
14153   f64 timeout = ~0;
14154
14155   if (!vam->json_output)
14156     {
14157       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14158                "%=16s%=16s%=16s%=16s%=16s\n",
14159                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14160                "Decap next", "Lisp version", "Flags", "Next protocol",
14161                "ver_res", "res", "iid");
14162     }
14163
14164   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14165   /* send it... */
14166   S;
14167
14168   /* Use a control ping for synchronization */
14169   {
14170     vl_api_control_ping_t *mp;
14171     M (CONTROL_PING, control_ping);
14172     S;
14173   }
14174   /* Wait for a reply... */
14175   W;
14176
14177   /* NOTREACHED */
14178   return 0;
14179 }
14180
14181 static int
14182 api_lisp_adjacencies_get (vat_main_t * vam)
14183 {
14184   unformat_input_t *i = vam->input;
14185   vl_api_lisp_adjacencies_get_t *mp;
14186   f64 timeout = ~0;
14187   u8 vni_set = 0;
14188   u32 vni = ~0;
14189
14190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14191     {
14192       if (unformat (i, "vni %d", &vni))
14193         {
14194           vni_set = 1;
14195         }
14196       else
14197         {
14198           errmsg ("parse error '%U'\n", format_unformat_error, i);
14199           return -99;
14200         }
14201     }
14202
14203   if (!vni_set)
14204     {
14205       errmsg ("vni not set!\n");
14206       return -99;
14207     }
14208
14209   if (!vam->json_output)
14210     {
14211       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14212     }
14213
14214   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14215   mp->vni = clib_host_to_net_u32 (vni);
14216
14217   /* send it... */
14218   S;
14219
14220   /* Wait for a reply... */
14221   W;
14222
14223   /* NOTREACHED */
14224   return 0;
14225 }
14226
14227 static int
14228 api_lisp_map_resolver_dump (vat_main_t * vam)
14229 {
14230   vl_api_lisp_map_resolver_dump_t *mp;
14231   f64 timeout = ~0;
14232
14233   if (!vam->json_output)
14234     {
14235       fformat (vam->ofp, "%=20s\n", "Map resolver");
14236     }
14237
14238   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14239   /* send it... */
14240   S;
14241
14242   /* Use a control ping for synchronization */
14243   {
14244     vl_api_control_ping_t *mp;
14245     M (CONTROL_PING, control_ping);
14246     S;
14247   }
14248   /* Wait for a reply... */
14249   W;
14250
14251   /* NOTREACHED */
14252   return 0;
14253 }
14254
14255 static int
14256 api_show_lisp_status (vat_main_t * vam)
14257 {
14258   vl_api_show_lisp_status_t *mp;
14259   f64 timeout = ~0;
14260
14261   if (!vam->json_output)
14262     {
14263       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14264     }
14265
14266   M (SHOW_LISP_STATUS, show_lisp_status);
14267   /* send it... */
14268   S;
14269   /* Wait for a reply... */
14270   W;
14271
14272   /* NOTREACHED */
14273   return 0;
14274 }
14275
14276 static int
14277 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14278 {
14279   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14280   f64 timeout = ~0;
14281
14282   if (!vam->json_output)
14283     {
14284       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14285     }
14286
14287   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14288   /* send it... */
14289   S;
14290   /* Wait for a reply... */
14291   W;
14292
14293   /* NOTREACHED */
14294   return 0;
14295 }
14296
14297 static int
14298 api_af_packet_create (vat_main_t * vam)
14299 {
14300   unformat_input_t *i = vam->input;
14301   vl_api_af_packet_create_t *mp;
14302   f64 timeout;
14303   u8 *host_if_name = 0;
14304   u8 hw_addr[6];
14305   u8 random_hw_addr = 1;
14306
14307   memset (hw_addr, 0, sizeof (hw_addr));
14308
14309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14310     {
14311       if (unformat (i, "name %s", &host_if_name))
14312         vec_add1 (host_if_name, 0);
14313       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14314         random_hw_addr = 0;
14315       else
14316         break;
14317     }
14318
14319   if (!vec_len (host_if_name))
14320     {
14321       errmsg ("host-interface name must be specified");
14322       return -99;
14323     }
14324
14325   if (vec_len (host_if_name) > 64)
14326     {
14327       errmsg ("host-interface name too long");
14328       return -99;
14329     }
14330
14331   M (AF_PACKET_CREATE, af_packet_create);
14332
14333   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14334   clib_memcpy (mp->hw_addr, hw_addr, 6);
14335   mp->use_random_hw_addr = random_hw_addr;
14336   vec_free (host_if_name);
14337
14338   S;
14339   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14340   /* NOTREACHED */
14341   return 0;
14342 }
14343
14344 static int
14345 api_af_packet_delete (vat_main_t * vam)
14346 {
14347   unformat_input_t *i = vam->input;
14348   vl_api_af_packet_delete_t *mp;
14349   f64 timeout;
14350   u8 *host_if_name = 0;
14351
14352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14353     {
14354       if (unformat (i, "name %s", &host_if_name))
14355         vec_add1 (host_if_name, 0);
14356       else
14357         break;
14358     }
14359
14360   if (!vec_len (host_if_name))
14361     {
14362       errmsg ("host-interface name must be specified");
14363       return -99;
14364     }
14365
14366   if (vec_len (host_if_name) > 64)
14367     {
14368       errmsg ("host-interface name too long");
14369       return -99;
14370     }
14371
14372   M (AF_PACKET_DELETE, af_packet_delete);
14373
14374   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14375   vec_free (host_if_name);
14376
14377   S;
14378   W;
14379   /* NOTREACHED */
14380   return 0;
14381 }
14382
14383 static int
14384 api_policer_add_del (vat_main_t * vam)
14385 {
14386   unformat_input_t *i = vam->input;
14387   vl_api_policer_add_del_t *mp;
14388   f64 timeout;
14389   u8 is_add = 1;
14390   u8 *name = 0;
14391   u32 cir = 0;
14392   u32 eir = 0;
14393   u64 cb = 0;
14394   u64 eb = 0;
14395   u8 rate_type = 0;
14396   u8 round_type = 0;
14397   u8 type = 0;
14398   u8 color_aware = 0;
14399   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14400
14401   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14402   conform_action.dscp = 0;
14403   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14404   exceed_action.dscp = 0;
14405   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14406   violate_action.dscp = 0;
14407
14408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14409     {
14410       if (unformat (i, "del"))
14411         is_add = 0;
14412       else if (unformat (i, "name %s", &name))
14413         vec_add1 (name, 0);
14414       else if (unformat (i, "cir %u", &cir))
14415         ;
14416       else if (unformat (i, "eir %u", &eir))
14417         ;
14418       else if (unformat (i, "cb %u", &cb))
14419         ;
14420       else if (unformat (i, "eb %u", &eb))
14421         ;
14422       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14423                          &rate_type))
14424         ;
14425       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14426                          &round_type))
14427         ;
14428       else if (unformat (i, "type %U", unformat_policer_type, &type))
14429         ;
14430       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14431                          &conform_action))
14432         ;
14433       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14434                          &exceed_action))
14435         ;
14436       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14437                          &violate_action))
14438         ;
14439       else if (unformat (i, "color-aware"))
14440         color_aware = 1;
14441       else
14442         break;
14443     }
14444
14445   if (!vec_len (name))
14446     {
14447       errmsg ("policer name must be specified");
14448       return -99;
14449     }
14450
14451   if (vec_len (name) > 64)
14452     {
14453       errmsg ("policer name too long");
14454       return -99;
14455     }
14456
14457   M (POLICER_ADD_DEL, policer_add_del);
14458
14459   clib_memcpy (mp->name, name, vec_len (name));
14460   vec_free (name);
14461   mp->is_add = is_add;
14462   mp->cir = cir;
14463   mp->eir = eir;
14464   mp->cb = cb;
14465   mp->eb = eb;
14466   mp->rate_type = rate_type;
14467   mp->round_type = round_type;
14468   mp->type = type;
14469   mp->conform_action_type = conform_action.action_type;
14470   mp->conform_dscp = conform_action.dscp;
14471   mp->exceed_action_type = exceed_action.action_type;
14472   mp->exceed_dscp = exceed_action.dscp;
14473   mp->violate_action_type = violate_action.action_type;
14474   mp->violate_dscp = violate_action.dscp;
14475   mp->color_aware = color_aware;
14476
14477   S;
14478   W;
14479   /* NOTREACHED */
14480   return 0;
14481 }
14482
14483 static int
14484 api_policer_dump (vat_main_t * vam)
14485 {
14486   unformat_input_t *i = vam->input;
14487   vl_api_policer_dump_t *mp;
14488   f64 timeout = ~0;
14489   u8 *match_name = 0;
14490   u8 match_name_valid = 0;
14491
14492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14493     {
14494       if (unformat (i, "name %s", &match_name))
14495         {
14496           vec_add1 (match_name, 0);
14497           match_name_valid = 1;
14498         }
14499       else
14500         break;
14501     }
14502
14503   M (POLICER_DUMP, policer_dump);
14504   mp->match_name_valid = match_name_valid;
14505   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14506   vec_free (match_name);
14507   /* send it... */
14508   S;
14509
14510   /* Use a control ping for synchronization */
14511   {
14512     vl_api_control_ping_t *mp;
14513     M (CONTROL_PING, control_ping);
14514     S;
14515   }
14516   /* Wait for a reply... */
14517   W;
14518
14519   /* NOTREACHED */
14520   return 0;
14521 }
14522
14523 static int
14524 api_policer_classify_set_interface (vat_main_t * vam)
14525 {
14526   unformat_input_t *i = vam->input;
14527   vl_api_policer_classify_set_interface_t *mp;
14528   f64 timeout;
14529   u32 sw_if_index;
14530   int sw_if_index_set;
14531   u32 ip4_table_index = ~0;
14532   u32 ip6_table_index = ~0;
14533   u32 l2_table_index = ~0;
14534   u8 is_add = 1;
14535
14536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14537     {
14538       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14539         sw_if_index_set = 1;
14540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14541         sw_if_index_set = 1;
14542       else if (unformat (i, "del"))
14543         is_add = 0;
14544       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14545         ;
14546       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14547         ;
14548       else if (unformat (i, "l2-table %d", &l2_table_index))
14549         ;
14550       else
14551         {
14552           clib_warning ("parse error '%U'", format_unformat_error, i);
14553           return -99;
14554         }
14555     }
14556
14557   if (sw_if_index_set == 0)
14558     {
14559       errmsg ("missing interface name or sw_if_index\n");
14560       return -99;
14561     }
14562
14563   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14564
14565   mp->sw_if_index = ntohl (sw_if_index);
14566   mp->ip4_table_index = ntohl (ip4_table_index);
14567   mp->ip6_table_index = ntohl (ip6_table_index);
14568   mp->l2_table_index = ntohl (l2_table_index);
14569   mp->is_add = is_add;
14570
14571   S;
14572   W;
14573   /* NOTREACHED */
14574   return 0;
14575 }
14576
14577 static int
14578 api_policer_classify_dump (vat_main_t * vam)
14579 {
14580   unformat_input_t *i = vam->input;
14581   vl_api_policer_classify_dump_t *mp;
14582   f64 timeout = ~0;
14583   u8 type = POLICER_CLASSIFY_N_TABLES;
14584
14585   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14586     ;
14587   else
14588     {
14589       errmsg ("classify table type must be specified\n");
14590       return -99;
14591     }
14592
14593   if (!vam->json_output)
14594     {
14595       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14596     }
14597
14598   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14599   mp->type = type;
14600   /* send it... */
14601   S;
14602
14603   /* Use a control ping for synchronization */
14604   {
14605     vl_api_control_ping_t *mp;
14606     M (CONTROL_PING, control_ping);
14607     S;
14608   }
14609   /* Wait for a reply... */
14610   W;
14611
14612   /* NOTREACHED */
14613   return 0;
14614 }
14615
14616 static int
14617 api_netmap_create (vat_main_t * vam)
14618 {
14619   unformat_input_t *i = vam->input;
14620   vl_api_netmap_create_t *mp;
14621   f64 timeout;
14622   u8 *if_name = 0;
14623   u8 hw_addr[6];
14624   u8 random_hw_addr = 1;
14625   u8 is_pipe = 0;
14626   u8 is_master = 0;
14627
14628   memset (hw_addr, 0, sizeof (hw_addr));
14629
14630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14631     {
14632       if (unformat (i, "name %s", &if_name))
14633         vec_add1 (if_name, 0);
14634       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14635         random_hw_addr = 0;
14636       else if (unformat (i, "pipe"))
14637         is_pipe = 1;
14638       else if (unformat (i, "master"))
14639         is_master = 1;
14640       else if (unformat (i, "slave"))
14641         is_master = 0;
14642       else
14643         break;
14644     }
14645
14646   if (!vec_len (if_name))
14647     {
14648       errmsg ("interface name must be specified");
14649       return -99;
14650     }
14651
14652   if (vec_len (if_name) > 64)
14653     {
14654       errmsg ("interface name too long");
14655       return -99;
14656     }
14657
14658   M (NETMAP_CREATE, netmap_create);
14659
14660   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14661   clib_memcpy (mp->hw_addr, hw_addr, 6);
14662   mp->use_random_hw_addr = random_hw_addr;
14663   mp->is_pipe = is_pipe;
14664   mp->is_master = is_master;
14665   vec_free (if_name);
14666
14667   S;
14668   W;
14669   /* NOTREACHED */
14670   return 0;
14671 }
14672
14673 static int
14674 api_netmap_delete (vat_main_t * vam)
14675 {
14676   unformat_input_t *i = vam->input;
14677   vl_api_netmap_delete_t *mp;
14678   f64 timeout;
14679   u8 *if_name = 0;
14680
14681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14682     {
14683       if (unformat (i, "name %s", &if_name))
14684         vec_add1 (if_name, 0);
14685       else
14686         break;
14687     }
14688
14689   if (!vec_len (if_name))
14690     {
14691       errmsg ("interface name must be specified");
14692       return -99;
14693     }
14694
14695   if (vec_len (if_name) > 64)
14696     {
14697       errmsg ("interface name too long");
14698       return -99;
14699     }
14700
14701   M (NETMAP_DELETE, netmap_delete);
14702
14703   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14704   vec_free (if_name);
14705
14706   S;
14707   W;
14708   /* NOTREACHED */
14709   return 0;
14710 }
14711
14712 static void vl_api_mpls_eth_tunnel_details_t_handler
14713   (vl_api_mpls_eth_tunnel_details_t * mp)
14714 {
14715   vat_main_t *vam = &vat_main;
14716   i32 i;
14717   i32 len = ntohl (mp->nlabels);
14718
14719   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14720            ntohl (mp->tunnel_index),
14721            format_ethernet_address, &mp->tunnel_dst_mac,
14722            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14723   for (i = 0; i < len; i++)
14724     {
14725       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14726     }
14727   fformat (vam->ofp, "\n");
14728   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14729            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14730 }
14731
14732 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14733   (vl_api_mpls_eth_tunnel_details_t * mp)
14734 {
14735   vat_main_t *vam = &vat_main;
14736   vat_json_node_t *node = NULL;
14737   struct in_addr ip4;
14738   i32 i;
14739   i32 len = ntohl (mp->nlabels);
14740
14741   if (VAT_JSON_ARRAY != vam->json_tree.type)
14742     {
14743       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14744       vat_json_init_array (&vam->json_tree);
14745     }
14746   node = vat_json_array_add (&vam->json_tree);
14747
14748   vat_json_init_object (node);
14749   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14750   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14751   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14752   vat_json_object_add_uint (node, "inner_fib_index",
14753                             ntohl (mp->inner_fib_index));
14754   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14755   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14756   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14757   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14758   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14759                                    format (0, "%U", format_ethernet_address,
14760                                            &mp->tunnel_dst_mac));
14761   vat_json_object_add_uint (node, "tx_sw_if_index",
14762                             ntohl (mp->tx_sw_if_index));
14763   vat_json_object_add_uint (node, "label_count", len);
14764   for (i = 0; i < len; i++)
14765     {
14766       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14767     }
14768 }
14769
14770 static int
14771 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14772 {
14773   vl_api_mpls_eth_tunnel_dump_t *mp;
14774   f64 timeout;
14775   i32 index = -1;
14776
14777   /* Parse args required to build the message */
14778   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14779     {
14780       if (!unformat (vam->input, "tunnel_index %d", &index))
14781         {
14782           index = -1;
14783           break;
14784         }
14785     }
14786
14787   fformat (vam->ofp, "  tunnel_index %d\n", index);
14788
14789   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14790   mp->tunnel_index = htonl (index);
14791   S;
14792
14793   /* Use a control ping for synchronization */
14794   {
14795     vl_api_control_ping_t *mp;
14796     M (CONTROL_PING, control_ping);
14797     S;
14798   }
14799   W;
14800 }
14801
14802 static void vl_api_mpls_fib_encap_details_t_handler
14803   (vl_api_mpls_fib_encap_details_t * mp)
14804 {
14805   vat_main_t *vam = &vat_main;
14806   i32 i;
14807   i32 len = ntohl (mp->nlabels);
14808
14809   fformat (vam->ofp, "table %d, dest %U, label ",
14810            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14811   for (i = 0; i < len; i++)
14812     {
14813       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14814     }
14815   fformat (vam->ofp, "\n");
14816 }
14817
14818 static void vl_api_mpls_fib_encap_details_t_handler_json
14819   (vl_api_mpls_fib_encap_details_t * mp)
14820 {
14821   vat_main_t *vam = &vat_main;
14822   vat_json_node_t *node = NULL;
14823   i32 i;
14824   i32 len = ntohl (mp->nlabels);
14825   struct in_addr ip4;
14826
14827   if (VAT_JSON_ARRAY != vam->json_tree.type)
14828     {
14829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14830       vat_json_init_array (&vam->json_tree);
14831     }
14832   node = vat_json_array_add (&vam->json_tree);
14833
14834   vat_json_init_object (node);
14835   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14836   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14837   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14838   vat_json_object_add_ip4 (node, "dest", ip4);
14839   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14840   vat_json_object_add_uint (node, "label_count", len);
14841   for (i = 0; i < len; i++)
14842     {
14843       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14844     }
14845 }
14846
14847 static int
14848 api_mpls_fib_encap_dump (vat_main_t * vam)
14849 {
14850   vl_api_mpls_fib_encap_dump_t *mp;
14851   f64 timeout;
14852
14853   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14854   S;
14855
14856   /* Use a control ping for synchronization */
14857   {
14858     vl_api_control_ping_t *mp;
14859     M (CONTROL_PING, control_ping);
14860     S;
14861   }
14862   W;
14863 }
14864
14865 static void
14866 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14867 {
14868   vat_main_t *vam = &vat_main;
14869
14870   fformat (vam->ofp,
14871            "table-id %d, label %u, ess_bit %u\n",
14872            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14873 }
14874
14875 static void vl_api_mpls_fib_details_t_handler_json
14876   (vl_api_mpls_fib_details_t * mp)
14877 {
14878   vat_main_t *vam = &vat_main;
14879   vat_json_node_t *node = NULL;
14880
14881   if (VAT_JSON_ARRAY != vam->json_tree.type)
14882     {
14883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14884       vat_json_init_array (&vam->json_tree);
14885     }
14886   node = vat_json_array_add (&vam->json_tree);
14887
14888   vat_json_init_object (node);
14889   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14890   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14891   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14892 }
14893
14894 static int
14895 api_mpls_fib_dump (vat_main_t * vam)
14896 {
14897   vl_api_mpls_fib_dump_t *mp;
14898   f64 timeout;
14899
14900   M (MPLS_FIB_DUMP, mpls_fib_dump);
14901   S;
14902
14903   /* Use a control ping for synchronization */
14904   {
14905     vl_api_control_ping_t *mp;
14906     M (CONTROL_PING, control_ping);
14907     S;
14908   }
14909   W;
14910 }
14911
14912 int
14913 api_classify_table_ids (vat_main_t * vam)
14914 {
14915   vl_api_classify_table_ids_t *mp;
14916   f64 timeout;
14917
14918   /* Construct the API message */
14919   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14920   mp->context = 0;
14921
14922   S;
14923   W;
14924   /* NOTREACHED */
14925   return 0;
14926 }
14927
14928 int
14929 api_classify_table_by_interface (vat_main_t * vam)
14930 {
14931   unformat_input_t *input = vam->input;
14932   vl_api_classify_table_by_interface_t *mp;
14933   f64 timeout;
14934
14935   u32 sw_if_index = ~0;
14936   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14937     {
14938       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14939         ;
14940       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14941         ;
14942       else
14943         break;
14944     }
14945   if (sw_if_index == ~0)
14946     {
14947       errmsg ("missing interface name or sw_if_index\n");
14948       return -99;
14949     }
14950
14951   /* Construct the API message */
14952   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14953   mp->context = 0;
14954   mp->sw_if_index = ntohl (sw_if_index);
14955
14956   S;
14957   W;
14958   /* NOTREACHED */
14959   return 0;
14960 }
14961
14962 int
14963 api_classify_table_info (vat_main_t * vam)
14964 {
14965   unformat_input_t *input = vam->input;
14966   vl_api_classify_table_info_t *mp;
14967   f64 timeout;
14968
14969   u32 table_id = ~0;
14970   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14971     {
14972       if (unformat (input, "table_id %d", &table_id))
14973         ;
14974       else
14975         break;
14976     }
14977   if (table_id == ~0)
14978     {
14979       errmsg ("missing table id\n");
14980       return -99;
14981     }
14982
14983   /* Construct the API message */
14984   M (CLASSIFY_TABLE_INFO, classify_table_info);
14985   mp->context = 0;
14986   mp->table_id = ntohl (table_id);
14987
14988   S;
14989   W;
14990   /* NOTREACHED */
14991   return 0;
14992 }
14993
14994 int
14995 api_classify_session_dump (vat_main_t * vam)
14996 {
14997   unformat_input_t *input = vam->input;
14998   vl_api_classify_session_dump_t *mp;
14999   f64 timeout;
15000
15001   u32 table_id = ~0;
15002   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15003     {
15004       if (unformat (input, "table_id %d", &table_id))
15005         ;
15006       else
15007         break;
15008     }
15009   if (table_id == ~0)
15010     {
15011       errmsg ("missing table id\n");
15012       return -99;
15013     }
15014
15015   /* Construct the API message */
15016   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15017   mp->context = 0;
15018   mp->table_id = ntohl (table_id);
15019   S;
15020
15021   /* Use a control ping for synchronization */
15022   {
15023     vl_api_control_ping_t *mp;
15024     M (CONTROL_PING, control_ping);
15025     S;
15026   }
15027   W;
15028   /* NOTREACHED */
15029   return 0;
15030 }
15031
15032 static void
15033 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15034 {
15035   vat_main_t *vam = &vat_main;
15036
15037   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15038            "src_address %U, vrf_id %d, path_mtu %u, "
15039            "template_interval %u, udp_checksum %d\n",
15040            format_ip4_address, mp->collector_address,
15041            ntohs (mp->collector_port),
15042            format_ip4_address, mp->src_address,
15043            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15044            ntohl (mp->template_interval), mp->udp_checksum);
15045
15046   vam->retval = 0;
15047   vam->result_ready = 1;
15048 }
15049
15050 static void
15051   vl_api_ipfix_exporter_details_t_handler_json
15052   (vl_api_ipfix_exporter_details_t * mp)
15053 {
15054   vat_main_t *vam = &vat_main;
15055   vat_json_node_t node;
15056   struct in_addr collector_address;
15057   struct in_addr src_address;
15058
15059   vat_json_init_object (&node);
15060   clib_memcpy (&collector_address, &mp->collector_address,
15061                sizeof (collector_address));
15062   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15063   vat_json_object_add_uint (&node, "collector_port",
15064                             ntohs (mp->collector_port));
15065   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15066   vat_json_object_add_ip4 (&node, "src_address", src_address);
15067   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15068   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15069   vat_json_object_add_uint (&node, "template_interval",
15070                             ntohl (mp->template_interval));
15071   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15072
15073   vat_json_print (vam->ofp, &node);
15074   vat_json_free (&node);
15075   vam->retval = 0;
15076   vam->result_ready = 1;
15077 }
15078
15079 int
15080 api_ipfix_exporter_dump (vat_main_t * vam)
15081 {
15082   vl_api_ipfix_exporter_dump_t *mp;
15083   f64 timeout;
15084
15085   /* Construct the API message */
15086   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15087   mp->context = 0;
15088
15089   S;
15090   W;
15091   /* NOTREACHED */
15092   return 0;
15093 }
15094
15095 static int
15096 api_ipfix_classify_stream_dump (vat_main_t * vam)
15097 {
15098   vl_api_ipfix_classify_stream_dump_t *mp;
15099   f64 timeout;
15100
15101   /* Construct the API message */
15102   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15103   mp->context = 0;
15104
15105   S;
15106   W;
15107   /* NOTREACHED */
15108   return 0;
15109 }
15110
15111 static void
15112   vl_api_ipfix_classify_stream_details_t_handler
15113   (vl_api_ipfix_classify_stream_details_t * mp)
15114 {
15115   vat_main_t *vam = &vat_main;
15116   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15117            ntohl (mp->domain_id), ntohs (mp->src_port));
15118   vam->retval = 0;
15119   vam->result_ready = 1;
15120 }
15121
15122 static void
15123   vl_api_ipfix_classify_stream_details_t_handler_json
15124   (vl_api_ipfix_classify_stream_details_t * mp)
15125 {
15126   vat_main_t *vam = &vat_main;
15127   vat_json_node_t node;
15128
15129   vat_json_init_object (&node);
15130   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15131   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15132
15133   vat_json_print (vam->ofp, &node);
15134   vat_json_free (&node);
15135   vam->retval = 0;
15136   vam->result_ready = 1;
15137 }
15138
15139 static int
15140 api_ipfix_classify_table_dump (vat_main_t * vam)
15141 {
15142   vl_api_ipfix_classify_table_dump_t *mp;
15143   f64 timeout;
15144
15145   if (!vam->json_output)
15146     {
15147       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15148                "transport_protocol");
15149     }
15150
15151   /* Construct the API message */
15152   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15153
15154   /* send it... */
15155   S;
15156
15157   /* Use a control ping for synchronization */
15158   {
15159     vl_api_control_ping_t *mp;
15160     M (CONTROL_PING, control_ping);
15161     S;
15162   }
15163   W;
15164 }
15165
15166 static void
15167   vl_api_ipfix_classify_table_details_t_handler
15168   (vl_api_ipfix_classify_table_details_t * mp)
15169 {
15170   vat_main_t *vam = &vat_main;
15171   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15172            mp->transport_protocol);
15173 }
15174
15175 static void
15176   vl_api_ipfix_classify_table_details_t_handler_json
15177   (vl_api_ipfix_classify_table_details_t * mp)
15178 {
15179   vat_json_node_t *node = NULL;
15180   vat_main_t *vam = &vat_main;
15181
15182   if (VAT_JSON_ARRAY != vam->json_tree.type)
15183     {
15184       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15185       vat_json_init_array (&vam->json_tree);
15186     }
15187
15188   node = vat_json_array_add (&vam->json_tree);
15189   vat_json_init_object (node);
15190
15191   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15192   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15193   vat_json_object_add_uint (node, "transport_protocol",
15194                             mp->transport_protocol);
15195 }
15196
15197 int
15198 api_pg_create_interface (vat_main_t * vam)
15199 {
15200   unformat_input_t *input = vam->input;
15201   vl_api_pg_create_interface_t *mp;
15202   f64 timeout;
15203
15204   u32 if_id = ~0;
15205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15206     {
15207       if (unformat (input, "if_id %d", &if_id))
15208         ;
15209       else
15210         break;
15211     }
15212   if (if_id == ~0)
15213     {
15214       errmsg ("missing pg interface index\n");
15215       return -99;
15216     }
15217
15218   /* Construct the API message */
15219   M (PG_CREATE_INTERFACE, pg_create_interface);
15220   mp->context = 0;
15221   mp->interface_id = ntohl (if_id);
15222
15223   S;
15224   W;
15225   /* NOTREACHED */
15226   return 0;
15227 }
15228
15229 int
15230 api_pg_capture (vat_main_t * vam)
15231 {
15232   unformat_input_t *input = vam->input;
15233   vl_api_pg_capture_t *mp;
15234   f64 timeout;
15235
15236   u32 if_id = ~0;
15237   u8 enable = 1;
15238   u32 count = 1;
15239   u8 pcap_file_set = 0;
15240   u8 *pcap_file = 0;
15241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15242     {
15243       if (unformat (input, "if_id %d", &if_id))
15244         ;
15245       else if (unformat (input, "pcap %s", &pcap_file))
15246         pcap_file_set = 1;
15247       else if (unformat (input, "count %d", &count))
15248         ;
15249       else if (unformat (input, "disable"))
15250         enable = 0;
15251       else
15252         break;
15253     }
15254   if (if_id == ~0)
15255     {
15256       errmsg ("missing pg interface index\n");
15257       return -99;
15258     }
15259   if (pcap_file_set > 0)
15260     {
15261       if (vec_len (pcap_file) > 255)
15262         {
15263           errmsg ("pcap file name is too long\n");
15264           return -99;
15265         }
15266     }
15267
15268   u32 name_len = vec_len (pcap_file);
15269   /* Construct the API message */
15270   M (PG_CAPTURE, pg_capture);
15271   mp->context = 0;
15272   mp->interface_id = ntohl (if_id);
15273   mp->is_enabled = enable;
15274   mp->count = ntohl (count);
15275   mp->pcap_name_length = ntohl (name_len);
15276   if (pcap_file_set != 0)
15277     {
15278       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15279     }
15280   vec_free (pcap_file);
15281
15282   S;
15283   W;
15284   /* NOTREACHED */
15285   return 0;
15286 }
15287
15288 int
15289 api_pg_enable_disable (vat_main_t * vam)
15290 {
15291   unformat_input_t *input = vam->input;
15292   vl_api_pg_enable_disable_t *mp;
15293   f64 timeout;
15294
15295   u8 enable = 1;
15296   u8 stream_name_set = 0;
15297   u8 *stream_name = 0;
15298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15299     {
15300       if (unformat (input, "stream %s", &stream_name))
15301         stream_name_set = 1;
15302       else if (unformat (input, "disable"))
15303         enable = 0;
15304       else
15305         break;
15306     }
15307
15308   if (stream_name_set > 0)
15309     {
15310       if (vec_len (stream_name) > 255)
15311         {
15312           errmsg ("stream name too long\n");
15313           return -99;
15314         }
15315     }
15316
15317   u32 name_len = vec_len (stream_name);
15318   /* Construct the API message */
15319   M (PG_ENABLE_DISABLE, pg_enable_disable);
15320   mp->context = 0;
15321   mp->is_enabled = enable;
15322   if (stream_name_set != 0)
15323     {
15324       mp->stream_name_length = ntohl (name_len);
15325       clib_memcpy (mp->stream_name, stream_name, name_len);
15326     }
15327   vec_free (stream_name);
15328
15329   S;
15330   W;
15331   /* NOTREACHED */
15332   return 0;
15333 }
15334
15335 int
15336 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15337 {
15338   unformat_input_t *input = vam->input;
15339   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15340   f64 timeout;
15341
15342   u16 *low_ports = 0;
15343   u16 *high_ports = 0;
15344   u16 this_low;
15345   u16 this_hi;
15346   ip4_address_t ip4_addr;
15347   ip6_address_t ip6_addr;
15348   u32 length;
15349   u32 tmp, tmp2;
15350   u8 prefix_set = 0;
15351   u32 vrf_id = ~0;
15352   u8 is_add = 1;
15353   u8 is_ipv6 = 0;
15354
15355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15356     {
15357       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15358         {
15359           prefix_set = 1;
15360         }
15361       else
15362         if (unformat
15363             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15364         {
15365           prefix_set = 1;
15366           is_ipv6 = 1;
15367         }
15368       else if (unformat (input, "vrf %d", &vrf_id))
15369         ;
15370       else if (unformat (input, "del"))
15371         is_add = 0;
15372       else if (unformat (input, "port %d", &tmp))
15373         {
15374           if (tmp == 0 || tmp > 65535)
15375             {
15376               errmsg ("port %d out of range", tmp);
15377               return -99;
15378             }
15379           this_low = tmp;
15380           this_hi = this_low + 1;
15381           vec_add1 (low_ports, this_low);
15382           vec_add1 (high_ports, this_hi);
15383         }
15384       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15385         {
15386           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15387             {
15388               errmsg ("incorrect range parameters\n");
15389               return -99;
15390             }
15391           this_low = tmp;
15392           /* Note: in debug CLI +1 is added to high before
15393              passing to real fn that does "the work"
15394              (ip_source_and_port_range_check_add_del).
15395              This fn is a wrapper around the binary API fn a
15396              control plane will call, which expects this increment
15397              to have occurred. Hence letting the binary API control
15398              plane fn do the increment for consistency between VAT
15399              and other control planes.
15400            */
15401           this_hi = tmp2;
15402           vec_add1 (low_ports, this_low);
15403           vec_add1 (high_ports, this_hi);
15404         }
15405       else
15406         break;
15407     }
15408
15409   if (prefix_set == 0)
15410     {
15411       errmsg ("<address>/<mask> not specified\n");
15412       return -99;
15413     }
15414
15415   if (vrf_id == ~0)
15416     {
15417       errmsg ("VRF ID required, not specified\n");
15418       return -99;
15419     }
15420
15421   if (vrf_id == 0)
15422     {
15423       errmsg
15424         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15425       return -99;
15426     }
15427
15428   if (vec_len (low_ports) == 0)
15429     {
15430       errmsg ("At least one port or port range required\n");
15431       return -99;
15432     }
15433
15434   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15435      ip_source_and_port_range_check_add_del);
15436
15437   mp->is_add = is_add;
15438
15439   if (is_ipv6)
15440     {
15441       mp->is_ipv6 = 1;
15442       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15443     }
15444   else
15445     {
15446       mp->is_ipv6 = 0;
15447       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15448     }
15449
15450   mp->mask_length = length;
15451   mp->number_of_ranges = vec_len (low_ports);
15452
15453   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15454   vec_free (low_ports);
15455
15456   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15457   vec_free (high_ports);
15458
15459   mp->vrf_id = ntohl (vrf_id);
15460
15461   S;
15462   W;
15463   /* NOTREACHED */
15464   return 0;
15465 }
15466
15467 int
15468 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15469 {
15470   unformat_input_t *input = vam->input;
15471   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15472   f64 timeout;
15473   u32 sw_if_index = ~0;
15474   int vrf_set = 0;
15475   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15476   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15477   u8 is_add = 1;
15478
15479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15480     {
15481       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15482         ;
15483       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15484         ;
15485       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15486         vrf_set = 1;
15487       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15488         vrf_set = 1;
15489       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15490         vrf_set = 1;
15491       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15492         vrf_set = 1;
15493       else if (unformat (input, "del"))
15494         is_add = 0;
15495       else
15496         break;
15497     }
15498
15499   if (sw_if_index == ~0)
15500     {
15501       errmsg ("Interface required but not specified\n");
15502       return -99;
15503     }
15504
15505   if (vrf_set == 0)
15506     {
15507       errmsg ("VRF ID required but not specified\n");
15508       return -99;
15509     }
15510
15511   if (tcp_out_vrf_id == 0
15512       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15513     {
15514       errmsg
15515         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15516       return -99;
15517     }
15518
15519   /* Construct the API message */
15520   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15521      ip_source_and_port_range_check_interface_add_del);
15522
15523   mp->sw_if_index = ntohl (sw_if_index);
15524   mp->is_add = is_add;
15525   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15526   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15527   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15528   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15529
15530   /* send it... */
15531   S;
15532
15533   /* Wait for a reply... */
15534   W;
15535 }
15536
15537 static int
15538 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15539 {
15540   unformat_input_t *i = vam->input;
15541   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15542   f64 timeout;
15543   u32 local_sa_id = 0;
15544   u32 remote_sa_id = 0;
15545   ip4_address_t src_address;
15546   ip4_address_t dst_address;
15547   u8 is_add = 1;
15548
15549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15550     {
15551       if (unformat (i, "local_sa %d", &local_sa_id))
15552         ;
15553       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15554         ;
15555       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15556         ;
15557       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15558         ;
15559       else if (unformat (i, "del"))
15560         is_add = 0;
15561       else
15562         {
15563           clib_warning ("parse error '%U'", format_unformat_error, i);
15564           return -99;
15565         }
15566     }
15567
15568   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15569
15570   mp->local_sa_id = ntohl (local_sa_id);
15571   mp->remote_sa_id = ntohl (remote_sa_id);
15572   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15573   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15574   mp->is_add = is_add;
15575
15576   S;
15577   W;
15578   /* NOTREACHED */
15579   return 0;
15580 }
15581
15582 static int
15583 api_punt (vat_main_t * vam)
15584 {
15585   unformat_input_t *i = vam->input;
15586   vl_api_punt_t *mp;
15587   f64 timeout;
15588   u32 ipv = ~0;
15589   u32 protocol = ~0;
15590   u32 port = ~0;
15591   int is_add = 1;
15592
15593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15594     {
15595       if (unformat (i, "ip %d", &ipv))
15596         ;
15597       else if (unformat (i, "protocol %d", &protocol))
15598         ;
15599       else if (unformat (i, "port %d", &port))
15600         ;
15601       else if (unformat (i, "del"))
15602         is_add = 0;
15603       else
15604         {
15605           clib_warning ("parse error '%U'", format_unformat_error, i);
15606           return -99;
15607         }
15608     }
15609
15610   M (PUNT, punt);
15611
15612   mp->is_add = (u8) is_add;
15613   mp->ipv = (u8) ipv;
15614   mp->l4_protocol = (u8) protocol;
15615   mp->l4_port = htons ((u16) port);
15616
15617   S;
15618   W;
15619   /* NOTREACHED */
15620   return 0;
15621 }
15622
15623 static void vl_api_ipsec_gre_tunnel_details_t_handler
15624   (vl_api_ipsec_gre_tunnel_details_t * mp)
15625 {
15626   vat_main_t *vam = &vat_main;
15627
15628   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15629            ntohl (mp->sw_if_index),
15630            format_ip4_address, &mp->src_address,
15631            format_ip4_address, &mp->dst_address,
15632            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15633 }
15634
15635 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15636   (vl_api_ipsec_gre_tunnel_details_t * mp)
15637 {
15638   vat_main_t *vam = &vat_main;
15639   vat_json_node_t *node = NULL;
15640   struct in_addr ip4;
15641
15642   if (VAT_JSON_ARRAY != vam->json_tree.type)
15643     {
15644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15645       vat_json_init_array (&vam->json_tree);
15646     }
15647   node = vat_json_array_add (&vam->json_tree);
15648
15649   vat_json_init_object (node);
15650   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15651   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15652   vat_json_object_add_ip4 (node, "src_address", ip4);
15653   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15654   vat_json_object_add_ip4 (node, "dst_address", ip4);
15655   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15656   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15657 }
15658
15659 static int
15660 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15661 {
15662   unformat_input_t *i = vam->input;
15663   vl_api_ipsec_gre_tunnel_dump_t *mp;
15664   f64 timeout;
15665   u32 sw_if_index;
15666   u8 sw_if_index_set = 0;
15667
15668   /* Parse args required to build the message */
15669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15670     {
15671       if (unformat (i, "sw_if_index %d", &sw_if_index))
15672         sw_if_index_set = 1;
15673       else
15674         break;
15675     }
15676
15677   if (sw_if_index_set == 0)
15678     {
15679       sw_if_index = ~0;
15680     }
15681
15682   if (!vam->json_output)
15683     {
15684       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15685                "sw_if_index", "src_address", "dst_address",
15686                "local_sa_id", "remote_sa_id");
15687     }
15688
15689   /* Get list of gre-tunnel interfaces */
15690   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15691
15692   mp->sw_if_index = htonl (sw_if_index);
15693
15694   S;
15695
15696   /* Use a control ping for synchronization */
15697   {
15698     vl_api_control_ping_t *mp;
15699     M (CONTROL_PING, control_ping);
15700     S;
15701   }
15702   W;
15703 }
15704
15705 static int
15706 api_delete_subif (vat_main_t * vam)
15707 {
15708   unformat_input_t *i = vam->input;
15709   vl_api_delete_subif_t *mp;
15710   f64 timeout;
15711   u32 sw_if_index = ~0;
15712
15713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15714     {
15715       if (unformat (i, "sw_if_index %d", &sw_if_index))
15716         ;
15717       else
15718         break;
15719     }
15720
15721   if (sw_if_index == ~0)
15722     {
15723       errmsg ("missing sw_if_index\n");
15724       return -99;
15725     }
15726
15727   /* Construct the API message */
15728   M (DELETE_SUBIF, delete_subif);
15729   mp->sw_if_index = ntohl (sw_if_index);
15730
15731   S;
15732   W;
15733 }
15734
15735 #define foreach_pbb_vtr_op      \
15736 _("disable",  L2_VTR_DISABLED)  \
15737 _("pop",  L2_VTR_POP_2)         \
15738 _("push",  L2_VTR_PUSH_2)
15739
15740 static int
15741 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15742 {
15743   unformat_input_t *i = vam->input;
15744   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15745   f64 timeout;
15746   u32 sw_if_index = ~0, vtr_op = ~0;
15747   u16 outer_tag = ~0;
15748   u8 dmac[6], smac[6];
15749   u8 dmac_set = 0, smac_set = 0;
15750   u16 vlanid = 0;
15751   u32 sid = ~0;
15752   u32 tmp;
15753
15754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15755     {
15756       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15757         ;
15758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15759         ;
15760       else if (unformat (i, "vtr_op %d", &vtr_op))
15761         ;
15762 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15763       foreach_pbb_vtr_op
15764 #undef _
15765         else if (unformat (i, "translate_pbb_stag"))
15766         {
15767           if (unformat (i, "%d", &tmp))
15768             {
15769               vtr_op = L2_VTR_TRANSLATE_2_1;
15770               outer_tag = tmp;
15771             }
15772           else
15773             {
15774               errmsg
15775                 ("translate_pbb_stag operation requires outer tag definition\n");
15776               return -99;
15777             }
15778         }
15779       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15780         dmac_set++;
15781       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15782         smac_set++;
15783       else if (unformat (i, "sid %d", &sid))
15784         ;
15785       else if (unformat (i, "vlanid %d", &tmp))
15786         vlanid = tmp;
15787       else
15788         {
15789           clib_warning ("parse error '%U'", format_unformat_error, i);
15790           return -99;
15791         }
15792     }
15793
15794   if ((sw_if_index == ~0) || (vtr_op == ~0))
15795     {
15796       errmsg ("missing sw_if_index or vtr operation\n");
15797       return -99;
15798     }
15799   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15800       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15801     {
15802       errmsg
15803         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15804       return -99;
15805     }
15806
15807   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15808   mp->sw_if_index = ntohl (sw_if_index);
15809   mp->vtr_op = ntohl (vtr_op);
15810   mp->outer_tag = ntohs (outer_tag);
15811   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15812   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15813   mp->b_vlanid = ntohs (vlanid);
15814   mp->i_sid = ntohl (sid);
15815
15816   S;
15817   W;
15818   /* NOTREACHED */
15819   return 0;
15820 }
15821
15822 static int
15823 api_flow_classify_set_interface (vat_main_t * vam)
15824 {
15825   unformat_input_t *i = vam->input;
15826   vl_api_flow_classify_set_interface_t *mp;
15827   f64 timeout;
15828   u32 sw_if_index;
15829   int sw_if_index_set;
15830   u32 ip4_table_index = ~0;
15831   u32 ip6_table_index = ~0;
15832   u8 is_add = 1;
15833
15834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15835     {
15836       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15837         sw_if_index_set = 1;
15838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15839         sw_if_index_set = 1;
15840       else if (unformat (i, "del"))
15841         is_add = 0;
15842       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15843         ;
15844       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15845         ;
15846       else
15847         {
15848           clib_warning ("parse error '%U'", format_unformat_error, i);
15849           return -99;
15850         }
15851     }
15852
15853   if (sw_if_index_set == 0)
15854     {
15855       errmsg ("missing interface name or sw_if_index\n");
15856       return -99;
15857     }
15858
15859   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
15860
15861   mp->sw_if_index = ntohl (sw_if_index);
15862   mp->ip4_table_index = ntohl (ip4_table_index);
15863   mp->ip6_table_index = ntohl (ip6_table_index);
15864   mp->is_add = is_add;
15865
15866   S;
15867   W;
15868   /* NOTREACHED */
15869   return 0;
15870 }
15871
15872 static int
15873 api_flow_classify_dump (vat_main_t * vam)
15874 {
15875   unformat_input_t *i = vam->input;
15876   vl_api_flow_classify_dump_t *mp;
15877   f64 timeout = ~0;
15878   u8 type = FLOW_CLASSIFY_N_TABLES;
15879
15880   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
15881     ;
15882   else
15883     {
15884       errmsg ("classify table type must be specified\n");
15885       return -99;
15886     }
15887
15888   if (!vam->json_output)
15889     {
15890       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15891     }
15892
15893   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
15894   mp->type = type;
15895   /* send it... */
15896   S;
15897
15898   /* Use a control ping for synchronization */
15899   {
15900     vl_api_control_ping_t *mp;
15901     M (CONTROL_PING, control_ping);
15902     S;
15903   }
15904   /* Wait for a reply... */
15905   W;
15906
15907   /* NOTREACHED */
15908   return 0;
15909 }
15910
15911 static int
15912 q_or_quit (vat_main_t * vam)
15913 {
15914   longjmp (vam->jump_buf, 1);
15915   return 0;                     /* not so much */
15916 }
15917
15918 static int
15919 q (vat_main_t * vam)
15920 {
15921   return q_or_quit (vam);
15922 }
15923
15924 static int
15925 quit (vat_main_t * vam)
15926 {
15927   return q_or_quit (vam);
15928 }
15929
15930 static int
15931 comment (vat_main_t * vam)
15932 {
15933   return 0;
15934 }
15935
15936 static int
15937 cmd_cmp (void *a1, void *a2)
15938 {
15939   u8 **c1 = a1;
15940   u8 **c2 = a2;
15941
15942   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15943 }
15944
15945 static int
15946 help (vat_main_t * vam)
15947 {
15948   u8 **cmds = 0;
15949   u8 *name = 0;
15950   hash_pair_t *p;
15951   unformat_input_t *i = vam->input;
15952   int j;
15953
15954   if (unformat (i, "%s", &name))
15955     {
15956       uword *hs;
15957
15958       vec_add1 (name, 0);
15959
15960       hs = hash_get_mem (vam->help_by_name, name);
15961       if (hs)
15962         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15963       else
15964         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15965       vec_free (name);
15966       return 0;
15967     }
15968
15969   fformat (vam->ofp, "Help is available for the following:\n");
15970
15971     /* *INDENT-OFF* */
15972     hash_foreach_pair (p, vam->function_by_name,
15973     ({
15974       vec_add1 (cmds, (u8 *)(p->key));
15975     }));
15976     /* *INDENT-ON* */
15977
15978   vec_sort_with_function (cmds, cmd_cmp);
15979
15980   for (j = 0; j < vec_len (cmds); j++)
15981     fformat (vam->ofp, "%s\n", cmds[j]);
15982
15983   vec_free (cmds);
15984   return 0;
15985 }
15986
15987 static int
15988 set (vat_main_t * vam)
15989 {
15990   u8 *name = 0, *value = 0;
15991   unformat_input_t *i = vam->input;
15992
15993   if (unformat (i, "%s", &name))
15994     {
15995       /* The input buffer is a vector, not a string. */
15996       value = vec_dup (i->buffer);
15997       vec_delete (value, i->index, 0);
15998       /* Almost certainly has a trailing newline */
15999       if (value[vec_len (value) - 1] == '\n')
16000         value[vec_len (value) - 1] = 0;
16001       /* Make sure it's a proper string, one way or the other */
16002       vec_add1 (value, 0);
16003       (void) clib_macro_set_value (&vam->macro_main,
16004                                    (char *) name, (char *) value);
16005     }
16006   else
16007     errmsg ("usage: set <name> <value>\n");
16008
16009   vec_free (name);
16010   vec_free (value);
16011   return 0;
16012 }
16013
16014 static int
16015 unset (vat_main_t * vam)
16016 {
16017   u8 *name = 0;
16018
16019   if (unformat (vam->input, "%s", &name))
16020     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16021       errmsg ("unset: %s wasn't set\n", name);
16022   vec_free (name);
16023   return 0;
16024 }
16025
16026 typedef struct
16027 {
16028   u8 *name;
16029   u8 *value;
16030 } macro_sort_t;
16031
16032
16033 static int
16034 macro_sort_cmp (void *a1, void *a2)
16035 {
16036   macro_sort_t *s1 = a1;
16037   macro_sort_t *s2 = a2;
16038
16039   return strcmp ((char *) (s1->name), (char *) (s2->name));
16040 }
16041
16042 static int
16043 dump_macro_table (vat_main_t * vam)
16044 {
16045   macro_sort_t *sort_me = 0, *sm;
16046   int i;
16047   hash_pair_t *p;
16048
16049     /* *INDENT-OFF* */
16050     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16051     ({
16052       vec_add2 (sort_me, sm, 1);
16053       sm->name = (u8 *)(p->key);
16054       sm->value = (u8 *) (p->value[0]);
16055     }));
16056     /* *INDENT-ON* */
16057
16058   vec_sort_with_function (sort_me, macro_sort_cmp);
16059
16060   if (vec_len (sort_me))
16061     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16062   else
16063     fformat (vam->ofp, "The macro table is empty...\n");
16064
16065   for (i = 0; i < vec_len (sort_me); i++)
16066     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16067   return 0;
16068 }
16069
16070 static int
16071 dump_node_table (vat_main_t * vam)
16072 {
16073   int i, j;
16074   vlib_node_t *node, *next_node;
16075
16076   if (vec_len (vam->graph_nodes) == 0)
16077     {
16078       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16079       return 0;
16080     }
16081
16082   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16083     {
16084       node = vam->graph_nodes[i];
16085       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16086       for (j = 0; j < vec_len (node->next_nodes); j++)
16087         {
16088           if (node->next_nodes[j] != ~0)
16089             {
16090               next_node = vam->graph_nodes[node->next_nodes[j]];
16091               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16092             }
16093         }
16094     }
16095   return 0;
16096 }
16097
16098 static int
16099 search_node_table (vat_main_t * vam)
16100 {
16101   unformat_input_t *line_input = vam->input;
16102   u8 *node_to_find;
16103   int j;
16104   vlib_node_t *node, *next_node;
16105   uword *p;
16106
16107   if (vam->graph_node_index_by_name == 0)
16108     {
16109       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16110       return 0;
16111     }
16112
16113   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16114     {
16115       if (unformat (line_input, "%s", &node_to_find))
16116         {
16117           vec_add1 (node_to_find, 0);
16118           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16119           if (p == 0)
16120             {
16121               fformat (vam->ofp, "%s not found...\n", node_to_find);
16122               goto out;
16123             }
16124           node = vam->graph_nodes[p[0]];
16125           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16126           for (j = 0; j < vec_len (node->next_nodes); j++)
16127             {
16128               if (node->next_nodes[j] != ~0)
16129                 {
16130                   next_node = vam->graph_nodes[node->next_nodes[j]];
16131                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16132                 }
16133             }
16134         }
16135
16136       else
16137         {
16138           clib_warning ("parse error '%U'", format_unformat_error,
16139                         line_input);
16140           return -99;
16141         }
16142
16143     out:
16144       vec_free (node_to_find);
16145
16146     }
16147
16148   return 0;
16149 }
16150
16151
16152 static int
16153 script (vat_main_t * vam)
16154 {
16155   u8 *s = 0;
16156   char *save_current_file;
16157   unformat_input_t save_input;
16158   jmp_buf save_jump_buf;
16159   u32 save_line_number;
16160
16161   FILE *new_fp, *save_ifp;
16162
16163   if (unformat (vam->input, "%s", &s))
16164     {
16165       new_fp = fopen ((char *) s, "r");
16166       if (new_fp == 0)
16167         {
16168           errmsg ("Couldn't open script file %s\n", s);
16169           vec_free (s);
16170           return -99;
16171         }
16172     }
16173   else
16174     {
16175       errmsg ("Missing script name\n");
16176       return -99;
16177     }
16178
16179   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16180   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16181   save_ifp = vam->ifp;
16182   save_line_number = vam->input_line_number;
16183   save_current_file = (char *) vam->current_file;
16184
16185   vam->input_line_number = 0;
16186   vam->ifp = new_fp;
16187   vam->current_file = s;
16188   do_one_file (vam);
16189
16190   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16191   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16192   vam->ifp = save_ifp;
16193   vam->input_line_number = save_line_number;
16194   vam->current_file = (u8 *) save_current_file;
16195   vec_free (s);
16196
16197   return 0;
16198 }
16199
16200 static int
16201 echo (vat_main_t * vam)
16202 {
16203   fformat (vam->ofp, "%v", vam->input->buffer);
16204   return 0;
16205 }
16206
16207 /* List of API message constructors, CLI names map to api_xxx */
16208 #define foreach_vpe_api_msg                                             \
16209 _(create_loopback,"[mac <mac-addr>]")                                   \
16210 _(sw_interface_dump,"")                                                 \
16211 _(sw_interface_set_flags,                                               \
16212   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16213 _(sw_interface_add_del_address,                                         \
16214   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16215 _(sw_interface_set_table,                                               \
16216   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16217 _(sw_interface_set_mpls_enable,                                                \
16218   "<intfc> | sw_if_index [disable | dis]")                                \
16219 _(sw_interface_set_vpath,                                               \
16220   "<intfc> | sw_if_index <id> enable | disable")                        \
16221 _(sw_interface_set_l2_xconnect,                                         \
16222   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16223   "enable | disable")                                                   \
16224 _(sw_interface_set_l2_bridge,                                           \
16225   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16226   "[shg <split-horizon-group>] [bvi]\n"                                 \
16227   "enable | disable")                                                   \
16228 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16229   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16230   "profile <profile-id>\n")                                             \
16231 _(sw_interface_set_dpdk_hqos_subport,                                   \
16232   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16233   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16234 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16235   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16236 _(bridge_domain_add_del,                                                \
16237   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16238 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16239 _(l2fib_add_del,                                                        \
16240   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16241 _(l2_flags,                                                             \
16242   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16243 _(bridge_flags,                                                         \
16244   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16245 _(tap_connect,                                                          \
16246   "tapname <name> mac <mac-addr> | random-mac")                         \
16247 _(tap_modify,                                                           \
16248   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16249 _(tap_delete,                                                           \
16250   "<vpp-if-name> | sw_if_index <id>")                                   \
16251 _(sw_interface_tap_dump, "")                                            \
16252 _(ip_add_del_route,                                                     \
16253   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16254   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16255   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16256   "[multipath] [count <n>]")                                            \
16257 _(mpls_route_add_del,                                                   \
16258   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16259   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16260   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16261   "[multipath] [count <n>]")                                            \
16262 _(mpls_ip_bind_unbind,                                                  \
16263   "<label> <addr/len>")                                                 \
16264 _(proxy_arp_add_del,                                                    \
16265   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16266 _(proxy_arp_intfc_enable_disable,                                       \
16267   "<intfc> | sw_if_index <id> enable | disable")                        \
16268 _(mpls_add_del_encap,                                                   \
16269   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16270 _(sw_interface_set_unnumbered,                                          \
16271   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16272 _(ip_neighbor_add_del,                                                  \
16273   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16274   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16275 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16276 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16277 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16278   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16279   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16280   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16281 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16282 _(reset_fib, "vrf <n> [ipv6]")                                          \
16283 _(dhcp_proxy_config,                                                    \
16284   "svr <v46-address> src <v46-address>\n"                               \
16285    "insert-cid <n> [del]")                                              \
16286 _(dhcp_proxy_config_2,                                                  \
16287   "svr <v46-address> src <v46-address>\n"                               \
16288    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16289 _(dhcp_proxy_set_vss,                                                   \
16290   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16291 _(dhcp_client_config,                                                   \
16292   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16293 _(set_ip_flow_hash,                                                     \
16294   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16295 _(sw_interface_ip6_enable_disable,                                      \
16296   "<intfc> | sw_if_index <id> enable | disable")                        \
16297 _(sw_interface_ip6_set_link_local_address,                              \
16298   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16299 _(sw_interface_ip6nd_ra_prefix,                                         \
16300   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16301   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16302   "[nolink] [isno]")                                                    \
16303 _(sw_interface_ip6nd_ra_config,                                         \
16304   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16305   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16306   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16307 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16308 _(l2_patch_add_del,                                                     \
16309   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16310   "enable | disable")                                                   \
16311 _(mpls_ethernet_add_del_tunnel,                                         \
16312   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16313   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16314 _(mpls_ethernet_add_del_tunnel_2,                                       \
16315   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16316   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16317 _(sr_tunnel_add_del,                                                    \
16318   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16319   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16320   "[policy <policy_name>]")                                             \
16321 _(sr_policy_add_del,                                                    \
16322   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16323 _(sr_multicast_map_add_del,                                             \
16324   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16325 _(classify_add_del_table,                                               \
16326   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16327   "[del] mask <mask-value>\n"                                           \
16328   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
16329 _(classify_add_del_session,                                             \
16330   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16331   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16332   "  [l3 [ip4|ip6]]")                                                   \
16333 _(classify_set_interface_ip_table,                                      \
16334   "<intfc> | sw_if_index <nn> table <nn>")                              \
16335 _(classify_set_interface_l2_tables,                                     \
16336   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16337   "  [other-table <nn>]")                                               \
16338 _(get_node_index, "node <node-name")                                    \
16339 _(add_node_next, "node <node-name> next <next-node-name>")              \
16340 _(l2tpv3_create_tunnel,                                                 \
16341   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16342   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16343   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16344 _(l2tpv3_set_tunnel_cookies,                                            \
16345   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16346   "[new_remote_cookie <nn>]\n")                                         \
16347 _(l2tpv3_interface_enable_disable,                                      \
16348   "<intfc> | sw_if_index <nn> enable | disable")                        \
16349 _(l2tpv3_set_lookup_key,                                                \
16350   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16351 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16352 _(vxlan_add_del_tunnel,                                                 \
16353   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16354   " [decap-next l2|ip4|ip6] [del]")                                     \
16355 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16356 _(gre_add_del_tunnel,                                                   \
16357   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16358 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16359 _(l2_fib_clear_table, "")                                               \
16360 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16361 _(l2_interface_vlan_tag_rewrite,                                        \
16362   "<intfc> | sw_if_index <nn> \n"                                       \
16363   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16364   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16365 _(create_vhost_user_if,                                                 \
16366         "socket <filename> [server] [renumber <dev_instance>] "         \
16367         "[mac <mac_address>]")                                          \
16368 _(modify_vhost_user_if,                                                 \
16369         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16370         "[server] [renumber <dev_instance>]")                           \
16371 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16372 _(sw_interface_vhost_user_dump, "")                                     \
16373 _(show_version, "")                                                     \
16374 _(vxlan_gpe_add_del_tunnel,                                             \
16375   "local <addr> remote <addr> vni <nn>\n"                               \
16376     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16377   "[next-ethernet] [next-nsh]\n")                                       \
16378 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16379 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16380 _(interface_name_renumber,                                              \
16381   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16382 _(input_acl_set_interface,                                              \
16383   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16384   "  [l2-table <nn>] [del]")                                            \
16385 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16386 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16387 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16388 _(ip_dump, "ipv4 | ipv6")                                               \
16389 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16390 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16391   "  spid_id <n> ")                                                     \
16392 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16393   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16394   "  integ_alg <alg> integ_key <hex>")                                  \
16395 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16396   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16397   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16398   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16399 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16400 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16401 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16402   "(auth_data 0x<data> | auth_data <data>)")                            \
16403 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16404   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16405 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16406   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16407   "(local|remote)")                                                     \
16408 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16409 _(delete_loopback,"sw_if_index <nn>")                                   \
16410 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16411 _(map_add_domain,                                                       \
16412   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16413   "ip6-src <ip6addr> "                                                  \
16414   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16415 _(map_del_domain, "index <n>")                                          \
16416 _(map_add_del_rule,                                                     \
16417   "index <n> psid <n> dst <ip6addr> [del]")                             \
16418 _(map_domain_dump, "")                                                  \
16419 _(map_rule_dump, "index <map-domain>")                                  \
16420 _(want_interface_events,  "enable|disable")                             \
16421 _(want_stats,"enable|disable")                                          \
16422 _(get_first_msg_id, "client <name>")                                    \
16423 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16424 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16425   "fib-id <nn> [ip4][ip6][default]")                                    \
16426 _(get_node_graph, " ")                                                  \
16427 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16428 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16429 _(ioam_disable, "")                                                \
16430 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16431                             " sw_if_index <sw_if_index> p <priority> "  \
16432                             "w <weight>] [del]")                        \
16433 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16434                         "iface <intf> | sw_if_index <sw_if_index> "     \
16435                         "p <priority> w <weight> [del]")                \
16436 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16437                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16438                           "locator-set <locator_name> [del]")           \
16439 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16440   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16441 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16442 _(lisp_gpe_enable_disable, "enable|disable")                            \
16443 _(lisp_enable_disable, "enable|disable")                                \
16444 _(lisp_gpe_add_del_iface, "up|down")                                    \
16445 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16446                                "[seid <seid>] "                         \
16447                                "rloc <locator> p <prio> "               \
16448                                "w <weight> [rloc <loc> ... ] "          \
16449                                "action <action> [del-all]")             \
16450 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16451                           "<local-eid>")                                \
16452 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16453 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16454 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16455 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16456 _(lisp_locator_set_dump, "[local | remote]")                            \
16457 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16458 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16459                        "[local] | [remote]")                            \
16460 _(lisp_eid_table_vni_dump, "")                                          \
16461 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16462 _(lisp_gpe_tunnel_dump, "")                                             \
16463 _(lisp_map_resolver_dump, "")                                           \
16464 _(lisp_adjacencies_get, "vni <vni>")                                    \
16465 _(show_lisp_status, "")                                                 \
16466 _(lisp_get_map_request_itr_rlocs, "")                                   \
16467 _(show_lisp_pitr, "")                                                   \
16468 _(show_lisp_map_request_mode, "")                                       \
16469 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16470 _(af_packet_delete, "name <host interface name>")                       \
16471 _(policer_add_del, "name <policer name> <params> [del]")                \
16472 _(policer_dump, "[name <policer name>]")                                \
16473 _(policer_classify_set_interface,                                       \
16474   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16475   "  [l2-table <nn>] [del]")                                            \
16476 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16477 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16478     "[master|slave]")                                                   \
16479 _(netmap_delete, "name <interface name>")                               \
16480 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16481 _(mpls_fib_encap_dump, "")                                              \
16482 _(mpls_fib_dump, "")                                                    \
16483 _(classify_table_ids, "")                                               \
16484 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16485 _(classify_table_info, "table_id <nn>")                                 \
16486 _(classify_session_dump, "table_id <nn>")                               \
16487 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16488     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16489     "[template_interval <nn>] [udp_checksum]")                          \
16490 _(ipfix_exporter_dump, "")                                              \
16491 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16492 _(ipfix_classify_stream_dump, "")                                       \
16493 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16494 _(ipfix_classify_table_dump, "")                                        \
16495 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16496 _(pg_create_interface, "if_id <nn>")                                    \
16497 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16498 _(pg_enable_disable, "[stream <id>] disable")                           \
16499 _(ip_source_and_port_range_check_add_del,                               \
16500   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16501 _(ip_source_and_port_range_check_interface_add_del,                     \
16502   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16503   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16504 _(ipsec_gre_add_del_tunnel,                                             \
16505   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16506 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16507 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
16508 _(l2_interface_pbb_tag_rewrite,                                         \
16509   "<intfc> | sw_if_index <nn> \n"                                       \
16510   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16511   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16512 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16513 _(flow_classify_set_interface,                                          \
16514   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16515 _(flow_classify_dump, "type [ip4|ip6]")
16516
16517 /* List of command functions, CLI names map directly to functions */
16518 #define foreach_cli_function                                    \
16519 _(comment, "usage: comment <ignore-rest-of-line>")              \
16520 _(dump_interface_table, "usage: dump_interface_table")          \
16521 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16522 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16523 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16524 _(dump_stats_table, "usage: dump_stats_table")                  \
16525 _(dump_macro_table, "usage: dump_macro_table ")                 \
16526 _(dump_node_table, "usage: dump_node_table")                    \
16527 _(echo, "usage: echo <message>")                                \
16528 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16529 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16530 _(help, "usage: help")                                          \
16531 _(q, "usage: quit")                                             \
16532 _(quit, "usage: quit")                                          \
16533 _(search_node_table, "usage: search_node_table <name>...")      \
16534 _(set, "usage: set <variable-name> <value>")                    \
16535 _(script, "usage: script <file-name>")                          \
16536 _(unset, "usage: unset <variable-name>")
16537
16538 #define _(N,n)                                  \
16539     static void vl_api_##n##_t_handler_uni      \
16540     (vl_api_##n##_t * mp)                       \
16541     {                                           \
16542         vat_main_t * vam = &vat_main;           \
16543         if (vam->json_output) {                 \
16544             vl_api_##n##_t_handler_json(mp);    \
16545         } else {                                \
16546             vl_api_##n##_t_handler(mp);         \
16547         }                                       \
16548     }
16549 foreach_vpe_api_reply_msg;
16550 #undef _
16551
16552 void
16553 vat_api_hookup (vat_main_t * vam)
16554 {
16555 #define _(N,n)                                                  \
16556     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16557                            vl_api_##n##_t_handler_uni,          \
16558                            vl_noop_handler,                     \
16559                            vl_api_##n##_t_endian,               \
16560                            vl_api_##n##_t_print,                \
16561                            sizeof(vl_api_##n##_t), 1);
16562   foreach_vpe_api_reply_msg;
16563 #undef _
16564
16565   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16566
16567   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16568
16569   vam->function_by_name = hash_create_string (0, sizeof (uword));
16570
16571   vam->help_by_name = hash_create_string (0, sizeof (uword));
16572
16573   /* API messages we can send */
16574 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16575   foreach_vpe_api_msg;
16576 #undef _
16577
16578   /* Help strings */
16579 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16580   foreach_vpe_api_msg;
16581 #undef _
16582
16583   /* CLI functions */
16584 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16585   foreach_cli_function;
16586 #undef _
16587
16588   /* Help strings */
16589 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16590   foreach_cli_function;
16591 #undef _
16592 }
16593
16594 #undef vl_api_version
16595 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16596 #include <vpp-api/vpe.api.h>
16597 #undef vl_api_version
16598
16599 void
16600 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16601 {
16602   /*
16603    * Send the main API signature in slot 0. This bit of code must
16604    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16605    */
16606   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16607 }
16608
16609 /*
16610  * fd.io coding-style-patch-verification: ON
16611  *
16612  * Local Variables:
16613  * eval: (c-set-style "gnu")
16614  * End:
16615  */