Add API call of sw_interface_set_mpls_enable to vpp_api_test
[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 create_vrf_if_needed = 0;
5761   u8 is_add = 1;
5762   u8 next_hop_weight = 1;
5763   u8 not_last = 0;
5764   u8 is_multipath = 0;
5765   u8 address_set = 0;
5766   u8 address_length_set = 0;
5767   u32 next_hop_table_id = 0;
5768   u32 resolve_attempts = 0;
5769   u32 dst_address_length = 0;
5770   u8 next_hop_set = 0;
5771   ip4_address_t v4_dst_address, v4_next_hop_address;
5772   ip6_address_t v6_dst_address, v6_next_hop_address;
5773   int count = 1;
5774   int j;
5775   f64 before = 0;
5776   u32 random_add_del = 0;
5777   u32 *random_vector = 0;
5778   uword *random_hash;
5779   u32 random_seed = 0xdeaddabe;
5780   u32 classify_table_index = ~0;
5781   u8 is_classify = 0;
5782   u8 resolve_host = 0, resolve_attached = 0;
5783   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5784
5785   /* Parse args required to build the message */
5786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5787     {
5788       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5789         sw_if_index_set = 1;
5790       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5791         sw_if_index_set = 1;
5792       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5793         {
5794           address_set = 1;
5795           is_ipv6 = 0;
5796         }
5797       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5798         {
5799           address_set = 1;
5800           is_ipv6 = 1;
5801         }
5802       else if (unformat (i, "/%d", &dst_address_length))
5803         {
5804           address_length_set = 1;
5805         }
5806
5807       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5808                                          &v4_next_hop_address))
5809         {
5810           next_hop_set = 1;
5811         }
5812       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5813                                          &v6_next_hop_address))
5814         {
5815           next_hop_set = 1;
5816         }
5817       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5818         ;
5819       else if (unformat (i, "weight %d", &next_hop_weight))
5820         ;
5821       else if (unformat (i, "drop"))
5822         {
5823           is_drop = 1;
5824         }
5825       else if (unformat (i, "local"))
5826         {
5827           is_local = 1;
5828         }
5829       else if (unformat (i, "classify %d", &classify_table_index))
5830         {
5831           is_classify = 1;
5832         }
5833       else if (unformat (i, "del"))
5834         is_add = 0;
5835       else if (unformat (i, "add"))
5836         is_add = 1;
5837       else if (unformat (i, "not-last"))
5838         not_last = 1;
5839       else if (unformat (i, "resolve-via-host"))
5840         resolve_host = 1;
5841       else if (unformat (i, "resolve-via-attached"))
5842         resolve_attached = 1;
5843       else if (unformat (i, "multipath"))
5844         is_multipath = 1;
5845       else if (unformat (i, "vrf %d", &vrf_id))
5846         ;
5847       else if (unformat (i, "create-vrf"))
5848         create_vrf_if_needed = 1;
5849       else if (unformat (i, "count %d", &count))
5850         ;
5851       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5852         ;
5853       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5854         ;
5855       else if (unformat (i, "out-label %d", &next_hop_out_label))
5856         ;
5857       else if (unformat (i, "random"))
5858         random_add_del = 1;
5859       else if (unformat (i, "seed %d", &random_seed))
5860         ;
5861       else
5862         {
5863           clib_warning ("parse error '%U'", format_unformat_error, i);
5864           return -99;
5865         }
5866     }
5867
5868   if (resolve_attempts > 0 && sw_if_index_set == 0)
5869     {
5870       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5871       return -99;
5872     }
5873
5874   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5875     {
5876       errmsg ("next hop / local / drop / classify not set\n");
5877       return -99;
5878     }
5879
5880   if (address_set == 0)
5881     {
5882       errmsg ("missing addresses\n");
5883       return -99;
5884     }
5885
5886   if (address_length_set == 0)
5887     {
5888       errmsg ("missing address length\n");
5889       return -99;
5890     }
5891
5892   /* Generate a pile of unique, random routes */
5893   if (random_add_del)
5894     {
5895       u32 this_random_address;
5896       random_hash = hash_create (count, sizeof (uword));
5897
5898       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5899       for (j = 0; j <= count; j++)
5900         {
5901           do
5902             {
5903               this_random_address = random_u32 (&random_seed);
5904               this_random_address =
5905                 clib_host_to_net_u32 (this_random_address);
5906             }
5907           while (hash_get (random_hash, this_random_address));
5908           vec_add1 (random_vector, this_random_address);
5909           hash_set (random_hash, this_random_address, 1);
5910         }
5911       hash_free (random_hash);
5912       v4_dst_address.as_u32 = random_vector[0];
5913     }
5914
5915   if (count > 1)
5916     {
5917       /* Turn on async mode */
5918       vam->async_mode = 1;
5919       vam->async_errors = 0;
5920       before = vat_time_now (vam);
5921     }
5922
5923   for (j = 0; j < count; j++)
5924     {
5925       /* Construct the API message */
5926       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5927
5928       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5929       mp->table_id = ntohl (vrf_id);
5930       if (resolve_attempts > 0)
5931         {
5932           mp->resolve_attempts = ntohl (resolve_attempts);
5933           mp->resolve_if_needed = 1;
5934         }
5935       mp->create_vrf_if_needed = create_vrf_if_needed;
5936
5937       mp->is_add = is_add;
5938       mp->is_drop = is_drop;
5939       mp->is_ipv6 = is_ipv6;
5940       mp->is_local = is_local;
5941       mp->is_classify = is_classify;
5942       mp->is_multipath = is_multipath;
5943       mp->is_resolve_host = resolve_host;
5944       mp->is_resolve_attached = resolve_attached;
5945       mp->not_last = not_last;
5946       mp->next_hop_weight = next_hop_weight;
5947       mp->dst_address_length = dst_address_length;
5948       mp->next_hop_table_id = ntohl (next_hop_table_id);
5949       mp->classify_table_index = ntohl (classify_table_index);
5950       mp->next_hop_out_label = ntohl (next_hop_out_label);
5951
5952       if (is_ipv6)
5953         {
5954           clib_memcpy (mp->dst_address, &v6_dst_address,
5955                        sizeof (v6_dst_address));
5956           if (next_hop_set)
5957             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5958                          sizeof (v6_next_hop_address));
5959           increment_v6_address (&v6_dst_address);
5960         }
5961       else
5962         {
5963           clib_memcpy (mp->dst_address, &v4_dst_address,
5964                        sizeof (v4_dst_address));
5965           if (next_hop_set)
5966             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5967                          sizeof (v4_next_hop_address));
5968           if (random_add_del)
5969             v4_dst_address.as_u32 = random_vector[j + 1];
5970           else
5971             increment_v4_address (&v4_dst_address);
5972         }
5973       /* send it... */
5974       S;
5975       /* If we receive SIGTERM, stop now... */
5976       if (vam->do_exit)
5977         break;
5978     }
5979
5980   /* When testing multiple add/del ops, use a control-ping to sync */
5981   if (count > 1)
5982     {
5983       vl_api_control_ping_t *mp;
5984       f64 after;
5985
5986       /* Shut off async mode */
5987       vam->async_mode = 0;
5988
5989       M (CONTROL_PING, control_ping);
5990       S;
5991
5992       timeout = vat_time_now (vam) + 1.0;
5993       while (vat_time_now (vam) < timeout)
5994         if (vam->result_ready == 1)
5995           goto out;
5996       vam->retval = -99;
5997
5998     out:
5999       if (vam->retval == -99)
6000         errmsg ("timeout\n");
6001
6002       if (vam->async_errors > 0)
6003         {
6004           errmsg ("%d asynchronous errors\n", vam->async_errors);
6005           vam->retval = -98;
6006         }
6007       vam->async_errors = 0;
6008       after = vat_time_now (vam);
6009
6010       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6011       if (j > 0)
6012         count = j;
6013
6014       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6015                count, after - before, count / (after - before));
6016     }
6017   else
6018     {
6019       /* Wait for a reply... */
6020       W;
6021     }
6022
6023   /* Return the good/bad news */
6024   return (vam->retval);
6025 }
6026
6027 static int
6028 api_mpls_route_add_del (vat_main_t * vam)
6029 {
6030   unformat_input_t *i = vam->input;
6031   vl_api_mpls_route_add_del_t *mp;
6032   f64 timeout;
6033   u32 sw_if_index = ~0, table_id = 0;
6034   u8 create_table_if_needed = 0;
6035   u8 is_add = 1;
6036   u8 next_hop_weight = 1;
6037   u8 is_multipath = 0;
6038   u32 next_hop_table_id = 0;
6039   u8 next_hop_set = 0;
6040   ip4_address_t v4_next_hop_address = {
6041     .as_u32 = 0,
6042   };
6043   ip6_address_t v6_next_hop_address = { {0} };
6044   int count = 1;
6045   int j;
6046   f64 before = 0;
6047   u32 classify_table_index = ~0;
6048   u8 is_classify = 0;
6049   u8 resolve_host = 0, resolve_attached = 0;
6050   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6051   mpls_label_t local_label = MPLS_LABEL_INVALID;
6052   u8 is_eos = 1;
6053   u8 next_hop_proto_is_ip4 = 1;
6054
6055   /* Parse args required to build the message */
6056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6057     {
6058       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6059         ;
6060       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6061         ;
6062       else if (unformat (i, "%d", &local_label))
6063         ;
6064       else if (unformat (i, "eos"))
6065         is_eos = 1;
6066       else if (unformat (i, "non-eos"))
6067         is_eos = 0;
6068       else if (unformat (i, "via %U", unformat_ip4_address,
6069                          &v4_next_hop_address))
6070         {
6071           next_hop_set = 1;
6072           next_hop_proto_is_ip4 = 1;
6073         }
6074       else if (unformat (i, "via %U", unformat_ip6_address,
6075                          &v6_next_hop_address))
6076         {
6077           next_hop_set = 1;
6078           next_hop_proto_is_ip4 = 0;
6079         }
6080       else if (unformat (i, "weight %d", &next_hop_weight))
6081         ;
6082       else if (unformat (i, "create-table"))
6083         create_table_if_needed = 1;
6084       else if (unformat (i, "classify %d", &classify_table_index))
6085         {
6086           is_classify = 1;
6087         }
6088       else if (unformat (i, "del"))
6089         is_add = 0;
6090       else if (unformat (i, "add"))
6091         is_add = 1;
6092       else if (unformat (i, "resolve-via-host"))
6093         resolve_host = 1;
6094       else if (unformat (i, "resolve-via-attached"))
6095         resolve_attached = 1;
6096       else if (unformat (i, "multipath"))
6097         is_multipath = 1;
6098       else if (unformat (i, "count %d", &count))
6099         ;
6100       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6101         {
6102           next_hop_set = 1;
6103           next_hop_proto_is_ip4 = 1;
6104         }
6105       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6106         {
6107           next_hop_set = 1;
6108           next_hop_proto_is_ip4 = 0;
6109         }
6110       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6111         ;
6112       else if (unformat (i, "out-label %d", &next_hop_out_label))
6113         ;
6114       else
6115         {
6116           clib_warning ("parse error '%U'", format_unformat_error, i);
6117           return -99;
6118         }
6119     }
6120
6121   if (!next_hop_set && !is_classify)
6122     {
6123       errmsg ("next hop / classify not set\n");
6124       return -99;
6125     }
6126
6127   if (MPLS_LABEL_INVALID == local_label)
6128     {
6129       errmsg ("missing label\n");
6130       return -99;
6131     }
6132
6133   if (count > 1)
6134     {
6135       /* Turn on async mode */
6136       vam->async_mode = 1;
6137       vam->async_errors = 0;
6138       before = vat_time_now (vam);
6139     }
6140
6141   for (j = 0; j < count; j++)
6142     {
6143       /* Construct the API message */
6144       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6145
6146       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6147       mp->mr_table_id = ntohl (table_id);
6148       mp->mr_create_table_if_needed = create_table_if_needed;
6149
6150       mp->mr_is_add = is_add;
6151       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6152       mp->mr_is_classify = is_classify;
6153       mp->mr_is_multipath = is_multipath;
6154       mp->mr_is_resolve_host = resolve_host;
6155       mp->mr_is_resolve_attached = resolve_attached;
6156       mp->mr_next_hop_weight = next_hop_weight;
6157       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6158       mp->mr_classify_table_index = ntohl (classify_table_index);
6159       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6160       mp->mr_label = ntohl (local_label);
6161       mp->mr_eos = is_eos;
6162
6163       if (next_hop_set)
6164         {
6165           if (next_hop_proto_is_ip4)
6166             {
6167               clib_memcpy (mp->mr_next_hop,
6168                            &v4_next_hop_address,
6169                            sizeof (v4_next_hop_address));
6170             }
6171           else
6172             {
6173               clib_memcpy (mp->mr_next_hop,
6174                            &v6_next_hop_address,
6175                            sizeof (v6_next_hop_address));
6176             }
6177         }
6178       local_label++;
6179
6180       /* send it... */
6181       S;
6182       /* If we receive SIGTERM, stop now... */
6183       if (vam->do_exit)
6184         break;
6185     }
6186
6187   /* When testing multiple add/del ops, use a control-ping to sync */
6188   if (count > 1)
6189     {
6190       vl_api_control_ping_t *mp;
6191       f64 after;
6192
6193       /* Shut off async mode */
6194       vam->async_mode = 0;
6195
6196       M (CONTROL_PING, control_ping);
6197       S;
6198
6199       timeout = vat_time_now (vam) + 1.0;
6200       while (vat_time_now (vam) < timeout)
6201         if (vam->result_ready == 1)
6202           goto out;
6203       vam->retval = -99;
6204
6205     out:
6206       if (vam->retval == -99)
6207         errmsg ("timeout\n");
6208
6209       if (vam->async_errors > 0)
6210         {
6211           errmsg ("%d asynchronous errors\n", vam->async_errors);
6212           vam->retval = -98;
6213         }
6214       vam->async_errors = 0;
6215       after = vat_time_now (vam);
6216
6217       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6218       if (j > 0)
6219         count = j;
6220
6221       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6222                count, after - before, count / (after - before));
6223     }
6224   else
6225     {
6226       /* Wait for a reply... */
6227       W;
6228     }
6229
6230   /* Return the good/bad news */
6231   return (vam->retval);
6232 }
6233
6234 static int
6235 api_mpls_ip_bind_unbind (vat_main_t * vam)
6236 {
6237   unformat_input_t *i = vam->input;
6238   vl_api_mpls_ip_bind_unbind_t *mp;
6239   f64 timeout;
6240   u32 ip_table_id = 0;
6241   u8 create_table_if_needed = 0;
6242   u8 is_bind = 1;
6243   u8 is_ip4 = 1;
6244   ip4_address_t v4_address;
6245   ip6_address_t v6_address;
6246   u32 address_length;
6247   u8 address_set = 0;
6248   mpls_label_t local_label = MPLS_LABEL_INVALID;
6249
6250   /* Parse args required to build the message */
6251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6252     {
6253       if (unformat (i, "%U/%d", unformat_ip4_address,
6254                     &v4_address, &address_length))
6255         {
6256           is_ip4 = 1;
6257           address_set = 1;
6258         }
6259       else if (unformat (i, "%U/%d", unformat_ip6_address,
6260                          &v6_address, &address_length))
6261         {
6262           is_ip4 = 0;
6263           address_set = 1;
6264         }
6265       else if (unformat (i, "%d", &local_label))
6266         ;
6267       else if (unformat (i, "create-table"))
6268         create_table_if_needed = 1;
6269       else if (unformat (i, "table-id %d", &ip_table_id))
6270         ;
6271       else if (unformat (i, "unbind"))
6272         is_bind = 0;
6273       else if (unformat (i, "bind"))
6274         is_bind = 1;
6275       else
6276         {
6277           clib_warning ("parse error '%U'", format_unformat_error, i);
6278           return -99;
6279         }
6280     }
6281
6282   if (!address_set)
6283     {
6284       errmsg ("IP addres not set\n");
6285       return -99;
6286     }
6287
6288   if (MPLS_LABEL_INVALID == local_label)
6289     {
6290       errmsg ("missing label\n");
6291       return -99;
6292     }
6293
6294   /* Construct the API message */
6295   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6296
6297   mp->mb_create_table_if_needed = create_table_if_needed;
6298   mp->mb_is_bind = is_bind;
6299   mp->mb_is_ip4 = is_ip4;
6300   mp->mb_ip_table_id = ntohl (ip_table_id);
6301   mp->mb_mpls_table_id = 0;
6302   mp->mb_label = ntohl (local_label);
6303   mp->mb_address_length = address_length;
6304
6305   if (is_ip4)
6306     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6307   else
6308     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6309
6310   /* send it... */
6311   S;
6312
6313   /* Wait for a reply... */
6314   W;
6315
6316   /* Return the good/bad news */
6317   return (vam->retval);
6318 }
6319
6320 static int
6321 api_proxy_arp_add_del (vat_main_t * vam)
6322 {
6323   unformat_input_t *i = vam->input;
6324   vl_api_proxy_arp_add_del_t *mp;
6325   f64 timeout;
6326   u32 vrf_id = 0;
6327   u8 is_add = 1;
6328   ip4_address_t lo, hi;
6329   u8 range_set = 0;
6330
6331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332     {
6333       if (unformat (i, "vrf %d", &vrf_id))
6334         ;
6335       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6336                          unformat_ip4_address, &hi))
6337         range_set = 1;
6338       else if (unformat (i, "del"))
6339         is_add = 0;
6340       else
6341         {
6342           clib_warning ("parse error '%U'", format_unformat_error, i);
6343           return -99;
6344         }
6345     }
6346
6347   if (range_set == 0)
6348     {
6349       errmsg ("address range not set\n");
6350       return -99;
6351     }
6352
6353   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6354
6355   mp->vrf_id = ntohl (vrf_id);
6356   mp->is_add = is_add;
6357   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6358   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6359
6360   S;
6361   W;
6362   /* NOTREACHED */
6363   return 0;
6364 }
6365
6366 static int
6367 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6368 {
6369   unformat_input_t *i = vam->input;
6370   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6371   f64 timeout;
6372   u32 sw_if_index;
6373   u8 enable = 1;
6374   u8 sw_if_index_set = 0;
6375
6376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6377     {
6378       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6379         sw_if_index_set = 1;
6380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6381         sw_if_index_set = 1;
6382       else if (unformat (i, "enable"))
6383         enable = 1;
6384       else if (unformat (i, "disable"))
6385         enable = 0;
6386       else
6387         {
6388           clib_warning ("parse error '%U'", format_unformat_error, i);
6389           return -99;
6390         }
6391     }
6392
6393   if (sw_if_index_set == 0)
6394     {
6395       errmsg ("missing interface name or sw_if_index\n");
6396       return -99;
6397     }
6398
6399   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6400
6401   mp->sw_if_index = ntohl (sw_if_index);
6402   mp->enable_disable = enable;
6403
6404   S;
6405   W;
6406   /* NOTREACHED */
6407   return 0;
6408 }
6409
6410 static int
6411 api_mpls_add_del_encap (vat_main_t * vam)
6412 {
6413   unformat_input_t *i = vam->input;
6414   vl_api_mpls_add_del_encap_t *mp;
6415   f64 timeout;
6416   u32 vrf_id = 0;
6417   u32 *labels = 0;
6418   u32 label;
6419   ip4_address_t dst_address;
6420   u8 is_add = 1;
6421
6422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6423     {
6424       if (unformat (i, "vrf %d", &vrf_id))
6425         ;
6426       else if (unformat (i, "label %d", &label))
6427         vec_add1 (labels, ntohl (label));
6428       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6429         ;
6430       else if (unformat (i, "del"))
6431         is_add = 0;
6432       else
6433         {
6434           clib_warning ("parse error '%U'", format_unformat_error, i);
6435           return -99;
6436         }
6437     }
6438
6439   if (vec_len (labels) == 0)
6440     {
6441       errmsg ("missing encap label stack\n");
6442       return -99;
6443     }
6444
6445   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6446       sizeof (u32) * vec_len (labels));
6447
6448   mp->vrf_id = ntohl (vrf_id);
6449   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6450   mp->is_add = is_add;
6451   mp->nlabels = vec_len (labels);
6452   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6453
6454   vec_free (labels);
6455
6456   S;
6457   W;
6458   /* NOTREACHED */
6459   return 0;
6460 }
6461
6462 static int
6463 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6464 {
6465   unformat_input_t *i = vam->input;
6466   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6467   f64 timeout;
6468   u32 inner_vrf_id = 0;
6469   ip4_address_t intfc_address;
6470   u8 dst_mac_address[6];
6471   int dst_set = 1;
6472   u32 tmp;
6473   u8 intfc_address_length = 0;
6474   u8 is_add = 1;
6475   u8 l2_only = 0;
6476   u32 tx_sw_if_index;
6477   int tx_sw_if_index_set = 0;
6478
6479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6480     {
6481       if (unformat (i, "vrf %d", &inner_vrf_id))
6482         ;
6483       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6484                          &intfc_address, &tmp))
6485         intfc_address_length = tmp;
6486       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6487         tx_sw_if_index_set = 1;
6488       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6489         tx_sw_if_index_set = 1;
6490       else if (unformat (i, "dst %U", unformat_ethernet_address,
6491                          dst_mac_address))
6492         dst_set = 1;
6493       else if (unformat (i, "l2-only"))
6494         l2_only = 1;
6495       else if (unformat (i, "del"))
6496         is_add = 0;
6497       else
6498         {
6499           clib_warning ("parse error '%U'", format_unformat_error, i);
6500           return -99;
6501         }
6502     }
6503
6504   if (!dst_set)
6505     {
6506       errmsg ("dst (mac address) not set\n");
6507       return -99;
6508     }
6509   if (!tx_sw_if_index_set)
6510     {
6511       errmsg ("tx-intfc not set\n");
6512       return -99;
6513     }
6514
6515   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6516
6517   mp->vrf_id = ntohl (inner_vrf_id);
6518   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6519   mp->adj_address_length = intfc_address_length;
6520   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6521                sizeof (dst_mac_address));
6522   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6523   mp->l2_only = l2_only;
6524   mp->is_add = is_add;
6525
6526   S;
6527   W;
6528   /* NOTREACHED */
6529   return 0;
6530 }
6531
6532 static int
6533 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6534 {
6535   unformat_input_t *i = vam->input;
6536   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6537   f64 timeout;
6538   u32 inner_vrf_id = 0;
6539   u32 outer_vrf_id = 0;
6540   ip4_address_t adj_address;
6541   int adj_address_set = 0;
6542   ip4_address_t next_hop_address;
6543   int next_hop_address_set = 0;
6544   u32 tmp;
6545   u8 adj_address_length = 0;
6546   u8 l2_only = 0;
6547   u8 is_add = 1;
6548   u32 resolve_attempts = 5;
6549   u8 resolve_if_needed = 1;
6550
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6554         ;
6555       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6556         ;
6557       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6558                          &adj_address, &tmp))
6559         {
6560           adj_address_length = tmp;
6561           adj_address_set = 1;
6562         }
6563       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6564                          &next_hop_address))
6565         next_hop_address_set = 1;
6566       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6567         ;
6568       else if (unformat (i, "resolve-if-needed %d", &tmp))
6569         resolve_if_needed = tmp;
6570       else if (unformat (i, "l2-only"))
6571         l2_only = 1;
6572       else if (unformat (i, "del"))
6573         is_add = 0;
6574       else
6575         {
6576           clib_warning ("parse error '%U'", format_unformat_error, i);
6577           return -99;
6578         }
6579     }
6580
6581   if (!adj_address_set)
6582     {
6583       errmsg ("adjacency address/mask not set\n");
6584       return -99;
6585     }
6586   if (!next_hop_address_set)
6587     {
6588       errmsg ("ip4 next hop address (in outer fib) not set\n");
6589       return -99;
6590     }
6591
6592   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6593
6594   mp->inner_vrf_id = ntohl (inner_vrf_id);
6595   mp->outer_vrf_id = ntohl (outer_vrf_id);
6596   mp->resolve_attempts = ntohl (resolve_attempts);
6597   mp->resolve_if_needed = resolve_if_needed;
6598   mp->is_add = is_add;
6599   mp->l2_only = l2_only;
6600   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6601   mp->adj_address_length = adj_address_length;
6602   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6603                sizeof (next_hop_address));
6604
6605   S;
6606   W;
6607   /* NOTREACHED */
6608   return 0;
6609 }
6610
6611 static int
6612 api_sw_interface_set_unnumbered (vat_main_t * vam)
6613 {
6614   unformat_input_t *i = vam->input;
6615   vl_api_sw_interface_set_unnumbered_t *mp;
6616   f64 timeout;
6617   u32 sw_if_index;
6618   u32 unnum_sw_index = ~0;
6619   u8 is_add = 1;
6620   u8 sw_if_index_set = 0;
6621
6622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6623     {
6624       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6625         sw_if_index_set = 1;
6626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6627         sw_if_index_set = 1;
6628       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6629         ;
6630       else if (unformat (i, "del"))
6631         is_add = 0;
6632       else
6633         {
6634           clib_warning ("parse error '%U'", format_unformat_error, i);
6635           return -99;
6636         }
6637     }
6638
6639   if (sw_if_index_set == 0)
6640     {
6641       errmsg ("missing interface name or sw_if_index\n");
6642       return -99;
6643     }
6644
6645   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6646
6647   mp->sw_if_index = ntohl (sw_if_index);
6648   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6649   mp->is_add = is_add;
6650
6651   S;
6652   W;
6653   /* NOTREACHED */
6654   return 0;
6655 }
6656
6657 static int
6658 api_ip_neighbor_add_del (vat_main_t * vam)
6659 {
6660   unformat_input_t *i = vam->input;
6661   vl_api_ip_neighbor_add_del_t *mp;
6662   f64 timeout;
6663   u32 sw_if_index;
6664   u8 sw_if_index_set = 0;
6665   u32 vrf_id = 0;
6666   u8 is_add = 1;
6667   u8 is_static = 0;
6668   u8 mac_address[6];
6669   u8 mac_set = 0;
6670   u8 v4_address_set = 0;
6671   u8 v6_address_set = 0;
6672   ip4_address_t v4address;
6673   ip6_address_t v6address;
6674
6675   memset (mac_address, 0, sizeof (mac_address));
6676
6677   /* Parse args required to build the message */
6678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6679     {
6680       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6681         {
6682           mac_set = 1;
6683         }
6684       else if (unformat (i, "del"))
6685         is_add = 0;
6686       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6687         sw_if_index_set = 1;
6688       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6689         sw_if_index_set = 1;
6690       else if (unformat (i, "is_static"))
6691         is_static = 1;
6692       else if (unformat (i, "vrf %d", &vrf_id))
6693         ;
6694       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6695         v4_address_set = 1;
6696       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6697         v6_address_set = 1;
6698       else
6699         {
6700           clib_warning ("parse error '%U'", format_unformat_error, i);
6701           return -99;
6702         }
6703     }
6704
6705   if (sw_if_index_set == 0)
6706     {
6707       errmsg ("missing interface name or sw_if_index\n");
6708       return -99;
6709     }
6710   if (v4_address_set && v6_address_set)
6711     {
6712       errmsg ("both v4 and v6 addresses set\n");
6713       return -99;
6714     }
6715   if (!v4_address_set && !v6_address_set)
6716     {
6717       errmsg ("no address set\n");
6718       return -99;
6719     }
6720
6721   /* Construct the API message */
6722   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6723
6724   mp->sw_if_index = ntohl (sw_if_index);
6725   mp->is_add = is_add;
6726   mp->vrf_id = ntohl (vrf_id);
6727   mp->is_static = is_static;
6728   if (mac_set)
6729     clib_memcpy (mp->mac_address, mac_address, 6);
6730   if (v6_address_set)
6731     {
6732       mp->is_ipv6 = 1;
6733       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6734     }
6735   else
6736     {
6737       /* mp->is_ipv6 = 0; via memset in M macro above */
6738       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6739     }
6740
6741   /* send it... */
6742   S;
6743
6744   /* Wait for a reply, return good/bad news  */
6745   W;
6746
6747   /* NOTREACHED */
6748   return 0;
6749 }
6750
6751 static int
6752 api_reset_vrf (vat_main_t * vam)
6753 {
6754   unformat_input_t *i = vam->input;
6755   vl_api_reset_vrf_t *mp;
6756   f64 timeout;
6757   u32 vrf_id = 0;
6758   u8 is_ipv6 = 0;
6759   u8 vrf_id_set = 0;
6760
6761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6762     {
6763       if (unformat (i, "vrf %d", &vrf_id))
6764         vrf_id_set = 1;
6765       else if (unformat (i, "ipv6"))
6766         is_ipv6 = 1;
6767       else
6768         {
6769           clib_warning ("parse error '%U'", format_unformat_error, i);
6770           return -99;
6771         }
6772     }
6773
6774   if (vrf_id_set == 0)
6775     {
6776       errmsg ("missing vrf id\n");
6777       return -99;
6778     }
6779
6780   M (RESET_VRF, reset_vrf);
6781
6782   mp->vrf_id = ntohl (vrf_id);
6783   mp->is_ipv6 = is_ipv6;
6784
6785   S;
6786   W;
6787   /* NOTREACHED */
6788   return 0;
6789 }
6790
6791 static int
6792 api_create_vlan_subif (vat_main_t * vam)
6793 {
6794   unformat_input_t *i = vam->input;
6795   vl_api_create_vlan_subif_t *mp;
6796   f64 timeout;
6797   u32 sw_if_index;
6798   u8 sw_if_index_set = 0;
6799   u32 vlan_id;
6800   u8 vlan_id_set = 0;
6801
6802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6803     {
6804       if (unformat (i, "sw_if_index %d", &sw_if_index))
6805         sw_if_index_set = 1;
6806       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6807         sw_if_index_set = 1;
6808       else if (unformat (i, "vlan %d", &vlan_id))
6809         vlan_id_set = 1;
6810       else
6811         {
6812           clib_warning ("parse error '%U'", format_unformat_error, i);
6813           return -99;
6814         }
6815     }
6816
6817   if (sw_if_index_set == 0)
6818     {
6819       errmsg ("missing interface name or sw_if_index\n");
6820       return -99;
6821     }
6822
6823   if (vlan_id_set == 0)
6824     {
6825       errmsg ("missing vlan_id\n");
6826       return -99;
6827     }
6828   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6829
6830   mp->sw_if_index = ntohl (sw_if_index);
6831   mp->vlan_id = ntohl (vlan_id);
6832
6833   S;
6834   W;
6835   /* NOTREACHED */
6836   return 0;
6837 }
6838
6839 #define foreach_create_subif_bit                \
6840 _(no_tags)                                      \
6841 _(one_tag)                                      \
6842 _(two_tags)                                     \
6843 _(dot1ad)                                       \
6844 _(exact_match)                                  \
6845 _(default_sub)                                  \
6846 _(outer_vlan_id_any)                            \
6847 _(inner_vlan_id_any)
6848
6849 static int
6850 api_create_subif (vat_main_t * vam)
6851 {
6852   unformat_input_t *i = vam->input;
6853   vl_api_create_subif_t *mp;
6854   f64 timeout;
6855   u32 sw_if_index;
6856   u8 sw_if_index_set = 0;
6857   u32 sub_id;
6858   u8 sub_id_set = 0;
6859   u32 no_tags = 0;
6860   u32 one_tag = 0;
6861   u32 two_tags = 0;
6862   u32 dot1ad = 0;
6863   u32 exact_match = 0;
6864   u32 default_sub = 0;
6865   u32 outer_vlan_id_any = 0;
6866   u32 inner_vlan_id_any = 0;
6867   u32 tmp;
6868   u16 outer_vlan_id = 0;
6869   u16 inner_vlan_id = 0;
6870
6871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6872     {
6873       if (unformat (i, "sw_if_index %d", &sw_if_index))
6874         sw_if_index_set = 1;
6875       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6876         sw_if_index_set = 1;
6877       else if (unformat (i, "sub_id %d", &sub_id))
6878         sub_id_set = 1;
6879       else if (unformat (i, "outer_vlan_id %d", &tmp))
6880         outer_vlan_id = tmp;
6881       else if (unformat (i, "inner_vlan_id %d", &tmp))
6882         inner_vlan_id = tmp;
6883
6884 #define _(a) else if (unformat (i, #a)) a = 1 ;
6885       foreach_create_subif_bit
6886 #undef _
6887         else
6888         {
6889           clib_warning ("parse error '%U'", format_unformat_error, i);
6890           return -99;
6891         }
6892     }
6893
6894   if (sw_if_index_set == 0)
6895     {
6896       errmsg ("missing interface name or sw_if_index\n");
6897       return -99;
6898     }
6899
6900   if (sub_id_set == 0)
6901     {
6902       errmsg ("missing sub_id\n");
6903       return -99;
6904     }
6905   M (CREATE_SUBIF, create_subif);
6906
6907   mp->sw_if_index = ntohl (sw_if_index);
6908   mp->sub_id = ntohl (sub_id);
6909
6910 #define _(a) mp->a = a;
6911   foreach_create_subif_bit;
6912 #undef _
6913
6914   mp->outer_vlan_id = ntohs (outer_vlan_id);
6915   mp->inner_vlan_id = ntohs (inner_vlan_id);
6916
6917   S;
6918   W;
6919   /* NOTREACHED */
6920   return 0;
6921 }
6922
6923 static int
6924 api_oam_add_del (vat_main_t * vam)
6925 {
6926   unformat_input_t *i = vam->input;
6927   vl_api_oam_add_del_t *mp;
6928   f64 timeout;
6929   u32 vrf_id = 0;
6930   u8 is_add = 1;
6931   ip4_address_t src, dst;
6932   u8 src_set = 0;
6933   u8 dst_set = 0;
6934
6935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6936     {
6937       if (unformat (i, "vrf %d", &vrf_id))
6938         ;
6939       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6940         src_set = 1;
6941       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6942         dst_set = 1;
6943       else if (unformat (i, "del"))
6944         is_add = 0;
6945       else
6946         {
6947           clib_warning ("parse error '%U'", format_unformat_error, i);
6948           return -99;
6949         }
6950     }
6951
6952   if (src_set == 0)
6953     {
6954       errmsg ("missing src addr\n");
6955       return -99;
6956     }
6957
6958   if (dst_set == 0)
6959     {
6960       errmsg ("missing dst addr\n");
6961       return -99;
6962     }
6963
6964   M (OAM_ADD_DEL, oam_add_del);
6965
6966   mp->vrf_id = ntohl (vrf_id);
6967   mp->is_add = is_add;
6968   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6969   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6970
6971   S;
6972   W;
6973   /* NOTREACHED */
6974   return 0;
6975 }
6976
6977 static int
6978 api_reset_fib (vat_main_t * vam)
6979 {
6980   unformat_input_t *i = vam->input;
6981   vl_api_reset_fib_t *mp;
6982   f64 timeout;
6983   u32 vrf_id = 0;
6984   u8 is_ipv6 = 0;
6985   u8 vrf_id_set = 0;
6986
6987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6988     {
6989       if (unformat (i, "vrf %d", &vrf_id))
6990         vrf_id_set = 1;
6991       else if (unformat (i, "ipv6"))
6992         is_ipv6 = 1;
6993       else
6994         {
6995           clib_warning ("parse error '%U'", format_unformat_error, i);
6996           return -99;
6997         }
6998     }
6999
7000   if (vrf_id_set == 0)
7001     {
7002       errmsg ("missing vrf id\n");
7003       return -99;
7004     }
7005
7006   M (RESET_FIB, reset_fib);
7007
7008   mp->vrf_id = ntohl (vrf_id);
7009   mp->is_ipv6 = is_ipv6;
7010
7011   S;
7012   W;
7013   /* NOTREACHED */
7014   return 0;
7015 }
7016
7017 static int
7018 api_dhcp_proxy_config (vat_main_t * vam)
7019 {
7020   unformat_input_t *i = vam->input;
7021   vl_api_dhcp_proxy_config_t *mp;
7022   f64 timeout;
7023   u32 vrf_id = 0;
7024   u8 is_add = 1;
7025   u8 insert_cid = 1;
7026   u8 v4_address_set = 0;
7027   u8 v6_address_set = 0;
7028   ip4_address_t v4address;
7029   ip6_address_t v6address;
7030   u8 v4_src_address_set = 0;
7031   u8 v6_src_address_set = 0;
7032   ip4_address_t v4srcaddress;
7033   ip6_address_t v6srcaddress;
7034
7035   /* Parse args required to build the message */
7036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7037     {
7038       if (unformat (i, "del"))
7039         is_add = 0;
7040       else if (unformat (i, "vrf %d", &vrf_id))
7041         ;
7042       else if (unformat (i, "insert-cid %d", &insert_cid))
7043         ;
7044       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7045         v4_address_set = 1;
7046       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7047         v6_address_set = 1;
7048       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7049         v4_src_address_set = 1;
7050       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7051         v6_src_address_set = 1;
7052       else
7053         break;
7054     }
7055
7056   if (v4_address_set && v6_address_set)
7057     {
7058       errmsg ("both v4 and v6 server addresses set\n");
7059       return -99;
7060     }
7061   if (!v4_address_set && !v6_address_set)
7062     {
7063       errmsg ("no server addresses set\n");
7064       return -99;
7065     }
7066
7067   if (v4_src_address_set && v6_src_address_set)
7068     {
7069       errmsg ("both v4 and v6  src addresses set\n");
7070       return -99;
7071     }
7072   if (!v4_src_address_set && !v6_src_address_set)
7073     {
7074       errmsg ("no src addresses set\n");
7075       return -99;
7076     }
7077
7078   if (!(v4_src_address_set && v4_address_set) &&
7079       !(v6_src_address_set && v6_address_set))
7080     {
7081       errmsg ("no matching server and src addresses set\n");
7082       return -99;
7083     }
7084
7085   /* Construct the API message */
7086   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7087
7088   mp->insert_circuit_id = insert_cid;
7089   mp->is_add = is_add;
7090   mp->vrf_id = ntohl (vrf_id);
7091   if (v6_address_set)
7092     {
7093       mp->is_ipv6 = 1;
7094       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7095       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7096     }
7097   else
7098     {
7099       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7100       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7101     }
7102
7103   /* send it... */
7104   S;
7105
7106   /* Wait for a reply, return good/bad news  */
7107   W;
7108   /* NOTREACHED */
7109   return 0;
7110 }
7111
7112 static int
7113 api_dhcp_proxy_config_2 (vat_main_t * vam)
7114 {
7115   unformat_input_t *i = vam->input;
7116   vl_api_dhcp_proxy_config_2_t *mp;
7117   f64 timeout;
7118   u32 rx_vrf_id = 0;
7119   u32 server_vrf_id = 0;
7120   u8 is_add = 1;
7121   u8 insert_cid = 1;
7122   u8 v4_address_set = 0;
7123   u8 v6_address_set = 0;
7124   ip4_address_t v4address;
7125   ip6_address_t v6address;
7126   u8 v4_src_address_set = 0;
7127   u8 v6_src_address_set = 0;
7128   ip4_address_t v4srcaddress;
7129   ip6_address_t v6srcaddress;
7130
7131   /* Parse args required to build the message */
7132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7133     {
7134       if (unformat (i, "del"))
7135         is_add = 0;
7136       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7137         ;
7138       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7139         ;
7140       else if (unformat (i, "insert-cid %d", &insert_cid))
7141         ;
7142       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7143         v4_address_set = 1;
7144       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7145         v6_address_set = 1;
7146       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7147         v4_src_address_set = 1;
7148       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7149         v6_src_address_set = 1;
7150       else
7151         break;
7152     }
7153
7154   if (v4_address_set && v6_address_set)
7155     {
7156       errmsg ("both v4 and v6 server addresses set\n");
7157       return -99;
7158     }
7159   if (!v4_address_set && !v6_address_set)
7160     {
7161       errmsg ("no server addresses set\n");
7162       return -99;
7163     }
7164
7165   if (v4_src_address_set && v6_src_address_set)
7166     {
7167       errmsg ("both v4 and v6  src addresses set\n");
7168       return -99;
7169     }
7170   if (!v4_src_address_set && !v6_src_address_set)
7171     {
7172       errmsg ("no src addresses set\n");
7173       return -99;
7174     }
7175
7176   if (!(v4_src_address_set && v4_address_set) &&
7177       !(v6_src_address_set && v6_address_set))
7178     {
7179       errmsg ("no matching server and src addresses set\n");
7180       return -99;
7181     }
7182
7183   /* Construct the API message */
7184   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7185
7186   mp->insert_circuit_id = insert_cid;
7187   mp->is_add = is_add;
7188   mp->rx_vrf_id = ntohl (rx_vrf_id);
7189   mp->server_vrf_id = ntohl (server_vrf_id);
7190   if (v6_address_set)
7191     {
7192       mp->is_ipv6 = 1;
7193       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7194       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7195     }
7196   else
7197     {
7198       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7199       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7200     }
7201
7202   /* send it... */
7203   S;
7204
7205   /* Wait for a reply, return good/bad news  */
7206   W;
7207   /* NOTREACHED */
7208   return 0;
7209 }
7210
7211 static int
7212 api_dhcp_proxy_set_vss (vat_main_t * vam)
7213 {
7214   unformat_input_t *i = vam->input;
7215   vl_api_dhcp_proxy_set_vss_t *mp;
7216   f64 timeout;
7217   u8 is_ipv6 = 0;
7218   u8 is_add = 1;
7219   u32 tbl_id;
7220   u8 tbl_id_set = 0;
7221   u32 oui;
7222   u8 oui_set = 0;
7223   u32 fib_id;
7224   u8 fib_id_set = 0;
7225
7226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7227     {
7228       if (unformat (i, "tbl_id %d", &tbl_id))
7229         tbl_id_set = 1;
7230       if (unformat (i, "fib_id %d", &fib_id))
7231         fib_id_set = 1;
7232       if (unformat (i, "oui %d", &oui))
7233         oui_set = 1;
7234       else if (unformat (i, "ipv6"))
7235         is_ipv6 = 1;
7236       else if (unformat (i, "del"))
7237         is_add = 0;
7238       else
7239         {
7240           clib_warning ("parse error '%U'", format_unformat_error, i);
7241           return -99;
7242         }
7243     }
7244
7245   if (tbl_id_set == 0)
7246     {
7247       errmsg ("missing tbl id\n");
7248       return -99;
7249     }
7250
7251   if (fib_id_set == 0)
7252     {
7253       errmsg ("missing fib id\n");
7254       return -99;
7255     }
7256   if (oui_set == 0)
7257     {
7258       errmsg ("missing oui\n");
7259       return -99;
7260     }
7261
7262   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7263   mp->tbl_id = ntohl (tbl_id);
7264   mp->fib_id = ntohl (fib_id);
7265   mp->oui = ntohl (oui);
7266   mp->is_ipv6 = is_ipv6;
7267   mp->is_add = is_add;
7268
7269   S;
7270   W;
7271   /* NOTREACHED */
7272   return 0;
7273 }
7274
7275 static int
7276 api_dhcp_client_config (vat_main_t * vam)
7277 {
7278   unformat_input_t *i = vam->input;
7279   vl_api_dhcp_client_config_t *mp;
7280   f64 timeout;
7281   u32 sw_if_index;
7282   u8 sw_if_index_set = 0;
7283   u8 is_add = 1;
7284   u8 *hostname = 0;
7285   u8 disable_event = 0;
7286
7287   /* Parse args required to build the message */
7288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7289     {
7290       if (unformat (i, "del"))
7291         is_add = 0;
7292       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7293         sw_if_index_set = 1;
7294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7295         sw_if_index_set = 1;
7296       else if (unformat (i, "hostname %s", &hostname))
7297         ;
7298       else if (unformat (i, "disable_event"))
7299         disable_event = 1;
7300       else
7301         break;
7302     }
7303
7304   if (sw_if_index_set == 0)
7305     {
7306       errmsg ("missing interface name or sw_if_index\n");
7307       return -99;
7308     }
7309
7310   if (vec_len (hostname) > 63)
7311     {
7312       errmsg ("hostname too long\n");
7313     }
7314   vec_add1 (hostname, 0);
7315
7316   /* Construct the API message */
7317   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7318
7319   mp->sw_if_index = ntohl (sw_if_index);
7320   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7321   vec_free (hostname);
7322   mp->is_add = is_add;
7323   mp->want_dhcp_event = disable_event ? 0 : 1;
7324   mp->pid = getpid ();
7325
7326   /* send it... */
7327   S;
7328
7329   /* Wait for a reply, return good/bad news  */
7330   W;
7331   /* NOTREACHED */
7332   return 0;
7333 }
7334
7335 static int
7336 api_set_ip_flow_hash (vat_main_t * vam)
7337 {
7338   unformat_input_t *i = vam->input;
7339   vl_api_set_ip_flow_hash_t *mp;
7340   f64 timeout;
7341   u32 vrf_id = 0;
7342   u8 is_ipv6 = 0;
7343   u8 vrf_id_set = 0;
7344   u8 src = 0;
7345   u8 dst = 0;
7346   u8 sport = 0;
7347   u8 dport = 0;
7348   u8 proto = 0;
7349   u8 reverse = 0;
7350
7351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7352     {
7353       if (unformat (i, "vrf %d", &vrf_id))
7354         vrf_id_set = 1;
7355       else if (unformat (i, "ipv6"))
7356         is_ipv6 = 1;
7357       else if (unformat (i, "src"))
7358         src = 1;
7359       else if (unformat (i, "dst"))
7360         dst = 1;
7361       else if (unformat (i, "sport"))
7362         sport = 1;
7363       else if (unformat (i, "dport"))
7364         dport = 1;
7365       else if (unformat (i, "proto"))
7366         proto = 1;
7367       else if (unformat (i, "reverse"))
7368         reverse = 1;
7369
7370       else
7371         {
7372           clib_warning ("parse error '%U'", format_unformat_error, i);
7373           return -99;
7374         }
7375     }
7376
7377   if (vrf_id_set == 0)
7378     {
7379       errmsg ("missing vrf id\n");
7380       return -99;
7381     }
7382
7383   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7384   mp->src = src;
7385   mp->dst = dst;
7386   mp->sport = sport;
7387   mp->dport = dport;
7388   mp->proto = proto;
7389   mp->reverse = reverse;
7390   mp->vrf_id = ntohl (vrf_id);
7391   mp->is_ipv6 = is_ipv6;
7392
7393   S;
7394   W;
7395   /* NOTREACHED */
7396   return 0;
7397 }
7398
7399 static int
7400 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7401 {
7402   unformat_input_t *i = vam->input;
7403   vl_api_sw_interface_ip6_enable_disable_t *mp;
7404   f64 timeout;
7405   u32 sw_if_index;
7406   u8 sw_if_index_set = 0;
7407   u8 enable = 0;
7408
7409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7410     {
7411       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7412         sw_if_index_set = 1;
7413       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7414         sw_if_index_set = 1;
7415       else if (unformat (i, "enable"))
7416         enable = 1;
7417       else if (unformat (i, "disable"))
7418         enable = 0;
7419       else
7420         {
7421           clib_warning ("parse error '%U'", format_unformat_error, i);
7422           return -99;
7423         }
7424     }
7425
7426   if (sw_if_index_set == 0)
7427     {
7428       errmsg ("missing interface name or sw_if_index\n");
7429       return -99;
7430     }
7431
7432   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7433
7434   mp->sw_if_index = ntohl (sw_if_index);
7435   mp->enable = enable;
7436
7437   S;
7438   W;
7439   /* NOTREACHED */
7440   return 0;
7441 }
7442
7443 static int
7444 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7445 {
7446   unformat_input_t *i = vam->input;
7447   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7448   f64 timeout;
7449   u32 sw_if_index;
7450   u8 sw_if_index_set = 0;
7451   u32 address_length = 0;
7452   u8 v6_address_set = 0;
7453   ip6_address_t v6address;
7454
7455   /* Parse args required to build the message */
7456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7457     {
7458       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7459         sw_if_index_set = 1;
7460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7461         sw_if_index_set = 1;
7462       else if (unformat (i, "%U/%d",
7463                          unformat_ip6_address, &v6address, &address_length))
7464         v6_address_set = 1;
7465       else
7466         break;
7467     }
7468
7469   if (sw_if_index_set == 0)
7470     {
7471       errmsg ("missing interface name or sw_if_index\n");
7472       return -99;
7473     }
7474   if (!v6_address_set)
7475     {
7476       errmsg ("no address set\n");
7477       return -99;
7478     }
7479
7480   /* Construct the API message */
7481   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7482      sw_interface_ip6_set_link_local_address);
7483
7484   mp->sw_if_index = ntohl (sw_if_index);
7485   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7486   mp->address_length = address_length;
7487
7488   /* send it... */
7489   S;
7490
7491   /* Wait for a reply, return good/bad news  */
7492   W;
7493
7494   /* NOTREACHED */
7495   return 0;
7496 }
7497
7498
7499 static int
7500 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7501 {
7502   unformat_input_t *i = vam->input;
7503   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7504   f64 timeout;
7505   u32 sw_if_index;
7506   u8 sw_if_index_set = 0;
7507   u32 address_length = 0;
7508   u8 v6_address_set = 0;
7509   ip6_address_t v6address;
7510   u8 use_default = 0;
7511   u8 no_advertise = 0;
7512   u8 off_link = 0;
7513   u8 no_autoconfig = 0;
7514   u8 no_onlink = 0;
7515   u8 is_no = 0;
7516   u32 val_lifetime = 0;
7517   u32 pref_lifetime = 0;
7518
7519   /* Parse args required to build the message */
7520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7521     {
7522       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7523         sw_if_index_set = 1;
7524       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7525         sw_if_index_set = 1;
7526       else if (unformat (i, "%U/%d",
7527                          unformat_ip6_address, &v6address, &address_length))
7528         v6_address_set = 1;
7529       else if (unformat (i, "val_life %d", &val_lifetime))
7530         ;
7531       else if (unformat (i, "pref_life %d", &pref_lifetime))
7532         ;
7533       else if (unformat (i, "def"))
7534         use_default = 1;
7535       else if (unformat (i, "noadv"))
7536         no_advertise = 1;
7537       else if (unformat (i, "offl"))
7538         off_link = 1;
7539       else if (unformat (i, "noauto"))
7540         no_autoconfig = 1;
7541       else if (unformat (i, "nolink"))
7542         no_onlink = 1;
7543       else if (unformat (i, "isno"))
7544         is_no = 1;
7545       else
7546         {
7547           clib_warning ("parse error '%U'", format_unformat_error, i);
7548           return -99;
7549         }
7550     }
7551
7552   if (sw_if_index_set == 0)
7553     {
7554       errmsg ("missing interface name or sw_if_index\n");
7555       return -99;
7556     }
7557   if (!v6_address_set)
7558     {
7559       errmsg ("no address set\n");
7560       return -99;
7561     }
7562
7563   /* Construct the API message */
7564   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7565
7566   mp->sw_if_index = ntohl (sw_if_index);
7567   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7568   mp->address_length = address_length;
7569   mp->use_default = use_default;
7570   mp->no_advertise = no_advertise;
7571   mp->off_link = off_link;
7572   mp->no_autoconfig = no_autoconfig;
7573   mp->no_onlink = no_onlink;
7574   mp->is_no = is_no;
7575   mp->val_lifetime = ntohl (val_lifetime);
7576   mp->pref_lifetime = ntohl (pref_lifetime);
7577
7578   /* send it... */
7579   S;
7580
7581   /* Wait for a reply, return good/bad news  */
7582   W;
7583
7584   /* NOTREACHED */
7585   return 0;
7586 }
7587
7588 static int
7589 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7590 {
7591   unformat_input_t *i = vam->input;
7592   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7593   f64 timeout;
7594   u32 sw_if_index;
7595   u8 sw_if_index_set = 0;
7596   u8 suppress = 0;
7597   u8 managed = 0;
7598   u8 other = 0;
7599   u8 ll_option = 0;
7600   u8 send_unicast = 0;
7601   u8 cease = 0;
7602   u8 is_no = 0;
7603   u8 default_router = 0;
7604   u32 max_interval = 0;
7605   u32 min_interval = 0;
7606   u32 lifetime = 0;
7607   u32 initial_count = 0;
7608   u32 initial_interval = 0;
7609
7610
7611   /* Parse args required to build the message */
7612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7613     {
7614       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7615         sw_if_index_set = 1;
7616       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7617         sw_if_index_set = 1;
7618       else if (unformat (i, "maxint %d", &max_interval))
7619         ;
7620       else if (unformat (i, "minint %d", &min_interval))
7621         ;
7622       else if (unformat (i, "life %d", &lifetime))
7623         ;
7624       else if (unformat (i, "count %d", &initial_count))
7625         ;
7626       else if (unformat (i, "interval %d", &initial_interval))
7627         ;
7628       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7629         suppress = 1;
7630       else if (unformat (i, "managed"))
7631         managed = 1;
7632       else if (unformat (i, "other"))
7633         other = 1;
7634       else if (unformat (i, "ll"))
7635         ll_option = 1;
7636       else if (unformat (i, "send"))
7637         send_unicast = 1;
7638       else if (unformat (i, "cease"))
7639         cease = 1;
7640       else if (unformat (i, "isno"))
7641         is_no = 1;
7642       else if (unformat (i, "def"))
7643         default_router = 1;
7644       else
7645         {
7646           clib_warning ("parse error '%U'", format_unformat_error, i);
7647           return -99;
7648         }
7649     }
7650
7651   if (sw_if_index_set == 0)
7652     {
7653       errmsg ("missing interface name or sw_if_index\n");
7654       return -99;
7655     }
7656
7657   /* Construct the API message */
7658   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7659
7660   mp->sw_if_index = ntohl (sw_if_index);
7661   mp->max_interval = ntohl (max_interval);
7662   mp->min_interval = ntohl (min_interval);
7663   mp->lifetime = ntohl (lifetime);
7664   mp->initial_count = ntohl (initial_count);
7665   mp->initial_interval = ntohl (initial_interval);
7666   mp->suppress = suppress;
7667   mp->managed = managed;
7668   mp->other = other;
7669   mp->ll_option = ll_option;
7670   mp->send_unicast = send_unicast;
7671   mp->cease = cease;
7672   mp->is_no = is_no;
7673   mp->default_router = default_router;
7674
7675   /* send it... */
7676   S;
7677
7678   /* Wait for a reply, return good/bad news  */
7679   W;
7680
7681   /* NOTREACHED */
7682   return 0;
7683 }
7684
7685 static int
7686 api_set_arp_neighbor_limit (vat_main_t * vam)
7687 {
7688   unformat_input_t *i = vam->input;
7689   vl_api_set_arp_neighbor_limit_t *mp;
7690   f64 timeout;
7691   u32 arp_nbr_limit;
7692   u8 limit_set = 0;
7693   u8 is_ipv6 = 0;
7694
7695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7696     {
7697       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7698         limit_set = 1;
7699       else if (unformat (i, "ipv6"))
7700         is_ipv6 = 1;
7701       else
7702         {
7703           clib_warning ("parse error '%U'", format_unformat_error, i);
7704           return -99;
7705         }
7706     }
7707
7708   if (limit_set == 0)
7709     {
7710       errmsg ("missing limit value\n");
7711       return -99;
7712     }
7713
7714   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7715
7716   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7717   mp->is_ipv6 = is_ipv6;
7718
7719   S;
7720   W;
7721   /* NOTREACHED */
7722   return 0;
7723 }
7724
7725 static int
7726 api_l2_patch_add_del (vat_main_t * vam)
7727 {
7728   unformat_input_t *i = vam->input;
7729   vl_api_l2_patch_add_del_t *mp;
7730   f64 timeout;
7731   u32 rx_sw_if_index;
7732   u8 rx_sw_if_index_set = 0;
7733   u32 tx_sw_if_index;
7734   u8 tx_sw_if_index_set = 0;
7735   u8 is_add = 1;
7736
7737   /* Parse args required to build the message */
7738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7739     {
7740       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7741         rx_sw_if_index_set = 1;
7742       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7743         tx_sw_if_index_set = 1;
7744       else if (unformat (i, "rx"))
7745         {
7746           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7747             {
7748               if (unformat (i, "%U", unformat_sw_if_index, vam,
7749                             &rx_sw_if_index))
7750                 rx_sw_if_index_set = 1;
7751             }
7752           else
7753             break;
7754         }
7755       else if (unformat (i, "tx"))
7756         {
7757           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7758             {
7759               if (unformat (i, "%U", unformat_sw_if_index, vam,
7760                             &tx_sw_if_index))
7761                 tx_sw_if_index_set = 1;
7762             }
7763           else
7764             break;
7765         }
7766       else if (unformat (i, "del"))
7767         is_add = 0;
7768       else
7769         break;
7770     }
7771
7772   if (rx_sw_if_index_set == 0)
7773     {
7774       errmsg ("missing rx interface name or rx_sw_if_index\n");
7775       return -99;
7776     }
7777
7778   if (tx_sw_if_index_set == 0)
7779     {
7780       errmsg ("missing tx interface name or tx_sw_if_index\n");
7781       return -99;
7782     }
7783
7784   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7785
7786   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7787   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7788   mp->is_add = is_add;
7789
7790   S;
7791   W;
7792   /* NOTREACHED */
7793   return 0;
7794 }
7795
7796 static int
7797 api_ioam_enable (vat_main_t * vam)
7798 {
7799   unformat_input_t *input = vam->input;
7800   vl_api_ioam_enable_t *mp;
7801   f64 timeout;
7802   u32 id = 0;
7803   int has_trace_option = 0;
7804   int has_pow_option = 0;
7805   int has_ppc_option = 0;
7806
7807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7808     {
7809       if (unformat (input, "trace"))
7810         has_trace_option = 1;
7811       else if (unformat (input, "pow"))
7812         has_pow_option = 1;
7813       else if (unformat (input, "ppc encap"))
7814         has_ppc_option = PPC_ENCAP;
7815       else if (unformat (input, "ppc decap"))
7816         has_ppc_option = PPC_DECAP;
7817       else if (unformat (input, "ppc none"))
7818         has_ppc_option = PPC_NONE;
7819       else
7820         break;
7821     }
7822   M (IOAM_ENABLE, ioam_enable);
7823   mp->id = htons (id);
7824   mp->trace_ppc = has_ppc_option;
7825   mp->pow_enable = has_pow_option;
7826   mp->trace_enable = has_trace_option;
7827
7828   S;
7829   W;
7830
7831   return (0);
7832
7833 }
7834
7835
7836 static int
7837 api_ioam_disable (vat_main_t * vam)
7838 {
7839   vl_api_ioam_disable_t *mp;
7840   f64 timeout;
7841
7842   M (IOAM_DISABLE, ioam_disable);
7843   S;
7844   W;
7845   return 0;
7846 }
7847
7848 static int
7849 api_sr_tunnel_add_del (vat_main_t * vam)
7850 {
7851   unformat_input_t *i = vam->input;
7852   vl_api_sr_tunnel_add_del_t *mp;
7853   f64 timeout;
7854   int is_del = 0;
7855   int pl_index;
7856   ip6_address_t src_address;
7857   int src_address_set = 0;
7858   ip6_address_t dst_address;
7859   u32 dst_mask_width;
7860   int dst_address_set = 0;
7861   u16 flags = 0;
7862   u32 rx_table_id = 0;
7863   u32 tx_table_id = 0;
7864   ip6_address_t *segments = 0;
7865   ip6_address_t *this_seg;
7866   ip6_address_t *tags = 0;
7867   ip6_address_t *this_tag;
7868   ip6_address_t next_address, tag;
7869   u8 *name = 0;
7870   u8 *policy_name = 0;
7871
7872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7873     {
7874       if (unformat (i, "del"))
7875         is_del = 1;
7876       else if (unformat (i, "name %s", &name))
7877         ;
7878       else if (unformat (i, "policy %s", &policy_name))
7879         ;
7880       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7881         ;
7882       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7883         ;
7884       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7885         src_address_set = 1;
7886       else if (unformat (i, "dst %U/%d",
7887                          unformat_ip6_address, &dst_address, &dst_mask_width))
7888         dst_address_set = 1;
7889       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7890         {
7891           vec_add2 (segments, this_seg, 1);
7892           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7893                        sizeof (*this_seg));
7894         }
7895       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7896         {
7897           vec_add2 (tags, this_tag, 1);
7898           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7899         }
7900       else if (unformat (i, "clean"))
7901         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7902       else if (unformat (i, "protected"))
7903         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7904       else if (unformat (i, "InPE %d", &pl_index))
7905         {
7906           if (pl_index <= 0 || pl_index > 4)
7907             {
7908             pl_index_range_error:
7909               errmsg ("pl index %d out of range\n", pl_index);
7910               return -99;
7911             }
7912           flags |=
7913             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7914         }
7915       else if (unformat (i, "EgPE %d", &pl_index))
7916         {
7917           if (pl_index <= 0 || pl_index > 4)
7918             goto pl_index_range_error;
7919           flags |=
7920             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7921         }
7922       else if (unformat (i, "OrgSrc %d", &pl_index))
7923         {
7924           if (pl_index <= 0 || pl_index > 4)
7925             goto pl_index_range_error;
7926           flags |=
7927             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7928         }
7929       else
7930         break;
7931     }
7932
7933   if (!src_address_set)
7934     {
7935       errmsg ("src address required\n");
7936       return -99;
7937     }
7938
7939   if (!dst_address_set)
7940     {
7941       errmsg ("dst address required\n");
7942       return -99;
7943     }
7944
7945   if (!segments)
7946     {
7947       errmsg ("at least one sr segment required\n");
7948       return -99;
7949     }
7950
7951   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7952       vec_len (segments) * sizeof (ip6_address_t)
7953       + vec_len (tags) * sizeof (ip6_address_t));
7954
7955   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7956   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7957   mp->dst_mask_width = dst_mask_width;
7958   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7959   mp->n_segments = vec_len (segments);
7960   mp->n_tags = vec_len (tags);
7961   mp->is_add = is_del == 0;
7962   clib_memcpy (mp->segs_and_tags, segments,
7963                vec_len (segments) * sizeof (ip6_address_t));
7964   clib_memcpy (mp->segs_and_tags +
7965                vec_len (segments) * sizeof (ip6_address_t), tags,
7966                vec_len (tags) * sizeof (ip6_address_t));
7967
7968   mp->outer_vrf_id = ntohl (rx_table_id);
7969   mp->inner_vrf_id = ntohl (tx_table_id);
7970   memcpy (mp->name, name, vec_len (name));
7971   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7972
7973   vec_free (segments);
7974   vec_free (tags);
7975
7976   S;
7977   W;
7978   /* NOTREACHED */
7979 }
7980
7981 static int
7982 api_sr_policy_add_del (vat_main_t * vam)
7983 {
7984   unformat_input_t *input = vam->input;
7985   vl_api_sr_policy_add_del_t *mp;
7986   f64 timeout;
7987   int is_del = 0;
7988   u8 *name = 0;
7989   u8 *tunnel_name = 0;
7990   u8 **tunnel_names = 0;
7991
7992   int name_set = 0;
7993   int tunnel_set = 0;
7994   int j = 0;
7995   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7996   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7997
7998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7999     {
8000       if (unformat (input, "del"))
8001         is_del = 1;
8002       else if (unformat (input, "name %s", &name))
8003         name_set = 1;
8004       else if (unformat (input, "tunnel %s", &tunnel_name))
8005         {
8006           if (tunnel_name)
8007             {
8008               vec_add1 (tunnel_names, tunnel_name);
8009               /* For serializer:
8010                  - length = #bytes to store in serial vector
8011                  - +1 = byte to store that length
8012                */
8013               tunnel_names_length += (vec_len (tunnel_name) + 1);
8014               tunnel_set = 1;
8015               tunnel_name = 0;
8016             }
8017         }
8018       else
8019         break;
8020     }
8021
8022   if (!name_set)
8023     {
8024       errmsg ("policy name required\n");
8025       return -99;
8026     }
8027
8028   if ((!tunnel_set) && (!is_del))
8029     {
8030       errmsg ("tunnel name required\n");
8031       return -99;
8032     }
8033
8034   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8035
8036
8037
8038   mp->is_add = !is_del;
8039
8040   memcpy (mp->name, name, vec_len (name));
8041   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8042   u8 *serial_orig = 0;
8043   vec_validate (serial_orig, tunnel_names_length);
8044   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8045   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8046
8047   for (j = 0; j < vec_len (tunnel_names); j++)
8048     {
8049       tun_name_len = vec_len (tunnel_names[j]);
8050       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8051       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8052       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8053       serial_orig += tun_name_len;      // Advance past the copy
8054     }
8055   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8056
8057   vec_free (tunnel_names);
8058   vec_free (tunnel_name);
8059
8060   S;
8061   W;
8062   /* NOTREACHED */
8063 }
8064
8065 static int
8066 api_sr_multicast_map_add_del (vat_main_t * vam)
8067 {
8068   unformat_input_t *input = vam->input;
8069   vl_api_sr_multicast_map_add_del_t *mp;
8070   f64 timeout;
8071   int is_del = 0;
8072   ip6_address_t multicast_address;
8073   u8 *policy_name = 0;
8074   int multicast_address_set = 0;
8075
8076   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8077     {
8078       if (unformat (input, "del"))
8079         is_del = 1;
8080       else
8081         if (unformat
8082             (input, "address %U", unformat_ip6_address, &multicast_address))
8083         multicast_address_set = 1;
8084       else if (unformat (input, "sr-policy %s", &policy_name))
8085         ;
8086       else
8087         break;
8088     }
8089
8090   if (!is_del && !policy_name)
8091     {
8092       errmsg ("sr-policy name required\n");
8093       return -99;
8094     }
8095
8096
8097   if (!multicast_address_set)
8098     {
8099       errmsg ("address required\n");
8100       return -99;
8101     }
8102
8103   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8104
8105   mp->is_add = !is_del;
8106   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8107   clib_memcpy (mp->multicast_address, &multicast_address,
8108                sizeof (mp->multicast_address));
8109
8110
8111   vec_free (policy_name);
8112
8113   S;
8114   W;
8115   /* NOTREACHED */
8116 }
8117
8118
8119 #define foreach_tcp_proto_field                 \
8120 _(src_port)                                     \
8121 _(dst_port)
8122
8123 #define foreach_udp_proto_field                 \
8124 _(src_port)                                     \
8125 _(dst_port)
8126
8127 #define foreach_ip4_proto_field                 \
8128 _(src_address)                                  \
8129 _(dst_address)                                  \
8130 _(tos)                                          \
8131 _(length)                                       \
8132 _(fragment_id)                                  \
8133 _(ttl)                                          \
8134 _(protocol)                                     \
8135 _(checksum)
8136
8137 uword
8138 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8139 {
8140   u8 **maskp = va_arg (*args, u8 **);
8141   u8 *mask = 0;
8142   u8 found_something = 0;
8143   tcp_header_t *tcp;
8144
8145 #define _(a) u8 a=0;
8146   foreach_tcp_proto_field;
8147 #undef _
8148
8149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8150     {
8151       if (0);
8152 #define _(a) else if (unformat (input, #a)) a=1;
8153       foreach_tcp_proto_field
8154 #undef _
8155         else
8156         break;
8157     }
8158
8159 #define _(a) found_something += a;
8160   foreach_tcp_proto_field;
8161 #undef _
8162
8163   if (found_something == 0)
8164     return 0;
8165
8166   vec_validate (mask, sizeof (*tcp) - 1);
8167
8168   tcp = (tcp_header_t *) mask;
8169
8170 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8171   foreach_tcp_proto_field;
8172 #undef _
8173
8174   *maskp = mask;
8175   return 1;
8176 }
8177
8178 uword
8179 unformat_udp_mask (unformat_input_t * input, va_list * args)
8180 {
8181   u8 **maskp = va_arg (*args, u8 **);
8182   u8 *mask = 0;
8183   u8 found_something = 0;
8184   udp_header_t *udp;
8185
8186 #define _(a) u8 a=0;
8187   foreach_udp_proto_field;
8188 #undef _
8189
8190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8191     {
8192       if (0);
8193 #define _(a) else if (unformat (input, #a)) a=1;
8194       foreach_udp_proto_field
8195 #undef _
8196         else
8197         break;
8198     }
8199
8200 #define _(a) found_something += a;
8201   foreach_udp_proto_field;
8202 #undef _
8203
8204   if (found_something == 0)
8205     return 0;
8206
8207   vec_validate (mask, sizeof (*udp) - 1);
8208
8209   udp = (udp_header_t *) mask;
8210
8211 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8212   foreach_udp_proto_field;
8213 #undef _
8214
8215   *maskp = mask;
8216   return 1;
8217 }
8218
8219 typedef struct
8220 {
8221   u16 src_port, dst_port;
8222 } tcpudp_header_t;
8223
8224 uword
8225 unformat_l4_mask (unformat_input_t * input, va_list * args)
8226 {
8227   u8 **maskp = va_arg (*args, u8 **);
8228   u16 src_port = 0, dst_port = 0;
8229   tcpudp_header_t *tcpudp;
8230
8231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8232     {
8233       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8234         return 1;
8235       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8236         return 1;
8237       else if (unformat (input, "src_port"))
8238         src_port = 0xFFFF;
8239       else if (unformat (input, "dst_port"))
8240         dst_port = 0xFFFF;
8241       else
8242         return 0;
8243     }
8244
8245   if (!src_port && !dst_port)
8246     return 0;
8247
8248   u8 *mask = 0;
8249   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8250
8251   tcpudp = (tcpudp_header_t *) mask;
8252   tcpudp->src_port = src_port;
8253   tcpudp->dst_port = dst_port;
8254
8255   *maskp = mask;
8256
8257   return 1;
8258 }
8259
8260 uword
8261 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8262 {
8263   u8 **maskp = va_arg (*args, u8 **);
8264   u8 *mask = 0;
8265   u8 found_something = 0;
8266   ip4_header_t *ip;
8267
8268 #define _(a) u8 a=0;
8269   foreach_ip4_proto_field;
8270 #undef _
8271   u8 version = 0;
8272   u8 hdr_length = 0;
8273
8274
8275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8276     {
8277       if (unformat (input, "version"))
8278         version = 1;
8279       else if (unformat (input, "hdr_length"))
8280         hdr_length = 1;
8281       else if (unformat (input, "src"))
8282         src_address = 1;
8283       else if (unformat (input, "dst"))
8284         dst_address = 1;
8285       else if (unformat (input, "proto"))
8286         protocol = 1;
8287
8288 #define _(a) else if (unformat (input, #a)) a=1;
8289       foreach_ip4_proto_field
8290 #undef _
8291         else
8292         break;
8293     }
8294
8295 #define _(a) found_something += a;
8296   foreach_ip4_proto_field;
8297 #undef _
8298
8299   if (found_something == 0)
8300     return 0;
8301
8302   vec_validate (mask, sizeof (*ip) - 1);
8303
8304   ip = (ip4_header_t *) mask;
8305
8306 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8307   foreach_ip4_proto_field;
8308 #undef _
8309
8310   ip->ip_version_and_header_length = 0;
8311
8312   if (version)
8313     ip->ip_version_and_header_length |= 0xF0;
8314
8315   if (hdr_length)
8316     ip->ip_version_and_header_length |= 0x0F;
8317
8318   *maskp = mask;
8319   return 1;
8320 }
8321
8322 #define foreach_ip6_proto_field                 \
8323 _(src_address)                                  \
8324 _(dst_address)                                  \
8325 _(payload_length)                               \
8326 _(hop_limit)                                    \
8327 _(protocol)
8328
8329 uword
8330 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8331 {
8332   u8 **maskp = va_arg (*args, u8 **);
8333   u8 *mask = 0;
8334   u8 found_something = 0;
8335   ip6_header_t *ip;
8336   u32 ip_version_traffic_class_and_flow_label;
8337
8338 #define _(a) u8 a=0;
8339   foreach_ip6_proto_field;
8340 #undef _
8341   u8 version = 0;
8342   u8 traffic_class = 0;
8343   u8 flow_label = 0;
8344
8345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8346     {
8347       if (unformat (input, "version"))
8348         version = 1;
8349       else if (unformat (input, "traffic-class"))
8350         traffic_class = 1;
8351       else if (unformat (input, "flow-label"))
8352         flow_label = 1;
8353       else if (unformat (input, "src"))
8354         src_address = 1;
8355       else if (unformat (input, "dst"))
8356         dst_address = 1;
8357       else if (unformat (input, "proto"))
8358         protocol = 1;
8359
8360 #define _(a) else if (unformat (input, #a)) a=1;
8361       foreach_ip6_proto_field
8362 #undef _
8363         else
8364         break;
8365     }
8366
8367 #define _(a) found_something += a;
8368   foreach_ip6_proto_field;
8369 #undef _
8370
8371   if (found_something == 0)
8372     return 0;
8373
8374   vec_validate (mask, sizeof (*ip) - 1);
8375
8376   ip = (ip6_header_t *) mask;
8377
8378 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8379   foreach_ip6_proto_field;
8380 #undef _
8381
8382   ip_version_traffic_class_and_flow_label = 0;
8383
8384   if (version)
8385     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8386
8387   if (traffic_class)
8388     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8389
8390   if (flow_label)
8391     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8392
8393   ip->ip_version_traffic_class_and_flow_label =
8394     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8395
8396   *maskp = mask;
8397   return 1;
8398 }
8399
8400 uword
8401 unformat_l3_mask (unformat_input_t * input, va_list * args)
8402 {
8403   u8 **maskp = va_arg (*args, u8 **);
8404
8405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8406     {
8407       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8408         return 1;
8409       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8410         return 1;
8411       else
8412         break;
8413     }
8414   return 0;
8415 }
8416
8417 uword
8418 unformat_l2_mask (unformat_input_t * input, va_list * args)
8419 {
8420   u8 **maskp = va_arg (*args, u8 **);
8421   u8 *mask = 0;
8422   u8 src = 0;
8423   u8 dst = 0;
8424   u8 proto = 0;
8425   u8 tag1 = 0;
8426   u8 tag2 = 0;
8427   u8 ignore_tag1 = 0;
8428   u8 ignore_tag2 = 0;
8429   u8 cos1 = 0;
8430   u8 cos2 = 0;
8431   u8 dot1q = 0;
8432   u8 dot1ad = 0;
8433   int len = 14;
8434
8435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8436     {
8437       if (unformat (input, "src"))
8438         src = 1;
8439       else if (unformat (input, "dst"))
8440         dst = 1;
8441       else if (unformat (input, "proto"))
8442         proto = 1;
8443       else if (unformat (input, "tag1"))
8444         tag1 = 1;
8445       else if (unformat (input, "tag2"))
8446         tag2 = 1;
8447       else if (unformat (input, "ignore-tag1"))
8448         ignore_tag1 = 1;
8449       else if (unformat (input, "ignore-tag2"))
8450         ignore_tag2 = 1;
8451       else if (unformat (input, "cos1"))
8452         cos1 = 1;
8453       else if (unformat (input, "cos2"))
8454         cos2 = 1;
8455       else if (unformat (input, "dot1q"))
8456         dot1q = 1;
8457       else if (unformat (input, "dot1ad"))
8458         dot1ad = 1;
8459       else
8460         break;
8461     }
8462   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8463        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8464     return 0;
8465
8466   if (tag1 || ignore_tag1 || cos1 || dot1q)
8467     len = 18;
8468   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8469     len = 22;
8470
8471   vec_validate (mask, len - 1);
8472
8473   if (dst)
8474     memset (mask, 0xff, 6);
8475
8476   if (src)
8477     memset (mask + 6, 0xff, 6);
8478
8479   if (tag2 || dot1ad)
8480     {
8481       /* inner vlan tag */
8482       if (tag2)
8483         {
8484           mask[19] = 0xff;
8485           mask[18] = 0x0f;
8486         }
8487       if (cos2)
8488         mask[18] |= 0xe0;
8489       if (proto)
8490         mask[21] = mask[20] = 0xff;
8491       if (tag1)
8492         {
8493           mask[15] = 0xff;
8494           mask[14] = 0x0f;
8495         }
8496       if (cos1)
8497         mask[14] |= 0xe0;
8498       *maskp = mask;
8499       return 1;
8500     }
8501   if (tag1 | dot1q)
8502     {
8503       if (tag1)
8504         {
8505           mask[15] = 0xff;
8506           mask[14] = 0x0f;
8507         }
8508       if (cos1)
8509         mask[14] |= 0xe0;
8510       if (proto)
8511         mask[16] = mask[17] = 0xff;
8512
8513       *maskp = mask;
8514       return 1;
8515     }
8516   if (cos2)
8517     mask[18] |= 0xe0;
8518   if (cos1)
8519     mask[14] |= 0xe0;
8520   if (proto)
8521     mask[12] = mask[13] = 0xff;
8522
8523   *maskp = mask;
8524   return 1;
8525 }
8526
8527 uword
8528 unformat_classify_mask (unformat_input_t * input, va_list * args)
8529 {
8530   u8 **maskp = va_arg (*args, u8 **);
8531   u32 *skipp = va_arg (*args, u32 *);
8532   u32 *matchp = va_arg (*args, u32 *);
8533   u32 match;
8534   u8 *mask = 0;
8535   u8 *l2 = 0;
8536   u8 *l3 = 0;
8537   u8 *l4 = 0;
8538   int i;
8539
8540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8541     {
8542       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8543         ;
8544       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8545         ;
8546       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8547         ;
8548       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8549         ;
8550       else
8551         break;
8552     }
8553
8554   if (l4 && !l3)
8555     {
8556       vec_free (mask);
8557       vec_free (l2);
8558       vec_free (l4);
8559       return 0;
8560     }
8561
8562   if (mask || l2 || l3 || l4)
8563     {
8564       if (l2 || l3 || l4)
8565         {
8566           /* "With a free Ethernet header in every package" */
8567           if (l2 == 0)
8568             vec_validate (l2, 13);
8569           mask = l2;
8570           if (vec_len (l3))
8571             {
8572               vec_append (mask, l3);
8573               vec_free (l3);
8574             }
8575           if (vec_len (l4))
8576             {
8577               vec_append (mask, l4);
8578               vec_free (l4);
8579             }
8580         }
8581
8582       /* Scan forward looking for the first significant mask octet */
8583       for (i = 0; i < vec_len (mask); i++)
8584         if (mask[i])
8585           break;
8586
8587       /* compute (skip, match) params */
8588       *skipp = i / sizeof (u32x4);
8589       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8590
8591       /* Pad mask to an even multiple of the vector size */
8592       while (vec_len (mask) % sizeof (u32x4))
8593         vec_add1 (mask, 0);
8594
8595       match = vec_len (mask) / sizeof (u32x4);
8596
8597       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8598         {
8599           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8600           if (*tmp || *(tmp + 1))
8601             break;
8602           match--;
8603         }
8604       if (match == 0)
8605         clib_warning ("BUG: match 0");
8606
8607       _vec_len (mask) = match * sizeof (u32x4);
8608
8609       *matchp = match;
8610       *maskp = mask;
8611
8612       return 1;
8613     }
8614
8615   return 0;
8616 }
8617
8618 #define foreach_l2_next                         \
8619 _(drop, DROP)                                   \
8620 _(ethernet, ETHERNET_INPUT)                     \
8621 _(ip4, IP4_INPUT)                               \
8622 _(ip6, IP6_INPUT)
8623
8624 uword
8625 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8626 {
8627   u32 *miss_next_indexp = va_arg (*args, u32 *);
8628   u32 next_index = 0;
8629   u32 tmp;
8630
8631 #define _(n,N) \
8632   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8633   foreach_l2_next;
8634 #undef _
8635
8636   if (unformat (input, "%d", &tmp))
8637     {
8638       next_index = tmp;
8639       goto out;
8640     }
8641
8642   return 0;
8643
8644 out:
8645   *miss_next_indexp = next_index;
8646   return 1;
8647 }
8648
8649 #define foreach_ip_next                         \
8650 _(drop, DROP)                                   \
8651 _(local, LOCAL)                                 \
8652 _(rewrite, REWRITE)
8653
8654 uword
8655 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8656 {
8657   u32 *miss_next_indexp = va_arg (*args, u32 *);
8658   u32 next_index = 0;
8659   u32 tmp;
8660
8661 #define _(n,N) \
8662   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8663   foreach_ip_next;
8664 #undef _
8665
8666   if (unformat (input, "%d", &tmp))
8667     {
8668       next_index = tmp;
8669       goto out;
8670     }
8671
8672   return 0;
8673
8674 out:
8675   *miss_next_indexp = next_index;
8676   return 1;
8677 }
8678
8679 #define foreach_acl_next                        \
8680 _(deny, DENY)
8681
8682 uword
8683 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8684 {
8685   u32 *miss_next_indexp = va_arg (*args, u32 *);
8686   u32 next_index = 0;
8687   u32 tmp;
8688
8689 #define _(n,N) \
8690   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8691   foreach_acl_next;
8692 #undef _
8693
8694   if (unformat (input, "permit"))
8695     {
8696       next_index = ~0;
8697       goto out;
8698     }
8699   else if (unformat (input, "%d", &tmp))
8700     {
8701       next_index = tmp;
8702       goto out;
8703     }
8704
8705   return 0;
8706
8707 out:
8708   *miss_next_indexp = next_index;
8709   return 1;
8710 }
8711
8712 uword
8713 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8714 {
8715   u32 *r = va_arg (*args, u32 *);
8716
8717   if (unformat (input, "conform-color"))
8718     *r = POLICE_CONFORM;
8719   else if (unformat (input, "exceed-color"))
8720     *r = POLICE_EXCEED;
8721   else
8722     return 0;
8723
8724   return 1;
8725 }
8726
8727 static int
8728 api_classify_add_del_table (vat_main_t * vam)
8729 {
8730   unformat_input_t *i = vam->input;
8731   vl_api_classify_add_del_table_t *mp;
8732
8733   u32 nbuckets = 2;
8734   u32 skip = ~0;
8735   u32 match = ~0;
8736   int is_add = 1;
8737   u32 table_index = ~0;
8738   u32 next_table_index = ~0;
8739   u32 miss_next_index = ~0;
8740   u32 memory_size = 32 << 20;
8741   u8 *mask = 0;
8742   f64 timeout;
8743
8744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8745     {
8746       if (unformat (i, "del"))
8747         is_add = 0;
8748       else if (unformat (i, "buckets %d", &nbuckets))
8749         ;
8750       else if (unformat (i, "memory_size %d", &memory_size))
8751         ;
8752       else if (unformat (i, "skip %d", &skip))
8753         ;
8754       else if (unformat (i, "match %d", &match))
8755         ;
8756       else if (unformat (i, "table %d", &table_index))
8757         ;
8758       else if (unformat (i, "mask %U", unformat_classify_mask,
8759                          &mask, &skip, &match))
8760         ;
8761       else if (unformat (i, "next-table %d", &next_table_index))
8762         ;
8763       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8764                          &miss_next_index))
8765         ;
8766       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8767                          &miss_next_index))
8768         ;
8769       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8770                          &miss_next_index))
8771         ;
8772       else
8773         break;
8774     }
8775
8776   if (is_add && mask == 0)
8777     {
8778       errmsg ("Mask required\n");
8779       return -99;
8780     }
8781
8782   if (is_add && skip == ~0)
8783     {
8784       errmsg ("skip count required\n");
8785       return -99;
8786     }
8787
8788   if (is_add && match == ~0)
8789     {
8790       errmsg ("match count required\n");
8791       return -99;
8792     }
8793
8794   if (!is_add && table_index == ~0)
8795     {
8796       errmsg ("table index required for delete\n");
8797       return -99;
8798     }
8799
8800   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8801
8802   mp->is_add = is_add;
8803   mp->table_index = ntohl (table_index);
8804   mp->nbuckets = ntohl (nbuckets);
8805   mp->memory_size = ntohl (memory_size);
8806   mp->skip_n_vectors = ntohl (skip);
8807   mp->match_n_vectors = ntohl (match);
8808   mp->next_table_index = ntohl (next_table_index);
8809   mp->miss_next_index = ntohl (miss_next_index);
8810   clib_memcpy (mp->mask, mask, vec_len (mask));
8811
8812   vec_free (mask);
8813
8814   S;
8815   W;
8816   /* NOTREACHED */
8817 }
8818
8819 uword
8820 unformat_l4_match (unformat_input_t * input, va_list * args)
8821 {
8822   u8 **matchp = va_arg (*args, u8 **);
8823
8824   u8 *proto_header = 0;
8825   int src_port = 0;
8826   int dst_port = 0;
8827
8828   tcpudp_header_t h;
8829
8830   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8831     {
8832       if (unformat (input, "src_port %d", &src_port))
8833         ;
8834       else if (unformat (input, "dst_port %d", &dst_port))
8835         ;
8836       else
8837         return 0;
8838     }
8839
8840   h.src_port = clib_host_to_net_u16 (src_port);
8841   h.dst_port = clib_host_to_net_u16 (dst_port);
8842   vec_validate (proto_header, sizeof (h) - 1);
8843   memcpy (proto_header, &h, sizeof (h));
8844
8845   *matchp = proto_header;
8846
8847   return 1;
8848 }
8849
8850 uword
8851 unformat_ip4_match (unformat_input_t * input, va_list * args)
8852 {
8853   u8 **matchp = va_arg (*args, u8 **);
8854   u8 *match = 0;
8855   ip4_header_t *ip;
8856   int version = 0;
8857   u32 version_val;
8858   int hdr_length = 0;
8859   u32 hdr_length_val;
8860   int src = 0, dst = 0;
8861   ip4_address_t src_val, dst_val;
8862   int proto = 0;
8863   u32 proto_val;
8864   int tos = 0;
8865   u32 tos_val;
8866   int length = 0;
8867   u32 length_val;
8868   int fragment_id = 0;
8869   u32 fragment_id_val;
8870   int ttl = 0;
8871   int ttl_val;
8872   int checksum = 0;
8873   u32 checksum_val;
8874
8875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8876     {
8877       if (unformat (input, "version %d", &version_val))
8878         version = 1;
8879       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8880         hdr_length = 1;
8881       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8882         src = 1;
8883       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8884         dst = 1;
8885       else if (unformat (input, "proto %d", &proto_val))
8886         proto = 1;
8887       else if (unformat (input, "tos %d", &tos_val))
8888         tos = 1;
8889       else if (unformat (input, "length %d", &length_val))
8890         length = 1;
8891       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8892         fragment_id = 1;
8893       else if (unformat (input, "ttl %d", &ttl_val))
8894         ttl = 1;
8895       else if (unformat (input, "checksum %d", &checksum_val))
8896         checksum = 1;
8897       else
8898         break;
8899     }
8900
8901   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8902       + ttl + checksum == 0)
8903     return 0;
8904
8905   /*
8906    * Aligned because we use the real comparison functions
8907    */
8908   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8909
8910   ip = (ip4_header_t *) match;
8911
8912   /* These are realistically matched in practice */
8913   if (src)
8914     ip->src_address.as_u32 = src_val.as_u32;
8915
8916   if (dst)
8917     ip->dst_address.as_u32 = dst_val.as_u32;
8918
8919   if (proto)
8920     ip->protocol = proto_val;
8921
8922
8923   /* These are not, but they're included for completeness */
8924   if (version)
8925     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8926
8927   if (hdr_length)
8928     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8929
8930   if (tos)
8931     ip->tos = tos_val;
8932
8933   if (length)
8934     ip->length = clib_host_to_net_u16 (length_val);
8935
8936   if (ttl)
8937     ip->ttl = ttl_val;
8938
8939   if (checksum)
8940     ip->checksum = clib_host_to_net_u16 (checksum_val);
8941
8942   *matchp = match;
8943   return 1;
8944 }
8945
8946 uword
8947 unformat_ip6_match (unformat_input_t * input, va_list * args)
8948 {
8949   u8 **matchp = va_arg (*args, u8 **);
8950   u8 *match = 0;
8951   ip6_header_t *ip;
8952   int version = 0;
8953   u32 version_val;
8954   u8 traffic_class = 0;
8955   u32 traffic_class_val = 0;
8956   u8 flow_label = 0;
8957   u8 flow_label_val;
8958   int src = 0, dst = 0;
8959   ip6_address_t src_val, dst_val;
8960   int proto = 0;
8961   u32 proto_val;
8962   int payload_length = 0;
8963   u32 payload_length_val;
8964   int hop_limit = 0;
8965   int hop_limit_val;
8966   u32 ip_version_traffic_class_and_flow_label;
8967
8968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8969     {
8970       if (unformat (input, "version %d", &version_val))
8971         version = 1;
8972       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8973         traffic_class = 1;
8974       else if (unformat (input, "flow_label %d", &flow_label_val))
8975         flow_label = 1;
8976       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8977         src = 1;
8978       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8979         dst = 1;
8980       else if (unformat (input, "proto %d", &proto_val))
8981         proto = 1;
8982       else if (unformat (input, "payload_length %d", &payload_length_val))
8983         payload_length = 1;
8984       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8985         hop_limit = 1;
8986       else
8987         break;
8988     }
8989
8990   if (version + traffic_class + flow_label + src + dst + proto +
8991       payload_length + hop_limit == 0)
8992     return 0;
8993
8994   /*
8995    * Aligned because we use the real comparison functions
8996    */
8997   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8998
8999   ip = (ip6_header_t *) match;
9000
9001   if (src)
9002     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9003
9004   if (dst)
9005     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9006
9007   if (proto)
9008     ip->protocol = proto_val;
9009
9010   ip_version_traffic_class_and_flow_label = 0;
9011
9012   if (version)
9013     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9014
9015   if (traffic_class)
9016     ip_version_traffic_class_and_flow_label |=
9017       (traffic_class_val & 0xFF) << 20;
9018
9019   if (flow_label)
9020     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9021
9022   ip->ip_version_traffic_class_and_flow_label =
9023     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9024
9025   if (payload_length)
9026     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9027
9028   if (hop_limit)
9029     ip->hop_limit = hop_limit_val;
9030
9031   *matchp = match;
9032   return 1;
9033 }
9034
9035 uword
9036 unformat_l3_match (unformat_input_t * input, va_list * args)
9037 {
9038   u8 **matchp = va_arg (*args, u8 **);
9039
9040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9041     {
9042       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9043         return 1;
9044       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9045         return 1;
9046       else
9047         break;
9048     }
9049   return 0;
9050 }
9051
9052 uword
9053 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9054 {
9055   u8 *tagp = va_arg (*args, u8 *);
9056   u32 tag;
9057
9058   if (unformat (input, "%d", &tag))
9059     {
9060       tagp[0] = (tag >> 8) & 0x0F;
9061       tagp[1] = tag & 0xFF;
9062       return 1;
9063     }
9064
9065   return 0;
9066 }
9067
9068 uword
9069 unformat_l2_match (unformat_input_t * input, va_list * args)
9070 {
9071   u8 **matchp = va_arg (*args, u8 **);
9072   u8 *match = 0;
9073   u8 src = 0;
9074   u8 src_val[6];
9075   u8 dst = 0;
9076   u8 dst_val[6];
9077   u8 proto = 0;
9078   u16 proto_val;
9079   u8 tag1 = 0;
9080   u8 tag1_val[2];
9081   u8 tag2 = 0;
9082   u8 tag2_val[2];
9083   int len = 14;
9084   u8 ignore_tag1 = 0;
9085   u8 ignore_tag2 = 0;
9086   u8 cos1 = 0;
9087   u8 cos2 = 0;
9088   u32 cos1_val = 0;
9089   u32 cos2_val = 0;
9090
9091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9092     {
9093       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9094         src = 1;
9095       else
9096         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9097         dst = 1;
9098       else if (unformat (input, "proto %U",
9099                          unformat_ethernet_type_host_byte_order, &proto_val))
9100         proto = 1;
9101       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9102         tag1 = 1;
9103       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9104         tag2 = 1;
9105       else if (unformat (input, "ignore-tag1"))
9106         ignore_tag1 = 1;
9107       else if (unformat (input, "ignore-tag2"))
9108         ignore_tag2 = 1;
9109       else if (unformat (input, "cos1 %d", &cos1_val))
9110         cos1 = 1;
9111       else if (unformat (input, "cos2 %d", &cos2_val))
9112         cos2 = 1;
9113       else
9114         break;
9115     }
9116   if ((src + dst + proto + tag1 + tag2 +
9117        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9118     return 0;
9119
9120   if (tag1 || ignore_tag1 || cos1)
9121     len = 18;
9122   if (tag2 || ignore_tag2 || cos2)
9123     len = 22;
9124
9125   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9126
9127   if (dst)
9128     clib_memcpy (match, dst_val, 6);
9129
9130   if (src)
9131     clib_memcpy (match + 6, src_val, 6);
9132
9133   if (tag2)
9134     {
9135       /* inner vlan tag */
9136       match[19] = tag2_val[1];
9137       match[18] = tag2_val[0];
9138       if (cos2)
9139         match[18] |= (cos2_val & 0x7) << 5;
9140       if (proto)
9141         {
9142           match[21] = proto_val & 0xff;
9143           match[20] = proto_val >> 8;
9144         }
9145       if (tag1)
9146         {
9147           match[15] = tag1_val[1];
9148           match[14] = tag1_val[0];
9149         }
9150       if (cos1)
9151         match[14] |= (cos1_val & 0x7) << 5;
9152       *matchp = match;
9153       return 1;
9154     }
9155   if (tag1)
9156     {
9157       match[15] = tag1_val[1];
9158       match[14] = tag1_val[0];
9159       if (proto)
9160         {
9161           match[17] = proto_val & 0xff;
9162           match[16] = proto_val >> 8;
9163         }
9164       if (cos1)
9165         match[14] |= (cos1_val & 0x7) << 5;
9166
9167       *matchp = match;
9168       return 1;
9169     }
9170   if (cos2)
9171     match[18] |= (cos2_val & 0x7) << 5;
9172   if (cos1)
9173     match[14] |= (cos1_val & 0x7) << 5;
9174   if (proto)
9175     {
9176       match[13] = proto_val & 0xff;
9177       match[12] = proto_val >> 8;
9178     }
9179
9180   *matchp = match;
9181   return 1;
9182 }
9183
9184
9185 uword
9186 unformat_classify_match (unformat_input_t * input, va_list * args)
9187 {
9188   u8 **matchp = va_arg (*args, u8 **);
9189   u32 skip_n_vectors = va_arg (*args, u32);
9190   u32 match_n_vectors = va_arg (*args, u32);
9191
9192   u8 *match = 0;
9193   u8 *l2 = 0;
9194   u8 *l3 = 0;
9195   u8 *l4 = 0;
9196
9197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9198     {
9199       if (unformat (input, "hex %U", unformat_hex_string, &match))
9200         ;
9201       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9202         ;
9203       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9204         ;
9205       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9206         ;
9207       else
9208         break;
9209     }
9210
9211   if (l4 && !l3)
9212     {
9213       vec_free (match);
9214       vec_free (l2);
9215       vec_free (l4);
9216       return 0;
9217     }
9218
9219   if (match || l2 || l3 || l4)
9220     {
9221       if (l2 || l3 || l4)
9222         {
9223           /* "Win a free Ethernet header in every packet" */
9224           if (l2 == 0)
9225             vec_validate_aligned (l2, 13, sizeof (u32x4));
9226           match = l2;
9227           if (vec_len (l3))
9228             {
9229               vec_append_aligned (match, l3, sizeof (u32x4));
9230               vec_free (l3);
9231             }
9232           if (vec_len (l4))
9233             {
9234               vec_append_aligned (match, l4, sizeof (u32x4));
9235               vec_free (l4);
9236             }
9237         }
9238
9239       /* Make sure the vector is big enough even if key is all 0's */
9240       vec_validate_aligned
9241         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9242          sizeof (u32x4));
9243
9244       /* Set size, include skipped vectors */
9245       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9246
9247       *matchp = match;
9248
9249       return 1;
9250     }
9251
9252   return 0;
9253 }
9254
9255 static int
9256 api_classify_add_del_session (vat_main_t * vam)
9257 {
9258   unformat_input_t *i = vam->input;
9259   vl_api_classify_add_del_session_t *mp;
9260   int is_add = 1;
9261   u32 table_index = ~0;
9262   u32 hit_next_index = ~0;
9263   u32 opaque_index = ~0;
9264   u8 *match = 0;
9265   i32 advance = 0;
9266   f64 timeout;
9267   u32 skip_n_vectors = 0;
9268   u32 match_n_vectors = 0;
9269
9270   /*
9271    * Warning: you have to supply skip_n and match_n
9272    * because the API client cant simply look at the classify
9273    * table object.
9274    */
9275
9276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9277     {
9278       if (unformat (i, "del"))
9279         is_add = 0;
9280       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9281                          &hit_next_index))
9282         ;
9283       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9284                          &hit_next_index))
9285         ;
9286       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9287                          &hit_next_index))
9288         ;
9289       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9290         ;
9291       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9292         ;
9293       else if (unformat (i, "opaque-index %d", &opaque_index))
9294         ;
9295       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9296         ;
9297       else if (unformat (i, "match_n %d", &match_n_vectors))
9298         ;
9299       else if (unformat (i, "match %U", unformat_classify_match,
9300                          &match, skip_n_vectors, match_n_vectors))
9301         ;
9302       else if (unformat (i, "advance %d", &advance))
9303         ;
9304       else if (unformat (i, "table-index %d", &table_index))
9305         ;
9306       else
9307         break;
9308     }
9309
9310   if (table_index == ~0)
9311     {
9312       errmsg ("Table index required\n");
9313       return -99;
9314     }
9315
9316   if (is_add && match == 0)
9317     {
9318       errmsg ("Match value required\n");
9319       return -99;
9320     }
9321
9322   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9323
9324   mp->is_add = is_add;
9325   mp->table_index = ntohl (table_index);
9326   mp->hit_next_index = ntohl (hit_next_index);
9327   mp->opaque_index = ntohl (opaque_index);
9328   mp->advance = ntohl (advance);
9329   clib_memcpy (mp->match, match, vec_len (match));
9330   vec_free (match);
9331
9332   S;
9333   W;
9334   /* NOTREACHED */
9335 }
9336
9337 static int
9338 api_classify_set_interface_ip_table (vat_main_t * vam)
9339 {
9340   unformat_input_t *i = vam->input;
9341   vl_api_classify_set_interface_ip_table_t *mp;
9342   f64 timeout;
9343   u32 sw_if_index;
9344   int sw_if_index_set;
9345   u32 table_index = ~0;
9346   u8 is_ipv6 = 0;
9347
9348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9349     {
9350       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9351         sw_if_index_set = 1;
9352       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9353         sw_if_index_set = 1;
9354       else if (unformat (i, "table %d", &table_index))
9355         ;
9356       else
9357         {
9358           clib_warning ("parse error '%U'", format_unformat_error, i);
9359           return -99;
9360         }
9361     }
9362
9363   if (sw_if_index_set == 0)
9364     {
9365       errmsg ("missing interface name or sw_if_index\n");
9366       return -99;
9367     }
9368
9369
9370   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9371
9372   mp->sw_if_index = ntohl (sw_if_index);
9373   mp->table_index = ntohl (table_index);
9374   mp->is_ipv6 = is_ipv6;
9375
9376   S;
9377   W;
9378   /* NOTREACHED */
9379   return 0;
9380 }
9381
9382 static int
9383 api_classify_set_interface_l2_tables (vat_main_t * vam)
9384 {
9385   unformat_input_t *i = vam->input;
9386   vl_api_classify_set_interface_l2_tables_t *mp;
9387   f64 timeout;
9388   u32 sw_if_index;
9389   int sw_if_index_set;
9390   u32 ip4_table_index = ~0;
9391   u32 ip6_table_index = ~0;
9392   u32 other_table_index = ~0;
9393   u32 is_input = 1;
9394
9395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9396     {
9397       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9398         sw_if_index_set = 1;
9399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9400         sw_if_index_set = 1;
9401       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9402         ;
9403       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9404         ;
9405       else if (unformat (i, "other-table %d", &other_table_index))
9406         ;
9407       else if (unformat (i, "is-input %d", &is_input))
9408         ;
9409       else
9410         {
9411           clib_warning ("parse error '%U'", format_unformat_error, i);
9412           return -99;
9413         }
9414     }
9415
9416   if (sw_if_index_set == 0)
9417     {
9418       errmsg ("missing interface name or sw_if_index\n");
9419       return -99;
9420     }
9421
9422
9423   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9424
9425   mp->sw_if_index = ntohl (sw_if_index);
9426   mp->ip4_table_index = ntohl (ip4_table_index);
9427   mp->ip6_table_index = ntohl (ip6_table_index);
9428   mp->other_table_index = ntohl (other_table_index);
9429   mp->is_input = (u8) is_input;
9430
9431   S;
9432   W;
9433   /* NOTREACHED */
9434   return 0;
9435 }
9436
9437 static int
9438 api_set_ipfix_exporter (vat_main_t * vam)
9439 {
9440   unformat_input_t *i = vam->input;
9441   vl_api_set_ipfix_exporter_t *mp;
9442   ip4_address_t collector_address;
9443   u8 collector_address_set = 0;
9444   u32 collector_port = ~0;
9445   ip4_address_t src_address;
9446   u8 src_address_set = 0;
9447   u32 vrf_id = ~0;
9448   u32 path_mtu = ~0;
9449   u32 template_interval = ~0;
9450   u8 udp_checksum = 0;
9451   f64 timeout;
9452
9453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9454     {
9455       if (unformat (i, "collector_address %U", unformat_ip4_address,
9456                     &collector_address))
9457         collector_address_set = 1;
9458       else if (unformat (i, "collector_port %d", &collector_port))
9459         ;
9460       else if (unformat (i, "src_address %U", unformat_ip4_address,
9461                          &src_address))
9462         src_address_set = 1;
9463       else if (unformat (i, "vrf_id %d", &vrf_id))
9464         ;
9465       else if (unformat (i, "path_mtu %d", &path_mtu))
9466         ;
9467       else if (unformat (i, "template_interval %d", &template_interval))
9468         ;
9469       else if (unformat (i, "udp_checksum"))
9470         udp_checksum = 1;
9471       else
9472         break;
9473     }
9474
9475   if (collector_address_set == 0)
9476     {
9477       errmsg ("collector_address required\n");
9478       return -99;
9479     }
9480
9481   if (src_address_set == 0)
9482     {
9483       errmsg ("src_address required\n");
9484       return -99;
9485     }
9486
9487   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9488
9489   memcpy (mp->collector_address, collector_address.data,
9490           sizeof (collector_address.data));
9491   mp->collector_port = htons ((u16) collector_port);
9492   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9493   mp->vrf_id = htonl (vrf_id);
9494   mp->path_mtu = htonl (path_mtu);
9495   mp->template_interval = htonl (template_interval);
9496   mp->udp_checksum = udp_checksum;
9497
9498   S;
9499   W;
9500   /* NOTREACHED */
9501 }
9502
9503 static int
9504 api_set_ipfix_classify_stream (vat_main_t * vam)
9505 {
9506   unformat_input_t *i = vam->input;
9507   vl_api_set_ipfix_classify_stream_t *mp;
9508   u32 domain_id = 0;
9509   u32 src_port = UDP_DST_PORT_ipfix;
9510   f64 timeout;
9511
9512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9513     {
9514       if (unformat (i, "domain %d", &domain_id))
9515         ;
9516       else if (unformat (i, "src_port %d", &src_port))
9517         ;
9518       else
9519         {
9520           errmsg ("unknown input `%U'", format_unformat_error, i);
9521           return -99;
9522         }
9523     }
9524
9525   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9526
9527   mp->domain_id = htonl (domain_id);
9528   mp->src_port = htons ((u16) src_port);
9529
9530   S;
9531   W;
9532   /* NOTREACHED */
9533 }
9534
9535 static int
9536 api_ipfix_classify_table_add_del (vat_main_t * vam)
9537 {
9538   unformat_input_t *i = vam->input;
9539   vl_api_ipfix_classify_table_add_del_t *mp;
9540   int is_add = -1;
9541   u32 classify_table_index = ~0;
9542   u8 ip_version = 0;
9543   u8 transport_protocol = 255;
9544   f64 timeout;
9545
9546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9547     {
9548       if (unformat (i, "add"))
9549         is_add = 1;
9550       else if (unformat (i, "del"))
9551         is_add = 0;
9552       else if (unformat (i, "table %d", &classify_table_index))
9553         ;
9554       else if (unformat (i, "ip4"))
9555         ip_version = 4;
9556       else if (unformat (i, "ip6"))
9557         ip_version = 6;
9558       else if (unformat (i, "tcp"))
9559         transport_protocol = 6;
9560       else if (unformat (i, "udp"))
9561         transport_protocol = 17;
9562       else
9563         {
9564           errmsg ("unknown input `%U'", format_unformat_error, i);
9565           return -99;
9566         }
9567     }
9568
9569   if (is_add == -1)
9570     {
9571       errmsg ("expecting: add|del");
9572       return -99;
9573     }
9574   if (classify_table_index == ~0)
9575     {
9576       errmsg ("classifier table not specified");
9577       return -99;
9578     }
9579   if (ip_version == 0)
9580     {
9581       errmsg ("IP version not specified");
9582       return -99;
9583     }
9584
9585   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9586
9587   mp->is_add = is_add;
9588   mp->table_id = htonl (classify_table_index);
9589   mp->ip_version = ip_version;
9590   mp->transport_protocol = transport_protocol;
9591
9592   S;
9593   W;
9594   /* NOTREACHED */
9595 }
9596
9597 static int
9598 api_get_node_index (vat_main_t * vam)
9599 {
9600   unformat_input_t *i = vam->input;
9601   vl_api_get_node_index_t *mp;
9602   f64 timeout;
9603   u8 *name = 0;
9604
9605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9606     {
9607       if (unformat (i, "node %s", &name))
9608         ;
9609       else
9610         break;
9611     }
9612   if (name == 0)
9613     {
9614       errmsg ("node name required\n");
9615       return -99;
9616     }
9617   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9618     {
9619       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9620       return -99;
9621     }
9622
9623   M (GET_NODE_INDEX, get_node_index);
9624   clib_memcpy (mp->node_name, name, vec_len (name));
9625   vec_free (name);
9626
9627   S;
9628   W;
9629   /* NOTREACHED */
9630   return 0;
9631 }
9632
9633 static int
9634 api_get_next_index (vat_main_t * vam)
9635 {
9636   unformat_input_t *i = vam->input;
9637   vl_api_get_next_index_t *mp;
9638   f64 timeout;
9639   u8 *node_name = 0, *next_node_name = 0;
9640
9641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9642     {
9643       if (unformat (i, "node-name %s", &node_name))
9644         ;
9645       else if (unformat (i, "next-node-name %s", &next_node_name))
9646         break;
9647     }
9648
9649   if (node_name == 0)
9650     {
9651       errmsg ("node name required\n");
9652       return -99;
9653     }
9654   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9655     {
9656       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9657       return -99;
9658     }
9659
9660   if (next_node_name == 0)
9661     {
9662       errmsg ("next node name required\n");
9663       return -99;
9664     }
9665   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9666     {
9667       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9668       return -99;
9669     }
9670
9671   M (GET_NEXT_INDEX, get_next_index);
9672   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9673   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9674   vec_free (node_name);
9675   vec_free (next_node_name);
9676
9677   S;
9678   W;
9679   /* NOTREACHED */
9680   return 0;
9681 }
9682
9683 static int
9684 api_add_node_next (vat_main_t * vam)
9685 {
9686   unformat_input_t *i = vam->input;
9687   vl_api_add_node_next_t *mp;
9688   f64 timeout;
9689   u8 *name = 0;
9690   u8 *next = 0;
9691
9692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9693     {
9694       if (unformat (i, "node %s", &name))
9695         ;
9696       else if (unformat (i, "next %s", &next))
9697         ;
9698       else
9699         break;
9700     }
9701   if (name == 0)
9702     {
9703       errmsg ("node name required\n");
9704       return -99;
9705     }
9706   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9707     {
9708       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9709       return -99;
9710     }
9711   if (next == 0)
9712     {
9713       errmsg ("next node required\n");
9714       return -99;
9715     }
9716   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9717     {
9718       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9719       return -99;
9720     }
9721
9722   M (ADD_NODE_NEXT, add_node_next);
9723   clib_memcpy (mp->node_name, name, vec_len (name));
9724   clib_memcpy (mp->next_name, next, vec_len (next));
9725   vec_free (name);
9726   vec_free (next);
9727
9728   S;
9729   W;
9730   /* NOTREACHED */
9731   return 0;
9732 }
9733
9734 static int
9735 api_l2tpv3_create_tunnel (vat_main_t * vam)
9736 {
9737   unformat_input_t *i = vam->input;
9738   ip6_address_t client_address, our_address;
9739   int client_address_set = 0;
9740   int our_address_set = 0;
9741   u32 local_session_id = 0;
9742   u32 remote_session_id = 0;
9743   u64 local_cookie = 0;
9744   u64 remote_cookie = 0;
9745   u8 l2_sublayer_present = 0;
9746   vl_api_l2tpv3_create_tunnel_t *mp;
9747   f64 timeout;
9748
9749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9750     {
9751       if (unformat (i, "client_address %U", unformat_ip6_address,
9752                     &client_address))
9753         client_address_set = 1;
9754       else if (unformat (i, "our_address %U", unformat_ip6_address,
9755                          &our_address))
9756         our_address_set = 1;
9757       else if (unformat (i, "local_session_id %d", &local_session_id))
9758         ;
9759       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9760         ;
9761       else if (unformat (i, "local_cookie %lld", &local_cookie))
9762         ;
9763       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9764         ;
9765       else if (unformat (i, "l2-sublayer-present"))
9766         l2_sublayer_present = 1;
9767       else
9768         break;
9769     }
9770
9771   if (client_address_set == 0)
9772     {
9773       errmsg ("client_address required\n");
9774       return -99;
9775     }
9776
9777   if (our_address_set == 0)
9778     {
9779       errmsg ("our_address required\n");
9780       return -99;
9781     }
9782
9783   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9784
9785   clib_memcpy (mp->client_address, client_address.as_u8,
9786                sizeof (mp->client_address));
9787
9788   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9789
9790   mp->local_session_id = ntohl (local_session_id);
9791   mp->remote_session_id = ntohl (remote_session_id);
9792   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9793   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9794   mp->l2_sublayer_present = l2_sublayer_present;
9795   mp->is_ipv6 = 1;
9796
9797   S;
9798   W;
9799   /* NOTREACHED */
9800   return 0;
9801 }
9802
9803 static int
9804 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9805 {
9806   unformat_input_t *i = vam->input;
9807   u32 sw_if_index;
9808   u8 sw_if_index_set = 0;
9809   u64 new_local_cookie = 0;
9810   u64 new_remote_cookie = 0;
9811   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9812   f64 timeout;
9813
9814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9815     {
9816       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9817         sw_if_index_set = 1;
9818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9819         sw_if_index_set = 1;
9820       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9821         ;
9822       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9823         ;
9824       else
9825         break;
9826     }
9827
9828   if (sw_if_index_set == 0)
9829     {
9830       errmsg ("missing interface name or sw_if_index\n");
9831       return -99;
9832     }
9833
9834   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9835
9836   mp->sw_if_index = ntohl (sw_if_index);
9837   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9838   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9839
9840   S;
9841   W;
9842   /* NOTREACHED */
9843   return 0;
9844 }
9845
9846 static int
9847 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9848 {
9849   unformat_input_t *i = vam->input;
9850   vl_api_l2tpv3_interface_enable_disable_t *mp;
9851   f64 timeout;
9852   u32 sw_if_index;
9853   u8 sw_if_index_set = 0;
9854   u8 enable_disable = 1;
9855
9856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9857     {
9858       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9859         sw_if_index_set = 1;
9860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9861         sw_if_index_set = 1;
9862       else if (unformat (i, "enable"))
9863         enable_disable = 1;
9864       else if (unformat (i, "disable"))
9865         enable_disable = 0;
9866       else
9867         break;
9868     }
9869
9870   if (sw_if_index_set == 0)
9871     {
9872       errmsg ("missing interface name or sw_if_index\n");
9873       return -99;
9874     }
9875
9876   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9877
9878   mp->sw_if_index = ntohl (sw_if_index);
9879   mp->enable_disable = enable_disable;
9880
9881   S;
9882   W;
9883   /* NOTREACHED */
9884   return 0;
9885 }
9886
9887 static int
9888 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9889 {
9890   unformat_input_t *i = vam->input;
9891   vl_api_l2tpv3_set_lookup_key_t *mp;
9892   f64 timeout;
9893   u8 key = ~0;
9894
9895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9896     {
9897       if (unformat (i, "lookup_v6_src"))
9898         key = L2T_LOOKUP_SRC_ADDRESS;
9899       else if (unformat (i, "lookup_v6_dst"))
9900         key = L2T_LOOKUP_DST_ADDRESS;
9901       else if (unformat (i, "lookup_session_id"))
9902         key = L2T_LOOKUP_SESSION_ID;
9903       else
9904         break;
9905     }
9906
9907   if (key == (u8) ~ 0)
9908     {
9909       errmsg ("l2tp session lookup key unset\n");
9910       return -99;
9911     }
9912
9913   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9914
9915   mp->key = key;
9916
9917   S;
9918   W;
9919   /* NOTREACHED */
9920   return 0;
9921 }
9922
9923 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9924   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9925 {
9926   vat_main_t *vam = &vat_main;
9927
9928   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9929            format_ip6_address, mp->our_address,
9930            format_ip6_address, mp->client_address,
9931            clib_net_to_host_u32 (mp->sw_if_index));
9932
9933   fformat (vam->ofp,
9934            "   local cookies %016llx %016llx remote cookie %016llx\n",
9935            clib_net_to_host_u64 (mp->local_cookie[0]),
9936            clib_net_to_host_u64 (mp->local_cookie[1]),
9937            clib_net_to_host_u64 (mp->remote_cookie));
9938
9939   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9940            clib_net_to_host_u32 (mp->local_session_id),
9941            clib_net_to_host_u32 (mp->remote_session_id));
9942
9943   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9944            mp->l2_sublayer_present ? "preset" : "absent");
9945
9946 }
9947
9948 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9949   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9950 {
9951   vat_main_t *vam = &vat_main;
9952   vat_json_node_t *node = NULL;
9953   struct in6_addr addr;
9954
9955   if (VAT_JSON_ARRAY != vam->json_tree.type)
9956     {
9957       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9958       vat_json_init_array (&vam->json_tree);
9959     }
9960   node = vat_json_array_add (&vam->json_tree);
9961
9962   vat_json_init_object (node);
9963
9964   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9965   vat_json_object_add_ip6 (node, "our_address", addr);
9966   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9967   vat_json_object_add_ip6 (node, "client_address", addr);
9968
9969   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9970   vat_json_init_array (lc);
9971   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9972   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9973   vat_json_object_add_uint (node, "remote_cookie",
9974                             clib_net_to_host_u64 (mp->remote_cookie));
9975
9976   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9977   vat_json_object_add_uint (node, "local_session_id",
9978                             clib_net_to_host_u32 (mp->local_session_id));
9979   vat_json_object_add_uint (node, "remote_session_id",
9980                             clib_net_to_host_u32 (mp->remote_session_id));
9981   vat_json_object_add_string_copy (node, "l2_sublayer",
9982                                    mp->l2_sublayer_present ? (u8 *) "present"
9983                                    : (u8 *) "absent");
9984 }
9985
9986 static int
9987 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9988 {
9989   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9990   f64 timeout;
9991
9992   /* Get list of l2tpv3-tunnel interfaces */
9993   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9994   S;
9995
9996   /* Use a control ping for synchronization */
9997   {
9998     vl_api_control_ping_t *mp;
9999     M (CONTROL_PING, control_ping);
10000     S;
10001   }
10002   W;
10003 }
10004
10005
10006 static void vl_api_sw_interface_tap_details_t_handler
10007   (vl_api_sw_interface_tap_details_t * mp)
10008 {
10009   vat_main_t *vam = &vat_main;
10010
10011   fformat (vam->ofp, "%-16s %d\n",
10012            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10013 }
10014
10015 static void vl_api_sw_interface_tap_details_t_handler_json
10016   (vl_api_sw_interface_tap_details_t * mp)
10017 {
10018   vat_main_t *vam = &vat_main;
10019   vat_json_node_t *node = NULL;
10020
10021   if (VAT_JSON_ARRAY != vam->json_tree.type)
10022     {
10023       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10024       vat_json_init_array (&vam->json_tree);
10025     }
10026   node = vat_json_array_add (&vam->json_tree);
10027
10028   vat_json_init_object (node);
10029   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10030   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10031 }
10032
10033 static int
10034 api_sw_interface_tap_dump (vat_main_t * vam)
10035 {
10036   vl_api_sw_interface_tap_dump_t *mp;
10037   f64 timeout;
10038
10039   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10040   /* Get list of tap interfaces */
10041   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10042   S;
10043
10044   /* Use a control ping for synchronization */
10045   {
10046     vl_api_control_ping_t *mp;
10047     M (CONTROL_PING, control_ping);
10048     S;
10049   }
10050   W;
10051 }
10052
10053 static uword unformat_vxlan_decap_next
10054   (unformat_input_t * input, va_list * args)
10055 {
10056   u32 *result = va_arg (*args, u32 *);
10057   u32 tmp;
10058
10059   if (unformat (input, "drop"))
10060     *result = VXLAN_INPUT_NEXT_DROP;
10061   else if (unformat (input, "ip4"))
10062     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
10063   else if (unformat (input, "ip6"))
10064     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
10065   else if (unformat (input, "l2"))
10066     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10067   else if (unformat (input, "%d", &tmp))
10068     *result = tmp;
10069   else
10070     return 0;
10071   return 1;
10072 }
10073
10074 static int
10075 api_vxlan_add_del_tunnel (vat_main_t * vam)
10076 {
10077   unformat_input_t *line_input = vam->input;
10078   vl_api_vxlan_add_del_tunnel_t *mp;
10079   f64 timeout;
10080   ip4_address_t src4, dst4;
10081   ip6_address_t src6, dst6;
10082   u8 is_add = 1;
10083   u8 ipv4_set = 0, ipv6_set = 0;
10084   u8 src_set = 0;
10085   u8 dst_set = 0;
10086   u32 encap_vrf_id = 0;
10087   u32 decap_next_index = ~0;
10088   u32 vni = 0;
10089
10090   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10091     {
10092       if (unformat (line_input, "del"))
10093         is_add = 0;
10094       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10095         {
10096           ipv4_set = 1;
10097           src_set = 1;
10098         }
10099       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10100         {
10101           ipv4_set = 1;
10102           dst_set = 1;
10103         }
10104       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10105         {
10106           ipv6_set = 1;
10107           src_set = 1;
10108         }
10109       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10110         {
10111           ipv6_set = 1;
10112           dst_set = 1;
10113         }
10114       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10115         ;
10116       else if (unformat (line_input, "decap-next %U",
10117                          unformat_vxlan_decap_next, &decap_next_index))
10118         ;
10119       else if (unformat (line_input, "vni %d", &vni))
10120         ;
10121       else
10122         {
10123           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10124           return -99;
10125         }
10126     }
10127
10128   if (src_set == 0)
10129     {
10130       errmsg ("tunnel src address not specified\n");
10131       return -99;
10132     }
10133   if (dst_set == 0)
10134     {
10135       errmsg ("tunnel dst address not specified\n");
10136       return -99;
10137     }
10138
10139   if (ipv4_set && ipv6_set)
10140     {
10141       errmsg ("both IPv4 and IPv6 addresses specified");
10142       return -99;
10143     }
10144
10145   if ((vni == 0) || (vni >> 24))
10146     {
10147       errmsg ("vni not specified or out of range\n");
10148       return -99;
10149     }
10150
10151   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10152
10153   if (ipv6_set)
10154     {
10155       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10156       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10157     }
10158   else
10159     {
10160       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10161       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10162     }
10163   mp->encap_vrf_id = ntohl (encap_vrf_id);
10164   mp->decap_next_index = ntohl (decap_next_index);
10165   mp->vni = ntohl (vni);
10166   mp->is_add = is_add;
10167   mp->is_ipv6 = ipv6_set;
10168
10169   S;
10170   W;
10171   /* NOTREACHED */
10172   return 0;
10173 }
10174
10175 static void vl_api_vxlan_tunnel_details_t_handler
10176   (vl_api_vxlan_tunnel_details_t * mp)
10177 {
10178   vat_main_t *vam = &vat_main;
10179
10180   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10181            ntohl (mp->sw_if_index),
10182            format_ip46_address, &(mp->src_address[0]),
10183            IP46_TYPE_ANY,
10184            format_ip46_address, &(mp->dst_address[0]),
10185            IP46_TYPE_ANY,
10186            ntohl (mp->encap_vrf_id),
10187            ntohl (mp->decap_next_index), ntohl (mp->vni));
10188 }
10189
10190 static void vl_api_vxlan_tunnel_details_t_handler_json
10191   (vl_api_vxlan_tunnel_details_t * mp)
10192 {
10193   vat_main_t *vam = &vat_main;
10194   vat_json_node_t *node = NULL;
10195   struct in_addr ip4;
10196   struct in6_addr ip6;
10197
10198   if (VAT_JSON_ARRAY != vam->json_tree.type)
10199     {
10200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10201       vat_json_init_array (&vam->json_tree);
10202     }
10203   node = vat_json_array_add (&vam->json_tree);
10204
10205   vat_json_init_object (node);
10206   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10207   if (mp->is_ipv6)
10208     {
10209       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10210       vat_json_object_add_ip6 (node, "src_address", ip6);
10211       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10212       vat_json_object_add_ip6 (node, "dst_address", ip6);
10213     }
10214   else
10215     {
10216       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10217       vat_json_object_add_ip4 (node, "src_address", ip4);
10218       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10219       vat_json_object_add_ip4 (node, "dst_address", ip4);
10220     }
10221   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10222   vat_json_object_add_uint (node, "decap_next_index",
10223                             ntohl (mp->decap_next_index));
10224   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10225   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10226 }
10227
10228 static int
10229 api_vxlan_tunnel_dump (vat_main_t * vam)
10230 {
10231   unformat_input_t *i = vam->input;
10232   vl_api_vxlan_tunnel_dump_t *mp;
10233   f64 timeout;
10234   u32 sw_if_index;
10235   u8 sw_if_index_set = 0;
10236
10237   /* Parse args required to build the message */
10238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10239     {
10240       if (unformat (i, "sw_if_index %d", &sw_if_index))
10241         sw_if_index_set = 1;
10242       else
10243         break;
10244     }
10245
10246   if (sw_if_index_set == 0)
10247     {
10248       sw_if_index = ~0;
10249     }
10250
10251   if (!vam->json_output)
10252     {
10253       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10254                "sw_if_index", "src_address", "dst_address",
10255                "encap_vrf_id", "decap_next_index", "vni");
10256     }
10257
10258   /* Get list of vxlan-tunnel interfaces */
10259   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10260
10261   mp->sw_if_index = htonl (sw_if_index);
10262
10263   S;
10264
10265   /* Use a control ping for synchronization */
10266   {
10267     vl_api_control_ping_t *mp;
10268     M (CONTROL_PING, control_ping);
10269     S;
10270   }
10271   W;
10272 }
10273
10274 static int
10275 api_gre_add_del_tunnel (vat_main_t * vam)
10276 {
10277   unformat_input_t *line_input = vam->input;
10278   vl_api_gre_add_del_tunnel_t *mp;
10279   f64 timeout;
10280   ip4_address_t src4, dst4;
10281   u8 is_add = 1;
10282   u8 teb = 0;
10283   u8 src_set = 0;
10284   u8 dst_set = 0;
10285   u32 outer_fib_id = 0;
10286
10287   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (line_input, "del"))
10290         is_add = 0;
10291       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10292         src_set = 1;
10293       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10294         dst_set = 1;
10295       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10296         ;
10297       else if (unformat (line_input, "teb"))
10298         teb = 1;
10299       else
10300         {
10301           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10302           return -99;
10303         }
10304     }
10305
10306   if (src_set == 0)
10307     {
10308       errmsg ("tunnel src address not specified\n");
10309       return -99;
10310     }
10311   if (dst_set == 0)
10312     {
10313       errmsg ("tunnel dst address not specified\n");
10314       return -99;
10315     }
10316
10317
10318   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10319
10320   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10321   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10322   mp->outer_fib_id = ntohl (outer_fib_id);
10323   mp->is_add = is_add;
10324   mp->teb = teb;
10325
10326   S;
10327   W;
10328   /* NOTREACHED */
10329   return 0;
10330 }
10331
10332 static void vl_api_gre_tunnel_details_t_handler
10333   (vl_api_gre_tunnel_details_t * mp)
10334 {
10335   vat_main_t *vam = &vat_main;
10336
10337   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10338            ntohl (mp->sw_if_index),
10339            format_ip4_address, &mp->src_address,
10340            format_ip4_address, &mp->dst_address,
10341            mp->teb, ntohl (mp->outer_fib_id));
10342 }
10343
10344 static void vl_api_gre_tunnel_details_t_handler_json
10345   (vl_api_gre_tunnel_details_t * mp)
10346 {
10347   vat_main_t *vam = &vat_main;
10348   vat_json_node_t *node = NULL;
10349   struct in_addr ip4;
10350
10351   if (VAT_JSON_ARRAY != vam->json_tree.type)
10352     {
10353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10354       vat_json_init_array (&vam->json_tree);
10355     }
10356   node = vat_json_array_add (&vam->json_tree);
10357
10358   vat_json_init_object (node);
10359   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10360   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10361   vat_json_object_add_ip4 (node, "src_address", ip4);
10362   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10363   vat_json_object_add_ip4 (node, "dst_address", ip4);
10364   vat_json_object_add_uint (node, "teb", mp->teb);
10365   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10366 }
10367
10368 static int
10369 api_gre_tunnel_dump (vat_main_t * vam)
10370 {
10371   unformat_input_t *i = vam->input;
10372   vl_api_gre_tunnel_dump_t *mp;
10373   f64 timeout;
10374   u32 sw_if_index;
10375   u8 sw_if_index_set = 0;
10376
10377   /* Parse args required to build the message */
10378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10379     {
10380       if (unformat (i, "sw_if_index %d", &sw_if_index))
10381         sw_if_index_set = 1;
10382       else
10383         break;
10384     }
10385
10386   if (sw_if_index_set == 0)
10387     {
10388       sw_if_index = ~0;
10389     }
10390
10391   if (!vam->json_output)
10392     {
10393       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10394                "sw_if_index", "src_address", "dst_address", "teb",
10395                "outer_fib_id");
10396     }
10397
10398   /* Get list of gre-tunnel interfaces */
10399   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10400
10401   mp->sw_if_index = htonl (sw_if_index);
10402
10403   S;
10404
10405   /* Use a control ping for synchronization */
10406   {
10407     vl_api_control_ping_t *mp;
10408     M (CONTROL_PING, control_ping);
10409     S;
10410   }
10411   W;
10412 }
10413
10414 static int
10415 api_l2_fib_clear_table (vat_main_t * vam)
10416 {
10417 //  unformat_input_t * i = vam->input;
10418   vl_api_l2_fib_clear_table_t *mp;
10419   f64 timeout;
10420
10421   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10422
10423   S;
10424   W;
10425   /* NOTREACHED */
10426   return 0;
10427 }
10428
10429 static int
10430 api_l2_interface_efp_filter (vat_main_t * vam)
10431 {
10432   unformat_input_t *i = vam->input;
10433   vl_api_l2_interface_efp_filter_t *mp;
10434   f64 timeout;
10435   u32 sw_if_index;
10436   u8 enable = 1;
10437   u8 sw_if_index_set = 0;
10438
10439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10440     {
10441       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10442         sw_if_index_set = 1;
10443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10444         sw_if_index_set = 1;
10445       else if (unformat (i, "enable"))
10446         enable = 1;
10447       else if (unformat (i, "disable"))
10448         enable = 0;
10449       else
10450         {
10451           clib_warning ("parse error '%U'", format_unformat_error, i);
10452           return -99;
10453         }
10454     }
10455
10456   if (sw_if_index_set == 0)
10457     {
10458       errmsg ("missing sw_if_index\n");
10459       return -99;
10460     }
10461
10462   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10463
10464   mp->sw_if_index = ntohl (sw_if_index);
10465   mp->enable_disable = enable;
10466
10467   S;
10468   W;
10469   /* NOTREACHED */
10470   return 0;
10471 }
10472
10473 #define foreach_vtr_op                          \
10474 _("disable",  L2_VTR_DISABLED)                  \
10475 _("push-1",  L2_VTR_PUSH_1)                     \
10476 _("push-2",  L2_VTR_PUSH_2)                     \
10477 _("pop-1",  L2_VTR_POP_1)                       \
10478 _("pop-2",  L2_VTR_POP_2)                       \
10479 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10480 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10481 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10482 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10483
10484 static int
10485 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10486 {
10487   unformat_input_t *i = vam->input;
10488   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10489   f64 timeout;
10490   u32 sw_if_index;
10491   u8 sw_if_index_set = 0;
10492   u8 vtr_op_set = 0;
10493   u32 vtr_op = 0;
10494   u32 push_dot1q = 1;
10495   u32 tag1 = ~0;
10496   u32 tag2 = ~0;
10497
10498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10499     {
10500       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10501         sw_if_index_set = 1;
10502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10503         sw_if_index_set = 1;
10504       else if (unformat (i, "vtr_op %d", &vtr_op))
10505         vtr_op_set = 1;
10506 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10507       foreach_vtr_op
10508 #undef _
10509         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10510         ;
10511       else if (unformat (i, "tag1 %d", &tag1))
10512         ;
10513       else if (unformat (i, "tag2 %d", &tag2))
10514         ;
10515       else
10516         {
10517           clib_warning ("parse error '%U'", format_unformat_error, i);
10518           return -99;
10519         }
10520     }
10521
10522   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10523     {
10524       errmsg ("missing vtr operation or sw_if_index\n");
10525       return -99;
10526     }
10527
10528   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10529     mp->sw_if_index = ntohl (sw_if_index);
10530   mp->vtr_op = ntohl (vtr_op);
10531   mp->push_dot1q = ntohl (push_dot1q);
10532   mp->tag1 = ntohl (tag1);
10533   mp->tag2 = ntohl (tag2);
10534
10535   S;
10536   W;
10537   /* NOTREACHED */
10538   return 0;
10539 }
10540
10541 static int
10542 api_create_vhost_user_if (vat_main_t * vam)
10543 {
10544   unformat_input_t *i = vam->input;
10545   vl_api_create_vhost_user_if_t *mp;
10546   f64 timeout;
10547   u8 *file_name;
10548   u8 is_server = 0;
10549   u8 file_name_set = 0;
10550   u32 custom_dev_instance = ~0;
10551   u8 hwaddr[6];
10552   u8 use_custom_mac = 0;
10553
10554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10555     {
10556       if (unformat (i, "socket %s", &file_name))
10557         {
10558           file_name_set = 1;
10559         }
10560       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10561         ;
10562       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10563         use_custom_mac = 1;
10564       else if (unformat (i, "server"))
10565         is_server = 1;
10566       else
10567         break;
10568     }
10569
10570   if (file_name_set == 0)
10571     {
10572       errmsg ("missing socket file name\n");
10573       return -99;
10574     }
10575
10576   if (vec_len (file_name) > 255)
10577     {
10578       errmsg ("socket file name too long\n");
10579       return -99;
10580     }
10581   vec_add1 (file_name, 0);
10582
10583   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10584
10585   mp->is_server = is_server;
10586   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10587   vec_free (file_name);
10588   if (custom_dev_instance != ~0)
10589     {
10590       mp->renumber = 1;
10591       mp->custom_dev_instance = ntohl (custom_dev_instance);
10592     }
10593   mp->use_custom_mac = use_custom_mac;
10594   clib_memcpy (mp->mac_address, hwaddr, 6);
10595
10596   S;
10597   W;
10598   /* NOTREACHED */
10599   return 0;
10600 }
10601
10602 static int
10603 api_modify_vhost_user_if (vat_main_t * vam)
10604 {
10605   unformat_input_t *i = vam->input;
10606   vl_api_modify_vhost_user_if_t *mp;
10607   f64 timeout;
10608   u8 *file_name;
10609   u8 is_server = 0;
10610   u8 file_name_set = 0;
10611   u32 custom_dev_instance = ~0;
10612   u8 sw_if_index_set = 0;
10613   u32 sw_if_index = (u32) ~ 0;
10614
10615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10616     {
10617       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10618         sw_if_index_set = 1;
10619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10620         sw_if_index_set = 1;
10621       else if (unformat (i, "socket %s", &file_name))
10622         {
10623           file_name_set = 1;
10624         }
10625       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10626         ;
10627       else if (unformat (i, "server"))
10628         is_server = 1;
10629       else
10630         break;
10631     }
10632
10633   if (sw_if_index_set == 0)
10634     {
10635       errmsg ("missing sw_if_index or interface name\n");
10636       return -99;
10637     }
10638
10639   if (file_name_set == 0)
10640     {
10641       errmsg ("missing socket file name\n");
10642       return -99;
10643     }
10644
10645   if (vec_len (file_name) > 255)
10646     {
10647       errmsg ("socket file name too long\n");
10648       return -99;
10649     }
10650   vec_add1 (file_name, 0);
10651
10652   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10653
10654   mp->sw_if_index = ntohl (sw_if_index);
10655   mp->is_server = is_server;
10656   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10657   vec_free (file_name);
10658   if (custom_dev_instance != ~0)
10659     {
10660       mp->renumber = 1;
10661       mp->custom_dev_instance = ntohl (custom_dev_instance);
10662     }
10663
10664   S;
10665   W;
10666   /* NOTREACHED */
10667   return 0;
10668 }
10669
10670 static int
10671 api_delete_vhost_user_if (vat_main_t * vam)
10672 {
10673   unformat_input_t *i = vam->input;
10674   vl_api_delete_vhost_user_if_t *mp;
10675   f64 timeout;
10676   u32 sw_if_index = ~0;
10677   u8 sw_if_index_set = 0;
10678
10679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10682         sw_if_index_set = 1;
10683       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10684         sw_if_index_set = 1;
10685       else
10686         break;
10687     }
10688
10689   if (sw_if_index_set == 0)
10690     {
10691       errmsg ("missing sw_if_index or interface name\n");
10692       return -99;
10693     }
10694
10695
10696   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10697
10698   mp->sw_if_index = ntohl (sw_if_index);
10699
10700   S;
10701   W;
10702   /* NOTREACHED */
10703   return 0;
10704 }
10705
10706 static void vl_api_sw_interface_vhost_user_details_t_handler
10707   (vl_api_sw_interface_vhost_user_details_t * mp)
10708 {
10709   vat_main_t *vam = &vat_main;
10710
10711   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10712            (char *) mp->interface_name,
10713            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10714            clib_net_to_host_u64 (mp->features), mp->is_server,
10715            ntohl (mp->num_regions), (char *) mp->sock_filename);
10716   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10717 }
10718
10719 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10720   (vl_api_sw_interface_vhost_user_details_t * mp)
10721 {
10722   vat_main_t *vam = &vat_main;
10723   vat_json_node_t *node = NULL;
10724
10725   if (VAT_JSON_ARRAY != vam->json_tree.type)
10726     {
10727       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10728       vat_json_init_array (&vam->json_tree);
10729     }
10730   node = vat_json_array_add (&vam->json_tree);
10731
10732   vat_json_init_object (node);
10733   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10734   vat_json_object_add_string_copy (node, "interface_name",
10735                                    mp->interface_name);
10736   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10737                             ntohl (mp->virtio_net_hdr_sz));
10738   vat_json_object_add_uint (node, "features",
10739                             clib_net_to_host_u64 (mp->features));
10740   vat_json_object_add_uint (node, "is_server", mp->is_server);
10741   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10742   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10743   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10744 }
10745
10746 static int
10747 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10748 {
10749   vl_api_sw_interface_vhost_user_dump_t *mp;
10750   f64 timeout;
10751   fformat (vam->ofp,
10752            "Interface name           idx hdr_sz features server regions filename\n");
10753
10754   /* Get list of vhost-user interfaces */
10755   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10756   S;
10757
10758   /* Use a control ping for synchronization */
10759   {
10760     vl_api_control_ping_t *mp;
10761     M (CONTROL_PING, control_ping);
10762     S;
10763   }
10764   W;
10765 }
10766
10767 static int
10768 api_show_version (vat_main_t * vam)
10769 {
10770   vl_api_show_version_t *mp;
10771   f64 timeout;
10772
10773   M (SHOW_VERSION, show_version);
10774
10775   S;
10776   W;
10777   /* NOTREACHED */
10778   return 0;
10779 }
10780
10781
10782 static int
10783 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10784 {
10785   unformat_input_t *line_input = vam->input;
10786   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10787   f64 timeout;
10788   ip4_address_t local4, remote4;
10789   ip6_address_t local6, remote6;
10790   u8 is_add = 1;
10791   u8 ipv4_set = 0, ipv6_set = 0;
10792   u8 local_set = 0;
10793   u8 remote_set = 0;
10794   u32 encap_vrf_id = 0;
10795   u32 decap_vrf_id = 0;
10796   u8 protocol = ~0;
10797   u32 vni;
10798   u8 vni_set = 0;
10799
10800   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10801     {
10802       if (unformat (line_input, "del"))
10803         is_add = 0;
10804       else if (unformat (line_input, "local %U",
10805                          unformat_ip4_address, &local4))
10806         {
10807           local_set = 1;
10808           ipv4_set = 1;
10809         }
10810       else if (unformat (line_input, "remote %U",
10811                          unformat_ip4_address, &remote4))
10812         {
10813           remote_set = 1;
10814           ipv4_set = 1;
10815         }
10816       else if (unformat (line_input, "local %U",
10817                          unformat_ip6_address, &local6))
10818         {
10819           local_set = 1;
10820           ipv6_set = 1;
10821         }
10822       else if (unformat (line_input, "remote %U",
10823                          unformat_ip6_address, &remote6))
10824         {
10825           remote_set = 1;
10826           ipv6_set = 1;
10827         }
10828       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10829         ;
10830       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10831         ;
10832       else if (unformat (line_input, "vni %d", &vni))
10833         vni_set = 1;
10834       else if (unformat (line_input, "next-ip4"))
10835         protocol = 1;
10836       else if (unformat (line_input, "next-ip6"))
10837         protocol = 2;
10838       else if (unformat (line_input, "next-ethernet"))
10839         protocol = 3;
10840       else if (unformat (line_input, "next-nsh"))
10841         protocol = 4;
10842       else
10843         {
10844           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10845           return -99;
10846         }
10847     }
10848
10849   if (local_set == 0)
10850     {
10851       errmsg ("tunnel local address not specified\n");
10852       return -99;
10853     }
10854   if (remote_set == 0)
10855     {
10856       errmsg ("tunnel remote address not specified\n");
10857       return -99;
10858     }
10859   if (ipv4_set && ipv6_set)
10860     {
10861       errmsg ("both IPv4 and IPv6 addresses specified");
10862       return -99;
10863     }
10864
10865   if (vni_set == 0)
10866     {
10867       errmsg ("vni not specified\n");
10868       return -99;
10869     }
10870
10871   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10872
10873
10874   if (ipv6_set)
10875     {
10876       clib_memcpy (&mp->local, &local6, sizeof (local6));
10877       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10878     }
10879   else
10880     {
10881       clib_memcpy (&mp->local, &local4, sizeof (local4));
10882       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10883     }
10884
10885   mp->encap_vrf_id = ntohl (encap_vrf_id);
10886   mp->decap_vrf_id = ntohl (decap_vrf_id);
10887   mp->protocol = ntohl (protocol);
10888   mp->vni = ntohl (vni);
10889   mp->is_add = is_add;
10890   mp->is_ipv6 = ipv6_set;
10891
10892   S;
10893   W;
10894   /* NOTREACHED */
10895   return 0;
10896 }
10897
10898 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10899   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10900 {
10901   vat_main_t *vam = &vat_main;
10902
10903   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10904            ntohl (mp->sw_if_index),
10905            format_ip46_address, &(mp->local[0]),
10906            format_ip46_address, &(mp->remote[0]),
10907            ntohl (mp->vni),
10908            ntohl (mp->protocol),
10909            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10910 }
10911
10912 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10913   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10914 {
10915   vat_main_t *vam = &vat_main;
10916   vat_json_node_t *node = NULL;
10917   struct in_addr ip4;
10918   struct in6_addr ip6;
10919
10920   if (VAT_JSON_ARRAY != vam->json_tree.type)
10921     {
10922       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10923       vat_json_init_array (&vam->json_tree);
10924     }
10925   node = vat_json_array_add (&vam->json_tree);
10926
10927   vat_json_init_object (node);
10928   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10929   if (mp->is_ipv6)
10930     {
10931       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10932       vat_json_object_add_ip6 (node, "local", ip6);
10933       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10934       vat_json_object_add_ip6 (node, "remote", ip6);
10935     }
10936   else
10937     {
10938       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10939       vat_json_object_add_ip4 (node, "local", ip4);
10940       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10941       vat_json_object_add_ip4 (node, "remote", ip4);
10942     }
10943   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10944   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10945   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10946   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10947   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10948 }
10949
10950 static int
10951 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10952 {
10953   unformat_input_t *i = vam->input;
10954   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10955   f64 timeout;
10956   u32 sw_if_index;
10957   u8 sw_if_index_set = 0;
10958
10959   /* Parse args required to build the message */
10960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10961     {
10962       if (unformat (i, "sw_if_index %d", &sw_if_index))
10963         sw_if_index_set = 1;
10964       else
10965         break;
10966     }
10967
10968   if (sw_if_index_set == 0)
10969     {
10970       sw_if_index = ~0;
10971     }
10972
10973   if (!vam->json_output)
10974     {
10975       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10976                "sw_if_index", "local", "remote", "vni",
10977                "protocol", "encap_vrf_id", "decap_vrf_id");
10978     }
10979
10980   /* Get list of vxlan-tunnel interfaces */
10981   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10982
10983   mp->sw_if_index = htonl (sw_if_index);
10984
10985   S;
10986
10987   /* Use a control ping for synchronization */
10988   {
10989     vl_api_control_ping_t *mp;
10990     M (CONTROL_PING, control_ping);
10991     S;
10992   }
10993   W;
10994 }
10995
10996 u8 *
10997 format_l2_fib_mac_address (u8 * s, va_list * args)
10998 {
10999   u8 *a = va_arg (*args, u8 *);
11000
11001   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11002                  a[2], a[3], a[4], a[5], a[6], a[7]);
11003 }
11004
11005 static void vl_api_l2_fib_table_entry_t_handler
11006   (vl_api_l2_fib_table_entry_t * mp)
11007 {
11008   vat_main_t *vam = &vat_main;
11009
11010   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11011            "       %d       %d     %d\n",
11012            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11013            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11014            mp->bvi_mac);
11015 }
11016
11017 static void vl_api_l2_fib_table_entry_t_handler_json
11018   (vl_api_l2_fib_table_entry_t * mp)
11019 {
11020   vat_main_t *vam = &vat_main;
11021   vat_json_node_t *node = NULL;
11022
11023   if (VAT_JSON_ARRAY != vam->json_tree.type)
11024     {
11025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11026       vat_json_init_array (&vam->json_tree);
11027     }
11028   node = vat_json_array_add (&vam->json_tree);
11029
11030   vat_json_init_object (node);
11031   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11032   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11033   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11034   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11035   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11036   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11037 }
11038
11039 static int
11040 api_l2_fib_table_dump (vat_main_t * vam)
11041 {
11042   unformat_input_t *i = vam->input;
11043   vl_api_l2_fib_table_dump_t *mp;
11044   f64 timeout;
11045   u32 bd_id;
11046   u8 bd_id_set = 0;
11047
11048   /* Parse args required to build the message */
11049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11050     {
11051       if (unformat (i, "bd_id %d", &bd_id))
11052         bd_id_set = 1;
11053       else
11054         break;
11055     }
11056
11057   if (bd_id_set == 0)
11058     {
11059       errmsg ("missing bridge domain\n");
11060       return -99;
11061     }
11062
11063   fformat (vam->ofp,
11064            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11065
11066   /* Get list of l2 fib entries */
11067   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11068
11069   mp->bd_id = ntohl (bd_id);
11070   S;
11071
11072   /* Use a control ping for synchronization */
11073   {
11074     vl_api_control_ping_t *mp;
11075     M (CONTROL_PING, control_ping);
11076     S;
11077   }
11078   W;
11079 }
11080
11081
11082 static int
11083 api_interface_name_renumber (vat_main_t * vam)
11084 {
11085   unformat_input_t *line_input = vam->input;
11086   vl_api_interface_name_renumber_t *mp;
11087   u32 sw_if_index = ~0;
11088   f64 timeout;
11089   u32 new_show_dev_instance = ~0;
11090
11091   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11092     {
11093       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11094                     &sw_if_index))
11095         ;
11096       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11097         ;
11098       else if (unformat (line_input, "new_show_dev_instance %d",
11099                          &new_show_dev_instance))
11100         ;
11101       else
11102         break;
11103     }
11104
11105   if (sw_if_index == ~0)
11106     {
11107       errmsg ("missing interface name or sw_if_index\n");
11108       return -99;
11109     }
11110
11111   if (new_show_dev_instance == ~0)
11112     {
11113       errmsg ("missing new_show_dev_instance\n");
11114       return -99;
11115     }
11116
11117   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11118
11119   mp->sw_if_index = ntohl (sw_if_index);
11120   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11121
11122   S;
11123   W;
11124 }
11125
11126 static int
11127 api_want_ip4_arp_events (vat_main_t * vam)
11128 {
11129   unformat_input_t *line_input = vam->input;
11130   vl_api_want_ip4_arp_events_t *mp;
11131   f64 timeout;
11132   ip4_address_t address;
11133   int address_set = 0;
11134   u32 enable_disable = 1;
11135
11136   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11137     {
11138       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11139         address_set = 1;
11140       else if (unformat (line_input, "del"))
11141         enable_disable = 0;
11142       else
11143         break;
11144     }
11145
11146   if (address_set == 0)
11147     {
11148       errmsg ("missing addresses\n");
11149       return -99;
11150     }
11151
11152   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11153   mp->enable_disable = enable_disable;
11154   mp->pid = getpid ();
11155   mp->address = address.as_u32;
11156
11157   S;
11158   W;
11159 }
11160
11161 static int
11162 api_want_ip6_nd_events (vat_main_t * vam)
11163 {
11164   unformat_input_t *line_input = vam->input;
11165   vl_api_want_ip6_nd_events_t *mp;
11166   f64 timeout;
11167   ip6_address_t address;
11168   int address_set = 0;
11169   u32 enable_disable = 1;
11170
11171   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11172     {
11173       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11174         address_set = 1;
11175       else if (unformat (line_input, "del"))
11176         enable_disable = 0;
11177       else
11178         break;
11179     }
11180
11181   if (address_set == 0)
11182     {
11183       errmsg ("missing addresses\n");
11184       return -99;
11185     }
11186
11187   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11188   mp->enable_disable = enable_disable;
11189   mp->pid = getpid ();
11190   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11191
11192   S;
11193   W;
11194 }
11195
11196 static int
11197 api_input_acl_set_interface (vat_main_t * vam)
11198 {
11199   unformat_input_t *i = vam->input;
11200   vl_api_input_acl_set_interface_t *mp;
11201   f64 timeout;
11202   u32 sw_if_index;
11203   int sw_if_index_set;
11204   u32 ip4_table_index = ~0;
11205   u32 ip6_table_index = ~0;
11206   u32 l2_table_index = ~0;
11207   u8 is_add = 1;
11208
11209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11210     {
11211       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11212         sw_if_index_set = 1;
11213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11214         sw_if_index_set = 1;
11215       else if (unformat (i, "del"))
11216         is_add = 0;
11217       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11218         ;
11219       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11220         ;
11221       else if (unformat (i, "l2-table %d", &l2_table_index))
11222         ;
11223       else
11224         {
11225           clib_warning ("parse error '%U'", format_unformat_error, i);
11226           return -99;
11227         }
11228     }
11229
11230   if (sw_if_index_set == 0)
11231     {
11232       errmsg ("missing interface name or sw_if_index\n");
11233       return -99;
11234     }
11235
11236   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11237
11238   mp->sw_if_index = ntohl (sw_if_index);
11239   mp->ip4_table_index = ntohl (ip4_table_index);
11240   mp->ip6_table_index = ntohl (ip6_table_index);
11241   mp->l2_table_index = ntohl (l2_table_index);
11242   mp->is_add = is_add;
11243
11244   S;
11245   W;
11246   /* NOTREACHED */
11247   return 0;
11248 }
11249
11250 static int
11251 api_ip_address_dump (vat_main_t * vam)
11252 {
11253   unformat_input_t *i = vam->input;
11254   vl_api_ip_address_dump_t *mp;
11255   u32 sw_if_index = ~0;
11256   u8 sw_if_index_set = 0;
11257   u8 ipv4_set = 0;
11258   u8 ipv6_set = 0;
11259   f64 timeout;
11260
11261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11262     {
11263       if (unformat (i, "sw_if_index %d", &sw_if_index))
11264         sw_if_index_set = 1;
11265       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11266         sw_if_index_set = 1;
11267       else if (unformat (i, "ipv4"))
11268         ipv4_set = 1;
11269       else if (unformat (i, "ipv6"))
11270         ipv6_set = 1;
11271       else
11272         break;
11273     }
11274
11275   if (ipv4_set && ipv6_set)
11276     {
11277       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11278       return -99;
11279     }
11280
11281   if ((!ipv4_set) && (!ipv6_set))
11282     {
11283       errmsg ("no ipv4 nor ipv6 flag set\n");
11284       return -99;
11285     }
11286
11287   if (sw_if_index_set == 0)
11288     {
11289       errmsg ("missing interface name or sw_if_index\n");
11290       return -99;
11291     }
11292
11293   vam->current_sw_if_index = sw_if_index;
11294   vam->is_ipv6 = ipv6_set;
11295
11296   M (IP_ADDRESS_DUMP, ip_address_dump);
11297   mp->sw_if_index = ntohl (sw_if_index);
11298   mp->is_ipv6 = ipv6_set;
11299   S;
11300
11301   /* Use a control ping for synchronization */
11302   {
11303     vl_api_control_ping_t *mp;
11304     M (CONTROL_PING, control_ping);
11305     S;
11306   }
11307   W;
11308 }
11309
11310 static int
11311 api_ip_dump (vat_main_t * vam)
11312 {
11313   vl_api_ip_dump_t *mp;
11314   unformat_input_t *in = vam->input;
11315   int ipv4_set = 0;
11316   int ipv6_set = 0;
11317   int is_ipv6;
11318   f64 timeout;
11319   int i;
11320
11321   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11322     {
11323       if (unformat (in, "ipv4"))
11324         ipv4_set = 1;
11325       else if (unformat (in, "ipv6"))
11326         ipv6_set = 1;
11327       else
11328         break;
11329     }
11330
11331   if (ipv4_set && ipv6_set)
11332     {
11333       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11334       return -99;
11335     }
11336
11337   if ((!ipv4_set) && (!ipv6_set))
11338     {
11339       errmsg ("no ipv4 nor ipv6 flag set\n");
11340       return -99;
11341     }
11342
11343   is_ipv6 = ipv6_set;
11344   vam->is_ipv6 = is_ipv6;
11345
11346   /* free old data */
11347   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11348     {
11349       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11350     }
11351   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11352
11353   M (IP_DUMP, ip_dump);
11354   mp->is_ipv6 = ipv6_set;
11355   S;
11356
11357   /* Use a control ping for synchronization */
11358   {
11359     vl_api_control_ping_t *mp;
11360     M (CONTROL_PING, control_ping);
11361     S;
11362   }
11363   W;
11364 }
11365
11366 static int
11367 api_ipsec_spd_add_del (vat_main_t * vam)
11368 {
11369 #if DPDK > 0
11370   unformat_input_t *i = vam->input;
11371   vl_api_ipsec_spd_add_del_t *mp;
11372   f64 timeout;
11373   u32 spd_id = ~0;
11374   u8 is_add = 1;
11375
11376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11377     {
11378       if (unformat (i, "spd_id %d", &spd_id))
11379         ;
11380       else if (unformat (i, "del"))
11381         is_add = 0;
11382       else
11383         {
11384           clib_warning ("parse error '%U'", format_unformat_error, i);
11385           return -99;
11386         }
11387     }
11388   if (spd_id == ~0)
11389     {
11390       errmsg ("spd_id must be set\n");
11391       return -99;
11392     }
11393
11394   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11395
11396   mp->spd_id = ntohl (spd_id);
11397   mp->is_add = is_add;
11398
11399   S;
11400   W;
11401   /* NOTREACHED */
11402   return 0;
11403 #else
11404   clib_warning ("unsupported (no dpdk)");
11405   return -99;
11406 #endif
11407 }
11408
11409 static int
11410 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11411 {
11412 #if DPDK > 0
11413   unformat_input_t *i = vam->input;
11414   vl_api_ipsec_interface_add_del_spd_t *mp;
11415   f64 timeout;
11416   u32 sw_if_index;
11417   u8 sw_if_index_set = 0;
11418   u32 spd_id = (u32) ~ 0;
11419   u8 is_add = 1;
11420
11421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11422     {
11423       if (unformat (i, "del"))
11424         is_add = 0;
11425       else if (unformat (i, "spd_id %d", &spd_id))
11426         ;
11427       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11428         sw_if_index_set = 1;
11429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11430         sw_if_index_set = 1;
11431       else
11432         {
11433           clib_warning ("parse error '%U'", format_unformat_error, i);
11434           return -99;
11435         }
11436
11437     }
11438
11439   if (spd_id == (u32) ~ 0)
11440     {
11441       errmsg ("spd_id must be set\n");
11442       return -99;
11443     }
11444
11445   if (sw_if_index_set == 0)
11446     {
11447       errmsg ("missing interface name or sw_if_index\n");
11448       return -99;
11449     }
11450
11451   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11452
11453   mp->spd_id = ntohl (spd_id);
11454   mp->sw_if_index = ntohl (sw_if_index);
11455   mp->is_add = is_add;
11456
11457   S;
11458   W;
11459   /* NOTREACHED */
11460   return 0;
11461 #else
11462   clib_warning ("unsupported (no dpdk)");
11463   return -99;
11464 #endif
11465 }
11466
11467 static int
11468 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11469 {
11470 #if DPDK > 0
11471   unformat_input_t *i = vam->input;
11472   vl_api_ipsec_spd_add_del_entry_t *mp;
11473   f64 timeout;
11474   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11475   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11476   i32 priority = 0;
11477   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11478   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11479   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11480   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11481
11482   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11483   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11484   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11485   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11486   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11487   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11488
11489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11490     {
11491       if (unformat (i, "del"))
11492         is_add = 0;
11493       if (unformat (i, "outbound"))
11494         is_outbound = 1;
11495       if (unformat (i, "inbound"))
11496         is_outbound = 0;
11497       else if (unformat (i, "spd_id %d", &spd_id))
11498         ;
11499       else if (unformat (i, "sa_id %d", &sa_id))
11500         ;
11501       else if (unformat (i, "priority %d", &priority))
11502         ;
11503       else if (unformat (i, "protocol %d", &protocol))
11504         ;
11505       else if (unformat (i, "lport_start %d", &lport_start))
11506         ;
11507       else if (unformat (i, "lport_stop %d", &lport_stop))
11508         ;
11509       else if (unformat (i, "rport_start %d", &rport_start))
11510         ;
11511       else if (unformat (i, "rport_stop %d", &rport_stop))
11512         ;
11513       else
11514         if (unformat
11515             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11516         {
11517           is_ipv6 = 0;
11518           is_ip_any = 0;
11519         }
11520       else
11521         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11522         {
11523           is_ipv6 = 0;
11524           is_ip_any = 0;
11525         }
11526       else
11527         if (unformat
11528             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11529         {
11530           is_ipv6 = 0;
11531           is_ip_any = 0;
11532         }
11533       else
11534         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11535         {
11536           is_ipv6 = 0;
11537           is_ip_any = 0;
11538         }
11539       else
11540         if (unformat
11541             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11542         {
11543           is_ipv6 = 1;
11544           is_ip_any = 0;
11545         }
11546       else
11547         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11548         {
11549           is_ipv6 = 1;
11550           is_ip_any = 0;
11551         }
11552       else
11553         if (unformat
11554             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11555         {
11556           is_ipv6 = 1;
11557           is_ip_any = 0;
11558         }
11559       else
11560         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11561         {
11562           is_ipv6 = 1;
11563           is_ip_any = 0;
11564         }
11565       else
11566         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11567         {
11568           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11569             {
11570               clib_warning ("unsupported action: 'resolve'");
11571               return -99;
11572             }
11573         }
11574       else
11575         {
11576           clib_warning ("parse error '%U'", format_unformat_error, i);
11577           return -99;
11578         }
11579
11580     }
11581
11582   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11583
11584   mp->spd_id = ntohl (spd_id);
11585   mp->priority = ntohl (priority);
11586   mp->is_outbound = is_outbound;
11587
11588   mp->is_ipv6 = is_ipv6;
11589   if (is_ipv6 || is_ip_any)
11590     {
11591       clib_memcpy (mp->remote_address_start, &raddr6_start,
11592                    sizeof (ip6_address_t));
11593       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11594                    sizeof (ip6_address_t));
11595       clib_memcpy (mp->local_address_start, &laddr6_start,
11596                    sizeof (ip6_address_t));
11597       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11598                    sizeof (ip6_address_t));
11599     }
11600   else
11601     {
11602       clib_memcpy (mp->remote_address_start, &raddr4_start,
11603                    sizeof (ip4_address_t));
11604       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11605                    sizeof (ip4_address_t));
11606       clib_memcpy (mp->local_address_start, &laddr4_start,
11607                    sizeof (ip4_address_t));
11608       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11609                    sizeof (ip4_address_t));
11610     }
11611   mp->protocol = (u8) protocol;
11612   mp->local_port_start = ntohs ((u16) lport_start);
11613   mp->local_port_stop = ntohs ((u16) lport_stop);
11614   mp->remote_port_start = ntohs ((u16) rport_start);
11615   mp->remote_port_stop = ntohs ((u16) rport_stop);
11616   mp->policy = (u8) policy;
11617   mp->sa_id = ntohl (sa_id);
11618   mp->is_add = is_add;
11619   mp->is_ip_any = is_ip_any;
11620   S;
11621   W;
11622   /* NOTREACHED */
11623   return 0;
11624 #else
11625   clib_warning ("unsupported (no dpdk)");
11626   return -99;
11627 #endif
11628 }
11629
11630 static int
11631 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11632 {
11633 #if DPDK > 0
11634   unformat_input_t *i = vam->input;
11635   vl_api_ipsec_sad_add_del_entry_t *mp;
11636   f64 timeout;
11637   u32 sad_id = 0, spi = 0;
11638   u8 *ck = 0, *ik = 0;
11639   u8 is_add = 1;
11640
11641   u8 protocol = IPSEC_PROTOCOL_AH;
11642   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11643   u32 crypto_alg = 0, integ_alg = 0;
11644   ip4_address_t tun_src4;
11645   ip4_address_t tun_dst4;
11646   ip6_address_t tun_src6;
11647   ip6_address_t tun_dst6;
11648
11649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11650     {
11651       if (unformat (i, "del"))
11652         is_add = 0;
11653       else if (unformat (i, "sad_id %d", &sad_id))
11654         ;
11655       else if (unformat (i, "spi %d", &spi))
11656         ;
11657       else if (unformat (i, "esp"))
11658         protocol = IPSEC_PROTOCOL_ESP;
11659       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11660         {
11661           is_tunnel = 1;
11662           is_tunnel_ipv6 = 0;
11663         }
11664       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11665         {
11666           is_tunnel = 1;
11667           is_tunnel_ipv6 = 0;
11668         }
11669       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11670         {
11671           is_tunnel = 1;
11672           is_tunnel_ipv6 = 1;
11673         }
11674       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11675         {
11676           is_tunnel = 1;
11677           is_tunnel_ipv6 = 1;
11678         }
11679       else
11680         if (unformat
11681             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11682         {
11683           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11684               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11685             {
11686               clib_warning ("unsupported crypto-alg: '%U'",
11687                             format_ipsec_crypto_alg, crypto_alg);
11688               return -99;
11689             }
11690         }
11691       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11692         ;
11693       else
11694         if (unformat
11695             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11696         {
11697           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11698               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11699             {
11700               clib_warning ("unsupported integ-alg: '%U'",
11701                             format_ipsec_integ_alg, integ_alg);
11702               return -99;
11703             }
11704         }
11705       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11706         ;
11707       else
11708         {
11709           clib_warning ("parse error '%U'", format_unformat_error, i);
11710           return -99;
11711         }
11712
11713     }
11714
11715   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11716
11717   mp->sad_id = ntohl (sad_id);
11718   mp->is_add = is_add;
11719   mp->protocol = protocol;
11720   mp->spi = ntohl (spi);
11721   mp->is_tunnel = is_tunnel;
11722   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11723   mp->crypto_algorithm = crypto_alg;
11724   mp->integrity_algorithm = integ_alg;
11725   mp->crypto_key_length = vec_len (ck);
11726   mp->integrity_key_length = vec_len (ik);
11727
11728   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11729     mp->crypto_key_length = sizeof (mp->crypto_key);
11730
11731   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11732     mp->integrity_key_length = sizeof (mp->integrity_key);
11733
11734   if (ck)
11735     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11736   if (ik)
11737     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11738
11739   if (is_tunnel)
11740     {
11741       if (is_tunnel_ipv6)
11742         {
11743           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11744                        sizeof (ip6_address_t));
11745           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11746                        sizeof (ip6_address_t));
11747         }
11748       else
11749         {
11750           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11751                        sizeof (ip4_address_t));
11752           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11753                        sizeof (ip4_address_t));
11754         }
11755     }
11756
11757   S;
11758   W;
11759   /* NOTREACHED */
11760   return 0;
11761 #else
11762   clib_warning ("unsupported (no dpdk)");
11763   return -99;
11764 #endif
11765 }
11766
11767 static int
11768 api_ipsec_sa_set_key (vat_main_t * vam)
11769 {
11770 #if DPDK > 0
11771   unformat_input_t *i = vam->input;
11772   vl_api_ipsec_sa_set_key_t *mp;
11773   f64 timeout;
11774   u32 sa_id;
11775   u8 *ck = 0, *ik = 0;
11776
11777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11778     {
11779       if (unformat (i, "sa_id %d", &sa_id))
11780         ;
11781       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11782         ;
11783       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11784         ;
11785       else
11786         {
11787           clib_warning ("parse error '%U'", format_unformat_error, i);
11788           return -99;
11789         }
11790     }
11791
11792   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11793
11794   mp->sa_id = ntohl (sa_id);
11795   mp->crypto_key_length = vec_len (ck);
11796   mp->integrity_key_length = vec_len (ik);
11797
11798   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11799     mp->crypto_key_length = sizeof (mp->crypto_key);
11800
11801   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11802     mp->integrity_key_length = sizeof (mp->integrity_key);
11803
11804   if (ck)
11805     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11806   if (ik)
11807     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11808
11809   S;
11810   W;
11811   /* NOTREACHED */
11812   return 0;
11813 #else
11814   clib_warning ("unsupported (no dpdk)");
11815   return -99;
11816 #endif
11817 }
11818
11819 static int
11820 api_ikev2_profile_add_del (vat_main_t * vam)
11821 {
11822 #if DPDK > 0
11823   unformat_input_t *i = vam->input;
11824   vl_api_ikev2_profile_add_del_t *mp;
11825   f64 timeout;
11826   u8 is_add = 1;
11827   u8 *name = 0;
11828
11829   const char *valid_chars = "a-zA-Z0-9_";
11830
11831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11832     {
11833       if (unformat (i, "del"))
11834         is_add = 0;
11835       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11836         vec_add1 (name, 0);
11837       else
11838         {
11839           errmsg ("parse error '%U'", format_unformat_error, i);
11840           return -99;
11841         }
11842     }
11843
11844   if (!vec_len (name))
11845     {
11846       errmsg ("profile name must be specified");
11847       return -99;
11848     }
11849
11850   if (vec_len (name) > 64)
11851     {
11852       errmsg ("profile name too long");
11853       return -99;
11854     }
11855
11856   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11857
11858   clib_memcpy (mp->name, name, vec_len (name));
11859   mp->is_add = is_add;
11860   vec_free (name);
11861
11862   S;
11863   W;
11864   /* NOTREACHED */
11865   return 0;
11866 #else
11867   clib_warning ("unsupported (no dpdk)");
11868   return -99;
11869 #endif
11870 }
11871
11872 static int
11873 api_ikev2_profile_set_auth (vat_main_t * vam)
11874 {
11875 #if DPDK > 0
11876   unformat_input_t *i = vam->input;
11877   vl_api_ikev2_profile_set_auth_t *mp;
11878   f64 timeout;
11879   u8 *name = 0;
11880   u8 *data = 0;
11881   u32 auth_method = 0;
11882   u8 is_hex = 0;
11883
11884   const char *valid_chars = "a-zA-Z0-9_";
11885
11886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11887     {
11888       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11889         vec_add1 (name, 0);
11890       else if (unformat (i, "auth_method %U",
11891                          unformat_ikev2_auth_method, &auth_method))
11892         ;
11893       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11894         is_hex = 1;
11895       else if (unformat (i, "auth_data %v", &data))
11896         ;
11897       else
11898         {
11899           errmsg ("parse error '%U'", format_unformat_error, i);
11900           return -99;
11901         }
11902     }
11903
11904   if (!vec_len (name))
11905     {
11906       errmsg ("profile name must be specified");
11907       return -99;
11908     }
11909
11910   if (vec_len (name) > 64)
11911     {
11912       errmsg ("profile name too long");
11913       return -99;
11914     }
11915
11916   if (!vec_len (data))
11917     {
11918       errmsg ("auth_data must be specified");
11919       return -99;
11920     }
11921
11922   if (!auth_method)
11923     {
11924       errmsg ("auth_method must be specified");
11925       return -99;
11926     }
11927
11928   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11929
11930   mp->is_hex = is_hex;
11931   mp->auth_method = (u8) auth_method;
11932   mp->data_len = vec_len (data);
11933   clib_memcpy (mp->name, name, vec_len (name));
11934   clib_memcpy (mp->data, data, vec_len (data));
11935   vec_free (name);
11936   vec_free (data);
11937
11938   S;
11939   W;
11940   /* NOTREACHED */
11941   return 0;
11942 #else
11943   clib_warning ("unsupported (no dpdk)");
11944   return -99;
11945 #endif
11946 }
11947
11948 static int
11949 api_ikev2_profile_set_id (vat_main_t * vam)
11950 {
11951 #if DPDK > 0
11952   unformat_input_t *i = vam->input;
11953   vl_api_ikev2_profile_set_id_t *mp;
11954   f64 timeout;
11955   u8 *name = 0;
11956   u8 *data = 0;
11957   u8 is_local = 0;
11958   u32 id_type = 0;
11959   ip4_address_t ip4;
11960
11961   const char *valid_chars = "a-zA-Z0-9_";
11962
11963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11964     {
11965       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11966         vec_add1 (name, 0);
11967       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11968         ;
11969       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11970         {
11971           data = vec_new (u8, 4);
11972           clib_memcpy (data, ip4.as_u8, 4);
11973         }
11974       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11975         ;
11976       else if (unformat (i, "id_data %v", &data))
11977         ;
11978       else if (unformat (i, "local"))
11979         is_local = 1;
11980       else if (unformat (i, "remote"))
11981         is_local = 0;
11982       else
11983         {
11984           errmsg ("parse error '%U'", format_unformat_error, i);
11985           return -99;
11986         }
11987     }
11988
11989   if (!vec_len (name))
11990     {
11991       errmsg ("profile name must be specified");
11992       return -99;
11993     }
11994
11995   if (vec_len (name) > 64)
11996     {
11997       errmsg ("profile name too long");
11998       return -99;
11999     }
12000
12001   if (!vec_len (data))
12002     {
12003       errmsg ("id_data must be specified");
12004       return -99;
12005     }
12006
12007   if (!id_type)
12008     {
12009       errmsg ("id_type must be specified");
12010       return -99;
12011     }
12012
12013   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12014
12015   mp->is_local = is_local;
12016   mp->id_type = (u8) id_type;
12017   mp->data_len = vec_len (data);
12018   clib_memcpy (mp->name, name, vec_len (name));
12019   clib_memcpy (mp->data, data, vec_len (data));
12020   vec_free (name);
12021   vec_free (data);
12022
12023   S;
12024   W;
12025   /* NOTREACHED */
12026   return 0;
12027 #else
12028   clib_warning ("unsupported (no dpdk)");
12029   return -99;
12030 #endif
12031 }
12032
12033 static int
12034 api_ikev2_profile_set_ts (vat_main_t * vam)
12035 {
12036 #if DPDK > 0
12037   unformat_input_t *i = vam->input;
12038   vl_api_ikev2_profile_set_ts_t *mp;
12039   f64 timeout;
12040   u8 *name = 0;
12041   u8 is_local = 0;
12042   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12043   ip4_address_t start_addr, end_addr;
12044
12045   const char *valid_chars = "a-zA-Z0-9_";
12046
12047   start_addr.as_u32 = 0;
12048   end_addr.as_u32 = (u32) ~ 0;
12049
12050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12051     {
12052       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12053         vec_add1 (name, 0);
12054       else if (unformat (i, "protocol %d", &proto))
12055         ;
12056       else if (unformat (i, "start_port %d", &start_port))
12057         ;
12058       else if (unformat (i, "end_port %d", &end_port))
12059         ;
12060       else
12061         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12062         ;
12063       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12064         ;
12065       else if (unformat (i, "local"))
12066         is_local = 1;
12067       else if (unformat (i, "remote"))
12068         is_local = 0;
12069       else
12070         {
12071           errmsg ("parse error '%U'", format_unformat_error, i);
12072           return -99;
12073         }
12074     }
12075
12076   if (!vec_len (name))
12077     {
12078       errmsg ("profile name must be specified");
12079       return -99;
12080     }
12081
12082   if (vec_len (name) > 64)
12083     {
12084       errmsg ("profile name too long");
12085       return -99;
12086     }
12087
12088   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12089
12090   mp->is_local = is_local;
12091   mp->proto = (u8) proto;
12092   mp->start_port = (u16) start_port;
12093   mp->end_port = (u16) end_port;
12094   mp->start_addr = start_addr.as_u32;
12095   mp->end_addr = end_addr.as_u32;
12096   clib_memcpy (mp->name, name, vec_len (name));
12097   vec_free (name);
12098
12099   S;
12100   W;
12101   /* NOTREACHED */
12102   return 0;
12103 #else
12104   clib_warning ("unsupported (no dpdk)");
12105   return -99;
12106 #endif
12107 }
12108
12109 static int
12110 api_ikev2_set_local_key (vat_main_t * vam)
12111 {
12112 #if DPDK > 0
12113   unformat_input_t *i = vam->input;
12114   vl_api_ikev2_set_local_key_t *mp;
12115   f64 timeout;
12116   u8 *file = 0;
12117
12118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12119     {
12120       if (unformat (i, "file %v", &file))
12121         vec_add1 (file, 0);
12122       else
12123         {
12124           errmsg ("parse error '%U'", format_unformat_error, i);
12125           return -99;
12126         }
12127     }
12128
12129   if (!vec_len (file))
12130     {
12131       errmsg ("RSA key file must be specified");
12132       return -99;
12133     }
12134
12135   if (vec_len (file) > 256)
12136     {
12137       errmsg ("file name too long");
12138       return -99;
12139     }
12140
12141   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12142
12143   clib_memcpy (mp->key_file, file, vec_len (file));
12144   vec_free (file);
12145
12146   S;
12147   W;
12148   /* NOTREACHED */
12149   return 0;
12150 #else
12151   clib_warning ("unsupported (no dpdk)");
12152   return -99;
12153 #endif
12154 }
12155
12156 /*
12157  * MAP
12158  */
12159 static int
12160 api_map_add_domain (vat_main_t * vam)
12161 {
12162   unformat_input_t *i = vam->input;
12163   vl_api_map_add_domain_t *mp;
12164   f64 timeout;
12165
12166   ip4_address_t ip4_prefix;
12167   ip6_address_t ip6_prefix;
12168   ip6_address_t ip6_src;
12169   u32 num_m_args = 0;
12170   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12171     0, psid_length = 0;
12172   u8 is_translation = 0;
12173   u32 mtu = 0;
12174   u32 ip6_src_len = 128;
12175
12176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12177     {
12178       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12179                     &ip4_prefix, &ip4_prefix_len))
12180         num_m_args++;
12181       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12182                          &ip6_prefix, &ip6_prefix_len))
12183         num_m_args++;
12184       else
12185         if (unformat
12186             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12187              &ip6_src_len))
12188         num_m_args++;
12189       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12190         num_m_args++;
12191       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12192         num_m_args++;
12193       else if (unformat (i, "psid-offset %d", &psid_offset))
12194         num_m_args++;
12195       else if (unformat (i, "psid-len %d", &psid_length))
12196         num_m_args++;
12197       else if (unformat (i, "mtu %d", &mtu))
12198         num_m_args++;
12199       else if (unformat (i, "map-t"))
12200         is_translation = 1;
12201       else
12202         {
12203           clib_warning ("parse error '%U'", format_unformat_error, i);
12204           return -99;
12205         }
12206     }
12207
12208   if (num_m_args < 3)
12209     {
12210       errmsg ("mandatory argument(s) missing\n");
12211       return -99;
12212     }
12213
12214   /* Construct the API message */
12215   M (MAP_ADD_DOMAIN, map_add_domain);
12216
12217   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12218   mp->ip4_prefix_len = ip4_prefix_len;
12219
12220   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12221   mp->ip6_prefix_len = ip6_prefix_len;
12222
12223   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12224   mp->ip6_src_prefix_len = ip6_src_len;
12225
12226   mp->ea_bits_len = ea_bits_len;
12227   mp->psid_offset = psid_offset;
12228   mp->psid_length = psid_length;
12229   mp->is_translation = is_translation;
12230   mp->mtu = htons (mtu);
12231
12232   /* send it... */
12233   S;
12234
12235   /* Wait for a reply, return good/bad news  */
12236   W;
12237 }
12238
12239 static int
12240 api_map_del_domain (vat_main_t * vam)
12241 {
12242   unformat_input_t *i = vam->input;
12243   vl_api_map_del_domain_t *mp;
12244   f64 timeout;
12245
12246   u32 num_m_args = 0;
12247   u32 index;
12248
12249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12250     {
12251       if (unformat (i, "index %d", &index))
12252         num_m_args++;
12253       else
12254         {
12255           clib_warning ("parse error '%U'", format_unformat_error, i);
12256           return -99;
12257         }
12258     }
12259
12260   if (num_m_args != 1)
12261     {
12262       errmsg ("mandatory argument(s) missing\n");
12263       return -99;
12264     }
12265
12266   /* Construct the API message */
12267   M (MAP_DEL_DOMAIN, map_del_domain);
12268
12269   mp->index = ntohl (index);
12270
12271   /* send it... */
12272   S;
12273
12274   /* Wait for a reply, return good/bad news  */
12275   W;
12276 }
12277
12278 static int
12279 api_map_add_del_rule (vat_main_t * vam)
12280 {
12281   unformat_input_t *i = vam->input;
12282   vl_api_map_add_del_rule_t *mp;
12283   f64 timeout;
12284   u8 is_add = 1;
12285   ip6_address_t ip6_dst;
12286   u32 num_m_args = 0, index, psid = 0;
12287
12288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12289     {
12290       if (unformat (i, "index %d", &index))
12291         num_m_args++;
12292       else if (unformat (i, "psid %d", &psid))
12293         num_m_args++;
12294       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12295         num_m_args++;
12296       else if (unformat (i, "del"))
12297         {
12298           is_add = 0;
12299         }
12300       else
12301         {
12302           clib_warning ("parse error '%U'", format_unformat_error, i);
12303           return -99;
12304         }
12305     }
12306
12307   /* Construct the API message */
12308   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12309
12310   mp->index = ntohl (index);
12311   mp->is_add = is_add;
12312   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12313   mp->psid = ntohs (psid);
12314
12315   /* send it... */
12316   S;
12317
12318   /* Wait for a reply, return good/bad news  */
12319   W;
12320 }
12321
12322 static int
12323 api_map_domain_dump (vat_main_t * vam)
12324 {
12325   vl_api_map_domain_dump_t *mp;
12326   f64 timeout;
12327
12328   /* Construct the API message */
12329   M (MAP_DOMAIN_DUMP, map_domain_dump);
12330
12331   /* send it... */
12332   S;
12333
12334   /* Use a control ping for synchronization */
12335   {
12336     vl_api_control_ping_t *mp;
12337     M (CONTROL_PING, control_ping);
12338     S;
12339   }
12340   W;
12341 }
12342
12343 static int
12344 api_map_rule_dump (vat_main_t * vam)
12345 {
12346   unformat_input_t *i = vam->input;
12347   vl_api_map_rule_dump_t *mp;
12348   f64 timeout;
12349   u32 domain_index = ~0;
12350
12351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12352     {
12353       if (unformat (i, "index %u", &domain_index))
12354         ;
12355       else
12356         break;
12357     }
12358
12359   if (domain_index == ~0)
12360     {
12361       clib_warning ("parse error: domain index expected");
12362       return -99;
12363     }
12364
12365   /* Construct the API message */
12366   M (MAP_RULE_DUMP, map_rule_dump);
12367
12368   mp->domain_index = htonl (domain_index);
12369
12370   /* send it... */
12371   S;
12372
12373   /* Use a control ping for synchronization */
12374   {
12375     vl_api_control_ping_t *mp;
12376     M (CONTROL_PING, control_ping);
12377     S;
12378   }
12379   W;
12380 }
12381
12382 static void vl_api_map_add_domain_reply_t_handler
12383   (vl_api_map_add_domain_reply_t * mp)
12384 {
12385   vat_main_t *vam = &vat_main;
12386   i32 retval = ntohl (mp->retval);
12387
12388   if (vam->async_mode)
12389     {
12390       vam->async_errors += (retval < 0);
12391     }
12392   else
12393     {
12394       vam->retval = retval;
12395       vam->result_ready = 1;
12396     }
12397 }
12398
12399 static void vl_api_map_add_domain_reply_t_handler_json
12400   (vl_api_map_add_domain_reply_t * mp)
12401 {
12402   vat_main_t *vam = &vat_main;
12403   vat_json_node_t node;
12404
12405   vat_json_init_object (&node);
12406   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12407   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12408
12409   vat_json_print (vam->ofp, &node);
12410   vat_json_free (&node);
12411
12412   vam->retval = ntohl (mp->retval);
12413   vam->result_ready = 1;
12414 }
12415
12416 static int
12417 api_get_first_msg_id (vat_main_t * vam)
12418 {
12419   vl_api_get_first_msg_id_t *mp;
12420   f64 timeout;
12421   unformat_input_t *i = vam->input;
12422   u8 *name;
12423   u8 name_set = 0;
12424
12425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12426     {
12427       if (unformat (i, "client %s", &name))
12428         name_set = 1;
12429       else
12430         break;
12431     }
12432
12433   if (name_set == 0)
12434     {
12435       errmsg ("missing client name\n");
12436       return -99;
12437     }
12438   vec_add1 (name, 0);
12439
12440   if (vec_len (name) > 63)
12441     {
12442       errmsg ("client name too long\n");
12443       return -99;
12444     }
12445
12446   M (GET_FIRST_MSG_ID, get_first_msg_id);
12447   clib_memcpy (mp->name, name, vec_len (name));
12448   S;
12449   W;
12450   /* NOTREACHED */
12451   return 0;
12452 }
12453
12454 static int
12455 api_cop_interface_enable_disable (vat_main_t * vam)
12456 {
12457   unformat_input_t *line_input = vam->input;
12458   vl_api_cop_interface_enable_disable_t *mp;
12459   f64 timeout;
12460   u32 sw_if_index = ~0;
12461   u8 enable_disable = 1;
12462
12463   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12464     {
12465       if (unformat (line_input, "disable"))
12466         enable_disable = 0;
12467       if (unformat (line_input, "enable"))
12468         enable_disable = 1;
12469       else if (unformat (line_input, "%U", unformat_sw_if_index,
12470                          vam, &sw_if_index))
12471         ;
12472       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12473         ;
12474       else
12475         break;
12476     }
12477
12478   if (sw_if_index == ~0)
12479     {
12480       errmsg ("missing interface name or sw_if_index\n");
12481       return -99;
12482     }
12483
12484   /* Construct the API message */
12485   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12486   mp->sw_if_index = ntohl (sw_if_index);
12487   mp->enable_disable = enable_disable;
12488
12489   /* send it... */
12490   S;
12491   /* Wait for the reply */
12492   W;
12493 }
12494
12495 static int
12496 api_cop_whitelist_enable_disable (vat_main_t * vam)
12497 {
12498   unformat_input_t *line_input = vam->input;
12499   vl_api_cop_whitelist_enable_disable_t *mp;
12500   f64 timeout;
12501   u32 sw_if_index = ~0;
12502   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12503   u32 fib_id = 0;
12504
12505   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12506     {
12507       if (unformat (line_input, "ip4"))
12508         ip4 = 1;
12509       else if (unformat (line_input, "ip6"))
12510         ip6 = 1;
12511       else if (unformat (line_input, "default"))
12512         default_cop = 1;
12513       else if (unformat (line_input, "%U", unformat_sw_if_index,
12514                          vam, &sw_if_index))
12515         ;
12516       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12517         ;
12518       else if (unformat (line_input, "fib-id %d", &fib_id))
12519         ;
12520       else
12521         break;
12522     }
12523
12524   if (sw_if_index == ~0)
12525     {
12526       errmsg ("missing interface name or sw_if_index\n");
12527       return -99;
12528     }
12529
12530   /* Construct the API message */
12531   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12532   mp->sw_if_index = ntohl (sw_if_index);
12533   mp->fib_id = ntohl (fib_id);
12534   mp->ip4 = ip4;
12535   mp->ip6 = ip6;
12536   mp->default_cop = default_cop;
12537
12538   /* send it... */
12539   S;
12540   /* Wait for the reply */
12541   W;
12542 }
12543
12544 static int
12545 api_get_node_graph (vat_main_t * vam)
12546 {
12547   vl_api_get_node_graph_t *mp;
12548   f64 timeout;
12549
12550   M (GET_NODE_GRAPH, get_node_graph);
12551
12552   /* send it... */
12553   S;
12554   /* Wait for the reply */
12555   W;
12556 }
12557
12558 /* *INDENT-OFF* */
12559 /** Used for parsing LISP eids */
12560 typedef CLIB_PACKED(struct{
12561   u8 addr[16];   /**< eid address */
12562   u32 len;       /**< prefix length if IP */
12563   u8 type;      /**< type of eid */
12564 }) lisp_eid_vat_t;
12565 /* *INDENT-ON* */
12566
12567 static uword
12568 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12569 {
12570   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12571
12572   memset (a, 0, sizeof (a[0]));
12573
12574   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12575     {
12576       a->type = 0;              /* ipv4 type */
12577     }
12578   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12579     {
12580       a->type = 1;              /* ipv6 type */
12581     }
12582   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12583     {
12584       a->type = 2;              /* mac type */
12585     }
12586   else
12587     {
12588       return 0;
12589     }
12590
12591   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12592     {
12593       return 0;
12594     }
12595
12596   return 1;
12597 }
12598
12599 static int
12600 lisp_eid_size_vat (u8 type)
12601 {
12602   switch (type)
12603     {
12604     case 0:
12605       return 4;
12606     case 1:
12607       return 16;
12608     case 2:
12609       return 6;
12610     }
12611   return 0;
12612 }
12613
12614 static void
12615 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12616 {
12617   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12618 }
12619
12620 /* *INDENT-OFF* */
12621 /** Used for transferring locators via VPP API */
12622 typedef CLIB_PACKED(struct
12623 {
12624   u32 sw_if_index; /**< locator sw_if_index */
12625   u8 priority; /**< locator priority */
12626   u8 weight;   /**< locator weight */
12627 }) ls_locator_t;
12628 /* *INDENT-ON* */
12629
12630 static int
12631 api_lisp_add_del_locator_set (vat_main_t * vam)
12632 {
12633   unformat_input_t *input = vam->input;
12634   vl_api_lisp_add_del_locator_set_t *mp;
12635   f64 timeout = ~0;
12636   u8 is_add = 1;
12637   u8 *locator_set_name = NULL;
12638   u8 locator_set_name_set = 0;
12639   ls_locator_t locator, *locators = 0;
12640   u32 sw_if_index, priority, weight;
12641   u32 data_len = 0;
12642
12643   /* Parse args required to build the message */
12644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12645     {
12646       if (unformat (input, "del"))
12647         {
12648           is_add = 0;
12649         }
12650       else if (unformat (input, "locator-set %s", &locator_set_name))
12651         {
12652           locator_set_name_set = 1;
12653         }
12654       else if (unformat (input, "sw_if_index %u p %u w %u",
12655                          &sw_if_index, &priority, &weight))
12656         {
12657           locator.sw_if_index = htonl (sw_if_index);
12658           locator.priority = priority;
12659           locator.weight = weight;
12660           vec_add1 (locators, locator);
12661         }
12662       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12663                          vam, &sw_if_index, &priority, &weight))
12664         {
12665           locator.sw_if_index = htonl (sw_if_index);
12666           locator.priority = priority;
12667           locator.weight = weight;
12668           vec_add1 (locators, locator);
12669         }
12670       else
12671         break;
12672     }
12673
12674   if (locator_set_name_set == 0)
12675     {
12676       errmsg ("missing locator-set name");
12677       vec_free (locators);
12678       return -99;
12679     }
12680
12681   if (vec_len (locator_set_name) > 64)
12682     {
12683       errmsg ("locator-set name too long\n");
12684       vec_free (locator_set_name);
12685       vec_free (locators);
12686       return -99;
12687     }
12688   vec_add1 (locator_set_name, 0);
12689
12690   data_len = sizeof (ls_locator_t) * vec_len (locators);
12691
12692   /* Construct the API message */
12693   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12694
12695   mp->is_add = is_add;
12696   clib_memcpy (mp->locator_set_name, locator_set_name,
12697                vec_len (locator_set_name));
12698   vec_free (locator_set_name);
12699
12700   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12701   if (locators)
12702     clib_memcpy (mp->locators, locators, data_len);
12703   vec_free (locators);
12704
12705   /* send it... */
12706   S;
12707
12708   /* Wait for a reply... */
12709   W;
12710
12711   /* NOTREACHED */
12712   return 0;
12713 }
12714
12715 static int
12716 api_lisp_add_del_locator (vat_main_t * vam)
12717 {
12718   unformat_input_t *input = vam->input;
12719   vl_api_lisp_add_del_locator_t *mp;
12720   f64 timeout = ~0;
12721   u32 tmp_if_index = ~0;
12722   u32 sw_if_index = ~0;
12723   u8 sw_if_index_set = 0;
12724   u8 sw_if_index_if_name_set = 0;
12725   u32 priority = ~0;
12726   u8 priority_set = 0;
12727   u32 weight = ~0;
12728   u8 weight_set = 0;
12729   u8 is_add = 1;
12730   u8 *locator_set_name = NULL;
12731   u8 locator_set_name_set = 0;
12732
12733   /* Parse args required to build the message */
12734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12735     {
12736       if (unformat (input, "del"))
12737         {
12738           is_add = 0;
12739         }
12740       else if (unformat (input, "locator-set %s", &locator_set_name))
12741         {
12742           locator_set_name_set = 1;
12743         }
12744       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12745                          &tmp_if_index))
12746         {
12747           sw_if_index_if_name_set = 1;
12748           sw_if_index = tmp_if_index;
12749         }
12750       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12751         {
12752           sw_if_index_set = 1;
12753           sw_if_index = tmp_if_index;
12754         }
12755       else if (unformat (input, "p %d", &priority))
12756         {
12757           priority_set = 1;
12758         }
12759       else if (unformat (input, "w %d", &weight))
12760         {
12761           weight_set = 1;
12762         }
12763       else
12764         break;
12765     }
12766
12767   if (locator_set_name_set == 0)
12768     {
12769       errmsg ("missing locator-set name");
12770       return -99;
12771     }
12772
12773   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12774     {
12775       errmsg ("missing sw_if_index");
12776       vec_free (locator_set_name);
12777       return -99;
12778     }
12779
12780   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12781     {
12782       errmsg ("cannot use both params interface name and sw_if_index");
12783       vec_free (locator_set_name);
12784       return -99;
12785     }
12786
12787   if (priority_set == 0)
12788     {
12789       errmsg ("missing locator-set priority\n");
12790       vec_free (locator_set_name);
12791       return -99;
12792     }
12793
12794   if (weight_set == 0)
12795     {
12796       errmsg ("missing locator-set weight\n");
12797       vec_free (locator_set_name);
12798       return -99;
12799     }
12800
12801   if (vec_len (locator_set_name) > 64)
12802     {
12803       errmsg ("locator-set name too long\n");
12804       vec_free (locator_set_name);
12805       return -99;
12806     }
12807   vec_add1 (locator_set_name, 0);
12808
12809   /* Construct the API message */
12810   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12811
12812   mp->is_add = is_add;
12813   mp->sw_if_index = ntohl (sw_if_index);
12814   mp->priority = priority;
12815   mp->weight = weight;
12816   clib_memcpy (mp->locator_set_name, locator_set_name,
12817                vec_len (locator_set_name));
12818   vec_free (locator_set_name);
12819
12820   /* send it... */
12821   S;
12822
12823   /* Wait for a reply... */
12824   W;
12825
12826   /* NOTREACHED */
12827   return 0;
12828 }
12829
12830 static int
12831 api_lisp_add_del_local_eid (vat_main_t * vam)
12832 {
12833   unformat_input_t *input = vam->input;
12834   vl_api_lisp_add_del_local_eid_t *mp;
12835   f64 timeout = ~0;
12836   u8 is_add = 1;
12837   u8 eid_set = 0;
12838   lisp_eid_vat_t _eid, *eid = &_eid;
12839   u8 *locator_set_name = 0;
12840   u8 locator_set_name_set = 0;
12841   u32 vni = 0;
12842
12843   /* Parse args required to build the message */
12844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12845     {
12846       if (unformat (input, "del"))
12847         {
12848           is_add = 0;
12849         }
12850       else if (unformat (input, "vni %d", &vni))
12851         {
12852           ;
12853         }
12854       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12855         {
12856           eid_set = 1;
12857         }
12858       else if (unformat (input, "locator-set %s", &locator_set_name))
12859         {
12860           locator_set_name_set = 1;
12861         }
12862       else
12863         break;
12864     }
12865
12866   if (locator_set_name_set == 0)
12867     {
12868       errmsg ("missing locator-set name\n");
12869       return -99;
12870     }
12871
12872   if (0 == eid_set)
12873     {
12874       errmsg ("EID address not set!");
12875       vec_free (locator_set_name);
12876       return -99;
12877     }
12878
12879   if (vec_len (locator_set_name) > 64)
12880     {
12881       errmsg ("locator-set name too long\n");
12882       vec_free (locator_set_name);
12883       return -99;
12884     }
12885   vec_add1 (locator_set_name, 0);
12886
12887   /* Construct the API message */
12888   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12889
12890   mp->is_add = is_add;
12891   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12892   mp->eid_type = eid->type;
12893   mp->prefix_len = eid->len;
12894   mp->vni = clib_host_to_net_u32 (vni);
12895   clib_memcpy (mp->locator_set_name, locator_set_name,
12896                vec_len (locator_set_name));
12897
12898   vec_free (locator_set_name);
12899
12900   /* send it... */
12901   S;
12902
12903   /* Wait for a reply... */
12904   W;
12905
12906   /* NOTREACHED */
12907   return 0;
12908 }
12909
12910 /* *INDENT-OFF* */
12911 /** Used for transferring locators via VPP API */
12912 typedef CLIB_PACKED(struct
12913 {
12914   u8 is_ip4; /**< is locator an IPv4 address? */
12915   u8 priority; /**< locator priority */
12916   u8 weight;   /**< locator weight */
12917   u8 addr[16]; /**< IPv4/IPv6 address */
12918 }) rloc_t;
12919 /* *INDENT-ON* */
12920
12921 static int
12922 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12923 {
12924   unformat_input_t *input = vam->input;
12925   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12926   f64 timeout = ~0;
12927   u8 is_add = 1;
12928   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12929   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12930   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12931   u32 action = ~0, p, w;
12932   ip4_address_t rmt_rloc4, lcl_rloc4;
12933   ip6_address_t rmt_rloc6, lcl_rloc6;
12934   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12935
12936   memset (&rloc, 0, sizeof (rloc));
12937
12938   /* Parse args required to build the message */
12939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12940     {
12941       if (unformat (input, "del"))
12942         {
12943           is_add = 0;
12944         }
12945       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12946         {
12947           rmt_eid_set = 1;
12948         }
12949       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12950         {
12951           lcl_eid_set = 1;
12952         }
12953       else if (unformat (input, "p %d w %d", &p, &w))
12954         {
12955           if (!curr_rloc)
12956             {
12957               errmsg ("No RLOC configured for setting priority/weight!");
12958               return -99;
12959             }
12960           curr_rloc->priority = p;
12961           curr_rloc->weight = w;
12962         }
12963       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12964                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12965         {
12966           rloc.is_ip4 = 1;
12967
12968           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12969           rloc.priority = rloc.weight = 0;
12970           vec_add1 (lcl_locs, rloc);
12971
12972           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12973           vec_add1 (rmt_locs, rloc);
12974           /* priority and weight saved in rmt loc */
12975           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12976         }
12977       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12978                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12979         {
12980           rloc.is_ip4 = 0;
12981           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12982           rloc.priority = rloc.weight = 0;
12983           vec_add1 (lcl_locs, rloc);
12984
12985           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
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, "action %d", &action))
12991         {
12992           ;
12993         }
12994       else
12995         {
12996           clib_warning ("parse error '%U'", format_unformat_error, input);
12997           return -99;
12998         }
12999     }
13000
13001   if (!rmt_eid_set)
13002     {
13003       errmsg ("remote eid addresses not set\n");
13004       return -99;
13005     }
13006
13007   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13008     {
13009       errmsg ("eid types don't match\n");
13010       return -99;
13011     }
13012
13013   if (0 == rmt_locs && (u32) ~ 0 == action)
13014     {
13015       errmsg ("action not set for negative mapping\n");
13016       return -99;
13017     }
13018
13019   /* Construct the API message */
13020   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13021
13022   mp->is_add = is_add;
13023   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13024   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13025   mp->eid_type = rmt_eid->type;
13026   mp->rmt_len = rmt_eid->len;
13027   mp->lcl_len = lcl_eid->len;
13028   mp->action = action;
13029
13030   if (0 != rmt_locs && 0 != lcl_locs)
13031     {
13032       mp->loc_num = vec_len (rmt_locs);
13033       clib_memcpy (mp->lcl_locs, lcl_locs,
13034                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13035       clib_memcpy (mp->rmt_locs, rmt_locs,
13036                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13037     }
13038   vec_free (lcl_locs);
13039   vec_free (rmt_locs);
13040
13041   /* send it... */
13042   S;
13043
13044   /* Wait for a reply... */
13045   W;
13046
13047   /* NOTREACHED */
13048   return 0;
13049 }
13050
13051 static int
13052 api_lisp_add_del_map_resolver (vat_main_t * vam)
13053 {
13054   unformat_input_t *input = vam->input;
13055   vl_api_lisp_add_del_map_resolver_t *mp;
13056   f64 timeout = ~0;
13057   u8 is_add = 1;
13058   u8 ipv4_set = 0;
13059   u8 ipv6_set = 0;
13060   ip4_address_t ipv4;
13061   ip6_address_t ipv6;
13062
13063   /* Parse args required to build the message */
13064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13065     {
13066       if (unformat (input, "del"))
13067         {
13068           is_add = 0;
13069         }
13070       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13071         {
13072           ipv4_set = 1;
13073         }
13074       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13075         {
13076           ipv6_set = 1;
13077         }
13078       else
13079         break;
13080     }
13081
13082   if (ipv4_set && ipv6_set)
13083     {
13084       errmsg ("both eid v4 and v6 addresses set\n");
13085       return -99;
13086     }
13087
13088   if (!ipv4_set && !ipv6_set)
13089     {
13090       errmsg ("eid addresses not set\n");
13091       return -99;
13092     }
13093
13094   /* Construct the API message */
13095   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13096
13097   mp->is_add = is_add;
13098   if (ipv6_set)
13099     {
13100       mp->is_ipv6 = 1;
13101       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13102     }
13103   else
13104     {
13105       mp->is_ipv6 = 0;
13106       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13107     }
13108
13109   /* send it... */
13110   S;
13111
13112   /* Wait for a reply... */
13113   W;
13114
13115   /* NOTREACHED */
13116   return 0;
13117 }
13118
13119 static int
13120 api_lisp_gpe_enable_disable (vat_main_t * vam)
13121 {
13122   unformat_input_t *input = vam->input;
13123   vl_api_lisp_gpe_enable_disable_t *mp;
13124   f64 timeout = ~0;
13125   u8 is_set = 0;
13126   u8 is_en = 1;
13127
13128   /* Parse args required to build the message */
13129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13130     {
13131       if (unformat (input, "enable"))
13132         {
13133           is_set = 1;
13134           is_en = 1;
13135         }
13136       else if (unformat (input, "disable"))
13137         {
13138           is_set = 1;
13139           is_en = 0;
13140         }
13141       else
13142         break;
13143     }
13144
13145   if (is_set == 0)
13146     {
13147       errmsg ("Value not set\n");
13148       return -99;
13149     }
13150
13151   /* Construct the API message */
13152   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13153
13154   mp->is_en = is_en;
13155
13156   /* send it... */
13157   S;
13158
13159   /* Wait for a reply... */
13160   W;
13161
13162   /* NOTREACHED */
13163   return 0;
13164 }
13165
13166 static int
13167 api_lisp_enable_disable (vat_main_t * vam)
13168 {
13169   unformat_input_t *input = vam->input;
13170   vl_api_lisp_enable_disable_t *mp;
13171   f64 timeout = ~0;
13172   u8 is_set = 0;
13173   u8 is_en = 0;
13174
13175   /* Parse args required to build the message */
13176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13177     {
13178       if (unformat (input, "enable"))
13179         {
13180           is_set = 1;
13181           is_en = 1;
13182         }
13183       else if (unformat (input, "disable"))
13184         {
13185           is_set = 1;
13186         }
13187       else
13188         break;
13189     }
13190
13191   if (!is_set)
13192     {
13193       errmsg ("Value not set\n");
13194       return -99;
13195     }
13196
13197   /* Construct the API message */
13198   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13199
13200   mp->is_en = is_en;
13201
13202   /* send it... */
13203   S;
13204
13205   /* Wait for a reply... */
13206   W;
13207
13208   /* NOTREACHED */
13209   return 0;
13210 }
13211
13212 static int
13213 api_show_lisp_map_request_mode (vat_main_t * vam)
13214 {
13215   f64 timeout = ~0;
13216   vl_api_show_lisp_map_request_mode_t *mp;
13217
13218   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13219
13220   /* send */
13221   S;
13222
13223   /* wait for reply */
13224   W;
13225
13226   return 0;
13227 }
13228
13229 static int
13230 api_lisp_map_request_mode (vat_main_t * vam)
13231 {
13232   f64 timeout = ~0;
13233   unformat_input_t *input = vam->input;
13234   vl_api_lisp_map_request_mode_t *mp;
13235   u8 mode = 0;
13236
13237   /* Parse args required to build the message */
13238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13239     {
13240       if (unformat (input, "dst-only"))
13241         mode = 0;
13242       else if (unformat (input, "src-dst"))
13243         mode = 1;
13244       else
13245         {
13246           errmsg ("parse error '%U'", format_unformat_error, input);
13247           return -99;
13248         }
13249     }
13250
13251   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13252
13253   mp->mode = mode;
13254
13255   /* send */
13256   S;
13257
13258   /* wait for reply */
13259   W;
13260
13261   /* notreached */
13262   return 0;
13263 }
13264
13265 /**
13266  * Enable/disable LISP proxy ITR.
13267  *
13268  * @param vam vpp API test context
13269  * @return return code
13270  */
13271 static int
13272 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13273 {
13274   f64 timeout = ~0;
13275   u8 ls_name_set = 0;
13276   unformat_input_t *input = vam->input;
13277   vl_api_lisp_pitr_set_locator_set_t *mp;
13278   u8 is_add = 1;
13279   u8 *ls_name = 0;
13280
13281   /* Parse args required to build the message */
13282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13283     {
13284       if (unformat (input, "del"))
13285         is_add = 0;
13286       else if (unformat (input, "locator-set %s", &ls_name))
13287         ls_name_set = 1;
13288       else
13289         {
13290           errmsg ("parse error '%U'", format_unformat_error, input);
13291           return -99;
13292         }
13293     }
13294
13295   if (!ls_name_set)
13296     {
13297       errmsg ("locator-set name not set!");
13298       return -99;
13299     }
13300
13301   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13302
13303   mp->is_add = is_add;
13304   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13305   vec_free (ls_name);
13306
13307   /* send */
13308   S;
13309
13310   /* wait for reply */
13311   W;
13312
13313   /* notreached */
13314   return 0;
13315 }
13316
13317 static int
13318 api_show_lisp_pitr (vat_main_t * vam)
13319 {
13320   vl_api_show_lisp_pitr_t *mp;
13321   f64 timeout = ~0;
13322
13323   if (!vam->json_output)
13324     {
13325       fformat (vam->ofp, "%=20s\n", "lisp status:");
13326     }
13327
13328   M (SHOW_LISP_PITR, show_lisp_pitr);
13329   /* send it... */
13330   S;
13331
13332   /* Wait for a reply... */
13333   W;
13334
13335   /* NOTREACHED */
13336   return 0;
13337 }
13338
13339 /**
13340  * Add/delete mapping between vni and vrf
13341  */
13342 static int
13343 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13344 {
13345   f64 timeout = ~0;
13346   unformat_input_t *input = vam->input;
13347   vl_api_lisp_eid_table_add_del_map_t *mp;
13348   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13349   u32 vni, vrf, bd_index;
13350
13351   /* Parse args required to build the message */
13352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13353     {
13354       if (unformat (input, "del"))
13355         is_add = 0;
13356       else if (unformat (input, "vrf %d", &vrf))
13357         vrf_set = 1;
13358       else if (unformat (input, "bd_index %d", &bd_index))
13359         bd_index_set = 1;
13360       else if (unformat (input, "vni %d", &vni))
13361         vni_set = 1;
13362       else
13363         break;
13364     }
13365
13366   if (!vni_set || (!vrf_set && !bd_index_set))
13367     {
13368       errmsg ("missing arguments!");
13369       return -99;
13370     }
13371
13372   if (vrf_set && bd_index_set)
13373     {
13374       errmsg ("error: both vrf and bd entered!");
13375       return -99;
13376     }
13377
13378   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13379
13380   mp->is_add = is_add;
13381   mp->vni = htonl (vni);
13382   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13383   mp->is_l2 = bd_index_set;
13384
13385   /* send */
13386   S;
13387
13388   /* wait for reply */
13389   W;
13390
13391   /* notreached */
13392   return 0;
13393 }
13394
13395 uword
13396 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13397 {
13398   u32 *action = va_arg (*args, u32 *);
13399   u8 *s = 0;
13400
13401   if (unformat (input, "%s", &s))
13402     {
13403       if (!strcmp ((char *) s, "no-action"))
13404         action[0] = 0;
13405       else if (!strcmp ((char *) s, "natively-forward"))
13406         action[0] = 1;
13407       else if (!strcmp ((char *) s, "send-map-request"))
13408         action[0] = 2;
13409       else if (!strcmp ((char *) s, "drop"))
13410         action[0] = 3;
13411       else
13412         {
13413           clib_warning ("invalid action: '%s'", s);
13414           action[0] = 3;
13415         }
13416     }
13417   else
13418     return 0;
13419
13420   vec_free (s);
13421   return 1;
13422 }
13423
13424 /**
13425  * Add/del remote mapping to/from LISP control plane
13426  *
13427  * @param vam vpp API test context
13428  * @return return code
13429  */
13430 static int
13431 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13432 {
13433   unformat_input_t *input = vam->input;
13434   vl_api_lisp_add_del_remote_mapping_t *mp;
13435   f64 timeout = ~0;
13436   u32 vni = 0;
13437   lisp_eid_vat_t _eid, *eid = &_eid;
13438   lisp_eid_vat_t _seid, *seid = &_seid;
13439   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13440   u32 action = ~0, p, w, data_len;
13441   ip4_address_t rloc4;
13442   ip6_address_t rloc6;
13443   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13444
13445   memset (&rloc, 0, sizeof (rloc));
13446
13447   /* Parse args required to build the message */
13448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13449     {
13450       if (unformat (input, "del-all"))
13451         {
13452           del_all = 1;
13453         }
13454       else if (unformat (input, "del"))
13455         {
13456           is_add = 0;
13457         }
13458       else if (unformat (input, "add"))
13459         {
13460           is_add = 1;
13461         }
13462       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13463         {
13464           eid_set = 1;
13465         }
13466       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13467         {
13468           seid_set = 1;
13469         }
13470       else if (unformat (input, "vni %d", &vni))
13471         {
13472           ;
13473         }
13474       else if (unformat (input, "p %d w %d", &p, &w))
13475         {
13476           if (!curr_rloc)
13477             {
13478               errmsg ("No RLOC configured for setting priority/weight!");
13479               return -99;
13480             }
13481           curr_rloc->priority = p;
13482           curr_rloc->weight = w;
13483         }
13484       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13485         {
13486           rloc.is_ip4 = 1;
13487           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13488           vec_add1 (rlocs, rloc);
13489           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13490         }
13491       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13492         {
13493           rloc.is_ip4 = 0;
13494           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13495           vec_add1 (rlocs, rloc);
13496           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13497         }
13498       else if (unformat (input, "action %U",
13499                          unformat_negative_mapping_action, &action))
13500         {
13501           ;
13502         }
13503       else
13504         {
13505           clib_warning ("parse error '%U'", format_unformat_error, input);
13506           return -99;
13507         }
13508     }
13509
13510   if (0 == eid_set)
13511     {
13512       errmsg ("missing params!");
13513       return -99;
13514     }
13515
13516   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13517     {
13518       errmsg ("no action set for negative map-reply!");
13519       return -99;
13520     }
13521
13522   data_len = vec_len (rlocs) * sizeof (rloc_t);
13523
13524   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13525   mp->is_add = is_add;
13526   mp->vni = htonl (vni);
13527   mp->action = (u8) action;
13528   mp->is_src_dst = seid_set;
13529   mp->eid_len = eid->len;
13530   mp->seid_len = seid->len;
13531   mp->del_all = del_all;
13532   mp->eid_type = eid->type;
13533   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13534   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13535
13536   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13537   clib_memcpy (mp->rlocs, rlocs, data_len);
13538   vec_free (rlocs);
13539
13540   /* send it... */
13541   S;
13542
13543   /* Wait for a reply... */
13544   W;
13545
13546   /* NOTREACHED */
13547   return 0;
13548 }
13549
13550 /**
13551  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13552  * forwarding entries in data-plane accordingly.
13553  *
13554  * @param vam vpp API test context
13555  * @return return code
13556  */
13557 static int
13558 api_lisp_add_del_adjacency (vat_main_t * vam)
13559 {
13560   unformat_input_t *input = vam->input;
13561   vl_api_lisp_add_del_adjacency_t *mp;
13562   f64 timeout = ~0;
13563   u32 vni = 0;
13564   ip4_address_t leid4, reid4;
13565   ip6_address_t leid6, reid6;
13566   u8 reid_mac[6] = { 0 };
13567   u8 leid_mac[6] = { 0 };
13568   u8 reid_type, leid_type;
13569   u32 leid_len = 0, reid_len = 0, len;
13570   u8 is_add = 1;
13571
13572   leid_type = reid_type = (u8) ~ 0;
13573
13574   /* Parse args required to build the message */
13575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13576     {
13577       if (unformat (input, "del"))
13578         {
13579           is_add = 0;
13580         }
13581       else if (unformat (input, "add"))
13582         {
13583           is_add = 1;
13584         }
13585       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13586                          &reid4, &len))
13587         {
13588           reid_type = 0;        /* ipv4 */
13589           reid_len = len;
13590         }
13591       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13592                          &reid6, &len))
13593         {
13594           reid_type = 1;        /* ipv6 */
13595           reid_len = len;
13596         }
13597       else if (unformat (input, "reid %U", unformat_ethernet_address,
13598                          reid_mac))
13599         {
13600           reid_type = 2;        /* mac */
13601         }
13602       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13603                          &leid4, &len))
13604         {
13605           leid_type = 0;        /* ipv4 */
13606           leid_len = len;
13607         }
13608       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13609                          &leid6, &len))
13610         {
13611           leid_type = 1;        /* ipv6 */
13612           leid_len = len;
13613         }
13614       else if (unformat (input, "leid %U", unformat_ethernet_address,
13615                          leid_mac))
13616         {
13617           leid_type = 2;        /* mac */
13618         }
13619       else if (unformat (input, "vni %d", &vni))
13620         {
13621           ;
13622         }
13623       else
13624         {
13625           errmsg ("parse error '%U'", format_unformat_error, input);
13626           return -99;
13627         }
13628     }
13629
13630   if ((u8) ~ 0 == reid_type)
13631     {
13632       errmsg ("missing params!");
13633       return -99;
13634     }
13635
13636   if (leid_type != reid_type)
13637     {
13638       errmsg ("remote and local EIDs are of different types!");
13639       return -99;
13640     }
13641
13642   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13643   mp->is_add = is_add;
13644   mp->vni = htonl (vni);
13645   mp->leid_len = leid_len;
13646   mp->reid_len = reid_len;
13647   mp->eid_type = reid_type;
13648
13649   switch (mp->eid_type)
13650     {
13651     case 0:
13652       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13653       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13654       break;
13655     case 1:
13656       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13657       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13658       break;
13659     case 2:
13660       clib_memcpy (mp->leid, leid_mac, 6);
13661       clib_memcpy (mp->reid, reid_mac, 6);
13662       break;
13663     default:
13664       errmsg ("unknown EID type %d!", mp->eid_type);
13665       return 0;
13666     }
13667
13668   /* send it... */
13669   S;
13670
13671   /* Wait for a reply... */
13672   W;
13673
13674   /* NOTREACHED */
13675   return 0;
13676 }
13677
13678 static int
13679 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13680 {
13681   unformat_input_t *input = vam->input;
13682   vl_api_lisp_gpe_add_del_iface_t *mp;
13683   f64 timeout = ~0;
13684   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13685   u32 dp_table = 0, vni = 0;
13686
13687   /* Parse args required to build the message */
13688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13689     {
13690       if (unformat (input, "up"))
13691         {
13692           action_set = 1;
13693           is_add = 1;
13694         }
13695       else if (unformat (input, "down"))
13696         {
13697           action_set = 1;
13698           is_add = 0;
13699         }
13700       else if (unformat (input, "table_id %d", &dp_table))
13701         {
13702           dp_table_set = 1;
13703         }
13704       else if (unformat (input, "bd_id %d", &dp_table))
13705         {
13706           dp_table_set = 1;
13707           is_l2 = 1;
13708         }
13709       else if (unformat (input, "vni %d", &vni))
13710         {
13711           vni_set = 1;
13712         }
13713       else
13714         break;
13715     }
13716
13717   if (action_set == 0)
13718     {
13719       errmsg ("Action not set\n");
13720       return -99;
13721     }
13722   if (dp_table_set == 0 || vni_set == 0)
13723     {
13724       errmsg ("vni and dp_table must be set\n");
13725       return -99;
13726     }
13727
13728   /* Construct the API message */
13729   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13730
13731   mp->is_add = is_add;
13732   mp->dp_table = dp_table;
13733   mp->is_l2 = is_l2;
13734   mp->vni = vni;
13735
13736   /* send it... */
13737   S;
13738
13739   /* Wait for a reply... */
13740   W;
13741
13742   /* NOTREACHED */
13743   return 0;
13744 }
13745
13746 /**
13747  * Add/del map request itr rlocs from LISP control plane and updates
13748  *
13749  * @param vam vpp API test context
13750  * @return return code
13751  */
13752 static int
13753 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13754 {
13755   unformat_input_t *input = vam->input;
13756   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13757   f64 timeout = ~0;
13758   u8 *locator_set_name = 0;
13759   u8 locator_set_name_set = 0;
13760   u8 is_add = 1;
13761
13762   /* Parse args required to build the message */
13763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13764     {
13765       if (unformat (input, "del"))
13766         {
13767           is_add = 0;
13768         }
13769       else if (unformat (input, "%_%v%_", &locator_set_name))
13770         {
13771           locator_set_name_set = 1;
13772         }
13773       else
13774         {
13775           clib_warning ("parse error '%U'", format_unformat_error, input);
13776           return -99;
13777         }
13778     }
13779
13780   if (is_add && !locator_set_name_set)
13781     {
13782       errmsg ("itr-rloc is not set!");
13783       return -99;
13784     }
13785
13786   if (is_add && vec_len (locator_set_name) > 64)
13787     {
13788       errmsg ("itr-rloc locator-set name too long\n");
13789       vec_free (locator_set_name);
13790       return -99;
13791     }
13792
13793   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13794   mp->is_add = is_add;
13795   if (is_add)
13796     {
13797       clib_memcpy (mp->locator_set_name, locator_set_name,
13798                    vec_len (locator_set_name));
13799     }
13800   else
13801     {
13802       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13803     }
13804   vec_free (locator_set_name);
13805
13806   /* send it... */
13807   S;
13808
13809   /* Wait for a reply... */
13810   W;
13811
13812   /* NOTREACHED */
13813   return 0;
13814 }
13815
13816 static int
13817 api_lisp_locator_dump (vat_main_t * vam)
13818 {
13819   unformat_input_t *input = vam->input;
13820   vl_api_lisp_locator_dump_t *mp;
13821   f64 timeout = ~0;
13822   u8 is_index_set = 0, is_name_set = 0;
13823   u8 *ls_name = 0;
13824   u32 ls_index = ~0;
13825
13826   /* Parse args required to build the message */
13827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13828     {
13829       if (unformat (input, "ls_name %_%v%_", &ls_name))
13830         {
13831           is_name_set = 1;
13832         }
13833       else if (unformat (input, "ls_index %d", &ls_index))
13834         {
13835           is_index_set = 1;
13836         }
13837       else
13838         {
13839           errmsg ("parse error '%U'", format_unformat_error, input);
13840           return -99;
13841         }
13842     }
13843
13844   if (!is_index_set && !is_name_set)
13845     {
13846       errmsg ("error: expected one of index or name!\n");
13847       return -99;
13848     }
13849
13850   if (is_index_set && is_name_set)
13851     {
13852       errmsg ("error: only one param expected!\n");
13853       return -99;
13854     }
13855
13856   if (vec_len (ls_name) > 62)
13857     {
13858       errmsg ("error: locator set name too long!");
13859       return -99;
13860     }
13861
13862   if (!vam->json_output)
13863     {
13864       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13865                "weight");
13866     }
13867
13868   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13869   mp->is_index_set = is_index_set;
13870
13871   if (is_index_set)
13872     mp->ls_index = clib_host_to_net_u32 (ls_index);
13873   else
13874     {
13875       vec_add1 (ls_name, 0);
13876       strncpy ((char *) mp->ls_name, (char *) ls_name,
13877                sizeof (mp->ls_name) - 1);
13878     }
13879
13880   /* send it... */
13881   S;
13882
13883   /* Use a control ping for synchronization */
13884   {
13885     vl_api_control_ping_t *mp;
13886     M (CONTROL_PING, control_ping);
13887     S;
13888   }
13889   /* Wait for a reply... */
13890   W;
13891
13892   /* NOTREACHED */
13893   return 0;
13894 }
13895
13896 static int
13897 api_lisp_locator_set_dump (vat_main_t * vam)
13898 {
13899   vl_api_lisp_locator_set_dump_t *mp;
13900   unformat_input_t *input = vam->input;
13901   f64 timeout = ~0;
13902   u8 filter = 0;
13903
13904   /* Parse args required to build the message */
13905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13906     {
13907       if (unformat (input, "local"))
13908         {
13909           filter = 1;
13910         }
13911       else if (unformat (input, "remote"))
13912         {
13913           filter = 2;
13914         }
13915       else
13916         {
13917           errmsg ("parse error '%U'", format_unformat_error, input);
13918           return -99;
13919         }
13920     }
13921
13922   if (!vam->json_output)
13923     {
13924       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13925     }
13926
13927   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13928
13929   mp->filter = filter;
13930
13931   /* send it... */
13932   S;
13933
13934   /* Use a control ping for synchronization */
13935   {
13936     vl_api_control_ping_t *mp;
13937     M (CONTROL_PING, control_ping);
13938     S;
13939   }
13940   /* Wait for a reply... */
13941   W;
13942
13943   /* NOTREACHED */
13944   return 0;
13945 }
13946
13947 static int
13948 api_lisp_eid_table_map_dump (vat_main_t * vam)
13949 {
13950   u8 is_l2 = 0;
13951   u8 mode_set = 0;
13952   unformat_input_t *input = vam->input;
13953   vl_api_lisp_eid_table_map_dump_t *mp;
13954   f64 timeout = ~0;
13955
13956   /* Parse args required to build the message */
13957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13958     {
13959       if (unformat (input, "l2"))
13960         {
13961           is_l2 = 1;
13962           mode_set = 1;
13963         }
13964       else if (unformat (input, "l3"))
13965         {
13966           is_l2 = 0;
13967           mode_set = 1;
13968         }
13969       else
13970         {
13971           errmsg ("parse error '%U'", format_unformat_error, input);
13972           return -99;
13973         }
13974     }
13975
13976   if (!mode_set)
13977     {
13978       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13979       return -99;
13980     }
13981
13982   if (!vam->json_output)
13983     {
13984       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13985     }
13986
13987   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13988   mp->is_l2 = is_l2;
13989
13990   /* send it... */
13991   S;
13992
13993   /* Use a control ping for synchronization */
13994   {
13995     vl_api_control_ping_t *mp;
13996     M (CONTROL_PING, control_ping);
13997     S;
13998   }
13999   /* Wait for a reply... */
14000   W;
14001
14002   /* NOTREACHED */
14003   return 0;
14004 }
14005
14006 static int
14007 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14008 {
14009   vl_api_lisp_eid_table_vni_dump_t *mp;
14010   f64 timeout = ~0;
14011
14012   if (!vam->json_output)
14013     {
14014       fformat (vam->ofp, "VNI\n");
14015     }
14016
14017   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14018
14019   /* send it... */
14020   S;
14021
14022   /* Use a control ping for synchronization */
14023   {
14024     vl_api_control_ping_t *mp;
14025     M (CONTROL_PING, control_ping);
14026     S;
14027   }
14028   /* Wait for a reply... */
14029   W;
14030
14031   /* NOTREACHED */
14032   return 0;
14033 }
14034
14035 static int
14036 api_lisp_eid_table_dump (vat_main_t * vam)
14037 {
14038   unformat_input_t *i = vam->input;
14039   vl_api_lisp_eid_table_dump_t *mp;
14040   f64 timeout = ~0;
14041   struct in_addr ip4;
14042   struct in6_addr ip6;
14043   u8 mac[6];
14044   u8 eid_type = ~0, eid_set = 0;
14045   u32 prefix_length = ~0, t, vni = 0;
14046   u8 filter = 0;
14047
14048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14049     {
14050       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14051         {
14052           eid_set = 1;
14053           eid_type = 0;
14054           prefix_length = t;
14055         }
14056       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14057         {
14058           eid_set = 1;
14059           eid_type = 1;
14060           prefix_length = t;
14061         }
14062       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14063         {
14064           eid_set = 1;
14065           eid_type = 2;
14066         }
14067       else if (unformat (i, "vni %d", &t))
14068         {
14069           vni = t;
14070         }
14071       else if (unformat (i, "local"))
14072         {
14073           filter = 1;
14074         }
14075       else if (unformat (i, "remote"))
14076         {
14077           filter = 2;
14078         }
14079       else
14080         {
14081           errmsg ("parse error '%U'", format_unformat_error, i);
14082           return -99;
14083         }
14084     }
14085
14086   if (!vam->json_output)
14087     {
14088       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14089                "ls_index", "ttl", "authoritative");
14090     }
14091
14092   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14093
14094   mp->filter = filter;
14095   if (eid_set)
14096     {
14097       mp->eid_set = 1;
14098       mp->vni = htonl (vni);
14099       mp->eid_type = eid_type;
14100       switch (eid_type)
14101         {
14102         case 0:
14103           mp->prefix_length = prefix_length;
14104           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14105           break;
14106         case 1:
14107           mp->prefix_length = prefix_length;
14108           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14109           break;
14110         case 2:
14111           clib_memcpy (mp->eid, mac, sizeof (mac));
14112           break;
14113         default:
14114           errmsg ("unknown EID type %d!", eid_type);
14115           return -99;
14116         }
14117     }
14118
14119   /* send it... */
14120   S;
14121
14122   /* Use a control ping for synchronization */
14123   {
14124     vl_api_control_ping_t *mp;
14125     M (CONTROL_PING, control_ping);
14126     S;
14127   }
14128
14129   /* Wait for a reply... */
14130   W;
14131
14132   /* NOTREACHED */
14133   return 0;
14134 }
14135
14136 static int
14137 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14138 {
14139   vl_api_lisp_gpe_tunnel_dump_t *mp;
14140   f64 timeout = ~0;
14141
14142   if (!vam->json_output)
14143     {
14144       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14145                "%=16s%=16s%=16s%=16s%=16s\n",
14146                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14147                "Decap next", "Lisp version", "Flags", "Next protocol",
14148                "ver_res", "res", "iid");
14149     }
14150
14151   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14152   /* send it... */
14153   S;
14154
14155   /* Use a control ping for synchronization */
14156   {
14157     vl_api_control_ping_t *mp;
14158     M (CONTROL_PING, control_ping);
14159     S;
14160   }
14161   /* Wait for a reply... */
14162   W;
14163
14164   /* NOTREACHED */
14165   return 0;
14166 }
14167
14168 static int
14169 api_lisp_adjacencies_get (vat_main_t * vam)
14170 {
14171   unformat_input_t *i = vam->input;
14172   vl_api_lisp_adjacencies_get_t *mp;
14173   f64 timeout = ~0;
14174   u8 vni_set = 0;
14175   u32 vni = ~0;
14176
14177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14178     {
14179       if (unformat (i, "vni %d", &vni))
14180         {
14181           vni_set = 1;
14182         }
14183       else
14184         {
14185           errmsg ("parse error '%U'\n", format_unformat_error, i);
14186           return -99;
14187         }
14188     }
14189
14190   if (!vni_set)
14191     {
14192       errmsg ("vni not set!\n");
14193       return -99;
14194     }
14195
14196   if (!vam->json_output)
14197     {
14198       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14199     }
14200
14201   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14202   mp->vni = clib_host_to_net_u32 (vni);
14203
14204   /* send it... */
14205   S;
14206
14207   /* Wait for a reply... */
14208   W;
14209
14210   /* NOTREACHED */
14211   return 0;
14212 }
14213
14214 static int
14215 api_lisp_map_resolver_dump (vat_main_t * vam)
14216 {
14217   vl_api_lisp_map_resolver_dump_t *mp;
14218   f64 timeout = ~0;
14219
14220   if (!vam->json_output)
14221     {
14222       fformat (vam->ofp, "%=20s\n", "Map resolver");
14223     }
14224
14225   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14226   /* send it... */
14227   S;
14228
14229   /* Use a control ping for synchronization */
14230   {
14231     vl_api_control_ping_t *mp;
14232     M (CONTROL_PING, control_ping);
14233     S;
14234   }
14235   /* Wait for a reply... */
14236   W;
14237
14238   /* NOTREACHED */
14239   return 0;
14240 }
14241
14242 static int
14243 api_show_lisp_status (vat_main_t * vam)
14244 {
14245   vl_api_show_lisp_status_t *mp;
14246   f64 timeout = ~0;
14247
14248   if (!vam->json_output)
14249     {
14250       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14251     }
14252
14253   M (SHOW_LISP_STATUS, show_lisp_status);
14254   /* send it... */
14255   S;
14256   /* Wait for a reply... */
14257   W;
14258
14259   /* NOTREACHED */
14260   return 0;
14261 }
14262
14263 static int
14264 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14265 {
14266   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14267   f64 timeout = ~0;
14268
14269   if (!vam->json_output)
14270     {
14271       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14272     }
14273
14274   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14275   /* send it... */
14276   S;
14277   /* Wait for a reply... */
14278   W;
14279
14280   /* NOTREACHED */
14281   return 0;
14282 }
14283
14284 static int
14285 api_af_packet_create (vat_main_t * vam)
14286 {
14287   unformat_input_t *i = vam->input;
14288   vl_api_af_packet_create_t *mp;
14289   f64 timeout;
14290   u8 *host_if_name = 0;
14291   u8 hw_addr[6];
14292   u8 random_hw_addr = 1;
14293
14294   memset (hw_addr, 0, sizeof (hw_addr));
14295
14296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14297     {
14298       if (unformat (i, "name %s", &host_if_name))
14299         vec_add1 (host_if_name, 0);
14300       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14301         random_hw_addr = 0;
14302       else
14303         break;
14304     }
14305
14306   if (!vec_len (host_if_name))
14307     {
14308       errmsg ("host-interface name must be specified");
14309       return -99;
14310     }
14311
14312   if (vec_len (host_if_name) > 64)
14313     {
14314       errmsg ("host-interface name too long");
14315       return -99;
14316     }
14317
14318   M (AF_PACKET_CREATE, af_packet_create);
14319
14320   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14321   clib_memcpy (mp->hw_addr, hw_addr, 6);
14322   mp->use_random_hw_addr = random_hw_addr;
14323   vec_free (host_if_name);
14324
14325   S;
14326   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14327   /* NOTREACHED */
14328   return 0;
14329 }
14330
14331 static int
14332 api_af_packet_delete (vat_main_t * vam)
14333 {
14334   unformat_input_t *i = vam->input;
14335   vl_api_af_packet_delete_t *mp;
14336   f64 timeout;
14337   u8 *host_if_name = 0;
14338
14339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14340     {
14341       if (unformat (i, "name %s", &host_if_name))
14342         vec_add1 (host_if_name, 0);
14343       else
14344         break;
14345     }
14346
14347   if (!vec_len (host_if_name))
14348     {
14349       errmsg ("host-interface name must be specified");
14350       return -99;
14351     }
14352
14353   if (vec_len (host_if_name) > 64)
14354     {
14355       errmsg ("host-interface name too long");
14356       return -99;
14357     }
14358
14359   M (AF_PACKET_DELETE, af_packet_delete);
14360
14361   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14362   vec_free (host_if_name);
14363
14364   S;
14365   W;
14366   /* NOTREACHED */
14367   return 0;
14368 }
14369
14370 static int
14371 api_policer_add_del (vat_main_t * vam)
14372 {
14373   unformat_input_t *i = vam->input;
14374   vl_api_policer_add_del_t *mp;
14375   f64 timeout;
14376   u8 is_add = 1;
14377   u8 *name = 0;
14378   u32 cir = 0;
14379   u32 eir = 0;
14380   u64 cb = 0;
14381   u64 eb = 0;
14382   u8 rate_type = 0;
14383   u8 round_type = 0;
14384   u8 type = 0;
14385   u8 color_aware = 0;
14386   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14387
14388   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14389   conform_action.dscp = 0;
14390   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14391   exceed_action.dscp = 0;
14392   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14393   violate_action.dscp = 0;
14394
14395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14396     {
14397       if (unformat (i, "del"))
14398         is_add = 0;
14399       else if (unformat (i, "name %s", &name))
14400         vec_add1 (name, 0);
14401       else if (unformat (i, "cir %u", &cir))
14402         ;
14403       else if (unformat (i, "eir %u", &eir))
14404         ;
14405       else if (unformat (i, "cb %u", &cb))
14406         ;
14407       else if (unformat (i, "eb %u", &eb))
14408         ;
14409       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14410                          &rate_type))
14411         ;
14412       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14413                          &round_type))
14414         ;
14415       else if (unformat (i, "type %U", unformat_policer_type, &type))
14416         ;
14417       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14418                          &conform_action))
14419         ;
14420       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14421                          &exceed_action))
14422         ;
14423       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14424                          &violate_action))
14425         ;
14426       else if (unformat (i, "color-aware"))
14427         color_aware = 1;
14428       else
14429         break;
14430     }
14431
14432   if (!vec_len (name))
14433     {
14434       errmsg ("policer name must be specified");
14435       return -99;
14436     }
14437
14438   if (vec_len (name) > 64)
14439     {
14440       errmsg ("policer name too long");
14441       return -99;
14442     }
14443
14444   M (POLICER_ADD_DEL, policer_add_del);
14445
14446   clib_memcpy (mp->name, name, vec_len (name));
14447   vec_free (name);
14448   mp->is_add = is_add;
14449   mp->cir = cir;
14450   mp->eir = eir;
14451   mp->cb = cb;
14452   mp->eb = eb;
14453   mp->rate_type = rate_type;
14454   mp->round_type = round_type;
14455   mp->type = type;
14456   mp->conform_action_type = conform_action.action_type;
14457   mp->conform_dscp = conform_action.dscp;
14458   mp->exceed_action_type = exceed_action.action_type;
14459   mp->exceed_dscp = exceed_action.dscp;
14460   mp->violate_action_type = violate_action.action_type;
14461   mp->violate_dscp = violate_action.dscp;
14462   mp->color_aware = color_aware;
14463
14464   S;
14465   W;
14466   /* NOTREACHED */
14467   return 0;
14468 }
14469
14470 static int
14471 api_policer_dump (vat_main_t * vam)
14472 {
14473   unformat_input_t *i = vam->input;
14474   vl_api_policer_dump_t *mp;
14475   f64 timeout = ~0;
14476   u8 *match_name = 0;
14477   u8 match_name_valid = 0;
14478
14479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14480     {
14481       if (unformat (i, "name %s", &match_name))
14482         {
14483           vec_add1 (match_name, 0);
14484           match_name_valid = 1;
14485         }
14486       else
14487         break;
14488     }
14489
14490   M (POLICER_DUMP, policer_dump);
14491   mp->match_name_valid = match_name_valid;
14492   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14493   vec_free (match_name);
14494   /* send it... */
14495   S;
14496
14497   /* Use a control ping for synchronization */
14498   {
14499     vl_api_control_ping_t *mp;
14500     M (CONTROL_PING, control_ping);
14501     S;
14502   }
14503   /* Wait for a reply... */
14504   W;
14505
14506   /* NOTREACHED */
14507   return 0;
14508 }
14509
14510 static int
14511 api_policer_classify_set_interface (vat_main_t * vam)
14512 {
14513   unformat_input_t *i = vam->input;
14514   vl_api_policer_classify_set_interface_t *mp;
14515   f64 timeout;
14516   u32 sw_if_index;
14517   int sw_if_index_set;
14518   u32 ip4_table_index = ~0;
14519   u32 ip6_table_index = ~0;
14520   u32 l2_table_index = ~0;
14521   u8 is_add = 1;
14522
14523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14524     {
14525       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14526         sw_if_index_set = 1;
14527       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14528         sw_if_index_set = 1;
14529       else if (unformat (i, "del"))
14530         is_add = 0;
14531       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14532         ;
14533       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14534         ;
14535       else if (unformat (i, "l2-table %d", &l2_table_index))
14536         ;
14537       else
14538         {
14539           clib_warning ("parse error '%U'", format_unformat_error, i);
14540           return -99;
14541         }
14542     }
14543
14544   if (sw_if_index_set == 0)
14545     {
14546       errmsg ("missing interface name or sw_if_index\n");
14547       return -99;
14548     }
14549
14550   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14551
14552   mp->sw_if_index = ntohl (sw_if_index);
14553   mp->ip4_table_index = ntohl (ip4_table_index);
14554   mp->ip6_table_index = ntohl (ip6_table_index);
14555   mp->l2_table_index = ntohl (l2_table_index);
14556   mp->is_add = is_add;
14557
14558   S;
14559   W;
14560   /* NOTREACHED */
14561   return 0;
14562 }
14563
14564 static int
14565 api_policer_classify_dump (vat_main_t * vam)
14566 {
14567   unformat_input_t *i = vam->input;
14568   vl_api_policer_classify_dump_t *mp;
14569   f64 timeout = ~0;
14570   u8 type = POLICER_CLASSIFY_N_TABLES;
14571
14572   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14573     ;
14574   else
14575     {
14576       errmsg ("classify table type must be specified\n");
14577       return -99;
14578     }
14579
14580   if (!vam->json_output)
14581     {
14582       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14583     }
14584
14585   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14586   mp->type = type;
14587   /* send it... */
14588   S;
14589
14590   /* Use a control ping for synchronization */
14591   {
14592     vl_api_control_ping_t *mp;
14593     M (CONTROL_PING, control_ping);
14594     S;
14595   }
14596   /* Wait for a reply... */
14597   W;
14598
14599   /* NOTREACHED */
14600   return 0;
14601 }
14602
14603 static int
14604 api_netmap_create (vat_main_t * vam)
14605 {
14606   unformat_input_t *i = vam->input;
14607   vl_api_netmap_create_t *mp;
14608   f64 timeout;
14609   u8 *if_name = 0;
14610   u8 hw_addr[6];
14611   u8 random_hw_addr = 1;
14612   u8 is_pipe = 0;
14613   u8 is_master = 0;
14614
14615   memset (hw_addr, 0, sizeof (hw_addr));
14616
14617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14618     {
14619       if (unformat (i, "name %s", &if_name))
14620         vec_add1 (if_name, 0);
14621       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14622         random_hw_addr = 0;
14623       else if (unformat (i, "pipe"))
14624         is_pipe = 1;
14625       else if (unformat (i, "master"))
14626         is_master = 1;
14627       else if (unformat (i, "slave"))
14628         is_master = 0;
14629       else
14630         break;
14631     }
14632
14633   if (!vec_len (if_name))
14634     {
14635       errmsg ("interface name must be specified");
14636       return -99;
14637     }
14638
14639   if (vec_len (if_name) > 64)
14640     {
14641       errmsg ("interface name too long");
14642       return -99;
14643     }
14644
14645   M (NETMAP_CREATE, netmap_create);
14646
14647   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14648   clib_memcpy (mp->hw_addr, hw_addr, 6);
14649   mp->use_random_hw_addr = random_hw_addr;
14650   mp->is_pipe = is_pipe;
14651   mp->is_master = is_master;
14652   vec_free (if_name);
14653
14654   S;
14655   W;
14656   /* NOTREACHED */
14657   return 0;
14658 }
14659
14660 static int
14661 api_netmap_delete (vat_main_t * vam)
14662 {
14663   unformat_input_t *i = vam->input;
14664   vl_api_netmap_delete_t *mp;
14665   f64 timeout;
14666   u8 *if_name = 0;
14667
14668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14669     {
14670       if (unformat (i, "name %s", &if_name))
14671         vec_add1 (if_name, 0);
14672       else
14673         break;
14674     }
14675
14676   if (!vec_len (if_name))
14677     {
14678       errmsg ("interface name must be specified");
14679       return -99;
14680     }
14681
14682   if (vec_len (if_name) > 64)
14683     {
14684       errmsg ("interface name too long");
14685       return -99;
14686     }
14687
14688   M (NETMAP_DELETE, netmap_delete);
14689
14690   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14691   vec_free (if_name);
14692
14693   S;
14694   W;
14695   /* NOTREACHED */
14696   return 0;
14697 }
14698
14699 static void vl_api_mpls_eth_tunnel_details_t_handler
14700   (vl_api_mpls_eth_tunnel_details_t * mp)
14701 {
14702   vat_main_t *vam = &vat_main;
14703   i32 i;
14704   i32 len = ntohl (mp->nlabels);
14705
14706   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14707            ntohl (mp->tunnel_index),
14708            format_ethernet_address, &mp->tunnel_dst_mac,
14709            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14710   for (i = 0; i < len; i++)
14711     {
14712       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14713     }
14714   fformat (vam->ofp, "\n");
14715   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14716            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14717 }
14718
14719 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14720   (vl_api_mpls_eth_tunnel_details_t * mp)
14721 {
14722   vat_main_t *vam = &vat_main;
14723   vat_json_node_t *node = NULL;
14724   struct in_addr ip4;
14725   i32 i;
14726   i32 len = ntohl (mp->nlabels);
14727
14728   if (VAT_JSON_ARRAY != vam->json_tree.type)
14729     {
14730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14731       vat_json_init_array (&vam->json_tree);
14732     }
14733   node = vat_json_array_add (&vam->json_tree);
14734
14735   vat_json_init_object (node);
14736   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14737   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14738   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14739   vat_json_object_add_uint (node, "inner_fib_index",
14740                             ntohl (mp->inner_fib_index));
14741   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14742   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14743   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14744   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14745   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14746                                    format (0, "%U", format_ethernet_address,
14747                                            &mp->tunnel_dst_mac));
14748   vat_json_object_add_uint (node, "tx_sw_if_index",
14749                             ntohl (mp->tx_sw_if_index));
14750   vat_json_object_add_uint (node, "label_count", len);
14751   for (i = 0; i < len; i++)
14752     {
14753       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14754     }
14755 }
14756
14757 static int
14758 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14759 {
14760   vl_api_mpls_eth_tunnel_dump_t *mp;
14761   f64 timeout;
14762   i32 index = -1;
14763
14764   /* Parse args required to build the message */
14765   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14766     {
14767       if (!unformat (vam->input, "tunnel_index %d", &index))
14768         {
14769           index = -1;
14770           break;
14771         }
14772     }
14773
14774   fformat (vam->ofp, "  tunnel_index %d\n", index);
14775
14776   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14777   mp->tunnel_index = htonl (index);
14778   S;
14779
14780   /* Use a control ping for synchronization */
14781   {
14782     vl_api_control_ping_t *mp;
14783     M (CONTROL_PING, control_ping);
14784     S;
14785   }
14786   W;
14787 }
14788
14789 static void vl_api_mpls_fib_encap_details_t_handler
14790   (vl_api_mpls_fib_encap_details_t * mp)
14791 {
14792   vat_main_t *vam = &vat_main;
14793   i32 i;
14794   i32 len = ntohl (mp->nlabels);
14795
14796   fformat (vam->ofp, "table %d, dest %U, label ",
14797            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14798   for (i = 0; i < len; i++)
14799     {
14800       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14801     }
14802   fformat (vam->ofp, "\n");
14803 }
14804
14805 static void vl_api_mpls_fib_encap_details_t_handler_json
14806   (vl_api_mpls_fib_encap_details_t * mp)
14807 {
14808   vat_main_t *vam = &vat_main;
14809   vat_json_node_t *node = NULL;
14810   i32 i;
14811   i32 len = ntohl (mp->nlabels);
14812   struct in_addr ip4;
14813
14814   if (VAT_JSON_ARRAY != vam->json_tree.type)
14815     {
14816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14817       vat_json_init_array (&vam->json_tree);
14818     }
14819   node = vat_json_array_add (&vam->json_tree);
14820
14821   vat_json_init_object (node);
14822   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14823   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14824   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14825   vat_json_object_add_ip4 (node, "dest", ip4);
14826   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14827   vat_json_object_add_uint (node, "label_count", len);
14828   for (i = 0; i < len; i++)
14829     {
14830       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14831     }
14832 }
14833
14834 static int
14835 api_mpls_fib_encap_dump (vat_main_t * vam)
14836 {
14837   vl_api_mpls_fib_encap_dump_t *mp;
14838   f64 timeout;
14839
14840   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14841   S;
14842
14843   /* Use a control ping for synchronization */
14844   {
14845     vl_api_control_ping_t *mp;
14846     M (CONTROL_PING, control_ping);
14847     S;
14848   }
14849   W;
14850 }
14851
14852 static void
14853 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14854 {
14855   vat_main_t *vam = &vat_main;
14856
14857   fformat (vam->ofp,
14858            "table-id %d, label %u, ess_bit %u\n",
14859            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14860 }
14861
14862 static void vl_api_mpls_fib_details_t_handler_json
14863   (vl_api_mpls_fib_details_t * mp)
14864 {
14865   vat_main_t *vam = &vat_main;
14866   vat_json_node_t *node = NULL;
14867
14868   if (VAT_JSON_ARRAY != vam->json_tree.type)
14869     {
14870       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14871       vat_json_init_array (&vam->json_tree);
14872     }
14873   node = vat_json_array_add (&vam->json_tree);
14874
14875   vat_json_init_object (node);
14876   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14877   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14878   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14879 }
14880
14881 static int
14882 api_mpls_fib_dump (vat_main_t * vam)
14883 {
14884   vl_api_mpls_fib_dump_t *mp;
14885   f64 timeout;
14886
14887   M (MPLS_FIB_DUMP, mpls_fib_dump);
14888   S;
14889
14890   /* Use a control ping for synchronization */
14891   {
14892     vl_api_control_ping_t *mp;
14893     M (CONTROL_PING, control_ping);
14894     S;
14895   }
14896   W;
14897 }
14898
14899 int
14900 api_classify_table_ids (vat_main_t * vam)
14901 {
14902   vl_api_classify_table_ids_t *mp;
14903   f64 timeout;
14904
14905   /* Construct the API message */
14906   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14907   mp->context = 0;
14908
14909   S;
14910   W;
14911   /* NOTREACHED */
14912   return 0;
14913 }
14914
14915 int
14916 api_classify_table_by_interface (vat_main_t * vam)
14917 {
14918   unformat_input_t *input = vam->input;
14919   vl_api_classify_table_by_interface_t *mp;
14920   f64 timeout;
14921
14922   u32 sw_if_index = ~0;
14923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14926         ;
14927       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14928         ;
14929       else
14930         break;
14931     }
14932   if (sw_if_index == ~0)
14933     {
14934       errmsg ("missing interface name or sw_if_index\n");
14935       return -99;
14936     }
14937
14938   /* Construct the API message */
14939   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14940   mp->context = 0;
14941   mp->sw_if_index = ntohl (sw_if_index);
14942
14943   S;
14944   W;
14945   /* NOTREACHED */
14946   return 0;
14947 }
14948
14949 int
14950 api_classify_table_info (vat_main_t * vam)
14951 {
14952   unformat_input_t *input = vam->input;
14953   vl_api_classify_table_info_t *mp;
14954   f64 timeout;
14955
14956   u32 table_id = ~0;
14957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14958     {
14959       if (unformat (input, "table_id %d", &table_id))
14960         ;
14961       else
14962         break;
14963     }
14964   if (table_id == ~0)
14965     {
14966       errmsg ("missing table id\n");
14967       return -99;
14968     }
14969
14970   /* Construct the API message */
14971   M (CLASSIFY_TABLE_INFO, classify_table_info);
14972   mp->context = 0;
14973   mp->table_id = ntohl (table_id);
14974
14975   S;
14976   W;
14977   /* NOTREACHED */
14978   return 0;
14979 }
14980
14981 int
14982 api_classify_session_dump (vat_main_t * vam)
14983 {
14984   unformat_input_t *input = vam->input;
14985   vl_api_classify_session_dump_t *mp;
14986   f64 timeout;
14987
14988   u32 table_id = ~0;
14989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14990     {
14991       if (unformat (input, "table_id %d", &table_id))
14992         ;
14993       else
14994         break;
14995     }
14996   if (table_id == ~0)
14997     {
14998       errmsg ("missing table id\n");
14999       return -99;
15000     }
15001
15002   /* Construct the API message */
15003   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15004   mp->context = 0;
15005   mp->table_id = ntohl (table_id);
15006   S;
15007
15008   /* Use a control ping for synchronization */
15009   {
15010     vl_api_control_ping_t *mp;
15011     M (CONTROL_PING, control_ping);
15012     S;
15013   }
15014   W;
15015   /* NOTREACHED */
15016   return 0;
15017 }
15018
15019 static void
15020 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15021 {
15022   vat_main_t *vam = &vat_main;
15023
15024   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15025            "src_address %U, vrf_id %d, path_mtu %u, "
15026            "template_interval %u, udp_checksum %d\n",
15027            format_ip4_address, mp->collector_address,
15028            ntohs (mp->collector_port),
15029            format_ip4_address, mp->src_address,
15030            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15031            ntohl (mp->template_interval), mp->udp_checksum);
15032
15033   vam->retval = 0;
15034   vam->result_ready = 1;
15035 }
15036
15037 static void
15038   vl_api_ipfix_exporter_details_t_handler_json
15039   (vl_api_ipfix_exporter_details_t * mp)
15040 {
15041   vat_main_t *vam = &vat_main;
15042   vat_json_node_t node;
15043   struct in_addr collector_address;
15044   struct in_addr src_address;
15045
15046   vat_json_init_object (&node);
15047   clib_memcpy (&collector_address, &mp->collector_address,
15048                sizeof (collector_address));
15049   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15050   vat_json_object_add_uint (&node, "collector_port",
15051                             ntohs (mp->collector_port));
15052   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15053   vat_json_object_add_ip4 (&node, "src_address", src_address);
15054   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15055   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15056   vat_json_object_add_uint (&node, "template_interval",
15057                             ntohl (mp->template_interval));
15058   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15059
15060   vat_json_print (vam->ofp, &node);
15061   vat_json_free (&node);
15062   vam->retval = 0;
15063   vam->result_ready = 1;
15064 }
15065
15066 int
15067 api_ipfix_exporter_dump (vat_main_t * vam)
15068 {
15069   vl_api_ipfix_exporter_dump_t *mp;
15070   f64 timeout;
15071
15072   /* Construct the API message */
15073   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15074   mp->context = 0;
15075
15076   S;
15077   W;
15078   /* NOTREACHED */
15079   return 0;
15080 }
15081
15082 static int
15083 api_ipfix_classify_stream_dump (vat_main_t * vam)
15084 {
15085   vl_api_ipfix_classify_stream_dump_t *mp;
15086   f64 timeout;
15087
15088   /* Construct the API message */
15089   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15090   mp->context = 0;
15091
15092   S;
15093   W;
15094   /* NOTREACHED */
15095   return 0;
15096 }
15097
15098 static void
15099   vl_api_ipfix_classify_stream_details_t_handler
15100   (vl_api_ipfix_classify_stream_details_t * mp)
15101 {
15102   vat_main_t *vam = &vat_main;
15103   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15104            ntohl (mp->domain_id), ntohs (mp->src_port));
15105   vam->retval = 0;
15106   vam->result_ready = 1;
15107 }
15108
15109 static void
15110   vl_api_ipfix_classify_stream_details_t_handler_json
15111   (vl_api_ipfix_classify_stream_details_t * mp)
15112 {
15113   vat_main_t *vam = &vat_main;
15114   vat_json_node_t node;
15115
15116   vat_json_init_object (&node);
15117   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15118   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15119
15120   vat_json_print (vam->ofp, &node);
15121   vat_json_free (&node);
15122   vam->retval = 0;
15123   vam->result_ready = 1;
15124 }
15125
15126 static int
15127 api_ipfix_classify_table_dump (vat_main_t * vam)
15128 {
15129   vl_api_ipfix_classify_table_dump_t *mp;
15130   f64 timeout;
15131
15132   if (!vam->json_output)
15133     {
15134       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15135                "transport_protocol");
15136     }
15137
15138   /* Construct the API message */
15139   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15140
15141   /* send it... */
15142   S;
15143
15144   /* Use a control ping for synchronization */
15145   {
15146     vl_api_control_ping_t *mp;
15147     M (CONTROL_PING, control_ping);
15148     S;
15149   }
15150   W;
15151 }
15152
15153 static void
15154   vl_api_ipfix_classify_table_details_t_handler
15155   (vl_api_ipfix_classify_table_details_t * mp)
15156 {
15157   vat_main_t *vam = &vat_main;
15158   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15159            mp->transport_protocol);
15160 }
15161
15162 static void
15163   vl_api_ipfix_classify_table_details_t_handler_json
15164   (vl_api_ipfix_classify_table_details_t * mp)
15165 {
15166   vat_json_node_t *node = NULL;
15167   vat_main_t *vam = &vat_main;
15168
15169   if (VAT_JSON_ARRAY != vam->json_tree.type)
15170     {
15171       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15172       vat_json_init_array (&vam->json_tree);
15173     }
15174
15175   node = vat_json_array_add (&vam->json_tree);
15176   vat_json_init_object (node);
15177
15178   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15179   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15180   vat_json_object_add_uint (node, "transport_protocol",
15181                             mp->transport_protocol);
15182 }
15183
15184 int
15185 api_pg_create_interface (vat_main_t * vam)
15186 {
15187   unformat_input_t *input = vam->input;
15188   vl_api_pg_create_interface_t *mp;
15189   f64 timeout;
15190
15191   u32 if_id = ~0;
15192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15193     {
15194       if (unformat (input, "if_id %d", &if_id))
15195         ;
15196       else
15197         break;
15198     }
15199   if (if_id == ~0)
15200     {
15201       errmsg ("missing pg interface index\n");
15202       return -99;
15203     }
15204
15205   /* Construct the API message */
15206   M (PG_CREATE_INTERFACE, pg_create_interface);
15207   mp->context = 0;
15208   mp->interface_id = ntohl (if_id);
15209
15210   S;
15211   W;
15212   /* NOTREACHED */
15213   return 0;
15214 }
15215
15216 int
15217 api_pg_capture (vat_main_t * vam)
15218 {
15219   unformat_input_t *input = vam->input;
15220   vl_api_pg_capture_t *mp;
15221   f64 timeout;
15222
15223   u32 if_id = ~0;
15224   u8 enable = 1;
15225   u32 count = 1;
15226   u8 pcap_file_set = 0;
15227   u8 *pcap_file = 0;
15228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15229     {
15230       if (unformat (input, "if_id %d", &if_id))
15231         ;
15232       else if (unformat (input, "pcap %s", &pcap_file))
15233         pcap_file_set = 1;
15234       else if (unformat (input, "count %d", &count))
15235         ;
15236       else if (unformat (input, "disable"))
15237         enable = 0;
15238       else
15239         break;
15240     }
15241   if (if_id == ~0)
15242     {
15243       errmsg ("missing pg interface index\n");
15244       return -99;
15245     }
15246   if (pcap_file_set > 0)
15247     {
15248       if (vec_len (pcap_file) > 255)
15249         {
15250           errmsg ("pcap file name is too long\n");
15251           return -99;
15252         }
15253     }
15254
15255   u32 name_len = vec_len (pcap_file);
15256   /* Construct the API message */
15257   M (PG_CAPTURE, pg_capture);
15258   mp->context = 0;
15259   mp->interface_id = ntohl (if_id);
15260   mp->is_enabled = enable;
15261   mp->count = ntohl (count);
15262   mp->pcap_name_length = ntohl (name_len);
15263   if (pcap_file_set != 0)
15264     {
15265       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15266     }
15267   vec_free (pcap_file);
15268
15269   S;
15270   W;
15271   /* NOTREACHED */
15272   return 0;
15273 }
15274
15275 int
15276 api_pg_enable_disable (vat_main_t * vam)
15277 {
15278   unformat_input_t *input = vam->input;
15279   vl_api_pg_enable_disable_t *mp;
15280   f64 timeout;
15281
15282   u8 enable = 1;
15283   u8 stream_name_set = 0;
15284   u8 *stream_name = 0;
15285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15286     {
15287       if (unformat (input, "stream %s", &stream_name))
15288         stream_name_set = 1;
15289       else if (unformat (input, "disable"))
15290         enable = 0;
15291       else
15292         break;
15293     }
15294
15295   if (stream_name_set > 0)
15296     {
15297       if (vec_len (stream_name) > 255)
15298         {
15299           errmsg ("stream name too long\n");
15300           return -99;
15301         }
15302     }
15303
15304   u32 name_len = vec_len (stream_name);
15305   /* Construct the API message */
15306   M (PG_ENABLE_DISABLE, pg_enable_disable);
15307   mp->context = 0;
15308   mp->is_enabled = enable;
15309   if (stream_name_set != 0)
15310     {
15311       mp->stream_name_length = ntohl (name_len);
15312       clib_memcpy (mp->stream_name, stream_name, name_len);
15313     }
15314   vec_free (stream_name);
15315
15316   S;
15317   W;
15318   /* NOTREACHED */
15319   return 0;
15320 }
15321
15322 int
15323 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15324 {
15325   unformat_input_t *input = vam->input;
15326   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15327   f64 timeout;
15328
15329   u16 *low_ports = 0;
15330   u16 *high_ports = 0;
15331   u16 this_low;
15332   u16 this_hi;
15333   ip4_address_t ip4_addr;
15334   ip6_address_t ip6_addr;
15335   u32 length;
15336   u32 tmp, tmp2;
15337   u8 prefix_set = 0;
15338   u32 vrf_id = ~0;
15339   u8 is_add = 1;
15340   u8 is_ipv6 = 0;
15341
15342   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15343     {
15344       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15345         {
15346           prefix_set = 1;
15347         }
15348       else
15349         if (unformat
15350             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15351         {
15352           prefix_set = 1;
15353           is_ipv6 = 1;
15354         }
15355       else if (unformat (input, "vrf %d", &vrf_id))
15356         ;
15357       else if (unformat (input, "del"))
15358         is_add = 0;
15359       else if (unformat (input, "port %d", &tmp))
15360         {
15361           if (tmp == 0 || tmp > 65535)
15362             {
15363               errmsg ("port %d out of range", tmp);
15364               return -99;
15365             }
15366           this_low = tmp;
15367           this_hi = this_low + 1;
15368           vec_add1 (low_ports, this_low);
15369           vec_add1 (high_ports, this_hi);
15370         }
15371       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15372         {
15373           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15374             {
15375               errmsg ("incorrect range parameters\n");
15376               return -99;
15377             }
15378           this_low = tmp;
15379           /* Note: in debug CLI +1 is added to high before
15380              passing to real fn that does "the work"
15381              (ip_source_and_port_range_check_add_del).
15382              This fn is a wrapper around the binary API fn a
15383              control plane will call, which expects this increment
15384              to have occurred. Hence letting the binary API control
15385              plane fn do the increment for consistency between VAT
15386              and other control planes.
15387            */
15388           this_hi = tmp2;
15389           vec_add1 (low_ports, this_low);
15390           vec_add1 (high_ports, this_hi);
15391         }
15392       else
15393         break;
15394     }
15395
15396   if (prefix_set == 0)
15397     {
15398       errmsg ("<address>/<mask> not specified\n");
15399       return -99;
15400     }
15401
15402   if (vrf_id == ~0)
15403     {
15404       errmsg ("VRF ID required, not specified\n");
15405       return -99;
15406     }
15407
15408   if (vrf_id == 0)
15409     {
15410       errmsg
15411         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15412       return -99;
15413     }
15414
15415   if (vec_len (low_ports) == 0)
15416     {
15417       errmsg ("At least one port or port range required\n");
15418       return -99;
15419     }
15420
15421   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15422      ip_source_and_port_range_check_add_del);
15423
15424   mp->is_add = is_add;
15425
15426   if (is_ipv6)
15427     {
15428       mp->is_ipv6 = 1;
15429       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15430     }
15431   else
15432     {
15433       mp->is_ipv6 = 0;
15434       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15435     }
15436
15437   mp->mask_length = length;
15438   mp->number_of_ranges = vec_len (low_ports);
15439
15440   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15441   vec_free (low_ports);
15442
15443   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15444   vec_free (high_ports);
15445
15446   mp->vrf_id = ntohl (vrf_id);
15447
15448   S;
15449   W;
15450   /* NOTREACHED */
15451   return 0;
15452 }
15453
15454 int
15455 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15456 {
15457   unformat_input_t *input = vam->input;
15458   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15459   f64 timeout;
15460   u32 sw_if_index = ~0;
15461   int vrf_set = 0;
15462   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15463   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15464   u8 is_add = 1;
15465
15466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15467     {
15468       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15469         ;
15470       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15471         ;
15472       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15473         vrf_set = 1;
15474       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15475         vrf_set = 1;
15476       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15477         vrf_set = 1;
15478       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15479         vrf_set = 1;
15480       else if (unformat (input, "del"))
15481         is_add = 0;
15482       else
15483         break;
15484     }
15485
15486   if (sw_if_index == ~0)
15487     {
15488       errmsg ("Interface required but not specified\n");
15489       return -99;
15490     }
15491
15492   if (vrf_set == 0)
15493     {
15494       errmsg ("VRF ID required but not specified\n");
15495       return -99;
15496     }
15497
15498   if (tcp_out_vrf_id == 0
15499       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15500     {
15501       errmsg
15502         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15503       return -99;
15504     }
15505
15506   /* Construct the API message */
15507   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15508      ip_source_and_port_range_check_interface_add_del);
15509
15510   mp->sw_if_index = ntohl (sw_if_index);
15511   mp->is_add = is_add;
15512   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15513   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15514   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15515   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15516
15517   /* send it... */
15518   S;
15519
15520   /* Wait for a reply... */
15521   W;
15522 }
15523
15524 static int
15525 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15526 {
15527   unformat_input_t *i = vam->input;
15528   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15529   f64 timeout;
15530   u32 local_sa_id = 0;
15531   u32 remote_sa_id = 0;
15532   ip4_address_t src_address;
15533   ip4_address_t dst_address;
15534   u8 is_add = 1;
15535
15536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15537     {
15538       if (unformat (i, "local_sa %d", &local_sa_id))
15539         ;
15540       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15541         ;
15542       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15543         ;
15544       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15545         ;
15546       else if (unformat (i, "del"))
15547         is_add = 0;
15548       else
15549         {
15550           clib_warning ("parse error '%U'", format_unformat_error, i);
15551           return -99;
15552         }
15553     }
15554
15555   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15556
15557   mp->local_sa_id = ntohl (local_sa_id);
15558   mp->remote_sa_id = ntohl (remote_sa_id);
15559   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15560   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15561   mp->is_add = is_add;
15562
15563   S;
15564   W;
15565   /* NOTREACHED */
15566   return 0;
15567 }
15568
15569 static int
15570 api_punt (vat_main_t * vam)
15571 {
15572   unformat_input_t *i = vam->input;
15573   vl_api_punt_t *mp;
15574   f64 timeout;
15575   u32 ipv = ~0;
15576   u32 protocol = ~0;
15577   u32 port = ~0;
15578   int is_add = 1;
15579
15580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15581     {
15582       if (unformat (i, "ip %d", &ipv))
15583         ;
15584       else if (unformat (i, "protocol %d", &protocol))
15585         ;
15586       else if (unformat (i, "port %d", &port))
15587         ;
15588       else if (unformat (i, "del"))
15589         is_add = 0;
15590       else
15591         {
15592           clib_warning ("parse error '%U'", format_unformat_error, i);
15593           return -99;
15594         }
15595     }
15596
15597   M (PUNT, punt);
15598
15599   mp->is_add = (u8) is_add;
15600   mp->ipv = (u8) ipv;
15601   mp->l4_protocol = (u8) protocol;
15602   mp->l4_port = htons ((u16) port);
15603
15604   S;
15605   W;
15606   /* NOTREACHED */
15607   return 0;
15608 }
15609
15610 static void vl_api_ipsec_gre_tunnel_details_t_handler
15611   (vl_api_ipsec_gre_tunnel_details_t * mp)
15612 {
15613   vat_main_t *vam = &vat_main;
15614
15615   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15616            ntohl (mp->sw_if_index),
15617            format_ip4_address, &mp->src_address,
15618            format_ip4_address, &mp->dst_address,
15619            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15620 }
15621
15622 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15623   (vl_api_ipsec_gre_tunnel_details_t * mp)
15624 {
15625   vat_main_t *vam = &vat_main;
15626   vat_json_node_t *node = NULL;
15627   struct in_addr ip4;
15628
15629   if (VAT_JSON_ARRAY != vam->json_tree.type)
15630     {
15631       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15632       vat_json_init_array (&vam->json_tree);
15633     }
15634   node = vat_json_array_add (&vam->json_tree);
15635
15636   vat_json_init_object (node);
15637   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15638   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15639   vat_json_object_add_ip4 (node, "src_address", ip4);
15640   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15641   vat_json_object_add_ip4 (node, "dst_address", ip4);
15642   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15643   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15644 }
15645
15646 static int
15647 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15648 {
15649   unformat_input_t *i = vam->input;
15650   vl_api_ipsec_gre_tunnel_dump_t *mp;
15651   f64 timeout;
15652   u32 sw_if_index;
15653   u8 sw_if_index_set = 0;
15654
15655   /* Parse args required to build the message */
15656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15657     {
15658       if (unformat (i, "sw_if_index %d", &sw_if_index))
15659         sw_if_index_set = 1;
15660       else
15661         break;
15662     }
15663
15664   if (sw_if_index_set == 0)
15665     {
15666       sw_if_index = ~0;
15667     }
15668
15669   if (!vam->json_output)
15670     {
15671       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15672                "sw_if_index", "src_address", "dst_address",
15673                "local_sa_id", "remote_sa_id");
15674     }
15675
15676   /* Get list of gre-tunnel interfaces */
15677   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15678
15679   mp->sw_if_index = htonl (sw_if_index);
15680
15681   S;
15682
15683   /* Use a control ping for synchronization */
15684   {
15685     vl_api_control_ping_t *mp;
15686     M (CONTROL_PING, control_ping);
15687     S;
15688   }
15689   W;
15690 }
15691
15692 static int
15693 api_delete_subif (vat_main_t * vam)
15694 {
15695   unformat_input_t *i = vam->input;
15696   vl_api_delete_subif_t *mp;
15697   f64 timeout;
15698   u32 sw_if_index = ~0;
15699
15700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15701     {
15702       if (unformat (i, "sw_if_index %d", &sw_if_index))
15703         ;
15704       else
15705         break;
15706     }
15707
15708   if (sw_if_index == ~0)
15709     {
15710       errmsg ("missing sw_if_index\n");
15711       return -99;
15712     }
15713
15714   /* Construct the API message */
15715   M (DELETE_SUBIF, delete_subif);
15716   mp->sw_if_index = ntohl (sw_if_index);
15717
15718   S;
15719   W;
15720 }
15721
15722 #define foreach_pbb_vtr_op      \
15723 _("disable",  L2_VTR_DISABLED)  \
15724 _("pop",  L2_VTR_POP_2)         \
15725 _("push",  L2_VTR_PUSH_2)
15726
15727 static int
15728 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15729 {
15730   unformat_input_t *i = vam->input;
15731   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15732   f64 timeout;
15733   u32 sw_if_index = ~0, vtr_op = ~0;
15734   u16 outer_tag = ~0;
15735   u8 dmac[6], smac[6];
15736   u8 dmac_set = 0, smac_set = 0;
15737   u16 vlanid = 0;
15738   u32 sid = ~0;
15739   u32 tmp;
15740
15741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15742     {
15743       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15744         ;
15745       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15746         ;
15747       else if (unformat (i, "vtr_op %d", &vtr_op))
15748         ;
15749 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15750       foreach_pbb_vtr_op
15751 #undef _
15752         else if (unformat (i, "translate_pbb_stag"))
15753         {
15754           if (unformat (i, "%d", &tmp))
15755             {
15756               vtr_op = L2_VTR_TRANSLATE_2_1;
15757               outer_tag = tmp;
15758             }
15759           else
15760             {
15761               errmsg
15762                 ("translate_pbb_stag operation requires outer tag definition\n");
15763               return -99;
15764             }
15765         }
15766       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15767         dmac_set++;
15768       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15769         smac_set++;
15770       else if (unformat (i, "sid %d", &sid))
15771         ;
15772       else if (unformat (i, "vlanid %d", &tmp))
15773         vlanid = tmp;
15774       else
15775         {
15776           clib_warning ("parse error '%U'", format_unformat_error, i);
15777           return -99;
15778         }
15779     }
15780
15781   if ((sw_if_index == ~0) || (vtr_op == ~0))
15782     {
15783       errmsg ("missing sw_if_index or vtr operation\n");
15784       return -99;
15785     }
15786   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15787       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15788     {
15789       errmsg
15790         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15791       return -99;
15792     }
15793
15794   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15795   mp->sw_if_index = ntohl (sw_if_index);
15796   mp->vtr_op = ntohl (vtr_op);
15797   mp->outer_tag = ntohs (outer_tag);
15798   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15799   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15800   mp->b_vlanid = ntohs (vlanid);
15801   mp->i_sid = ntohl (sid);
15802
15803   S;
15804   W;
15805   /* NOTREACHED */
15806   return 0;
15807 }
15808
15809 static int
15810 api_flow_classify_set_interface (vat_main_t * vam)
15811 {
15812   unformat_input_t *i = vam->input;
15813   vl_api_flow_classify_set_interface_t *mp;
15814   f64 timeout;
15815   u32 sw_if_index;
15816   int sw_if_index_set;
15817   u32 ip4_table_index = ~0;
15818   u32 ip6_table_index = ~0;
15819   u8 is_add = 1;
15820
15821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15822     {
15823       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15824         sw_if_index_set = 1;
15825       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15826         sw_if_index_set = 1;
15827       else if (unformat (i, "del"))
15828         is_add = 0;
15829       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15830         ;
15831       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15832         ;
15833       else
15834         {
15835           clib_warning ("parse error '%U'", format_unformat_error, i);
15836           return -99;
15837         }
15838     }
15839
15840   if (sw_if_index_set == 0)
15841     {
15842       errmsg ("missing interface name or sw_if_index\n");
15843       return -99;
15844     }
15845
15846   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
15847
15848   mp->sw_if_index = ntohl (sw_if_index);
15849   mp->ip4_table_index = ntohl (ip4_table_index);
15850   mp->ip6_table_index = ntohl (ip6_table_index);
15851   mp->is_add = is_add;
15852
15853   S;
15854   W;
15855   /* NOTREACHED */
15856   return 0;
15857 }
15858
15859 static int
15860 api_flow_classify_dump (vat_main_t * vam)
15861 {
15862   unformat_input_t *i = vam->input;
15863   vl_api_flow_classify_dump_t *mp;
15864   f64 timeout = ~0;
15865   u8 type = FLOW_CLASSIFY_N_TABLES;
15866
15867   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
15868     ;
15869   else
15870     {
15871       errmsg ("classify table type must be specified\n");
15872       return -99;
15873     }
15874
15875   if (!vam->json_output)
15876     {
15877       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15878     }
15879
15880   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
15881   mp->type = type;
15882   /* send it... */
15883   S;
15884
15885   /* Use a control ping for synchronization */
15886   {
15887     vl_api_control_ping_t *mp;
15888     M (CONTROL_PING, control_ping);
15889     S;
15890   }
15891   /* Wait for a reply... */
15892   W;
15893
15894   /* NOTREACHED */
15895   return 0;
15896 }
15897
15898 static int
15899 q_or_quit (vat_main_t * vam)
15900 {
15901   longjmp (vam->jump_buf, 1);
15902   return 0;                     /* not so much */
15903 }
15904
15905 static int
15906 q (vat_main_t * vam)
15907 {
15908   return q_or_quit (vam);
15909 }
15910
15911 static int
15912 quit (vat_main_t * vam)
15913 {
15914   return q_or_quit (vam);
15915 }
15916
15917 static int
15918 comment (vat_main_t * vam)
15919 {
15920   return 0;
15921 }
15922
15923 static int
15924 cmd_cmp (void *a1, void *a2)
15925 {
15926   u8 **c1 = a1;
15927   u8 **c2 = a2;
15928
15929   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15930 }
15931
15932 static int
15933 help (vat_main_t * vam)
15934 {
15935   u8 **cmds = 0;
15936   u8 *name = 0;
15937   hash_pair_t *p;
15938   unformat_input_t *i = vam->input;
15939   int j;
15940
15941   if (unformat (i, "%s", &name))
15942     {
15943       uword *hs;
15944
15945       vec_add1 (name, 0);
15946
15947       hs = hash_get_mem (vam->help_by_name, name);
15948       if (hs)
15949         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15950       else
15951         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15952       vec_free (name);
15953       return 0;
15954     }
15955
15956   fformat (vam->ofp, "Help is available for the following:\n");
15957
15958     /* *INDENT-OFF* */
15959     hash_foreach_pair (p, vam->function_by_name,
15960     ({
15961       vec_add1 (cmds, (u8 *)(p->key));
15962     }));
15963     /* *INDENT-ON* */
15964
15965   vec_sort_with_function (cmds, cmd_cmp);
15966
15967   for (j = 0; j < vec_len (cmds); j++)
15968     fformat (vam->ofp, "%s\n", cmds[j]);
15969
15970   vec_free (cmds);
15971   return 0;
15972 }
15973
15974 static int
15975 set (vat_main_t * vam)
15976 {
15977   u8 *name = 0, *value = 0;
15978   unformat_input_t *i = vam->input;
15979
15980   if (unformat (i, "%s", &name))
15981     {
15982       /* The input buffer is a vector, not a string. */
15983       value = vec_dup (i->buffer);
15984       vec_delete (value, i->index, 0);
15985       /* Almost certainly has a trailing newline */
15986       if (value[vec_len (value) - 1] == '\n')
15987         value[vec_len (value) - 1] = 0;
15988       /* Make sure it's a proper string, one way or the other */
15989       vec_add1 (value, 0);
15990       (void) clib_macro_set_value (&vam->macro_main,
15991                                    (char *) name, (char *) value);
15992     }
15993   else
15994     errmsg ("usage: set <name> <value>\n");
15995
15996   vec_free (name);
15997   vec_free (value);
15998   return 0;
15999 }
16000
16001 static int
16002 unset (vat_main_t * vam)
16003 {
16004   u8 *name = 0;
16005
16006   if (unformat (vam->input, "%s", &name))
16007     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16008       errmsg ("unset: %s wasn't set\n", name);
16009   vec_free (name);
16010   return 0;
16011 }
16012
16013 typedef struct
16014 {
16015   u8 *name;
16016   u8 *value;
16017 } macro_sort_t;
16018
16019
16020 static int
16021 macro_sort_cmp (void *a1, void *a2)
16022 {
16023   macro_sort_t *s1 = a1;
16024   macro_sort_t *s2 = a2;
16025
16026   return strcmp ((char *) (s1->name), (char *) (s2->name));
16027 }
16028
16029 static int
16030 dump_macro_table (vat_main_t * vam)
16031 {
16032   macro_sort_t *sort_me = 0, *sm;
16033   int i;
16034   hash_pair_t *p;
16035
16036     /* *INDENT-OFF* */
16037     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16038     ({
16039       vec_add2 (sort_me, sm, 1);
16040       sm->name = (u8 *)(p->key);
16041       sm->value = (u8 *) (p->value[0]);
16042     }));
16043     /* *INDENT-ON* */
16044
16045   vec_sort_with_function (sort_me, macro_sort_cmp);
16046
16047   if (vec_len (sort_me))
16048     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16049   else
16050     fformat (vam->ofp, "The macro table is empty...\n");
16051
16052   for (i = 0; i < vec_len (sort_me); i++)
16053     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16054   return 0;
16055 }
16056
16057 static int
16058 dump_node_table (vat_main_t * vam)
16059 {
16060   int i, j;
16061   vlib_node_t *node, *next_node;
16062
16063   if (vec_len (vam->graph_nodes) == 0)
16064     {
16065       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16066       return 0;
16067     }
16068
16069   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16070     {
16071       node = vam->graph_nodes[i];
16072       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16073       for (j = 0; j < vec_len (node->next_nodes); j++)
16074         {
16075           if (node->next_nodes[j] != ~0)
16076             {
16077               next_node = vam->graph_nodes[node->next_nodes[j]];
16078               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16079             }
16080         }
16081     }
16082   return 0;
16083 }
16084
16085 static int
16086 search_node_table (vat_main_t * vam)
16087 {
16088   unformat_input_t *line_input = vam->input;
16089   u8 *node_to_find;
16090   int j;
16091   vlib_node_t *node, *next_node;
16092   uword *p;
16093
16094   if (vam->graph_node_index_by_name == 0)
16095     {
16096       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16097       return 0;
16098     }
16099
16100   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16101     {
16102       if (unformat (line_input, "%s", &node_to_find))
16103         {
16104           vec_add1 (node_to_find, 0);
16105           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16106           if (p == 0)
16107             {
16108               fformat (vam->ofp, "%s not found...\n", node_to_find);
16109               goto out;
16110             }
16111           node = vam->graph_nodes[p[0]];
16112           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16113           for (j = 0; j < vec_len (node->next_nodes); j++)
16114             {
16115               if (node->next_nodes[j] != ~0)
16116                 {
16117                   next_node = vam->graph_nodes[node->next_nodes[j]];
16118                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16119                 }
16120             }
16121         }
16122
16123       else
16124         {
16125           clib_warning ("parse error '%U'", format_unformat_error,
16126                         line_input);
16127           return -99;
16128         }
16129
16130     out:
16131       vec_free (node_to_find);
16132
16133     }
16134
16135   return 0;
16136 }
16137
16138
16139 static int
16140 script (vat_main_t * vam)
16141 {
16142   u8 *s = 0;
16143   char *save_current_file;
16144   unformat_input_t save_input;
16145   jmp_buf save_jump_buf;
16146   u32 save_line_number;
16147
16148   FILE *new_fp, *save_ifp;
16149
16150   if (unformat (vam->input, "%s", &s))
16151     {
16152       new_fp = fopen ((char *) s, "r");
16153       if (new_fp == 0)
16154         {
16155           errmsg ("Couldn't open script file %s\n", s);
16156           vec_free (s);
16157           return -99;
16158         }
16159     }
16160   else
16161     {
16162       errmsg ("Missing script name\n");
16163       return -99;
16164     }
16165
16166   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16167   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16168   save_ifp = vam->ifp;
16169   save_line_number = vam->input_line_number;
16170   save_current_file = (char *) vam->current_file;
16171
16172   vam->input_line_number = 0;
16173   vam->ifp = new_fp;
16174   vam->current_file = s;
16175   do_one_file (vam);
16176
16177   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16178   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16179   vam->ifp = save_ifp;
16180   vam->input_line_number = save_line_number;
16181   vam->current_file = (u8 *) save_current_file;
16182   vec_free (s);
16183
16184   return 0;
16185 }
16186
16187 static int
16188 echo (vat_main_t * vam)
16189 {
16190   fformat (vam->ofp, "%v", vam->input->buffer);
16191   return 0;
16192 }
16193
16194 /* List of API message constructors, CLI names map to api_xxx */
16195 #define foreach_vpe_api_msg                                             \
16196 _(create_loopback,"[mac <mac-addr>]")                                   \
16197 _(sw_interface_dump,"")                                                 \
16198 _(sw_interface_set_flags,                                               \
16199   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16200 _(sw_interface_add_del_address,                                         \
16201   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16202 _(sw_interface_set_table,                                               \
16203   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16204 _(sw_interface_set_mpls_enable,                                                \
16205   "<intfc> | sw_if_index [disable | dis]")                                \
16206 _(sw_interface_set_vpath,                                               \
16207   "<intfc> | sw_if_index <id> enable | disable")                        \
16208 _(sw_interface_set_l2_xconnect,                                         \
16209   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16210   "enable | disable")                                                   \
16211 _(sw_interface_set_l2_bridge,                                           \
16212   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16213   "[shg <split-horizon-group>] [bvi]\n"                                 \
16214   "enable | disable")                                                   \
16215 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16216   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16217   "profile <profile-id>\n")                                             \
16218 _(sw_interface_set_dpdk_hqos_subport,                                   \
16219   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16220   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16221 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16222   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16223 _(bridge_domain_add_del,                                                \
16224   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16225 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16226 _(l2fib_add_del,                                                        \
16227   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16228 _(l2_flags,                                                             \
16229   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16230 _(bridge_flags,                                                         \
16231   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16232 _(tap_connect,                                                          \
16233   "tapname <name> mac <mac-addr> | random-mac")                         \
16234 _(tap_modify,                                                           \
16235   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16236 _(tap_delete,                                                           \
16237   "<vpp-if-name> | sw_if_index <id>")                                   \
16238 _(sw_interface_tap_dump, "")                                            \
16239 _(ip_add_del_route,                                                     \
16240   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16241   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16242   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16243   "[multipath] [count <n>]")                                            \
16244 _(mpls_route_add_del,                                                   \
16245   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16246   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16247   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16248   "[multipath] [count <n>]")                                            \
16249 _(mpls_ip_bind_unbind,                                                  \
16250   "<label> <addr/len>")                                                 \
16251 _(proxy_arp_add_del,                                                    \
16252   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16253 _(proxy_arp_intfc_enable_disable,                                       \
16254   "<intfc> | sw_if_index <id> enable | disable")                        \
16255 _(mpls_add_del_encap,                                                   \
16256   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16257 _(sw_interface_set_unnumbered,                                          \
16258   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16259 _(ip_neighbor_add_del,                                                  \
16260   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16261   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16262 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16263 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16264 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16265   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16266   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16267   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16268 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16269 _(reset_fib, "vrf <n> [ipv6]")                                          \
16270 _(dhcp_proxy_config,                                                    \
16271   "svr <v46-address> src <v46-address>\n"                               \
16272    "insert-cid <n> [del]")                                              \
16273 _(dhcp_proxy_config_2,                                                  \
16274   "svr <v46-address> src <v46-address>\n"                               \
16275    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16276 _(dhcp_proxy_set_vss,                                                   \
16277   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16278 _(dhcp_client_config,                                                   \
16279   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16280 _(set_ip_flow_hash,                                                     \
16281   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16282 _(sw_interface_ip6_enable_disable,                                      \
16283   "<intfc> | sw_if_index <id> enable | disable")                        \
16284 _(sw_interface_ip6_set_link_local_address,                              \
16285   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16286 _(sw_interface_ip6nd_ra_prefix,                                         \
16287   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16288   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16289   "[nolink] [isno]")                                                    \
16290 _(sw_interface_ip6nd_ra_config,                                         \
16291   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16292   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16293   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16294 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16295 _(l2_patch_add_del,                                                     \
16296   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16297   "enable | disable")                                                   \
16298 _(mpls_ethernet_add_del_tunnel,                                         \
16299   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16300   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16301 _(mpls_ethernet_add_del_tunnel_2,                                       \
16302   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16303   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16304 _(sr_tunnel_add_del,                                                    \
16305   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16306   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16307   "[policy <policy_name>]")                                             \
16308 _(sr_policy_add_del,                                                    \
16309   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16310 _(sr_multicast_map_add_del,                                             \
16311   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16312 _(classify_add_del_table,                                               \
16313   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16314   "[del] mask <mask-value>\n"                                           \
16315   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
16316 _(classify_add_del_session,                                             \
16317   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16318   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16319   "  [l3 [ip4|ip6]]")                                                   \
16320 _(classify_set_interface_ip_table,                                      \
16321   "<intfc> | sw_if_index <nn> table <nn>")                              \
16322 _(classify_set_interface_l2_tables,                                     \
16323   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16324   "  [other-table <nn>]")                                               \
16325 _(get_node_index, "node <node-name")                                    \
16326 _(add_node_next, "node <node-name> next <next-node-name>")              \
16327 _(l2tpv3_create_tunnel,                                                 \
16328   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16329   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16330   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16331 _(l2tpv3_set_tunnel_cookies,                                            \
16332   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16333   "[new_remote_cookie <nn>]\n")                                         \
16334 _(l2tpv3_interface_enable_disable,                                      \
16335   "<intfc> | sw_if_index <nn> enable | disable")                        \
16336 _(l2tpv3_set_lookup_key,                                                \
16337   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16338 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16339 _(vxlan_add_del_tunnel,                                                 \
16340   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16341   " [decap-next l2|ip4|ip6] [del]")                                     \
16342 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16343 _(gre_add_del_tunnel,                                                   \
16344   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16345 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16346 _(l2_fib_clear_table, "")                                               \
16347 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16348 _(l2_interface_vlan_tag_rewrite,                                        \
16349   "<intfc> | sw_if_index <nn> \n"                                       \
16350   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16351   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16352 _(create_vhost_user_if,                                                 \
16353         "socket <filename> [server] [renumber <dev_instance>] "         \
16354         "[mac <mac_address>]")                                          \
16355 _(modify_vhost_user_if,                                                 \
16356         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16357         "[server] [renumber <dev_instance>]")                           \
16358 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16359 _(sw_interface_vhost_user_dump, "")                                     \
16360 _(show_version, "")                                                     \
16361 _(vxlan_gpe_add_del_tunnel,                                             \
16362   "local <addr> remote <addr> vni <nn>\n"                               \
16363     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16364   "[next-ethernet] [next-nsh]\n")                                       \
16365 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16366 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16367 _(interface_name_renumber,                                              \
16368   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16369 _(input_acl_set_interface,                                              \
16370   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16371   "  [l2-table <nn>] [del]")                                            \
16372 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16373 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16374 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16375 _(ip_dump, "ipv4 | ipv6")                                               \
16376 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16377 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16378   "  spid_id <n> ")                                                     \
16379 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16380   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16381   "  integ_alg <alg> integ_key <hex>")                                  \
16382 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16383   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16384   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16385   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16386 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16387 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16388 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16389   "(auth_data 0x<data> | auth_data <data>)")                            \
16390 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16391   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16392 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16393   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16394   "(local|remote)")                                                     \
16395 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16396 _(delete_loopback,"sw_if_index <nn>")                                   \
16397 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16398 _(map_add_domain,                                                       \
16399   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16400   "ip6-src <ip6addr> "                                                  \
16401   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16402 _(map_del_domain, "index <n>")                                          \
16403 _(map_add_del_rule,                                                     \
16404   "index <n> psid <n> dst <ip6addr> [del]")                             \
16405 _(map_domain_dump, "")                                                  \
16406 _(map_rule_dump, "index <map-domain>")                                  \
16407 _(want_interface_events,  "enable|disable")                             \
16408 _(want_stats,"enable|disable")                                          \
16409 _(get_first_msg_id, "client <name>")                                    \
16410 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16411 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16412   "fib-id <nn> [ip4][ip6][default]")                                    \
16413 _(get_node_graph, " ")                                                  \
16414 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16415 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16416 _(ioam_disable, "")                                                \
16417 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16418                             " sw_if_index <sw_if_index> p <priority> "  \
16419                             "w <weight>] [del]")                        \
16420 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16421                         "iface <intf> | sw_if_index <sw_if_index> "     \
16422                         "p <priority> w <weight> [del]")                \
16423 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16424                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16425                           "locator-set <locator_name> [del]")           \
16426 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16427   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16428 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16429 _(lisp_gpe_enable_disable, "enable|disable")                            \
16430 _(lisp_enable_disable, "enable|disable")                                \
16431 _(lisp_gpe_add_del_iface, "up|down")                                    \
16432 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16433                                "[seid <seid>] "                         \
16434                                "rloc <locator> p <prio> "               \
16435                                "w <weight> [rloc <loc> ... ] "          \
16436                                "action <action> [del-all]")             \
16437 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16438                           "<local-eid>")                                \
16439 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16440 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16441 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16442 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16443 _(lisp_locator_set_dump, "[local | remote]")                            \
16444 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16445 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16446                        "[local] | [remote]")                            \
16447 _(lisp_eid_table_vni_dump, "")                                          \
16448 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16449 _(lisp_gpe_tunnel_dump, "")                                             \
16450 _(lisp_map_resolver_dump, "")                                           \
16451 _(lisp_adjacencies_get, "vni <vni>")                                    \
16452 _(show_lisp_status, "")                                                 \
16453 _(lisp_get_map_request_itr_rlocs, "")                                   \
16454 _(show_lisp_pitr, "")                                                   \
16455 _(show_lisp_map_request_mode, "")                                       \
16456 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16457 _(af_packet_delete, "name <host interface name>")                       \
16458 _(policer_add_del, "name <policer name> <params> [del]")                \
16459 _(policer_dump, "[name <policer name>]")                                \
16460 _(policer_classify_set_interface,                                       \
16461   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16462   "  [l2-table <nn>] [del]")                                            \
16463 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16464 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16465     "[master|slave]")                                                   \
16466 _(netmap_delete, "name <interface name>")                               \
16467 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16468 _(mpls_fib_encap_dump, "")                                              \
16469 _(mpls_fib_dump, "")                                                    \
16470 _(classify_table_ids, "")                                               \
16471 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16472 _(classify_table_info, "table_id <nn>")                                 \
16473 _(classify_session_dump, "table_id <nn>")                               \
16474 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16475     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16476     "[template_interval <nn>] [udp_checksum]")                          \
16477 _(ipfix_exporter_dump, "")                                              \
16478 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16479 _(ipfix_classify_stream_dump, "")                                       \
16480 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16481 _(ipfix_classify_table_dump, "")                                        \
16482 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16483 _(pg_create_interface, "if_id <nn>")                                    \
16484 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16485 _(pg_enable_disable, "[stream <id>] disable")                           \
16486 _(ip_source_and_port_range_check_add_del,                               \
16487   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16488 _(ip_source_and_port_range_check_interface_add_del,                     \
16489   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16490   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16491 _(ipsec_gre_add_del_tunnel,                                             \
16492   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16493 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16494 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
16495 _(l2_interface_pbb_tag_rewrite,                                         \
16496   "<intfc> | sw_if_index <nn> \n"                                       \
16497   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16498   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16499 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16500 _(flow_classify_set_interface,                                          \
16501   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16502 _(flow_classify_dump, "type [ip4|ip6]")
16503
16504 /* List of command functions, CLI names map directly to functions */
16505 #define foreach_cli_function                                    \
16506 _(comment, "usage: comment <ignore-rest-of-line>")              \
16507 _(dump_interface_table, "usage: dump_interface_table")          \
16508 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16509 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16510 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16511 _(dump_stats_table, "usage: dump_stats_table")                  \
16512 _(dump_macro_table, "usage: dump_macro_table ")                 \
16513 _(dump_node_table, "usage: dump_node_table")                    \
16514 _(echo, "usage: echo <message>")                                \
16515 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16516 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16517 _(help, "usage: help")                                          \
16518 _(q, "usage: quit")                                             \
16519 _(quit, "usage: quit")                                          \
16520 _(search_node_table, "usage: search_node_table <name>...")      \
16521 _(set, "usage: set <variable-name> <value>")                    \
16522 _(script, "usage: script <file-name>")                          \
16523 _(unset, "usage: unset <variable-name>")
16524
16525 #define _(N,n)                                  \
16526     static void vl_api_##n##_t_handler_uni      \
16527     (vl_api_##n##_t * mp)                       \
16528     {                                           \
16529         vat_main_t * vam = &vat_main;           \
16530         if (vam->json_output) {                 \
16531             vl_api_##n##_t_handler_json(mp);    \
16532         } else {                                \
16533             vl_api_##n##_t_handler(mp);         \
16534         }                                       \
16535     }
16536 foreach_vpe_api_reply_msg;
16537 #undef _
16538
16539 void
16540 vat_api_hookup (vat_main_t * vam)
16541 {
16542 #define _(N,n)                                                  \
16543     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16544                            vl_api_##n##_t_handler_uni,          \
16545                            vl_noop_handler,                     \
16546                            vl_api_##n##_t_endian,               \
16547                            vl_api_##n##_t_print,                \
16548                            sizeof(vl_api_##n##_t), 1);
16549   foreach_vpe_api_reply_msg;
16550 #undef _
16551
16552   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16553
16554   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16555
16556   vam->function_by_name = hash_create_string (0, sizeof (uword));
16557
16558   vam->help_by_name = hash_create_string (0, sizeof (uword));
16559
16560   /* API messages we can send */
16561 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16562   foreach_vpe_api_msg;
16563 #undef _
16564
16565   /* Help strings */
16566 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16567   foreach_vpe_api_msg;
16568 #undef _
16569
16570   /* CLI functions */
16571 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16572   foreach_cli_function;
16573 #undef _
16574
16575   /* Help strings */
16576 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16577   foreach_cli_function;
16578 #undef _
16579 }
16580
16581 #undef vl_api_version
16582 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16583 #include <vpp-api/vpe.api.h>
16584 #undef vl_api_version
16585
16586 void
16587 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16588 {
16589   /*
16590    * Send the main API signature in slot 0. This bit of code must
16591    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16592    */
16593   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16594 }
16595
16596 /*
16597  * fd.io coding-style-patch-verification: ON
16598  *
16599  * Local Variables:
16600  * eval: (c-set-style "gnu")
16601  * End:
16602  */