ipfix: add classification nodes for flow statistics (VPP-204)
[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_mpls_gre_add_del_tunnel_reply_t_handler
1097   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   i32 retval = ntohl (mp->retval);
1101   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1102
1103   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1104     {
1105       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1106     }
1107   vam->retval = retval;
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1112   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   vat_json_node_t node;
1116
1117   vat_json_init_object (&node);
1118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1119   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1120                             ntohl (mp->tunnel_sw_if_index));
1121
1122   vat_json_print (vam->ofp, &node);
1123   vat_json_free (&node);
1124
1125   vam->retval = ntohl (mp->retval);
1126   vam->result_ready = 1;
1127 }
1128
1129
1130 static void vl_api_show_version_reply_t_handler
1131   (vl_api_show_version_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   i32 retval = ntohl (mp->retval);
1135
1136   if (retval >= 0)
1137     {
1138       errmsg ("        program: %s\n", mp->program);
1139       errmsg ("        version: %s\n", mp->version);
1140       errmsg ("     build date: %s\n", mp->build_date);
1141       errmsg ("build directory: %s\n", mp->build_directory);
1142     }
1143   vam->retval = retval;
1144   vam->result_ready = 1;
1145 }
1146
1147 static void vl_api_show_version_reply_t_handler_json
1148   (vl_api_show_version_reply_t * mp)
1149 {
1150   vat_main_t *vam = &vat_main;
1151   vat_json_node_t node;
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "program", mp->program);
1156   vat_json_object_add_string_copy (&node, "version", mp->version);
1157   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1158   vat_json_object_add_string_copy (&node, "build_directory",
1159                                    mp->build_directory);
1160
1161   vat_json_print (vam->ofp, &node);
1162   vat_json_free (&node);
1163
1164   vam->retval = ntohl (mp->retval);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void
1169 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1173           mp->mac_ip ? "mac/ip binding" : "address resolution",
1174           format_ip4_address, &mp->address,
1175           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1176 }
1177
1178 static void
1179 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1180 {
1181   /* JSON output not supported */
1182 }
1183
1184 static void
1185 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1189           mp->mac_ip ? "mac/ip binding" : "address resolution",
1190           format_ip6_address, mp->address,
1191           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1192 }
1193
1194 static void
1195 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1196 {
1197   /* JSON output not supported */
1198 }
1199
1200 /*
1201  * Special-case: build the bridge domain table, maintain
1202  * the next bd id vbl.
1203  */
1204 static void vl_api_bridge_domain_details_t_handler
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1209
1210   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1211            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1212
1213   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1214            ntohl (mp->bd_id), mp->learn, mp->forward,
1215            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1216
1217   if (n_sw_ifs)
1218     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1219              "Interface Name");
1220 }
1221
1222 static void vl_api_bridge_domain_details_t_handler_json
1223   (vl_api_bridge_domain_details_t * mp)
1224 {
1225   vat_main_t *vam = &vat_main;
1226   vat_json_node_t *node, *array = NULL;
1227
1228   if (VAT_JSON_ARRAY != vam->json_tree.type)
1229     {
1230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1231       vat_json_init_array (&vam->json_tree);
1232     }
1233   node = vat_json_array_add (&vam->json_tree);
1234
1235   vat_json_init_object (node);
1236   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1237   vat_json_object_add_uint (node, "flood", mp->flood);
1238   vat_json_object_add_uint (node, "forward", mp->forward);
1239   vat_json_object_add_uint (node, "learn", mp->learn);
1240   vat_json_object_add_uint (node, "bvi_sw_if_index",
1241                             ntohl (mp->bvi_sw_if_index));
1242   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1243   array = vat_json_object_add (node, "sw_if");
1244   vat_json_init_array (array);
1245 }
1246
1247 /*
1248  * Special-case: build the bridge domain sw if table.
1249  */
1250 static void vl_api_bridge_domain_sw_if_details_t_handler
1251   (vl_api_bridge_domain_sw_if_details_t * mp)
1252 {
1253   vat_main_t *vam = &vat_main;
1254   hash_pair_t *p;
1255   u8 *sw_if_name = 0;
1256   u32 sw_if_index;
1257
1258   sw_if_index = ntohl (mp->sw_if_index);
1259   /* *INDENT-OFF* */
1260   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1261   ({
1262     if ((u32) p->value[0] == sw_if_index)
1263       {
1264         sw_if_name = (u8 *)(p->key);
1265         break;
1266       }
1267   }));
1268   /* *INDENT-ON* */
1269
1270   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1271            mp->shg, sw_if_name ? (char *) sw_if_name :
1272            "sw_if_index not found!");
1273 }
1274
1275 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1276   (vl_api_bridge_domain_sw_if_details_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   vat_json_node_t *node = NULL;
1280   uword last_index = 0;
1281
1282   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1283   ASSERT (vec_len (vam->json_tree.array) >= 1);
1284   last_index = vec_len (vam->json_tree.array) - 1;
1285   node = &vam->json_tree.array[last_index];
1286   node = vat_json_object_get_element (node, "sw_if");
1287   ASSERT (NULL != node);
1288   node = vat_json_array_add (node);
1289
1290   vat_json_init_object (node);
1291   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1292   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1293   vat_json_object_add_uint (node, "shg", mp->shg);
1294 }
1295
1296 static void vl_api_control_ping_reply_t_handler
1297   (vl_api_control_ping_reply_t * mp)
1298 {
1299   vat_main_t *vam = &vat_main;
1300   i32 retval = ntohl (mp->retval);
1301   if (vam->async_mode)
1302     {
1303       vam->async_errors += (retval < 0);
1304     }
1305   else
1306     {
1307       vam->retval = retval;
1308       vam->result_ready = 1;
1309     }
1310 }
1311
1312 static void vl_api_control_ping_reply_t_handler_json
1313   (vl_api_control_ping_reply_t * mp)
1314 {
1315   vat_main_t *vam = &vat_main;
1316   i32 retval = ntohl (mp->retval);
1317
1318   if (VAT_JSON_NONE != vam->json_tree.type)
1319     {
1320       vat_json_print (vam->ofp, &vam->json_tree);
1321       vat_json_free (&vam->json_tree);
1322       vam->json_tree.type = VAT_JSON_NONE;
1323     }
1324   else
1325     {
1326       /* just print [] */
1327       vat_json_init_array (&vam->json_tree);
1328       vat_json_print (vam->ofp, &vam->json_tree);
1329       vam->json_tree.type = VAT_JSON_NONE;
1330     }
1331
1332   vam->retval = retval;
1333   vam->result_ready = 1;
1334 }
1335
1336 static void
1337 vl_api_l2_flags_reply_t_handler (vl_api_l2_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_l2_flags_reply_t_handler_json
1353   (vl_api_l2_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_bridge_flags_reply_t_handler
1371   (vl_api_bridge_flags_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->result_ready = 1;
1383     }
1384 }
1385
1386 static void vl_api_bridge_flags_reply_t_handler_json
1387   (vl_api_bridge_flags_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   vat_json_node_t node;
1391
1392   vat_json_init_object (&node);
1393   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1394   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1395                             ntohl (mp->resulting_feature_bitmap));
1396
1397   vat_json_print (vam->ofp, &node);
1398   vat_json_free (&node);
1399
1400   vam->retval = ntohl (mp->retval);
1401   vam->result_ready = 1;
1402 }
1403
1404 static void vl_api_tap_connect_reply_t_handler
1405   (vl_api_tap_connect_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   i32 retval = ntohl (mp->retval);
1409   if (vam->async_mode)
1410     {
1411       vam->async_errors += (retval < 0);
1412     }
1413   else
1414     {
1415       vam->retval = retval;
1416       vam->sw_if_index = ntohl (mp->sw_if_index);
1417       vam->result_ready = 1;
1418     }
1419
1420 }
1421
1422 static void vl_api_tap_connect_reply_t_handler_json
1423   (vl_api_tap_connect_reply_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   vat_json_node_t node;
1427
1428   vat_json_init_object (&node);
1429   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1430   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1431
1432   vat_json_print (vam->ofp, &node);
1433   vat_json_free (&node);
1434
1435   vam->retval = ntohl (mp->retval);
1436   vam->result_ready = 1;
1437
1438 }
1439
1440 static void
1441 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_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->sw_if_index = ntohl (mp->sw_if_index);
1453       vam->result_ready = 1;
1454     }
1455 }
1456
1457 static void vl_api_tap_modify_reply_t_handler_json
1458   (vl_api_tap_modify_reply_t * mp)
1459 {
1460   vat_main_t *vam = &vat_main;
1461   vat_json_node_t node;
1462
1463   vat_json_init_object (&node);
1464   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1465   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1466
1467   vat_json_print (vam->ofp, &node);
1468   vat_json_free (&node);
1469
1470   vam->retval = ntohl (mp->retval);
1471   vam->result_ready = 1;
1472 }
1473
1474 static void
1475 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   i32 retval = ntohl (mp->retval);
1479   if (vam->async_mode)
1480     {
1481       vam->async_errors += (retval < 0);
1482     }
1483   else
1484     {
1485       vam->retval = retval;
1486       vam->result_ready = 1;
1487     }
1488 }
1489
1490 static void vl_api_tap_delete_reply_t_handler_json
1491   (vl_api_tap_delete_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   vat_json_node_t node;
1495
1496   vat_json_init_object (&node);
1497   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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_mpls_ethernet_add_del_tunnel_reply_t_handler
1507   (vl_api_mpls_ethernet_add_del_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->result_ready = 1;
1519     }
1520 }
1521
1522 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1523   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   vat_json_node_t node;
1527
1528   vat_json_init_object (&node);
1529   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1530   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1531                             ntohl (mp->tunnel_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 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1541   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   i32 retval = ntohl (mp->retval);
1545   if (vam->async_mode)
1546     {
1547       vam->async_errors += (retval < 0);
1548     }
1549   else
1550     {
1551       vam->retval = retval;
1552       vam->sw_if_index = ntohl (mp->sw_if_index);
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1558   (vl_api_l2tpv3_create_tunnel_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, "sw_if_index", ntohl (mp->sw_if_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
1575 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1576   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   i32 retval = ntohl (mp->retval);
1580   if (vam->async_mode)
1581     {
1582       vam->async_errors += (retval < 0);
1583     }
1584   else
1585     {
1586       vam->retval = retval;
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1592   (vl_api_lisp_add_del_locator_set_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, "locator_set_index", ntohl (mp->ls_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_vxlan_add_del_tunnel_reply_t_handler
1609   (vl_api_vxlan_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_vxlan_add_del_tunnel_reply_t_handler_json
1626   (vl_api_vxlan_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_gre_add_del_tunnel_reply_t_handler
1643   (vl_api_gre_add_del_tunnel_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_gre_add_del_tunnel_reply_t_handler_json
1660   (vl_api_gre_add_del_tunnel_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_create_vhost_user_if_reply_t_handler
1677   (vl_api_create_vhost_user_if_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   i32 retval = ntohl (mp->retval);
1681   if (vam->async_mode)
1682     {
1683       vam->async_errors += (retval < 0);
1684     }
1685   else
1686     {
1687       vam->retval = retval;
1688       vam->sw_if_index = ntohl (mp->sw_if_index);
1689       vam->result_ready = 1;
1690     }
1691 }
1692
1693 static void vl_api_create_vhost_user_if_reply_t_handler_json
1694   (vl_api_create_vhost_user_if_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   vat_json_node_t node;
1698
1699   vat_json_init_object (&node);
1700   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1701   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1702
1703   vat_json_print (vam->ofp, &node);
1704   vat_json_free (&node);
1705
1706   vam->retval = ntohl (mp->retval);
1707   vam->result_ready = 1;
1708 }
1709
1710 static void vl_api_ip_address_details_t_handler
1711   (vl_api_ip_address_details_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   static ip_address_details_t empty_ip_address_details = { {0} };
1715   ip_address_details_t *address = NULL;
1716   ip_details_t *current_ip_details = NULL;
1717   ip_details_t *details = NULL;
1718
1719   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1720
1721   if (!details || vam->current_sw_if_index >= vec_len (details)
1722       || !details[vam->current_sw_if_index].present)
1723     {
1724       errmsg ("ip address details arrived but not stored\n");
1725       errmsg ("ip_dump should be called first\n");
1726       return;
1727     }
1728
1729   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1730
1731 #define addresses (current_ip_details->addr)
1732
1733   vec_validate_init_empty (addresses, vec_len (addresses),
1734                            empty_ip_address_details);
1735
1736   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1737
1738   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1739   address->prefix_length = mp->prefix_length;
1740 #undef addresses
1741 }
1742
1743 static void vl_api_ip_address_details_t_handler_json
1744   (vl_api_ip_address_details_t * mp)
1745 {
1746   vat_main_t *vam = &vat_main;
1747   vat_json_node_t *node = NULL;
1748   struct in6_addr ip6;
1749   struct in_addr ip4;
1750
1751   if (VAT_JSON_ARRAY != vam->json_tree.type)
1752     {
1753       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1754       vat_json_init_array (&vam->json_tree);
1755     }
1756   node = vat_json_array_add (&vam->json_tree);
1757
1758   vat_json_init_object (node);
1759   if (vam->is_ipv6)
1760     {
1761       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1762       vat_json_object_add_ip6 (node, "ip", ip6);
1763     }
1764   else
1765     {
1766       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1767       vat_json_object_add_ip4 (node, "ip", ip4);
1768     }
1769   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1770 }
1771
1772 static void
1773 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   static ip_details_t empty_ip_details = { 0 };
1777   ip_details_t *ip = NULL;
1778   u32 sw_if_index = ~0;
1779
1780   sw_if_index = ntohl (mp->sw_if_index);
1781
1782   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1783                            sw_if_index, empty_ip_details);
1784
1785   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1786                          sw_if_index);
1787
1788   ip->present = 1;
1789 }
1790
1791 static void
1792 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795
1796   if (VAT_JSON_ARRAY != vam->json_tree.type)
1797     {
1798       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1799       vat_json_init_array (&vam->json_tree);
1800     }
1801   vat_json_array_add_uint (&vam->json_tree,
1802                            clib_net_to_host_u32 (mp->sw_if_index));
1803 }
1804
1805 static void vl_api_map_domain_details_t_handler_json
1806   (vl_api_map_domain_details_t * mp)
1807 {
1808   vat_json_node_t *node = NULL;
1809   vat_main_t *vam = &vat_main;
1810   struct in6_addr ip6;
1811   struct in_addr ip4;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "domain_index",
1823                             clib_net_to_host_u32 (mp->domain_index));
1824   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1825   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1826   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1827   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1828   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1829   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1830   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1831   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1832   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1833   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1834   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1835   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1836   vat_json_object_add_uint (node, "flags", mp->flags);
1837   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1838   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1839 }
1840
1841 static void vl_api_map_domain_details_t_handler
1842   (vl_api_map_domain_details_t * mp)
1843 {
1844   vat_main_t *vam = &vat_main;
1845
1846   if (mp->is_translation)
1847     {
1848       fformat (vam->ofp,
1849                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1850                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1851                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1852                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1853                clib_net_to_host_u32 (mp->domain_index));
1854     }
1855   else
1856     {
1857       fformat (vam->ofp,
1858                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1859                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1860                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1861                format_ip6_address, mp->ip6_src,
1862                clib_net_to_host_u32 (mp->domain_index));
1863     }
1864   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1865            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1866            mp->is_translation ? "map-t" : "");
1867 }
1868
1869 static void vl_api_map_rule_details_t_handler_json
1870   (vl_api_map_rule_details_t * mp)
1871 {
1872   struct in6_addr ip6;
1873   vat_json_node_t *node = NULL;
1874   vat_main_t *vam = &vat_main;
1875
1876   if (VAT_JSON_ARRAY != vam->json_tree.type)
1877     {
1878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1879       vat_json_init_array (&vam->json_tree);
1880     }
1881
1882   node = vat_json_array_add (&vam->json_tree);
1883   vat_json_init_object (node);
1884
1885   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1886   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1887   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1888 }
1889
1890 static void
1891 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1895            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1896 }
1897
1898 static void
1899 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1903           "router_addr %U host_mac %U\n",
1904           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1905           format_ip4_address, &mp->host_address,
1906           format_ip4_address, &mp->router_address,
1907           format_ethernet_address, mp->host_mac);
1908 }
1909
1910 static void vl_api_dhcp_compl_event_t_handler_json
1911   (vl_api_dhcp_compl_event_t * mp)
1912 {
1913   /* JSON output not supported */
1914 }
1915
1916 static void
1917 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1918                               u32 counter)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   static u64 default_counter = 0;
1922
1923   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1924                            NULL);
1925   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1926                            sw_if_index, default_counter);
1927   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1928 }
1929
1930 static void
1931 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1932                                 interface_counter_t counter)
1933 {
1934   vat_main_t *vam = &vat_main;
1935   static interface_counter_t default_counter = { 0, };
1936
1937   vec_validate_init_empty (vam->combined_interface_counters,
1938                            vnet_counter_type, NULL);
1939   vec_validate_init_empty (vam->combined_interface_counters
1940                            [vnet_counter_type], sw_if_index, default_counter);
1941   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1942 }
1943
1944 static void vl_api_vnet_interface_counters_t_handler
1945   (vl_api_vnet_interface_counters_t * mp)
1946 {
1947   /* not supported */
1948 }
1949
1950 static void vl_api_vnet_interface_counters_t_handler_json
1951   (vl_api_vnet_interface_counters_t * mp)
1952 {
1953   interface_counter_t counter;
1954   vlib_counter_t *v;
1955   u64 *v_packets;
1956   u64 packets;
1957   u32 count;
1958   u32 first_sw_if_index;
1959   int i;
1960
1961   count = ntohl (mp->count);
1962   first_sw_if_index = ntohl (mp->first_sw_if_index);
1963
1964   if (!mp->is_combined)
1965     {
1966       v_packets = (u64 *) & mp->data;
1967       for (i = 0; i < count; i++)
1968         {
1969           packets =
1970             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1971           set_simple_interface_counter (mp->vnet_counter_type,
1972                                         first_sw_if_index + i, packets);
1973           v_packets++;
1974         }
1975     }
1976   else
1977     {
1978       v = (vlib_counter_t *) & mp->data;
1979       for (i = 0; i < count; i++)
1980         {
1981           counter.packets =
1982             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1983           counter.bytes =
1984             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1985           set_combined_interface_counter (mp->vnet_counter_type,
1986                                           first_sw_if_index + i, counter);
1987           v++;
1988         }
1989     }
1990 }
1991
1992 static u32
1993 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   u32 i;
1997
1998   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1999     {
2000       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2001         {
2002           return i;
2003         }
2004     }
2005   return ~0;
2006 }
2007
2008 static u32
2009 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2010 {
2011   vat_main_t *vam = &vat_main;
2012   u32 i;
2013
2014   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2015     {
2016       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2017         {
2018           return i;
2019         }
2020     }
2021   return ~0;
2022 }
2023
2024 static void vl_api_vnet_ip4_fib_counters_t_handler
2025   (vl_api_vnet_ip4_fib_counters_t * mp)
2026 {
2027   /* not supported */
2028 }
2029
2030 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2031   (vl_api_vnet_ip4_fib_counters_t * mp)
2032 {
2033   vat_main_t *vam = &vat_main;
2034   vl_api_ip4_fib_counter_t *v;
2035   ip4_fib_counter_t *counter;
2036   struct in_addr ip4;
2037   u32 vrf_id;
2038   u32 vrf_index;
2039   u32 count;
2040   int i;
2041
2042   vrf_id = ntohl (mp->vrf_id);
2043   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2044   if (~0 == vrf_index)
2045     {
2046       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2047       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2048       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2049       vec_validate (vam->ip4_fib_counters, vrf_index);
2050       vam->ip4_fib_counters[vrf_index] = NULL;
2051     }
2052
2053   vec_free (vam->ip4_fib_counters[vrf_index]);
2054   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2055   count = ntohl (mp->count);
2056   for (i = 0; i < count; i++)
2057     {
2058       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2059       counter = &vam->ip4_fib_counters[vrf_index][i];
2060       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2061       counter->address = ip4;
2062       counter->address_length = v->address_length;
2063       counter->packets = clib_net_to_host_u64 (v->packets);
2064       counter->bytes = clib_net_to_host_u64 (v->bytes);
2065       v++;
2066     }
2067 }
2068
2069 static void vl_api_vnet_ip6_fib_counters_t_handler
2070   (vl_api_vnet_ip6_fib_counters_t * mp)
2071 {
2072   /* not supported */
2073 }
2074
2075 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2076   (vl_api_vnet_ip6_fib_counters_t * mp)
2077 {
2078   vat_main_t *vam = &vat_main;
2079   vl_api_ip6_fib_counter_t *v;
2080   ip6_fib_counter_t *counter;
2081   struct in6_addr ip6;
2082   u32 vrf_id;
2083   u32 vrf_index;
2084   u32 count;
2085   int i;
2086
2087   vrf_id = ntohl (mp->vrf_id);
2088   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2089   if (~0 == vrf_index)
2090     {
2091       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2092       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2093       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2094       vec_validate (vam->ip6_fib_counters, vrf_index);
2095       vam->ip6_fib_counters[vrf_index] = NULL;
2096     }
2097
2098   vec_free (vam->ip6_fib_counters[vrf_index]);
2099   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2100   count = ntohl (mp->count);
2101   for (i = 0; i < count; i++)
2102     {
2103       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2104       counter = &vam->ip6_fib_counters[vrf_index][i];
2105       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2106       counter->address = ip6;
2107       counter->address_length = v->address_length;
2108       counter->packets = clib_net_to_host_u64 (v->packets);
2109       counter->bytes = clib_net_to_host_u64 (v->bytes);
2110       v++;
2111     }
2112 }
2113
2114 static void vl_api_get_first_msg_id_reply_t_handler
2115   (vl_api_get_first_msg_id_reply_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   i32 retval = ntohl (mp->retval);
2119
2120   if (vam->async_mode)
2121     {
2122       vam->async_errors += (retval < 0);
2123     }
2124   else
2125     {
2126       vam->retval = retval;
2127       vam->result_ready = 1;
2128     }
2129   if (retval >= 0)
2130     {
2131       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2132     }
2133 }
2134
2135 static void vl_api_get_first_msg_id_reply_t_handler_json
2136   (vl_api_get_first_msg_id_reply_t * mp)
2137 {
2138   vat_main_t *vam = &vat_main;
2139   vat_json_node_t node;
2140
2141   vat_json_init_object (&node);
2142   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2143   vat_json_object_add_uint (&node, "first_msg_id",
2144                             (uint) ntohs (mp->first_msg_id));
2145
2146   vat_json_print (vam->ofp, &node);
2147   vat_json_free (&node);
2148
2149   vam->retval = ntohl (mp->retval);
2150   vam->result_ready = 1;
2151 }
2152
2153 static void vl_api_get_node_graph_reply_t_handler
2154   (vl_api_get_node_graph_reply_t * mp)
2155 {
2156   vat_main_t *vam = &vat_main;
2157   api_main_t *am = &api_main;
2158   i32 retval = ntohl (mp->retval);
2159   u8 *pvt_copy, *reply;
2160   void *oldheap;
2161   vlib_node_t *node;
2162   int i;
2163
2164   if (vam->async_mode)
2165     {
2166       vam->async_errors += (retval < 0);
2167     }
2168   else
2169     {
2170       vam->retval = retval;
2171       vam->result_ready = 1;
2172     }
2173
2174   /* "Should never happen..." */
2175   if (retval != 0)
2176     return;
2177
2178   reply = (u8 *) (mp->reply_in_shmem);
2179   pvt_copy = vec_dup (reply);
2180
2181   /* Toss the shared-memory original... */
2182   pthread_mutex_lock (&am->vlib_rp->mutex);
2183   oldheap = svm_push_data_heap (am->vlib_rp);
2184
2185   vec_free (reply);
2186
2187   svm_pop_heap (oldheap);
2188   pthread_mutex_unlock (&am->vlib_rp->mutex);
2189
2190   if (vam->graph_nodes)
2191     {
2192       hash_free (vam->graph_node_index_by_name);
2193
2194       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2195         {
2196           node = vam->graph_nodes[i];
2197           vec_free (node->name);
2198           vec_free (node->next_nodes);
2199           vec_free (node);
2200         }
2201       vec_free (vam->graph_nodes);
2202     }
2203
2204   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2205   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2206   vec_free (pvt_copy);
2207
2208   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2209     {
2210       node = vam->graph_nodes[i];
2211       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2212     }
2213 }
2214
2215 static void vl_api_get_node_graph_reply_t_handler_json
2216   (vl_api_get_node_graph_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   api_main_t *am = &api_main;
2220   void *oldheap;
2221   vat_json_node_t node;
2222   u8 *reply;
2223
2224   /* $$$$ make this real? */
2225   vat_json_init_object (&node);
2226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2227   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2228
2229   reply = (u8 *) (mp->reply_in_shmem);
2230
2231   /* Toss the shared-memory original... */
2232   pthread_mutex_lock (&am->vlib_rp->mutex);
2233   oldheap = svm_push_data_heap (am->vlib_rp);
2234
2235   vec_free (reply);
2236
2237   svm_pop_heap (oldheap);
2238   pthread_mutex_unlock (&am->vlib_rp->mutex);
2239
2240   vat_json_print (vam->ofp, &node);
2241   vat_json_free (&node);
2242
2243   vam->retval = ntohl (mp->retval);
2244   vam->result_ready = 1;
2245 }
2246
2247 static void
2248 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *s = 0;
2252
2253   if (mp->local)
2254     {
2255       s = format (s, "%=16d%=16d%=16d\n",
2256                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2257     }
2258   else
2259     {
2260       s = format (s, "%=16U%=16d%=16d\n",
2261                   mp->is_ipv6 ? format_ip6_address :
2262                   format_ip4_address,
2263                   mp->ip_address, mp->priority, mp->weight);
2264     }
2265
2266   fformat (vam->ofp, "%v", s);
2267   vec_free (s);
2268 }
2269
2270 static void
2271 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2272                                             mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t *node = NULL;
2276   struct in6_addr ip6;
2277   struct in_addr ip4;
2278
2279   if (VAT_JSON_ARRAY != vam->json_tree.type)
2280     {
2281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2282       vat_json_init_array (&vam->json_tree);
2283     }
2284   node = vat_json_array_add (&vam->json_tree);
2285   vat_json_init_object (node);
2286
2287   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2288   vat_json_object_add_uint (node, "priority", mp->priority);
2289   vat_json_object_add_uint (node, "weight", mp->weight);
2290
2291   if (mp->local)
2292     vat_json_object_add_uint (node, "sw_if_index",
2293                               clib_net_to_host_u32 (mp->sw_if_index));
2294   else
2295     {
2296       if (mp->is_ipv6)
2297         {
2298           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2299           vat_json_object_add_ip6 (node, "address", ip6);
2300         }
2301       else
2302         {
2303           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2304           vat_json_object_add_ip4 (node, "address", ip4);
2305         }
2306     }
2307 }
2308
2309 static void
2310 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2311                                            mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   u8 *ls_name = 0;
2315
2316   ls_name = format (0, "%s", mp->ls_name);
2317
2318   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2319            ls_name);
2320   vec_free (ls_name);
2321 }
2322
2323 static void
2324   vl_api_lisp_locator_set_details_t_handler_json
2325   (vl_api_lisp_locator_set_details_t * mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t *node = 0;
2329   u8 *ls_name = 0;
2330
2331   ls_name = format (0, "%s", mp->ls_name);
2332   vec_add1 (ls_name, 0);
2333
2334   if (VAT_JSON_ARRAY != vam->json_tree.type)
2335     {
2336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2337       vat_json_init_array (&vam->json_tree);
2338     }
2339   node = vat_json_array_add (&vam->json_tree);
2340
2341   vat_json_init_object (node);
2342   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2343   vat_json_object_add_uint (node, "ls_index",
2344                             clib_net_to_host_u32 (mp->ls_index));
2345   vec_free (ls_name);
2346 }
2347
2348 static u8 *
2349 format_lisp_flat_eid (u8 * s, va_list * args)
2350 {
2351   u32 type = va_arg (*args, u32);
2352   u8 *eid = va_arg (*args, u8 *);
2353   u32 eid_len = va_arg (*args, u32);
2354
2355   switch (type)
2356     {
2357     case 0:
2358       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2359     case 1:
2360       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2361     case 2:
2362       return format (s, "%U", format_ethernet_address, eid);
2363     }
2364   return 0;
2365 }
2366
2367 static u8 *
2368 format_lisp_eid_vat (u8 * s, va_list * args)
2369 {
2370   u32 type = va_arg (*args, u32);
2371   u8 *eid = va_arg (*args, u8 *);
2372   u32 eid_len = va_arg (*args, u32);
2373   u8 *seid = va_arg (*args, u8 *);
2374   u32 seid_len = va_arg (*args, u32);
2375   u32 is_src_dst = va_arg (*args, u32);
2376
2377   if (is_src_dst)
2378     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2379
2380   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2381
2382   return s;
2383 }
2384
2385 static void
2386 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2387 {
2388   vat_main_t *vam = &vat_main;
2389   u8 *s = 0, *eid = 0;
2390
2391   if (~0 == mp->locator_set_index)
2392     s = format (0, "action: %d", mp->action);
2393   else
2394     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2395
2396   eid = format (0, "%U", format_lisp_eid_vat,
2397                 mp->eid_type,
2398                 mp->eid,
2399                 mp->eid_prefix_len,
2400                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2401   vec_add1 (eid, 0);
2402
2403   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2404            clib_net_to_host_u32 (mp->vni),
2405            eid,
2406            mp->is_local ? "local" : "remote",
2407            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2408   vec_free (s);
2409   vec_free (eid);
2410 }
2411
2412 static void
2413 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2414                                               * mp)
2415 {
2416   vat_main_t *vam = &vat_main;
2417   vat_json_node_t *node = 0;
2418   u8 *eid = 0;
2419
2420   if (VAT_JSON_ARRAY != vam->json_tree.type)
2421     {
2422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2423       vat_json_init_array (&vam->json_tree);
2424     }
2425   node = vat_json_array_add (&vam->json_tree);
2426
2427   vat_json_init_object (node);
2428   if (~0 == mp->locator_set_index)
2429     vat_json_object_add_uint (node, "action", mp->action);
2430   else
2431     vat_json_object_add_uint (node, "locator_set_index",
2432                               clib_net_to_host_u32 (mp->locator_set_index));
2433
2434   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2435   eid = format (0, "%U", format_lisp_eid_vat,
2436                 mp->eid_type,
2437                 mp->eid,
2438                 mp->eid_prefix_len,
2439                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2440   vec_add1 (eid, 0);
2441   vat_json_object_add_string_copy (node, "eid", eid);
2442   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2443   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2444   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2445   vec_free (eid);
2446 }
2447
2448 static void
2449   vl_api_lisp_eid_table_map_details_t_handler
2450   (vl_api_lisp_eid_table_map_details_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453
2454   u8 *line = format (0, "%=10d%=10d",
2455                      clib_net_to_host_u32 (mp->vni),
2456                      clib_net_to_host_u32 (mp->dp_table));
2457   fformat (vam->ofp, "%v\n", line);
2458   vec_free (line);
2459 }
2460
2461 static void
2462   vl_api_lisp_eid_table_map_details_t_handler_json
2463   (vl_api_lisp_eid_table_map_details_t * mp)
2464 {
2465   vat_main_t *vam = &vat_main;
2466   vat_json_node_t *node = NULL;
2467
2468   if (VAT_JSON_ARRAY != vam->json_tree.type)
2469     {
2470       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2471       vat_json_init_array (&vam->json_tree);
2472     }
2473   node = vat_json_array_add (&vam->json_tree);
2474   vat_json_init_object (node);
2475   vat_json_object_add_uint (node, "dp_table",
2476                             clib_net_to_host_u32 (mp->dp_table));
2477   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2478 }
2479
2480 static void
2481   vl_api_lisp_eid_table_vni_details_t_handler
2482   (vl_api_lisp_eid_table_vni_details_t * mp)
2483 {
2484   vat_main_t *vam = &vat_main;
2485
2486   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2487   fformat (vam->ofp, "%v\n", line);
2488   vec_free (line);
2489 }
2490
2491 static void
2492   vl_api_lisp_eid_table_vni_details_t_handler_json
2493   (vl_api_lisp_eid_table_vni_details_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   vat_json_node_t *node = NULL;
2497
2498   if (VAT_JSON_ARRAY != vam->json_tree.type)
2499     {
2500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2501       vat_json_init_array (&vam->json_tree);
2502     }
2503   node = vat_json_array_add (&vam->json_tree);
2504   vat_json_init_object (node);
2505   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2506 }
2507
2508 static u8 *
2509 format_decap_next (u8 * s, va_list * args)
2510 {
2511   u32 next_index = va_arg (*args, u32);
2512
2513   switch (next_index)
2514     {
2515     case LISP_GPE_INPUT_NEXT_DROP:
2516       return format (s, "drop");
2517     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2518       return format (s, "ip4");
2519     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2520       return format (s, "ip6");
2521     default:
2522       return format (s, "unknown %d", next_index);
2523     }
2524   return s;
2525 }
2526
2527 static void
2528 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2529                                           mp)
2530 {
2531   vat_main_t *vam = &vat_main;
2532   u8 *iid_str;
2533   u8 *flag_str = NULL;
2534
2535   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2536
2537 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2538   foreach_lisp_gpe_flag_bit;
2539 #undef _
2540
2541   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2542            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2543            mp->tunnels,
2544            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2545            mp->source_ip,
2546            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2547            mp->destination_ip,
2548            ntohl (mp->encap_fib_id),
2549            ntohl (mp->decap_fib_id),
2550            format_decap_next, ntohl (mp->dcap_next),
2551            mp->ver_res >> 6,
2552            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2553
2554   vec_free (iid_str);
2555 }
2556
2557 static void
2558   vl_api_lisp_gpe_tunnel_details_t_handler_json
2559   (vl_api_lisp_gpe_tunnel_details_t * mp)
2560 {
2561   vat_main_t *vam = &vat_main;
2562   vat_json_node_t *node = NULL;
2563   struct in6_addr ip6;
2564   struct in_addr ip4;
2565   u8 *next_decap_str;
2566
2567   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2568
2569   if (VAT_JSON_ARRAY != vam->json_tree.type)
2570     {
2571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2572       vat_json_init_array (&vam->json_tree);
2573     }
2574   node = vat_json_array_add (&vam->json_tree);
2575
2576   vat_json_init_object (node);
2577   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2578   if (mp->is_ipv6)
2579     {
2580       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2581       vat_json_object_add_ip6 (node, "source address", ip6);
2582       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2583       vat_json_object_add_ip6 (node, "destination address", ip6);
2584     }
2585   else
2586     {
2587       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2588       vat_json_object_add_ip4 (node, "source address", ip4);
2589       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2590       vat_json_object_add_ip4 (node, "destination address", ip4);
2591     }
2592   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2593   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2594   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2595   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2596   vat_json_object_add_uint (node, "flags", mp->flags);
2597   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2598   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2599   vat_json_object_add_uint (node, "res", mp->res);
2600   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2601
2602   vec_free (next_decap_str);
2603 }
2604
2605 static void
2606 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2607                                             * mp)
2608 {
2609   vat_main_t *vam = &vat_main;
2610
2611   fformat (vam->ofp, "%=20U\n",
2612            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2613            mp->ip_address);
2614 }
2615
2616 static void
2617   vl_api_lisp_map_resolver_details_t_handler_json
2618   (vl_api_lisp_map_resolver_details_t * mp)
2619 {
2620   vat_main_t *vam = &vat_main;
2621   vat_json_node_t *node = NULL;
2622   struct in6_addr ip6;
2623   struct in_addr ip4;
2624
2625   if (VAT_JSON_ARRAY != vam->json_tree.type)
2626     {
2627       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2628       vat_json_init_array (&vam->json_tree);
2629     }
2630   node = vat_json_array_add (&vam->json_tree);
2631
2632   vat_json_init_object (node);
2633   if (mp->is_ipv6)
2634     {
2635       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2636       vat_json_object_add_ip6 (node, "map resolver", ip6);
2637     }
2638   else
2639     {
2640       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2641       vat_json_object_add_ip4 (node, "map resolver", ip4);
2642     }
2643 }
2644
2645 static void
2646   vl_api_show_lisp_status_reply_t_handler
2647   (vl_api_show_lisp_status_reply_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650   i32 retval = ntohl (mp->retval);
2651
2652   if (0 <= retval)
2653     {
2654       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2655                mp->feature_status ? "enabled" : "disabled",
2656                mp->gpe_status ? "enabled" : "disabled");
2657     }
2658
2659   vam->retval = retval;
2660   vam->result_ready = 1;
2661 }
2662
2663 static void
2664   vl_api_show_lisp_status_reply_t_handler_json
2665   (vl_api_show_lisp_status_reply_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   vat_json_node_t node;
2669   u8 *gpe_status = NULL;
2670   u8 *feature_status = NULL;
2671
2672   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2673   feature_status = format (0, "%s",
2674                            mp->feature_status ? "enabled" : "disabled");
2675   vec_add1 (gpe_status, 0);
2676   vec_add1 (feature_status, 0);
2677
2678   vat_json_init_object (&node);
2679   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2680   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2681
2682   vec_free (gpe_status);
2683   vec_free (feature_status);
2684
2685   vat_json_print (vam->ofp, &node);
2686   vat_json_free (&node);
2687
2688   vam->retval = ntohl (mp->retval);
2689   vam->result_ready = 1;
2690 }
2691
2692 static void
2693   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2694   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2695 {
2696   vat_main_t *vam = &vat_main;
2697   i32 retval = ntohl (mp->retval);
2698
2699   if (retval >= 0)
2700     {
2701       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2702     }
2703
2704   vam->retval = retval;
2705   vam->result_ready = 1;
2706 }
2707
2708 static void
2709   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2710   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713   vat_json_node_t *node = NULL;
2714
2715   if (VAT_JSON_ARRAY != vam->json_tree.type)
2716     {
2717       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2718       vat_json_init_array (&vam->json_tree);
2719     }
2720   node = vat_json_array_add (&vam->json_tree);
2721
2722   vat_json_init_object (node);
2723   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2724
2725   vat_json_print (vam->ofp, node);
2726   vat_json_free (node);
2727
2728   vam->retval = ntohl (mp->retval);
2729   vam->result_ready = 1;
2730 }
2731
2732 static u8 *
2733 format_lisp_map_request_mode (u8 * s, va_list * args)
2734 {
2735   u32 mode = va_arg (*args, u32);
2736
2737   switch (mode)
2738     {
2739     case 0:
2740       return format (0, "dst-only");
2741     case 1:
2742       return format (0, "src-dst");
2743     }
2744   return 0;
2745 }
2746
2747 static void
2748   vl_api_show_lisp_map_request_mode_reply_t_handler
2749   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752   i32 retval = ntohl (mp->retval);
2753
2754   if (0 <= retval)
2755     {
2756       u32 mode = mp->mode;
2757       fformat (vam->ofp, "map_request_mode: %U\n",
2758                format_lisp_map_request_mode, mode);
2759     }
2760
2761   vam->retval = retval;
2762   vam->result_ready = 1;
2763 }
2764
2765 static void
2766   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2767   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2768 {
2769   vat_main_t *vam = &vat_main;
2770   vat_json_node_t node;
2771   u8 *s = 0;
2772   u32 mode;
2773
2774   mode = mp->mode;
2775   s = format (0, "%U", format_lisp_map_request_mode, mode);
2776   vec_add1 (s, 0);
2777
2778   vat_json_init_object (&node);
2779   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2780   vat_json_print (vam->ofp, &node);
2781   vat_json_free (&node);
2782
2783   vec_free (s);
2784   vam->retval = ntohl (mp->retval);
2785   vam->result_ready = 1;
2786 }
2787
2788 static void
2789 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   i32 retval = ntohl (mp->retval);
2793
2794   if (0 <= retval)
2795     {
2796       fformat (vam->ofp, "%-20s%-16s\n",
2797                mp->status ? "enabled" : "disabled",
2798                mp->status ? (char *) mp->locator_set_name : "");
2799     }
2800
2801   vam->retval = retval;
2802   vam->result_ready = 1;
2803 }
2804
2805 static void
2806 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2807                                             mp)
2808 {
2809   vat_main_t *vam = &vat_main;
2810   vat_json_node_t node;
2811   u8 *status = 0;
2812
2813   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2814   vec_add1 (status, 0);
2815
2816   vat_json_init_object (&node);
2817   vat_json_object_add_string_copy (&node, "status", status);
2818   if (mp->status)
2819     {
2820       vat_json_object_add_string_copy (&node, "locator_set",
2821                                        mp->locator_set_name);
2822     }
2823
2824   vec_free (status);
2825
2826   vat_json_print (vam->ofp, &node);
2827   vat_json_free (&node);
2828
2829   vam->retval = ntohl (mp->retval);
2830   vam->result_ready = 1;
2831 }
2832
2833 static u8 *
2834 format_policer_type (u8 * s, va_list * va)
2835 {
2836   u32 i = va_arg (*va, u32);
2837
2838   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2839     s = format (s, "1r2c");
2840   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2841     s = format (s, "1r3c");
2842   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2843     s = format (s, "2r3c-2698");
2844   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2845     s = format (s, "2r3c-4115");
2846   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2847     s = format (s, "2r3c-mef5cf1");
2848   else
2849     s = format (s, "ILLEGAL");
2850   return s;
2851 }
2852
2853 static u8 *
2854 format_policer_rate_type (u8 * s, va_list * va)
2855 {
2856   u32 i = va_arg (*va, u32);
2857
2858   if (i == SSE2_QOS_RATE_KBPS)
2859     s = format (s, "kbps");
2860   else if (i == SSE2_QOS_RATE_PPS)
2861     s = format (s, "pps");
2862   else
2863     s = format (s, "ILLEGAL");
2864   return s;
2865 }
2866
2867 static u8 *
2868 format_policer_round_type (u8 * s, va_list * va)
2869 {
2870   u32 i = va_arg (*va, u32);
2871
2872   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2873     s = format (s, "closest");
2874   else if (i == SSE2_QOS_ROUND_TO_UP)
2875     s = format (s, "up");
2876   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2877     s = format (s, "down");
2878   else
2879     s = format (s, "ILLEGAL");
2880   return s;
2881 }
2882
2883 static u8 *
2884 format_policer_action_type (u8 * s, va_list * va)
2885 {
2886   u32 i = va_arg (*va, u32);
2887
2888   if (i == SSE2_QOS_ACTION_DROP)
2889     s = format (s, "drop");
2890   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2891     s = format (s, "transmit");
2892   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2893     s = format (s, "mark-and-transmit");
2894   else
2895     s = format (s, "ILLEGAL");
2896   return s;
2897 }
2898
2899 static u8 *
2900 format_dscp (u8 * s, va_list * va)
2901 {
2902   u32 i = va_arg (*va, u32);
2903   char *t = 0;
2904
2905   switch (i)
2906     {
2907 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2908       foreach_vnet_dscp
2909 #undef _
2910     default:
2911       return format (s, "ILLEGAL");
2912     }
2913   s = format (s, "%s", t);
2914   return s;
2915 }
2916
2917 static void
2918 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2922
2923   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2924     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2925   else
2926     conform_dscp_str = format (0, "");
2927
2928   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2929     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2930   else
2931     exceed_dscp_str = format (0, "");
2932
2933   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2934     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2935   else
2936     violate_dscp_str = format (0, "");
2937
2938   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2939            "rate type %U, round type %U, %s rate, %s color-aware, "
2940            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2941            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2942            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2943            mp->name,
2944            format_policer_type, mp->type,
2945            ntohl (mp->cir),
2946            ntohl (mp->eir),
2947            clib_net_to_host_u64 (mp->cb),
2948            clib_net_to_host_u64 (mp->eb),
2949            format_policer_rate_type, mp->rate_type,
2950            format_policer_round_type, mp->round_type,
2951            mp->single_rate ? "single" : "dual",
2952            mp->color_aware ? "is" : "not",
2953            ntohl (mp->cir_tokens_per_period),
2954            ntohl (mp->pir_tokens_per_period),
2955            ntohl (mp->scale),
2956            ntohl (mp->current_limit),
2957            ntohl (mp->current_bucket),
2958            ntohl (mp->extended_limit),
2959            ntohl (mp->extended_bucket),
2960            clib_net_to_host_u64 (mp->last_update_time),
2961            format_policer_action_type, mp->conform_action_type,
2962            conform_dscp_str,
2963            format_policer_action_type, mp->exceed_action_type,
2964            exceed_dscp_str,
2965            format_policer_action_type, mp->violate_action_type,
2966            violate_dscp_str);
2967
2968   vec_free (conform_dscp_str);
2969   vec_free (exceed_dscp_str);
2970   vec_free (violate_dscp_str);
2971 }
2972
2973 static void vl_api_policer_details_t_handler_json
2974   (vl_api_policer_details_t * mp)
2975 {
2976   vat_main_t *vam = &vat_main;
2977   vat_json_node_t *node;
2978   u8 *rate_type_str, *round_type_str, *type_str;
2979   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2980
2981   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2982   round_type_str =
2983     format (0, "%U", format_policer_round_type, mp->round_type);
2984   type_str = format (0, "%U", format_policer_type, mp->type);
2985   conform_action_str = format (0, "%U", format_policer_action_type,
2986                                mp->conform_action_type);
2987   exceed_action_str = format (0, "%U", format_policer_action_type,
2988                               mp->exceed_action_type);
2989   violate_action_str = format (0, "%U", format_policer_action_type,
2990                                mp->violate_action_type);
2991
2992   if (VAT_JSON_ARRAY != vam->json_tree.type)
2993     {
2994       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2995       vat_json_init_array (&vam->json_tree);
2996     }
2997   node = vat_json_array_add (&vam->json_tree);
2998
2999   vat_json_init_object (node);
3000   vat_json_object_add_string_copy (node, "name", mp->name);
3001   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3002   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3003   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3004   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3005   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3006   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3007   vat_json_object_add_string_copy (node, "type", type_str);
3008   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3009   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3010   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3011   vat_json_object_add_uint (node, "cir_tokens_per_period",
3012                             ntohl (mp->cir_tokens_per_period));
3013   vat_json_object_add_uint (node, "eir_tokens_per_period",
3014                             ntohl (mp->pir_tokens_per_period));
3015   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3016   vat_json_object_add_uint (node, "current_bucket",
3017                             ntohl (mp->current_bucket));
3018   vat_json_object_add_uint (node, "extended_limit",
3019                             ntohl (mp->extended_limit));
3020   vat_json_object_add_uint (node, "extended_bucket",
3021                             ntohl (mp->extended_bucket));
3022   vat_json_object_add_uint (node, "last_update_time",
3023                             ntohl (mp->last_update_time));
3024   vat_json_object_add_string_copy (node, "conform_action",
3025                                    conform_action_str);
3026   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3027     {
3028       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3029       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3030       vec_free (dscp_str);
3031     }
3032   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3033   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3034     {
3035       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3036       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3037       vec_free (dscp_str);
3038     }
3039   vat_json_object_add_string_copy (node, "violate_action",
3040                                    violate_action_str);
3041   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3042     {
3043       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3044       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3045       vec_free (dscp_str);
3046     }
3047
3048   vec_free (rate_type_str);
3049   vec_free (round_type_str);
3050   vec_free (type_str);
3051   vec_free (conform_action_str);
3052   vec_free (exceed_action_str);
3053   vec_free (violate_action_str);
3054 }
3055
3056 static void
3057 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3058                                            mp)
3059 {
3060   vat_main_t *vam = &vat_main;
3061   int i, count = ntohl (mp->count);
3062
3063   if (count > 0)
3064     fformat (vam->ofp, "classify table ids (%d) : ", count);
3065   for (i = 0; i < count; i++)
3066     {
3067       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3068       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3069     }
3070   vam->retval = ntohl (mp->retval);
3071   vam->result_ready = 1;
3072 }
3073
3074 static void
3075   vl_api_classify_table_ids_reply_t_handler_json
3076   (vl_api_classify_table_ids_reply_t * mp)
3077 {
3078   vat_main_t *vam = &vat_main;
3079   int i, count = ntohl (mp->count);
3080
3081   if (count > 0)
3082     {
3083       vat_json_node_t node;
3084
3085       vat_json_init_object (&node);
3086       for (i = 0; i < count; i++)
3087         {
3088           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3089         }
3090       vat_json_print (vam->ofp, &node);
3091       vat_json_free (&node);
3092     }
3093   vam->retval = ntohl (mp->retval);
3094   vam->result_ready = 1;
3095 }
3096
3097 static void
3098   vl_api_classify_table_by_interface_reply_t_handler
3099   (vl_api_classify_table_by_interface_reply_t * mp)
3100 {
3101   vat_main_t *vam = &vat_main;
3102   u32 table_id;
3103
3104   table_id = ntohl (mp->l2_table_id);
3105   if (table_id != ~0)
3106     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3107   else
3108     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3109   table_id = ntohl (mp->ip4_table_id);
3110   if (table_id != ~0)
3111     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3112   else
3113     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3114   table_id = ntohl (mp->ip6_table_id);
3115   if (table_id != ~0)
3116     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3117   else
3118     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3119   vam->retval = ntohl (mp->retval);
3120   vam->result_ready = 1;
3121 }
3122
3123 static void
3124   vl_api_classify_table_by_interface_reply_t_handler_json
3125   (vl_api_classify_table_by_interface_reply_t * mp)
3126 {
3127   vat_main_t *vam = &vat_main;
3128   vat_json_node_t node;
3129
3130   vat_json_init_object (&node);
3131
3132   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3133   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3134   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3135
3136   vat_json_print (vam->ofp, &node);
3137   vat_json_free (&node);
3138
3139   vam->retval = ntohl (mp->retval);
3140   vam->result_ready = 1;
3141 }
3142
3143 static void vl_api_policer_add_del_reply_t_handler
3144   (vl_api_policer_add_del_reply_t * mp)
3145 {
3146   vat_main_t *vam = &vat_main;
3147   i32 retval = ntohl (mp->retval);
3148   if (vam->async_mode)
3149     {
3150       vam->async_errors += (retval < 0);
3151     }
3152   else
3153     {
3154       vam->retval = retval;
3155       vam->result_ready = 1;
3156       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3157         /*
3158          * Note: this is just barely thread-safe, depends on
3159          * the main thread spinning waiting for an answer...
3160          */
3161         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3162     }
3163 }
3164
3165 static void vl_api_policer_add_del_reply_t_handler_json
3166   (vl_api_policer_add_del_reply_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169   vat_json_node_t node;
3170
3171   vat_json_init_object (&node);
3172   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3173   vat_json_object_add_uint (&node, "policer_index",
3174                             ntohl (mp->policer_index));
3175
3176   vat_json_print (vam->ofp, &node);
3177   vat_json_free (&node);
3178
3179   vam->retval = ntohl (mp->retval);
3180   vam->result_ready = 1;
3181 }
3182
3183 /* Format hex dump. */
3184 u8 *
3185 format_hex_bytes (u8 * s, va_list * va)
3186 {
3187   u8 *bytes = va_arg (*va, u8 *);
3188   int n_bytes = va_arg (*va, int);
3189   uword i;
3190
3191   /* Print short or long form depending on byte count. */
3192   uword short_form = n_bytes <= 32;
3193   uword indent = format_get_indent (s);
3194
3195   if (n_bytes == 0)
3196     return s;
3197
3198   for (i = 0; i < n_bytes; i++)
3199     {
3200       if (!short_form && (i % 32) == 0)
3201         s = format (s, "%08x: ", i);
3202       s = format (s, "%02x", bytes[i]);
3203       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3204         s = format (s, "\n%U", format_white_space, indent);
3205     }
3206
3207   return s;
3208 }
3209
3210 static void
3211 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3212                                             * mp)
3213 {
3214   vat_main_t *vam = &vat_main;
3215   i32 retval = ntohl (mp->retval);
3216   if (retval == 0)
3217     {
3218       fformat (vam->ofp, "classify table info :\n");
3219       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3220                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3221                ntohl (mp->miss_next_index));
3222       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3223                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3224                ntohl (mp->match_n_vectors));
3225       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3226                ntohl (mp->mask_length));
3227     }
3228   vam->retval = retval;
3229   vam->result_ready = 1;
3230 }
3231
3232 static void
3233   vl_api_classify_table_info_reply_t_handler_json
3234   (vl_api_classify_table_info_reply_t * mp)
3235 {
3236   vat_main_t *vam = &vat_main;
3237   vat_json_node_t node;
3238
3239   i32 retval = ntohl (mp->retval);
3240   if (retval == 0)
3241     {
3242       vat_json_init_object (&node);
3243
3244       vat_json_object_add_int (&node, "sessions",
3245                                ntohl (mp->active_sessions));
3246       vat_json_object_add_int (&node, "nexttbl",
3247                                ntohl (mp->next_table_index));
3248       vat_json_object_add_int (&node, "nextnode",
3249                                ntohl (mp->miss_next_index));
3250       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3251       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3252       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3253       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3254                       ntohl (mp->mask_length), 0);
3255       vat_json_object_add_string_copy (&node, "mask", s);
3256
3257       vat_json_print (vam->ofp, &node);
3258       vat_json_free (&node);
3259     }
3260   vam->retval = ntohl (mp->retval);
3261   vam->result_ready = 1;
3262 }
3263
3264 static void
3265 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3266                                            mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269
3270   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3271            ntohl (mp->hit_next_index), ntohl (mp->advance),
3272            ntohl (mp->opaque_index));
3273   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3274            ntohl (mp->match_length));
3275 }
3276
3277 static void
3278   vl_api_classify_session_details_t_handler_json
3279   (vl_api_classify_session_details_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   vat_json_node_t *node = NULL;
3283
3284   if (VAT_JSON_ARRAY != vam->json_tree.type)
3285     {
3286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3287       vat_json_init_array (&vam->json_tree);
3288     }
3289   node = vat_json_array_add (&vam->json_tree);
3290
3291   vat_json_init_object (node);
3292   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3293   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3294   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3295   u8 *s =
3296     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3297             0);
3298   vat_json_object_add_string_copy (node, "match", s);
3299 }
3300
3301 static void vl_api_pg_create_interface_reply_t_handler
3302   (vl_api_pg_create_interface_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305
3306   vam->retval = ntohl (mp->retval);
3307   vam->result_ready = 1;
3308 }
3309
3310 static void vl_api_pg_create_interface_reply_t_handler_json
3311   (vl_api_pg_create_interface_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314   vat_json_node_t node;
3315
3316   i32 retval = ntohl (mp->retval);
3317   if (retval == 0)
3318     {
3319       vat_json_init_object (&node);
3320
3321       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3322
3323       vat_json_print (vam->ofp, &node);
3324       vat_json_free (&node);
3325     }
3326   vam->retval = ntohl (mp->retval);
3327   vam->result_ready = 1;
3328 }
3329
3330 static void vl_api_policer_classify_details_t_handler
3331   (vl_api_policer_classify_details_t * mp)
3332 {
3333   vat_main_t *vam = &vat_main;
3334
3335   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3336            ntohl (mp->table_index));
3337 }
3338
3339 static void vl_api_policer_classify_details_t_handler_json
3340   (vl_api_policer_classify_details_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t *node;
3344
3345   if (VAT_JSON_ARRAY != vam->json_tree.type)
3346     {
3347       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3348       vat_json_init_array (&vam->json_tree);
3349     }
3350   node = vat_json_array_add (&vam->json_tree);
3351
3352   vat_json_init_object (node);
3353   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3354   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3355 }
3356
3357 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3358   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   i32 retval = ntohl (mp->retval);
3362   if (vam->async_mode)
3363     {
3364       vam->async_errors += (retval < 0);
3365     }
3366   else
3367     {
3368       vam->retval = retval;
3369       vam->sw_if_index = ntohl (mp->sw_if_index);
3370       vam->result_ready = 1;
3371     }
3372 }
3373
3374 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3375   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3376 {
3377   vat_main_t *vam = &vat_main;
3378   vat_json_node_t node;
3379
3380   vat_json_init_object (&node);
3381   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3382   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3383
3384   vat_json_print (vam->ofp, &node);
3385   vat_json_free (&node);
3386
3387   vam->retval = ntohl (mp->retval);
3388   vam->result_ready = 1;
3389 }
3390
3391 static void vl_api_flow_classify_details_t_handler
3392   (vl_api_flow_classify_details_t * mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395
3396   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3397            ntohl (mp->table_index));
3398 }
3399
3400 static void vl_api_flow_classify_details_t_handler_json
3401   (vl_api_flow_classify_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404   vat_json_node_t *node;
3405
3406   if (VAT_JSON_ARRAY != vam->json_tree.type)
3407     {
3408       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3409       vat_json_init_array (&vam->json_tree);
3410     }
3411   node = vat_json_array_add (&vam->json_tree);
3412
3413   vat_json_init_object (node);
3414   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3415   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3416 }
3417
3418
3419
3420 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3421 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3422 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3423 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3424
3425 /*
3426  * Generate boilerplate reply handlers, which
3427  * dig the return value out of the xxx_reply_t API message,
3428  * stick it into vam->retval, and set vam->result_ready
3429  *
3430  * Could also do this by pointing N message decode slots at
3431  * a single function, but that could break in subtle ways.
3432  */
3433
3434 #define foreach_standard_reply_retval_handler           \
3435 _(sw_interface_set_flags_reply)                         \
3436 _(sw_interface_add_del_address_reply)                   \
3437 _(sw_interface_set_table_reply)                         \
3438 _(sw_interface_set_vpath_reply)                         \
3439 _(sw_interface_set_l2_bridge_reply)                     \
3440 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3441 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3442 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3443 _(bridge_domain_add_del_reply)                          \
3444 _(sw_interface_set_l2_xconnect_reply)                   \
3445 _(l2fib_add_del_reply)                                  \
3446 _(ip_add_del_route_reply)                               \
3447 _(proxy_arp_add_del_reply)                              \
3448 _(proxy_arp_intfc_enable_disable_reply)                 \
3449 _(mpls_add_del_encap_reply)                             \
3450 _(mpls_add_del_decap_reply)                             \
3451 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3452 _(sw_interface_set_unnumbered_reply)                    \
3453 _(ip_neighbor_add_del_reply)                            \
3454 _(reset_vrf_reply)                                      \
3455 _(oam_add_del_reply)                                    \
3456 _(reset_fib_reply)                                      \
3457 _(dhcp_proxy_config_reply)                              \
3458 _(dhcp_proxy_config_2_reply)                            \
3459 _(dhcp_proxy_set_vss_reply)                             \
3460 _(dhcp_client_config_reply)                             \
3461 _(set_ip_flow_hash_reply)                               \
3462 _(sw_interface_ip6_enable_disable_reply)                \
3463 _(sw_interface_ip6_set_link_local_address_reply)        \
3464 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3465 _(sw_interface_ip6nd_ra_config_reply)                   \
3466 _(set_arp_neighbor_limit_reply)                         \
3467 _(l2_patch_add_del_reply)                               \
3468 _(sr_tunnel_add_del_reply)                              \
3469 _(sr_policy_add_del_reply)                              \
3470 _(sr_multicast_map_add_del_reply)                       \
3471 _(classify_add_del_session_reply)                       \
3472 _(classify_set_interface_ip_table_reply)                \
3473 _(classify_set_interface_l2_tables_reply)               \
3474 _(l2tpv3_set_tunnel_cookies_reply)                      \
3475 _(l2tpv3_interface_enable_disable_reply)                \
3476 _(l2tpv3_set_lookup_key_reply)                          \
3477 _(l2_fib_clear_table_reply)                             \
3478 _(l2_interface_efp_filter_reply)                        \
3479 _(l2_interface_vlan_tag_rewrite_reply)                  \
3480 _(modify_vhost_user_if_reply)                           \
3481 _(delete_vhost_user_if_reply)                           \
3482 _(want_ip4_arp_events_reply)                            \
3483 _(want_ip6_nd_events_reply)                             \
3484 _(input_acl_set_interface_reply)                        \
3485 _(ipsec_spd_add_del_reply)                              \
3486 _(ipsec_interface_add_del_spd_reply)                    \
3487 _(ipsec_spd_add_del_entry_reply)                        \
3488 _(ipsec_sad_add_del_entry_reply)                        \
3489 _(ipsec_sa_set_key_reply)                               \
3490 _(ikev2_profile_add_del_reply)                          \
3491 _(ikev2_profile_set_auth_reply)                         \
3492 _(ikev2_profile_set_id_reply)                           \
3493 _(ikev2_profile_set_ts_reply)                           \
3494 _(ikev2_set_local_key_reply)                            \
3495 _(delete_loopback_reply)                                \
3496 _(bd_ip_mac_add_del_reply)                              \
3497 _(map_del_domain_reply)                                 \
3498 _(map_add_del_rule_reply)                               \
3499 _(want_interface_events_reply)                          \
3500 _(want_stats_reply)                                     \
3501 _(cop_interface_enable_disable_reply)                   \
3502 _(cop_whitelist_enable_disable_reply)                   \
3503 _(sw_interface_clear_stats_reply)                       \
3504 _(ioam_enable_reply)                              \
3505 _(ioam_disable_reply)                              \
3506 _(lisp_add_del_locator_reply)                           \
3507 _(lisp_add_del_local_eid_reply)                         \
3508 _(lisp_add_del_remote_mapping_reply)                    \
3509 _(lisp_add_del_adjacency_reply)                         \
3510 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3511 _(lisp_add_del_map_resolver_reply)                      \
3512 _(lisp_gpe_enable_disable_reply)                        \
3513 _(lisp_gpe_add_del_iface_reply)                         \
3514 _(lisp_enable_disable_reply)                            \
3515 _(lisp_pitr_set_locator_set_reply)                      \
3516 _(lisp_map_request_mode_reply)                          \
3517 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3518 _(lisp_eid_table_add_del_map_reply)                     \
3519 _(vxlan_gpe_add_del_tunnel_reply)                       \
3520 _(af_packet_delete_reply)                               \
3521 _(policer_classify_set_interface_reply)                 \
3522 _(netmap_create_reply)                                  \
3523 _(netmap_delete_reply)                                  \
3524 _(set_ipfix_exporter_reply)                             \
3525 _(set_ipfix_classify_stream_reply)                      \
3526 _(ipfix_classify_table_add_del_reply)                   \
3527 _(flow_classify_set_interface_reply)                    \
3528 _(pg_capture_reply)                                     \
3529 _(pg_enable_disable_reply)                              \
3530 _(ip_source_and_port_range_check_add_del_reply)         \
3531 _(ip_source_and_port_range_check_interface_add_del_reply)\
3532 _(delete_subif_reply)                                   \
3533 _(l2_interface_pbb_tag_rewrite_reply)                   \
3534 _(punt_reply)
3535
3536 #define _(n)                                    \
3537     static void vl_api_##n##_t_handler          \
3538     (vl_api_##n##_t * mp)                       \
3539     {                                           \
3540         vat_main_t * vam = &vat_main;           \
3541         i32 retval = ntohl(mp->retval);         \
3542         if (vam->async_mode) {                  \
3543             vam->async_errors += (retval < 0);  \
3544         } else {                                \
3545             vam->retval = retval;               \
3546             vam->result_ready = 1;              \
3547         }                                       \
3548     }
3549 foreach_standard_reply_retval_handler;
3550 #undef _
3551
3552 #define _(n)                                    \
3553     static void vl_api_##n##_t_handler_json     \
3554     (vl_api_##n##_t * mp)                       \
3555     {                                           \
3556         vat_main_t * vam = &vat_main;           \
3557         vat_json_node_t node;                   \
3558         vat_json_init_object(&node);            \
3559         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3560         vat_json_print(vam->ofp, &node);        \
3561         vam->retval = ntohl(mp->retval);        \
3562         vam->result_ready = 1;                  \
3563     }
3564 foreach_standard_reply_retval_handler;
3565 #undef _
3566
3567 /*
3568  * Table of message reply handlers, must include boilerplate handlers
3569  * we just generated
3570  */
3571
3572 #define foreach_vpe_api_reply_msg                                       \
3573 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3574 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3575 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3576 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3577 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3578 _(CLI_REPLY, cli_reply)                                                 \
3579 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3580 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3581   sw_interface_add_del_address_reply)                                   \
3582 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3583 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3584 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3585   sw_interface_set_l2_xconnect_reply)                                   \
3586 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3587   sw_interface_set_l2_bridge_reply)                                     \
3588 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3589   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3590 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3591   sw_interface_set_dpdk_hqos_subport_reply)                             \
3592 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3593   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3594 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3595 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3596 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3597 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3598 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3599 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3600 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3601 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3602 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3603 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3604 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3605 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3606 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3607   proxy_arp_intfc_enable_disable_reply)                                 \
3608 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3609 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3610 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3611 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3612   mpls_ethernet_add_del_tunnel_reply)                                   \
3613 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3614   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3615 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3616   sw_interface_set_unnumbered_reply)                                    \
3617 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3618 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3619 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3620 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3621 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3622 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3623 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3624 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3625 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3626 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3627 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3628 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3629   sw_interface_ip6_enable_disable_reply)                                \
3630 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3631   sw_interface_ip6_set_link_local_address_reply)                        \
3632 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3633   sw_interface_ip6nd_ra_prefix_reply)                                   \
3634 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3635   sw_interface_ip6nd_ra_config_reply)                                   \
3636 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3637 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3638 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3639 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3640 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3641 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3642 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3643 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3644 classify_set_interface_ip_table_reply)                                  \
3645 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3646   classify_set_interface_l2_tables_reply)                               \
3647 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3648 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3649 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3650 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3651 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3652   l2tpv3_interface_enable_disable_reply)                                \
3653 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3654 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3655 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3656 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3657 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3658 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3659 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3660 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3661 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3662 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3663 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3664 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3665 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3666 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3667 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3668 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3669 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3670 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3671 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3672 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3673 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3674 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3675 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3676 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3677 _(IP_DETAILS, ip_details)                                               \
3678 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3679 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3680 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3681 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3682 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3683 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3684 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3685 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3686 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3687 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3688 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3689 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3690 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3691 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3692 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3693 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3694 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3695 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3696 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3697 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3698 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3699 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3700 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3701 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3702 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3703 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3704 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3705 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3706 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3707 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3708 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3709 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3710 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3711 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3712 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3713 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3714 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3715 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3716 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3717 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3718 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3719 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3720 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3721 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3722 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3723 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3724 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3725 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3726 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3727 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3728 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3729 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3730   lisp_add_del_map_request_itr_rlocs_reply)                             \
3731 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3732   lisp_get_map_request_itr_rlocs_reply)                                 \
3733 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3734 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3735 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3736 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3737 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3738 _(POLICER_DETAILS, policer_details)                                     \
3739 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3740 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3741 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3742 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3743 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3744 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3745 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3746 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3747 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3748 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3749 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3750 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3751 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3752 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3753 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3754 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3755 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3756 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3757 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3758 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3759 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3760 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3761 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3762 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3763 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3764  ip_source_and_port_range_check_add_del_reply)                          \
3765 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3766  ip_source_and_port_range_check_interface_add_del_reply)                \
3767 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3768 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3769 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3770 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3771 _(PUNT_REPLY, punt_reply)
3772
3773 /* M: construct, but don't yet send a message */
3774
3775 #define M(T,t)                                  \
3776 do {                                            \
3777     vam->result_ready = 0;                      \
3778     mp = vl_msg_api_alloc(sizeof(*mp));         \
3779     memset (mp, 0, sizeof (*mp));               \
3780     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3781     mp->client_index = vam->my_client_index;    \
3782 } while(0);
3783
3784 #define M2(T,t,n)                               \
3785 do {                                            \
3786     vam->result_ready = 0;                      \
3787     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3788     memset (mp, 0, sizeof (*mp));               \
3789     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3790     mp->client_index = vam->my_client_index;    \
3791 } while(0);
3792
3793
3794 /* S: send a message */
3795 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3796
3797 /* W: wait for results, with timeout */
3798 #define W                                       \
3799 do {                                            \
3800     timeout = vat_time_now (vam) + 1.0;         \
3801                                                 \
3802     while (vat_time_now (vam) < timeout) {      \
3803         if (vam->result_ready == 1) {           \
3804             return (vam->retval);               \
3805         }                                       \
3806     }                                           \
3807     return -99;                                 \
3808 } while(0);
3809
3810 /* W2: wait for results, with timeout */
3811 #define W2(body)                                \
3812 do {                                            \
3813     timeout = vat_time_now (vam) + 1.0;         \
3814                                                 \
3815     while (vat_time_now (vam) < timeout) {      \
3816         if (vam->result_ready == 1) {           \
3817           (body);                               \
3818           return (vam->retval);                 \
3819         }                                       \
3820     }                                           \
3821     return -99;                                 \
3822 } while(0);
3823
3824 typedef struct
3825 {
3826   u8 *name;
3827   u32 value;
3828 } name_sort_t;
3829
3830
3831 #define STR_VTR_OP_CASE(op)     \
3832     case L2_VTR_ ## op:         \
3833         return "" # op;
3834
3835 static const char *
3836 str_vtr_op (u32 vtr_op)
3837 {
3838   switch (vtr_op)
3839     {
3840       STR_VTR_OP_CASE (DISABLED);
3841       STR_VTR_OP_CASE (PUSH_1);
3842       STR_VTR_OP_CASE (PUSH_2);
3843       STR_VTR_OP_CASE (POP_1);
3844       STR_VTR_OP_CASE (POP_2);
3845       STR_VTR_OP_CASE (TRANSLATE_1_1);
3846       STR_VTR_OP_CASE (TRANSLATE_1_2);
3847       STR_VTR_OP_CASE (TRANSLATE_2_1);
3848       STR_VTR_OP_CASE (TRANSLATE_2_2);
3849     }
3850
3851   return "UNKNOWN";
3852 }
3853
3854 static int
3855 dump_sub_interface_table (vat_main_t * vam)
3856 {
3857   const sw_interface_subif_t *sub = NULL;
3858
3859   if (vam->json_output)
3860     {
3861       clib_warning
3862         ("JSON output supported only for VPE API calls and dump_stats_table");
3863       return -99;
3864     }
3865
3866   fformat (vam->ofp,
3867            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3868            "Interface", "sw_if_index",
3869            "sub id", "dot1ad", "tags", "outer id",
3870            "inner id", "exact", "default", "outer any", "inner any");
3871
3872   vec_foreach (sub, vam->sw_if_subif_table)
3873   {
3874     fformat (vam->ofp,
3875              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3876              sub->interface_name,
3877              sub->sw_if_index,
3878              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3879              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3880              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3881              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3882     if (sub->vtr_op != L2_VTR_DISABLED)
3883       {
3884         fformat (vam->ofp,
3885                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3886                  "tag1: %d tag2: %d ]\n",
3887                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3888                  sub->vtr_tag1, sub->vtr_tag2);
3889       }
3890   }
3891
3892   return 0;
3893 }
3894
3895 static int
3896 name_sort_cmp (void *a1, void *a2)
3897 {
3898   name_sort_t *n1 = a1;
3899   name_sort_t *n2 = a2;
3900
3901   return strcmp ((char *) n1->name, (char *) n2->name);
3902 }
3903
3904 static int
3905 dump_interface_table (vat_main_t * vam)
3906 {
3907   hash_pair_t *p;
3908   name_sort_t *nses = 0, *ns;
3909
3910   if (vam->json_output)
3911     {
3912       clib_warning
3913         ("JSON output supported only for VPE API calls and dump_stats_table");
3914       return -99;
3915     }
3916
3917   /* *INDENT-OFF* */
3918   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3919   ({
3920     vec_add2 (nses, ns, 1);
3921     ns->name = (u8 *)(p->key);
3922     ns->value = (u32) p->value[0];
3923   }));
3924   /* *INDENT-ON* */
3925
3926   vec_sort_with_function (nses, name_sort_cmp);
3927
3928   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3929   vec_foreach (ns, nses)
3930   {
3931     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3932   }
3933   vec_free (nses);
3934   return 0;
3935 }
3936
3937 static int
3938 dump_ip_table (vat_main_t * vam, int is_ipv6)
3939 {
3940   const ip_details_t *det = NULL;
3941   const ip_address_details_t *address = NULL;
3942   u32 i = ~0;
3943
3944   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3945
3946   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3947   {
3948     i++;
3949     if (!det->present)
3950       {
3951         continue;
3952       }
3953     fformat (vam->ofp, "%-12d\n", i);
3954     fformat (vam->ofp,
3955              "            %-30s%-13s\n", "Address", "Prefix length");
3956     if (!det->addr)
3957       {
3958         continue;
3959       }
3960     vec_foreach (address, det->addr)
3961     {
3962       fformat (vam->ofp,
3963                "            %-30U%-13d\n",
3964                is_ipv6 ? format_ip6_address : format_ip4_address,
3965                address->ip, address->prefix_length);
3966     }
3967   }
3968
3969   return 0;
3970 }
3971
3972 static int
3973 dump_ipv4_table (vat_main_t * vam)
3974 {
3975   if (vam->json_output)
3976     {
3977       clib_warning
3978         ("JSON output supported only for VPE API calls and dump_stats_table");
3979       return -99;
3980     }
3981
3982   return dump_ip_table (vam, 0);
3983 }
3984
3985 static int
3986 dump_ipv6_table (vat_main_t * vam)
3987 {
3988   if (vam->json_output)
3989     {
3990       clib_warning
3991         ("JSON output supported only for VPE API calls and dump_stats_table");
3992       return -99;
3993     }
3994
3995   return dump_ip_table (vam, 1);
3996 }
3997
3998 static char *
3999 counter_type_to_str (u8 counter_type, u8 is_combined)
4000 {
4001   if (!is_combined)
4002     {
4003       switch (counter_type)
4004         {
4005         case VNET_INTERFACE_COUNTER_DROP:
4006           return "drop";
4007         case VNET_INTERFACE_COUNTER_PUNT:
4008           return "punt";
4009         case VNET_INTERFACE_COUNTER_IP4:
4010           return "ip4";
4011         case VNET_INTERFACE_COUNTER_IP6:
4012           return "ip6";
4013         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4014           return "rx-no-buf";
4015         case VNET_INTERFACE_COUNTER_RX_MISS:
4016           return "rx-miss";
4017         case VNET_INTERFACE_COUNTER_RX_ERROR:
4018           return "rx-error";
4019         case VNET_INTERFACE_COUNTER_TX_ERROR:
4020           return "tx-error";
4021         default:
4022           return "INVALID-COUNTER-TYPE";
4023         }
4024     }
4025   else
4026     {
4027       switch (counter_type)
4028         {
4029         case VNET_INTERFACE_COUNTER_RX:
4030           return "rx";
4031         case VNET_INTERFACE_COUNTER_TX:
4032           return "tx";
4033         default:
4034           return "INVALID-COUNTER-TYPE";
4035         }
4036     }
4037 }
4038
4039 static int
4040 dump_stats_table (vat_main_t * vam)
4041 {
4042   vat_json_node_t node;
4043   vat_json_node_t *msg_array;
4044   vat_json_node_t *msg;
4045   vat_json_node_t *counter_array;
4046   vat_json_node_t *counter;
4047   interface_counter_t c;
4048   u64 packets;
4049   ip4_fib_counter_t *c4;
4050   ip6_fib_counter_t *c6;
4051   int i, j;
4052
4053   if (!vam->json_output)
4054     {
4055       clib_warning ("dump_stats_table supported only in JSON format");
4056       return -99;
4057     }
4058
4059   vat_json_init_object (&node);
4060
4061   /* interface counters */
4062   msg_array = vat_json_object_add (&node, "interface_counters");
4063   vat_json_init_array (msg_array);
4064   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4065     {
4066       msg = vat_json_array_add (msg_array);
4067       vat_json_init_object (msg);
4068       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4069                                        (u8 *) counter_type_to_str (i, 0));
4070       vat_json_object_add_int (msg, "is_combined", 0);
4071       counter_array = vat_json_object_add (msg, "data");
4072       vat_json_init_array (counter_array);
4073       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4074         {
4075           packets = vam->simple_interface_counters[i][j];
4076           vat_json_array_add_uint (counter_array, packets);
4077         }
4078     }
4079   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4080     {
4081       msg = vat_json_array_add (msg_array);
4082       vat_json_init_object (msg);
4083       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4084                                        (u8 *) counter_type_to_str (i, 1));
4085       vat_json_object_add_int (msg, "is_combined", 1);
4086       counter_array = vat_json_object_add (msg, "data");
4087       vat_json_init_array (counter_array);
4088       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4089         {
4090           c = vam->combined_interface_counters[i][j];
4091           counter = vat_json_array_add (counter_array);
4092           vat_json_init_object (counter);
4093           vat_json_object_add_uint (counter, "packets", c.packets);
4094           vat_json_object_add_uint (counter, "bytes", c.bytes);
4095         }
4096     }
4097
4098   /* ip4 fib counters */
4099   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4100   vat_json_init_array (msg_array);
4101   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4102     {
4103       msg = vat_json_array_add (msg_array);
4104       vat_json_init_object (msg);
4105       vat_json_object_add_uint (msg, "vrf_id",
4106                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4107       counter_array = vat_json_object_add (msg, "c");
4108       vat_json_init_array (counter_array);
4109       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4110         {
4111           counter = vat_json_array_add (counter_array);
4112           vat_json_init_object (counter);
4113           c4 = &vam->ip4_fib_counters[i][j];
4114           vat_json_object_add_ip4 (counter, "address", c4->address);
4115           vat_json_object_add_uint (counter, "address_length",
4116                                     c4->address_length);
4117           vat_json_object_add_uint (counter, "packets", c4->packets);
4118           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4119         }
4120     }
4121
4122   /* ip6 fib counters */
4123   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4124   vat_json_init_array (msg_array);
4125   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4126     {
4127       msg = vat_json_array_add (msg_array);
4128       vat_json_init_object (msg);
4129       vat_json_object_add_uint (msg, "vrf_id",
4130                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4131       counter_array = vat_json_object_add (msg, "c");
4132       vat_json_init_array (counter_array);
4133       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4134         {
4135           counter = vat_json_array_add (counter_array);
4136           vat_json_init_object (counter);
4137           c6 = &vam->ip6_fib_counters[i][j];
4138           vat_json_object_add_ip6 (counter, "address", c6->address);
4139           vat_json_object_add_uint (counter, "address_length",
4140                                     c6->address_length);
4141           vat_json_object_add_uint (counter, "packets", c6->packets);
4142           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4143         }
4144     }
4145
4146   vat_json_print (vam->ofp, &node);
4147   vat_json_free (&node);
4148
4149   return 0;
4150 }
4151
4152 int
4153 exec (vat_main_t * vam)
4154 {
4155   api_main_t *am = &api_main;
4156   vl_api_cli_request_t *mp;
4157   f64 timeout;
4158   void *oldheap;
4159   u8 *cmd = 0;
4160   unformat_input_t *i = vam->input;
4161
4162   if (vec_len (i->buffer) == 0)
4163     return -1;
4164
4165   if (vam->exec_mode == 0 && unformat (i, "mode"))
4166     {
4167       vam->exec_mode = 1;
4168       return 0;
4169     }
4170   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4171     {
4172       vam->exec_mode = 0;
4173       return 0;
4174     }
4175
4176
4177   M (CLI_REQUEST, cli_request);
4178
4179   /*
4180    * Copy cmd into shared memory.
4181    * In order for the CLI command to work, it
4182    * must be a vector ending in \n, not a C-string ending
4183    * in \n\0.
4184    */
4185   pthread_mutex_lock (&am->vlib_rp->mutex);
4186   oldheap = svm_push_data_heap (am->vlib_rp);
4187
4188   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4189   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4190
4191   svm_pop_heap (oldheap);
4192   pthread_mutex_unlock (&am->vlib_rp->mutex);
4193
4194   mp->cmd_in_shmem = (u64) cmd;
4195   S;
4196   timeout = vat_time_now (vam) + 10.0;
4197
4198   while (vat_time_now (vam) < timeout)
4199     {
4200       if (vam->result_ready == 1)
4201         {
4202           u8 *free_me;
4203           if (vam->shmem_result != NULL)
4204             fformat (vam->ofp, "%s", vam->shmem_result);
4205           pthread_mutex_lock (&am->vlib_rp->mutex);
4206           oldheap = svm_push_data_heap (am->vlib_rp);
4207
4208           free_me = (u8 *) vam->shmem_result;
4209           vec_free (free_me);
4210
4211           svm_pop_heap (oldheap);
4212           pthread_mutex_unlock (&am->vlib_rp->mutex);
4213           return 0;
4214         }
4215     }
4216   return -99;
4217 }
4218
4219 /*
4220  * Future replacement of exec() that passes CLI buffers directly in
4221  * the API messages instead of an additional shared memory area.
4222  */
4223 static int
4224 exec_inband (vat_main_t * vam)
4225 {
4226   vl_api_cli_inband_t *mp;
4227   f64 timeout;
4228   unformat_input_t *i = vam->input;
4229
4230   if (vec_len (i->buffer) == 0)
4231     return -1;
4232
4233   if (vam->exec_mode == 0 && unformat (i, "mode"))
4234     {
4235       vam->exec_mode = 1;
4236       return 0;
4237     }
4238   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4239     {
4240       vam->exec_mode = 0;
4241       return 0;
4242     }
4243
4244   /*
4245    * In order for the CLI command to work, it
4246    * must be a vector ending in \n, not a C-string ending
4247    * in \n\0.
4248    */
4249   u32 len = vec_len (vam->input->buffer);
4250   M2 (CLI_INBAND, cli_inband, len);
4251   clib_memcpy (mp->cmd, vam->input->buffer, len);
4252   mp->length = htonl (len);
4253
4254   S;
4255   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4256 }
4257
4258 static int
4259 api_create_loopback (vat_main_t * vam)
4260 {
4261   unformat_input_t *i = vam->input;
4262   vl_api_create_loopback_t *mp;
4263   f64 timeout;
4264   u8 mac_address[6];
4265   u8 mac_set = 0;
4266
4267   memset (mac_address, 0, sizeof (mac_address));
4268
4269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4270     {
4271       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4272         mac_set = 1;
4273       else
4274         break;
4275     }
4276
4277   /* Construct the API message */
4278   M (CREATE_LOOPBACK, create_loopback);
4279   if (mac_set)
4280     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4281
4282   S;
4283   W;
4284 }
4285
4286 static int
4287 api_delete_loopback (vat_main_t * vam)
4288 {
4289   unformat_input_t *i = vam->input;
4290   vl_api_delete_loopback_t *mp;
4291   f64 timeout;
4292   u32 sw_if_index = ~0;
4293
4294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4295     {
4296       if (unformat (i, "sw_if_index %d", &sw_if_index))
4297         ;
4298       else
4299         break;
4300     }
4301
4302   if (sw_if_index == ~0)
4303     {
4304       errmsg ("missing sw_if_index\n");
4305       return -99;
4306     }
4307
4308   /* Construct the API message */
4309   M (DELETE_LOOPBACK, delete_loopback);
4310   mp->sw_if_index = ntohl (sw_if_index);
4311
4312   S;
4313   W;
4314 }
4315
4316 static int
4317 api_want_stats (vat_main_t * vam)
4318 {
4319   unformat_input_t *i = vam->input;
4320   vl_api_want_stats_t *mp;
4321   f64 timeout;
4322   int enable = -1;
4323
4324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4325     {
4326       if (unformat (i, "enable"))
4327         enable = 1;
4328       else if (unformat (i, "disable"))
4329         enable = 0;
4330       else
4331         break;
4332     }
4333
4334   if (enable == -1)
4335     {
4336       errmsg ("missing enable|disable\n");
4337       return -99;
4338     }
4339
4340   M (WANT_STATS, want_stats);
4341   mp->enable_disable = enable;
4342
4343   S;
4344   W;
4345 }
4346
4347 static int
4348 api_want_interface_events (vat_main_t * vam)
4349 {
4350   unformat_input_t *i = vam->input;
4351   vl_api_want_interface_events_t *mp;
4352   f64 timeout;
4353   int enable = -1;
4354
4355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4356     {
4357       if (unformat (i, "enable"))
4358         enable = 1;
4359       else if (unformat (i, "disable"))
4360         enable = 0;
4361       else
4362         break;
4363     }
4364
4365   if (enable == -1)
4366     {
4367       errmsg ("missing enable|disable\n");
4368       return -99;
4369     }
4370
4371   M (WANT_INTERFACE_EVENTS, want_interface_events);
4372   mp->enable_disable = enable;
4373
4374   vam->interface_event_display = enable;
4375
4376   S;
4377   W;
4378 }
4379
4380
4381 /* Note: non-static, called once to set up the initial intfc table */
4382 int
4383 api_sw_interface_dump (vat_main_t * vam)
4384 {
4385   vl_api_sw_interface_dump_t *mp;
4386   f64 timeout;
4387   hash_pair_t *p;
4388   name_sort_t *nses = 0, *ns;
4389   sw_interface_subif_t *sub = NULL;
4390
4391   /* Toss the old name table */
4392   /* *INDENT-OFF* */
4393   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4394   ({
4395     vec_add2 (nses, ns, 1);
4396     ns->name = (u8 *)(p->key);
4397     ns->value = (u32) p->value[0];
4398   }));
4399   /* *INDENT-ON* */
4400
4401   hash_free (vam->sw_if_index_by_interface_name);
4402
4403   vec_foreach (ns, nses) vec_free (ns->name);
4404
4405   vec_free (nses);
4406
4407   vec_foreach (sub, vam->sw_if_subif_table)
4408   {
4409     vec_free (sub->interface_name);
4410   }
4411   vec_free (vam->sw_if_subif_table);
4412
4413   /* recreate the interface name hash table */
4414   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4415
4416   /* Get list of ethernets */
4417   M (SW_INTERFACE_DUMP, sw_interface_dump);
4418   mp->name_filter_valid = 1;
4419   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4420   S;
4421
4422   /* and local / loopback interfaces */
4423   M (SW_INTERFACE_DUMP, sw_interface_dump);
4424   mp->name_filter_valid = 1;
4425   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4426   S;
4427
4428   /* and packet-generator interfaces */
4429   M (SW_INTERFACE_DUMP, sw_interface_dump);
4430   mp->name_filter_valid = 1;
4431   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4432   S;
4433
4434   /* and vxlan-gpe tunnel interfaces */
4435   M (SW_INTERFACE_DUMP, sw_interface_dump);
4436   mp->name_filter_valid = 1;
4437   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4438            sizeof (mp->name_filter) - 1);
4439   S;
4440
4441   /* and vxlan tunnel interfaces */
4442   M (SW_INTERFACE_DUMP, sw_interface_dump);
4443   mp->name_filter_valid = 1;
4444   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4445   S;
4446
4447   /* and host (af_packet) interfaces */
4448   M (SW_INTERFACE_DUMP, sw_interface_dump);
4449   mp->name_filter_valid = 1;
4450   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4451   S;
4452
4453   /* and l2tpv3 tunnel interfaces */
4454   M (SW_INTERFACE_DUMP, sw_interface_dump);
4455   mp->name_filter_valid = 1;
4456   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4457            sizeof (mp->name_filter) - 1);
4458   S;
4459
4460   /* and GRE tunnel interfaces */
4461   M (SW_INTERFACE_DUMP, sw_interface_dump);
4462   mp->name_filter_valid = 1;
4463   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4464   S;
4465
4466   /* and LISP-GPE interfaces */
4467   M (SW_INTERFACE_DUMP, sw_interface_dump);
4468   mp->name_filter_valid = 1;
4469   strncpy ((char *) mp->name_filter, "lisp_gpe",
4470            sizeof (mp->name_filter) - 1);
4471   S;
4472
4473   /* and IPSEC tunnel interfaces */
4474   M (SW_INTERFACE_DUMP, sw_interface_dump);
4475   mp->name_filter_valid = 1;
4476   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4477   S;
4478
4479   /* Use a control ping for synchronization */
4480   {
4481     vl_api_control_ping_t *mp;
4482     M (CONTROL_PING, control_ping);
4483     S;
4484   }
4485   W;
4486 }
4487
4488 static int
4489 api_sw_interface_set_flags (vat_main_t * vam)
4490 {
4491   unformat_input_t *i = vam->input;
4492   vl_api_sw_interface_set_flags_t *mp;
4493   f64 timeout;
4494   u32 sw_if_index;
4495   u8 sw_if_index_set = 0;
4496   u8 admin_up = 0, link_up = 0;
4497
4498   /* Parse args required to build the message */
4499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4500     {
4501       if (unformat (i, "admin-up"))
4502         admin_up = 1;
4503       else if (unformat (i, "admin-down"))
4504         admin_up = 0;
4505       else if (unformat (i, "link-up"))
4506         link_up = 1;
4507       else if (unformat (i, "link-down"))
4508         link_up = 0;
4509       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4510         sw_if_index_set = 1;
4511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4512         sw_if_index_set = 1;
4513       else
4514         break;
4515     }
4516
4517   if (sw_if_index_set == 0)
4518     {
4519       errmsg ("missing interface name or sw_if_index\n");
4520       return -99;
4521     }
4522
4523   /* Construct the API message */
4524   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4525   mp->sw_if_index = ntohl (sw_if_index);
4526   mp->admin_up_down = admin_up;
4527   mp->link_up_down = link_up;
4528
4529   /* send it... */
4530   S;
4531
4532   /* Wait for a reply, return the good/bad news... */
4533   W;
4534 }
4535
4536 static int
4537 api_sw_interface_clear_stats (vat_main_t * vam)
4538 {
4539   unformat_input_t *i = vam->input;
4540   vl_api_sw_interface_clear_stats_t *mp;
4541   f64 timeout;
4542   u32 sw_if_index;
4543   u8 sw_if_index_set = 0;
4544
4545   /* Parse args required to build the message */
4546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4547     {
4548       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4549         sw_if_index_set = 1;
4550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4551         sw_if_index_set = 1;
4552       else
4553         break;
4554     }
4555
4556   /* Construct the API message */
4557   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4558
4559   if (sw_if_index_set == 1)
4560     mp->sw_if_index = ntohl (sw_if_index);
4561   else
4562     mp->sw_if_index = ~0;
4563
4564   /* send it... */
4565   S;
4566
4567   /* Wait for a reply, return the good/bad news... */
4568   W;
4569 }
4570
4571 static int
4572 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4573 {
4574   unformat_input_t *i = vam->input;
4575   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4576   f64 timeout;
4577   u32 sw_if_index;
4578   u8 sw_if_index_set = 0;
4579   u32 subport;
4580   u8 subport_set = 0;
4581   u32 pipe;
4582   u8 pipe_set = 0;
4583   u32 profile;
4584   u8 profile_set = 0;
4585
4586   /* Parse args required to build the message */
4587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4588     {
4589       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4590         sw_if_index_set = 1;
4591       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4592         sw_if_index_set = 1;
4593       else if (unformat (i, "subport %u", &subport))
4594         subport_set = 1;
4595       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4596         sw_if_index_set = 1;
4597       else if (unformat (i, "pipe %u", &pipe))
4598         pipe_set = 1;
4599       else if (unformat (i, "profile %u", &profile))
4600         profile_set = 1;
4601       else
4602         break;
4603     }
4604
4605   if (sw_if_index_set == 0)
4606     {
4607       errmsg ("missing interface name or sw_if_index\n");
4608       return -99;
4609     }
4610
4611   if (subport_set == 0)
4612     {
4613       errmsg ("missing subport \n");
4614       return -99;
4615     }
4616
4617   if (pipe_set == 0)
4618     {
4619       errmsg ("missing pipe\n");
4620       return -99;
4621     }
4622
4623   if (profile_set == 0)
4624     {
4625       errmsg ("missing profile\n");
4626       return -99;
4627     }
4628
4629   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4630
4631   mp->sw_if_index = ntohl (sw_if_index);
4632   mp->subport = ntohl (subport);
4633   mp->pipe = ntohl (pipe);
4634   mp->profile = ntohl (profile);
4635
4636
4637   S;
4638   W;
4639   /* NOTREACHED */
4640   return 0;
4641 }
4642
4643 static int
4644 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4645 {
4646   unformat_input_t *i = vam->input;
4647   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4648   f64 timeout;
4649   u32 sw_if_index;
4650   u8 sw_if_index_set = 0;
4651   u32 subport;
4652   u8 subport_set = 0;
4653   u32 tb_rate = 1250000000;     /* 10GbE */
4654   u32 tb_size = 1000000;
4655   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4656   u32 tc_period = 10;
4657
4658   /* Parse args required to build the message */
4659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4660     {
4661       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4662         sw_if_index_set = 1;
4663       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4664         sw_if_index_set = 1;
4665       else if (unformat (i, "subport %u", &subport))
4666         subport_set = 1;
4667       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4668         sw_if_index_set = 1;
4669       else if (unformat (i, "rate %u", &tb_rate))
4670         {
4671           u32 tc_id;
4672
4673           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4674                tc_id++)
4675             tc_rate[tc_id] = tb_rate;
4676         }
4677       else if (unformat (i, "bktsize %u", &tb_size))
4678         ;
4679       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4680         ;
4681       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4682         ;
4683       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4684         ;
4685       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4686         ;
4687       else if (unformat (i, "period %u", &tc_period))
4688         ;
4689       else
4690         break;
4691     }
4692
4693   if (sw_if_index_set == 0)
4694     {
4695       errmsg ("missing interface name or sw_if_index\n");
4696       return -99;
4697     }
4698
4699   if (subport_set == 0)
4700     {
4701       errmsg ("missing subport \n");
4702       return -99;
4703     }
4704
4705   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4706
4707   mp->sw_if_index = ntohl (sw_if_index);
4708   mp->subport = ntohl (subport);
4709   mp->tb_rate = ntohl (tb_rate);
4710   mp->tb_size = ntohl (tb_size);
4711   mp->tc_rate[0] = ntohl (tc_rate[0]);
4712   mp->tc_rate[1] = ntohl (tc_rate[1]);
4713   mp->tc_rate[2] = ntohl (tc_rate[2]);
4714   mp->tc_rate[3] = ntohl (tc_rate[3]);
4715   mp->tc_period = ntohl (tc_period);
4716
4717   S;
4718   W;
4719   /* NOTREACHED */
4720   return 0;
4721 }
4722
4723 static int
4724 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4725 {
4726   unformat_input_t *i = vam->input;
4727   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4728   f64 timeout;
4729   u32 sw_if_index;
4730   u8 sw_if_index_set = 0;
4731   u8 entry_set = 0;
4732   u8 tc_set = 0;
4733   u8 queue_set = 0;
4734   u32 entry, tc, queue;
4735
4736   /* Parse args required to build the message */
4737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4738     {
4739       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4740         sw_if_index_set = 1;
4741       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4742         sw_if_index_set = 1;
4743       else if (unformat (i, "entry %d", &entry))
4744         entry_set = 1;
4745       else if (unformat (i, "tc %d", &tc))
4746         tc_set = 1;
4747       else if (unformat (i, "queue %d", &queue))
4748         queue_set = 1;
4749       else
4750         break;
4751     }
4752
4753   if (sw_if_index_set == 0)
4754     {
4755       errmsg ("missing interface name or sw_if_index\n");
4756       return -99;
4757     }
4758
4759   if (entry_set == 0)
4760     {
4761       errmsg ("missing entry \n");
4762       return -99;
4763     }
4764
4765   if (tc_set == 0)
4766     {
4767       errmsg ("missing traffic class \n");
4768       return -99;
4769     }
4770
4771   if (queue_set == 0)
4772     {
4773       errmsg ("missing queue \n");
4774       return -99;
4775     }
4776
4777   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4778
4779   mp->sw_if_index = ntohl (sw_if_index);
4780   mp->entry = ntohl (entry);
4781   mp->tc = ntohl (tc);
4782   mp->queue = ntohl (queue);
4783
4784   S;
4785   W;
4786   /* NOTREACHED */
4787   return 0;
4788 }
4789
4790 static int
4791 api_sw_interface_add_del_address (vat_main_t * vam)
4792 {
4793   unformat_input_t *i = vam->input;
4794   vl_api_sw_interface_add_del_address_t *mp;
4795   f64 timeout;
4796   u32 sw_if_index;
4797   u8 sw_if_index_set = 0;
4798   u8 is_add = 1, del_all = 0;
4799   u32 address_length = 0;
4800   u8 v4_address_set = 0;
4801   u8 v6_address_set = 0;
4802   ip4_address_t v4address;
4803   ip6_address_t v6address;
4804
4805   /* Parse args required to build the message */
4806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4807     {
4808       if (unformat (i, "del-all"))
4809         del_all = 1;
4810       else if (unformat (i, "del"))
4811         is_add = 0;
4812       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4813         sw_if_index_set = 1;
4814       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4815         sw_if_index_set = 1;
4816       else if (unformat (i, "%U/%d",
4817                          unformat_ip4_address, &v4address, &address_length))
4818         v4_address_set = 1;
4819       else if (unformat (i, "%U/%d",
4820                          unformat_ip6_address, &v6address, &address_length))
4821         v6_address_set = 1;
4822       else
4823         break;
4824     }
4825
4826   if (sw_if_index_set == 0)
4827     {
4828       errmsg ("missing interface name or sw_if_index\n");
4829       return -99;
4830     }
4831   if (v4_address_set && v6_address_set)
4832     {
4833       errmsg ("both v4 and v6 addresses set\n");
4834       return -99;
4835     }
4836   if (!v4_address_set && !v6_address_set && !del_all)
4837     {
4838       errmsg ("no addresses set\n");
4839       return -99;
4840     }
4841
4842   /* Construct the API message */
4843   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4844
4845   mp->sw_if_index = ntohl (sw_if_index);
4846   mp->is_add = is_add;
4847   mp->del_all = del_all;
4848   if (v6_address_set)
4849     {
4850       mp->is_ipv6 = 1;
4851       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4852     }
4853   else
4854     {
4855       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4856     }
4857   mp->address_length = address_length;
4858
4859   /* send it... */
4860   S;
4861
4862   /* Wait for a reply, return good/bad news  */
4863   W;
4864 }
4865
4866 static int
4867 api_sw_interface_set_table (vat_main_t * vam)
4868 {
4869   unformat_input_t *i = vam->input;
4870   vl_api_sw_interface_set_table_t *mp;
4871   f64 timeout;
4872   u32 sw_if_index, vrf_id = 0;
4873   u8 sw_if_index_set = 0;
4874   u8 is_ipv6 = 0;
4875
4876   /* Parse args required to build the message */
4877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4878     {
4879       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4880         sw_if_index_set = 1;
4881       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4882         sw_if_index_set = 1;
4883       else if (unformat (i, "vrf %d", &vrf_id))
4884         ;
4885       else if (unformat (i, "ipv6"))
4886         is_ipv6 = 1;
4887       else
4888         break;
4889     }
4890
4891   if (sw_if_index_set == 0)
4892     {
4893       errmsg ("missing interface name or sw_if_index\n");
4894       return -99;
4895     }
4896
4897   /* Construct the API message */
4898   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4899
4900   mp->sw_if_index = ntohl (sw_if_index);
4901   mp->is_ipv6 = is_ipv6;
4902   mp->vrf_id = ntohl (vrf_id);
4903
4904   /* send it... */
4905   S;
4906
4907   /* Wait for a reply... */
4908   W;
4909 }
4910
4911 static int
4912 api_sw_interface_set_vpath (vat_main_t * vam)
4913 {
4914   unformat_input_t *i = vam->input;
4915   vl_api_sw_interface_set_vpath_t *mp;
4916   f64 timeout;
4917   u32 sw_if_index = 0;
4918   u8 sw_if_index_set = 0;
4919   u8 is_enable = 0;
4920
4921   /* Parse args required to build the message */
4922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4923     {
4924       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4925         sw_if_index_set = 1;
4926       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4927         sw_if_index_set = 1;
4928       else if (unformat (i, "enable"))
4929         is_enable = 1;
4930       else if (unformat (i, "disable"))
4931         is_enable = 0;
4932       else
4933         break;
4934     }
4935
4936   if (sw_if_index_set == 0)
4937     {
4938       errmsg ("missing interface name or sw_if_index\n");
4939       return -99;
4940     }
4941
4942   /* Construct the API message */
4943   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4944
4945   mp->sw_if_index = ntohl (sw_if_index);
4946   mp->enable = is_enable;
4947
4948   /* send it... */
4949   S;
4950
4951   /* Wait for a reply... */
4952   W;
4953 }
4954
4955 static int
4956 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4957 {
4958   unformat_input_t *i = vam->input;
4959   vl_api_sw_interface_set_l2_xconnect_t *mp;
4960   f64 timeout;
4961   u32 rx_sw_if_index;
4962   u8 rx_sw_if_index_set = 0;
4963   u32 tx_sw_if_index;
4964   u8 tx_sw_if_index_set = 0;
4965   u8 enable = 1;
4966
4967   /* Parse args required to build the message */
4968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4969     {
4970       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4971         rx_sw_if_index_set = 1;
4972       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4973         tx_sw_if_index_set = 1;
4974       else if (unformat (i, "rx"))
4975         {
4976           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4977             {
4978               if (unformat (i, "%U", unformat_sw_if_index, vam,
4979                             &rx_sw_if_index))
4980                 rx_sw_if_index_set = 1;
4981             }
4982           else
4983             break;
4984         }
4985       else if (unformat (i, "tx"))
4986         {
4987           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4988             {
4989               if (unformat (i, "%U", unformat_sw_if_index, vam,
4990                             &tx_sw_if_index))
4991                 tx_sw_if_index_set = 1;
4992             }
4993           else
4994             break;
4995         }
4996       else if (unformat (i, "enable"))
4997         enable = 1;
4998       else if (unformat (i, "disable"))
4999         enable = 0;
5000       else
5001         break;
5002     }
5003
5004   if (rx_sw_if_index_set == 0)
5005     {
5006       errmsg ("missing rx interface name or rx_sw_if_index\n");
5007       return -99;
5008     }
5009
5010   if (enable && (tx_sw_if_index_set == 0))
5011     {
5012       errmsg ("missing tx interface name or tx_sw_if_index\n");
5013       return -99;
5014     }
5015
5016   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5017
5018   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5019   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5020   mp->enable = enable;
5021
5022   S;
5023   W;
5024   /* NOTREACHED */
5025   return 0;
5026 }
5027
5028 static int
5029 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5030 {
5031   unformat_input_t *i = vam->input;
5032   vl_api_sw_interface_set_l2_bridge_t *mp;
5033   f64 timeout;
5034   u32 rx_sw_if_index;
5035   u8 rx_sw_if_index_set = 0;
5036   u32 bd_id;
5037   u8 bd_id_set = 0;
5038   u8 bvi = 0;
5039   u32 shg = 0;
5040   u8 enable = 1;
5041
5042   /* Parse args required to build the message */
5043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5044     {
5045       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5046         rx_sw_if_index_set = 1;
5047       else if (unformat (i, "bd_id %d", &bd_id))
5048         bd_id_set = 1;
5049       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5050         rx_sw_if_index_set = 1;
5051       else if (unformat (i, "shg %d", &shg))
5052         ;
5053       else if (unformat (i, "bvi"))
5054         bvi = 1;
5055       else if (unformat (i, "enable"))
5056         enable = 1;
5057       else if (unformat (i, "disable"))
5058         enable = 0;
5059       else
5060         break;
5061     }
5062
5063   if (rx_sw_if_index_set == 0)
5064     {
5065       errmsg ("missing rx interface name or sw_if_index\n");
5066       return -99;
5067     }
5068
5069   if (enable && (bd_id_set == 0))
5070     {
5071       errmsg ("missing bridge domain\n");
5072       return -99;
5073     }
5074
5075   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5076
5077   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5078   mp->bd_id = ntohl (bd_id);
5079   mp->shg = (u8) shg;
5080   mp->bvi = bvi;
5081   mp->enable = enable;
5082
5083   S;
5084   W;
5085   /* NOTREACHED */
5086   return 0;
5087 }
5088
5089 static int
5090 api_bridge_domain_dump (vat_main_t * vam)
5091 {
5092   unformat_input_t *i = vam->input;
5093   vl_api_bridge_domain_dump_t *mp;
5094   f64 timeout;
5095   u32 bd_id = ~0;
5096
5097   /* Parse args required to build the message */
5098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5099     {
5100       if (unformat (i, "bd_id %d", &bd_id))
5101         ;
5102       else
5103         break;
5104     }
5105
5106   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5107   mp->bd_id = ntohl (bd_id);
5108   S;
5109
5110   /* Use a control ping for synchronization */
5111   {
5112     vl_api_control_ping_t *mp;
5113     M (CONTROL_PING, control_ping);
5114     S;
5115   }
5116
5117   W;
5118   /* NOTREACHED */
5119   return 0;
5120 }
5121
5122 static int
5123 api_bridge_domain_add_del (vat_main_t * vam)
5124 {
5125   unformat_input_t *i = vam->input;
5126   vl_api_bridge_domain_add_del_t *mp;
5127   f64 timeout;
5128   u32 bd_id = ~0;
5129   u8 is_add = 1;
5130   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5131
5132   /* Parse args required to build the message */
5133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5134     {
5135       if (unformat (i, "bd_id %d", &bd_id))
5136         ;
5137       else if (unformat (i, "flood %d", &flood))
5138         ;
5139       else if (unformat (i, "uu-flood %d", &uu_flood))
5140         ;
5141       else if (unformat (i, "forward %d", &forward))
5142         ;
5143       else if (unformat (i, "learn %d", &learn))
5144         ;
5145       else if (unformat (i, "arp-term %d", &arp_term))
5146         ;
5147       else if (unformat (i, "del"))
5148         {
5149           is_add = 0;
5150           flood = uu_flood = forward = learn = 0;
5151         }
5152       else
5153         break;
5154     }
5155
5156   if (bd_id == ~0)
5157     {
5158       errmsg ("missing bridge domain\n");
5159       return -99;
5160     }
5161
5162   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5163
5164   mp->bd_id = ntohl (bd_id);
5165   mp->flood = flood;
5166   mp->uu_flood = uu_flood;
5167   mp->forward = forward;
5168   mp->learn = learn;
5169   mp->arp_term = arp_term;
5170   mp->is_add = is_add;
5171
5172   S;
5173   W;
5174   /* NOTREACHED */
5175   return 0;
5176 }
5177
5178 static int
5179 api_l2fib_add_del (vat_main_t * vam)
5180 {
5181   unformat_input_t *i = vam->input;
5182   vl_api_l2fib_add_del_t *mp;
5183   f64 timeout;
5184   u64 mac = 0;
5185   u8 mac_set = 0;
5186   u32 bd_id;
5187   u8 bd_id_set = 0;
5188   u32 sw_if_index;
5189   u8 sw_if_index_set = 0;
5190   u8 is_add = 1;
5191   u8 static_mac = 0;
5192   u8 filter_mac = 0;
5193   u8 bvi_mac = 0;
5194   int count = 1;
5195   f64 before = 0;
5196   int j;
5197
5198   /* Parse args required to build the message */
5199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5200     {
5201       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5202         mac_set = 1;
5203       else if (unformat (i, "bd_id %d", &bd_id))
5204         bd_id_set = 1;
5205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5206         sw_if_index_set = 1;
5207       else if (unformat (i, "sw_if"))
5208         {
5209           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5210             {
5211               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5212                 sw_if_index_set = 1;
5213             }
5214           else
5215             break;
5216         }
5217       else if (unformat (i, "static"))
5218         static_mac = 1;
5219       else if (unformat (i, "filter"))
5220         {
5221           filter_mac = 1;
5222           static_mac = 1;
5223         }
5224       else if (unformat (i, "bvi"))
5225         {
5226           bvi_mac = 1;
5227           static_mac = 1;
5228         }
5229       else if (unformat (i, "del"))
5230         is_add = 0;
5231       else if (unformat (i, "count %d", &count))
5232         ;
5233       else
5234         break;
5235     }
5236
5237   if (mac_set == 0)
5238     {
5239       errmsg ("missing mac address\n");
5240       return -99;
5241     }
5242
5243   if (bd_id_set == 0)
5244     {
5245       errmsg ("missing bridge domain\n");
5246       return -99;
5247     }
5248
5249   if (is_add && (sw_if_index_set == 0))
5250     {
5251       errmsg ("missing interface name or sw_if_index\n");
5252       return -99;
5253     }
5254
5255   if (count > 1)
5256     {
5257       /* Turn on async mode */
5258       vam->async_mode = 1;
5259       vam->async_errors = 0;
5260       before = vat_time_now (vam);
5261     }
5262
5263   for (j = 0; j < count; j++)
5264     {
5265       M (L2FIB_ADD_DEL, l2fib_add_del);
5266
5267       mp->mac = mac;
5268       mp->bd_id = ntohl (bd_id);
5269       mp->is_add = is_add;
5270
5271       if (is_add)
5272         {
5273           mp->sw_if_index = ntohl (sw_if_index);
5274           mp->static_mac = static_mac;
5275           mp->filter_mac = filter_mac;
5276           mp->bvi_mac = bvi_mac;
5277         }
5278       increment_mac_address (&mac);
5279       /* send it... */
5280       S;
5281     }
5282
5283   if (count > 1)
5284     {
5285       vl_api_control_ping_t *mp;
5286       f64 after;
5287
5288       /* Shut off async mode */
5289       vam->async_mode = 0;
5290
5291       M (CONTROL_PING, control_ping);
5292       S;
5293
5294       timeout = vat_time_now (vam) + 1.0;
5295       while (vat_time_now (vam) < timeout)
5296         if (vam->result_ready == 1)
5297           goto out;
5298       vam->retval = -99;
5299
5300     out:
5301       if (vam->retval == -99)
5302         errmsg ("timeout\n");
5303
5304       if (vam->async_errors > 0)
5305         {
5306           errmsg ("%d asynchronous errors\n", vam->async_errors);
5307           vam->retval = -98;
5308         }
5309       vam->async_errors = 0;
5310       after = vat_time_now (vam);
5311
5312       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5313                count, after - before, count / (after - before));
5314     }
5315   else
5316     {
5317       /* Wait for a reply... */
5318       W;
5319     }
5320   /* Return the good/bad news */
5321   return (vam->retval);
5322 }
5323
5324 static int
5325 api_l2_flags (vat_main_t * vam)
5326 {
5327   unformat_input_t *i = vam->input;
5328   vl_api_l2_flags_t *mp;
5329   f64 timeout;
5330   u32 sw_if_index;
5331   u32 feature_bitmap = 0;
5332   u8 sw_if_index_set = 0;
5333
5334   /* Parse args required to build the message */
5335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5336     {
5337       if (unformat (i, "sw_if_index %d", &sw_if_index))
5338         sw_if_index_set = 1;
5339       else if (unformat (i, "sw_if"))
5340         {
5341           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5342             {
5343               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5344                 sw_if_index_set = 1;
5345             }
5346           else
5347             break;
5348         }
5349       else if (unformat (i, "learn"))
5350         feature_bitmap |= L2INPUT_FEAT_LEARN;
5351       else if (unformat (i, "forward"))
5352         feature_bitmap |= L2INPUT_FEAT_FWD;
5353       else if (unformat (i, "flood"))
5354         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5355       else if (unformat (i, "uu-flood"))
5356         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5357       else
5358         break;
5359     }
5360
5361   if (sw_if_index_set == 0)
5362     {
5363       errmsg ("missing interface name or sw_if_index\n");
5364       return -99;
5365     }
5366
5367   M (L2_FLAGS, l2_flags);
5368
5369   mp->sw_if_index = ntohl (sw_if_index);
5370   mp->feature_bitmap = ntohl (feature_bitmap);
5371
5372   S;
5373   W;
5374   /* NOTREACHED */
5375   return 0;
5376 }
5377
5378 static int
5379 api_bridge_flags (vat_main_t * vam)
5380 {
5381   unformat_input_t *i = vam->input;
5382   vl_api_bridge_flags_t *mp;
5383   f64 timeout;
5384   u32 bd_id;
5385   u8 bd_id_set = 0;
5386   u8 is_set = 1;
5387   u32 flags = 0;
5388
5389   /* Parse args required to build the message */
5390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5391     {
5392       if (unformat (i, "bd_id %d", &bd_id))
5393         bd_id_set = 1;
5394       else if (unformat (i, "learn"))
5395         flags |= L2_LEARN;
5396       else if (unformat (i, "forward"))
5397         flags |= L2_FWD;
5398       else if (unformat (i, "flood"))
5399         flags |= L2_FLOOD;
5400       else if (unformat (i, "uu-flood"))
5401         flags |= L2_UU_FLOOD;
5402       else if (unformat (i, "arp-term"))
5403         flags |= L2_ARP_TERM;
5404       else if (unformat (i, "off"))
5405         is_set = 0;
5406       else if (unformat (i, "disable"))
5407         is_set = 0;
5408       else
5409         break;
5410     }
5411
5412   if (bd_id_set == 0)
5413     {
5414       errmsg ("missing bridge domain\n");
5415       return -99;
5416     }
5417
5418   M (BRIDGE_FLAGS, bridge_flags);
5419
5420   mp->bd_id = ntohl (bd_id);
5421   mp->feature_bitmap = ntohl (flags);
5422   mp->is_set = is_set;
5423
5424   S;
5425   W;
5426   /* NOTREACHED */
5427   return 0;
5428 }
5429
5430 static int
5431 api_bd_ip_mac_add_del (vat_main_t * vam)
5432 {
5433   unformat_input_t *i = vam->input;
5434   vl_api_bd_ip_mac_add_del_t *mp;
5435   f64 timeout;
5436   u32 bd_id;
5437   u8 is_ipv6 = 0;
5438   u8 is_add = 1;
5439   u8 bd_id_set = 0;
5440   u8 ip_set = 0;
5441   u8 mac_set = 0;
5442   ip4_address_t v4addr;
5443   ip6_address_t v6addr;
5444   u8 macaddr[6];
5445
5446
5447   /* Parse args required to build the message */
5448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5449     {
5450       if (unformat (i, "bd_id %d", &bd_id))
5451         {
5452           bd_id_set++;
5453         }
5454       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5455         {
5456           ip_set++;
5457         }
5458       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5459         {
5460           ip_set++;
5461           is_ipv6++;
5462         }
5463       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5464         {
5465           mac_set++;
5466         }
5467       else if (unformat (i, "del"))
5468         is_add = 0;
5469       else
5470         break;
5471     }
5472
5473   if (bd_id_set == 0)
5474     {
5475       errmsg ("missing bridge domain\n");
5476       return -99;
5477     }
5478   else if (ip_set == 0)
5479     {
5480       errmsg ("missing IP address\n");
5481       return -99;
5482     }
5483   else if (mac_set == 0)
5484     {
5485       errmsg ("missing MAC address\n");
5486       return -99;
5487     }
5488
5489   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5490
5491   mp->bd_id = ntohl (bd_id);
5492   mp->is_ipv6 = is_ipv6;
5493   mp->is_add = is_add;
5494   if (is_ipv6)
5495     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5496   else
5497     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5498   clib_memcpy (mp->mac_address, macaddr, 6);
5499   S;
5500   W;
5501   /* NOTREACHED */
5502   return 0;
5503 }
5504
5505 static int
5506 api_tap_connect (vat_main_t * vam)
5507 {
5508   unformat_input_t *i = vam->input;
5509   vl_api_tap_connect_t *mp;
5510   f64 timeout;
5511   u8 mac_address[6];
5512   u8 random_mac = 1;
5513   u8 name_set = 0;
5514   u8 *tap_name;
5515
5516   memset (mac_address, 0, sizeof (mac_address));
5517
5518   /* Parse args required to build the message */
5519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5520     {
5521       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5522         {
5523           random_mac = 0;
5524         }
5525       else if (unformat (i, "random-mac"))
5526         random_mac = 1;
5527       else if (unformat (i, "tapname %s", &tap_name))
5528         name_set = 1;
5529       else
5530         break;
5531     }
5532
5533   if (name_set == 0)
5534     {
5535       errmsg ("missing tap name\n");
5536       return -99;
5537     }
5538   if (vec_len (tap_name) > 63)
5539     {
5540       errmsg ("tap name too long\n");
5541     }
5542   vec_add1 (tap_name, 0);
5543
5544   /* Construct the API message */
5545   M (TAP_CONNECT, tap_connect);
5546
5547   mp->use_random_mac = random_mac;
5548   clib_memcpy (mp->mac_address, mac_address, 6);
5549   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5550   vec_free (tap_name);
5551
5552   /* send it... */
5553   S;
5554
5555   /* Wait for a reply... */
5556   W;
5557 }
5558
5559 static int
5560 api_tap_modify (vat_main_t * vam)
5561 {
5562   unformat_input_t *i = vam->input;
5563   vl_api_tap_modify_t *mp;
5564   f64 timeout;
5565   u8 mac_address[6];
5566   u8 random_mac = 1;
5567   u8 name_set = 0;
5568   u8 *tap_name;
5569   u32 sw_if_index = ~0;
5570   u8 sw_if_index_set = 0;
5571
5572   memset (mac_address, 0, sizeof (mac_address));
5573
5574   /* Parse args required to build the message */
5575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5576     {
5577       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5578         sw_if_index_set = 1;
5579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5580         sw_if_index_set = 1;
5581       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5582         {
5583           random_mac = 0;
5584         }
5585       else if (unformat (i, "random-mac"))
5586         random_mac = 1;
5587       else if (unformat (i, "tapname %s", &tap_name))
5588         name_set = 1;
5589       else
5590         break;
5591     }
5592
5593   if (sw_if_index_set == 0)
5594     {
5595       errmsg ("missing vpp interface name");
5596       return -99;
5597     }
5598   if (name_set == 0)
5599     {
5600       errmsg ("missing tap name\n");
5601       return -99;
5602     }
5603   if (vec_len (tap_name) > 63)
5604     {
5605       errmsg ("tap name too long\n");
5606     }
5607   vec_add1 (tap_name, 0);
5608
5609   /* Construct the API message */
5610   M (TAP_MODIFY, tap_modify);
5611
5612   mp->use_random_mac = random_mac;
5613   mp->sw_if_index = ntohl (sw_if_index);
5614   clib_memcpy (mp->mac_address, mac_address, 6);
5615   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5616   vec_free (tap_name);
5617
5618   /* send it... */
5619   S;
5620
5621   /* Wait for a reply... */
5622   W;
5623 }
5624
5625 static int
5626 api_tap_delete (vat_main_t * vam)
5627 {
5628   unformat_input_t *i = vam->input;
5629   vl_api_tap_delete_t *mp;
5630   f64 timeout;
5631   u32 sw_if_index = ~0;
5632   u8 sw_if_index_set = 0;
5633
5634   /* Parse args required to build the message */
5635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5636     {
5637       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5638         sw_if_index_set = 1;
5639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5640         sw_if_index_set = 1;
5641       else
5642         break;
5643     }
5644
5645   if (sw_if_index_set == 0)
5646     {
5647       errmsg ("missing vpp interface name");
5648       return -99;
5649     }
5650
5651   /* Construct the API message */
5652   M (TAP_DELETE, tap_delete);
5653
5654   mp->sw_if_index = ntohl (sw_if_index);
5655
5656   /* send it... */
5657   S;
5658
5659   /* Wait for a reply... */
5660   W;
5661 }
5662
5663 static int
5664 api_ip_add_del_route (vat_main_t * vam)
5665 {
5666   unformat_input_t *i = vam->input;
5667   vl_api_ip_add_del_route_t *mp;
5668   f64 timeout;
5669   u32 sw_if_index = ~0, vrf_id = 0;
5670   u8 sw_if_index_set = 0;
5671   u8 is_ipv6 = 0;
5672   u8 is_local = 0, is_drop = 0;
5673   u8 create_vrf_if_needed = 0;
5674   u8 is_add = 1;
5675   u8 next_hop_weight = 1;
5676   u8 not_last = 0;
5677   u8 is_multipath = 0;
5678   u8 address_set = 0;
5679   u8 address_length_set = 0;
5680   u32 lookup_in_vrf = 0;
5681   u32 resolve_attempts = 0;
5682   u32 dst_address_length = 0;
5683   u8 next_hop_set = 0;
5684   ip4_address_t v4_dst_address, v4_next_hop_address;
5685   ip6_address_t v6_dst_address, v6_next_hop_address;
5686   int count = 1;
5687   int j;
5688   f64 before = 0;
5689   u32 random_add_del = 0;
5690   u32 *random_vector = 0;
5691   uword *random_hash;
5692   u32 random_seed = 0xdeaddabe;
5693   u32 classify_table_index = ~0;
5694   u8 is_classify = 0;
5695   u8 resolve_host = 0, resolve_attached = 0;
5696
5697   /* Parse args required to build the message */
5698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5699     {
5700       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5701         sw_if_index_set = 1;
5702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5703         sw_if_index_set = 1;
5704       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5705         {
5706           address_set = 1;
5707           is_ipv6 = 0;
5708         }
5709       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5710         {
5711           address_set = 1;
5712           is_ipv6 = 1;
5713         }
5714       else if (unformat (i, "/%d", &dst_address_length))
5715         {
5716           address_length_set = 1;
5717         }
5718
5719       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5720                                          &v4_next_hop_address))
5721         {
5722           next_hop_set = 1;
5723         }
5724       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5725                                          &v6_next_hop_address))
5726         {
5727           next_hop_set = 1;
5728         }
5729       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5730         ;
5731       else if (unformat (i, "weight %d", &next_hop_weight))
5732         ;
5733       else if (unformat (i, "drop"))
5734         {
5735           is_drop = 1;
5736         }
5737       else if (unformat (i, "local"))
5738         {
5739           is_local = 1;
5740         }
5741       else if (unformat (i, "classify %d", &classify_table_index))
5742         {
5743           is_classify = 1;
5744         }
5745       else if (unformat (i, "del"))
5746         is_add = 0;
5747       else if (unformat (i, "add"))
5748         is_add = 1;
5749       else if (unformat (i, "not-last"))
5750         not_last = 1;
5751       else if (unformat (i, "resolve-via-host"))
5752         resolve_host = 1;
5753       else if (unformat (i, "resolve-via-attached"))
5754         resolve_attached = 1;
5755       else if (unformat (i, "multipath"))
5756         is_multipath = 1;
5757       else if (unformat (i, "vrf %d", &vrf_id))
5758         ;
5759       else if (unformat (i, "create-vrf"))
5760         create_vrf_if_needed = 1;
5761       else if (unformat (i, "count %d", &count))
5762         ;
5763       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5764         ;
5765       else if (unformat (i, "random"))
5766         random_add_del = 1;
5767       else if (unformat (i, "seed %d", &random_seed))
5768         ;
5769       else
5770         {
5771           clib_warning ("parse error '%U'", format_unformat_error, i);
5772           return -99;
5773         }
5774     }
5775
5776   if (resolve_attempts > 0 && sw_if_index_set == 0)
5777     {
5778       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5779       return -99;
5780     }
5781
5782   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5783     {
5784       errmsg ("next hop / local / drop / classify not set\n");
5785       return -99;
5786     }
5787
5788   if (address_set == 0)
5789     {
5790       errmsg ("missing addresses\n");
5791       return -99;
5792     }
5793
5794   if (address_length_set == 0)
5795     {
5796       errmsg ("missing address length\n");
5797       return -99;
5798     }
5799
5800   /* Generate a pile of unique, random routes */
5801   if (random_add_del)
5802     {
5803       u32 this_random_address;
5804       random_hash = hash_create (count, sizeof (uword));
5805
5806       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5807       for (j = 0; j <= count; j++)
5808         {
5809           do
5810             {
5811               this_random_address = random_u32 (&random_seed);
5812               this_random_address =
5813                 clib_host_to_net_u32 (this_random_address);
5814             }
5815           while (hash_get (random_hash, this_random_address));
5816           vec_add1 (random_vector, this_random_address);
5817           hash_set (random_hash, this_random_address, 1);
5818         }
5819       hash_free (random_hash);
5820       v4_dst_address.as_u32 = random_vector[0];
5821     }
5822
5823   if (count > 1)
5824     {
5825       /* Turn on async mode */
5826       vam->async_mode = 1;
5827       vam->async_errors = 0;
5828       before = vat_time_now (vam);
5829     }
5830
5831   for (j = 0; j < count; j++)
5832     {
5833       /* Construct the API message */
5834       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5835
5836       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5837       mp->vrf_id = ntohl (vrf_id);
5838       if (resolve_attempts > 0)
5839         {
5840           mp->resolve_attempts = ntohl (resolve_attempts);
5841           mp->resolve_if_needed = 1;
5842         }
5843       mp->create_vrf_if_needed = create_vrf_if_needed;
5844
5845       mp->is_add = is_add;
5846       mp->is_drop = is_drop;
5847       mp->is_ipv6 = is_ipv6;
5848       mp->is_local = is_local;
5849       mp->is_classify = is_classify;
5850       mp->is_multipath = is_multipath;
5851       mp->is_resolve_host = resolve_host;
5852       mp->is_resolve_attached = resolve_attached;
5853       mp->not_last = not_last;
5854       mp->next_hop_weight = next_hop_weight;
5855       mp->dst_address_length = dst_address_length;
5856       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5857       mp->classify_table_index = ntohl (classify_table_index);
5858
5859       if (is_ipv6)
5860         {
5861           clib_memcpy (mp->dst_address, &v6_dst_address,
5862                        sizeof (v6_dst_address));
5863           if (next_hop_set)
5864             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5865                          sizeof (v6_next_hop_address));
5866           increment_v6_address (&v6_dst_address);
5867         }
5868       else
5869         {
5870           clib_memcpy (mp->dst_address, &v4_dst_address,
5871                        sizeof (v4_dst_address));
5872           if (next_hop_set)
5873             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5874                          sizeof (v4_next_hop_address));
5875           if (random_add_del)
5876             v4_dst_address.as_u32 = random_vector[j + 1];
5877           else
5878             increment_v4_address (&v4_dst_address);
5879         }
5880       /* send it... */
5881       S;
5882       /* If we receive SIGTERM, stop now... */
5883       if (vam->do_exit)
5884         break;
5885     }
5886
5887   /* When testing multiple add/del ops, use a control-ping to sync */
5888   if (count > 1)
5889     {
5890       vl_api_control_ping_t *mp;
5891       f64 after;
5892
5893       /* Shut off async mode */
5894       vam->async_mode = 0;
5895
5896       M (CONTROL_PING, control_ping);
5897       S;
5898
5899       timeout = vat_time_now (vam) + 1.0;
5900       while (vat_time_now (vam) < timeout)
5901         if (vam->result_ready == 1)
5902           goto out;
5903       vam->retval = -99;
5904
5905     out:
5906       if (vam->retval == -99)
5907         errmsg ("timeout\n");
5908
5909       if (vam->async_errors > 0)
5910         {
5911           errmsg ("%d asynchronous errors\n", vam->async_errors);
5912           vam->retval = -98;
5913         }
5914       vam->async_errors = 0;
5915       after = vat_time_now (vam);
5916
5917       /* slim chance, but we might have eaten SIGTERM on the first iteration */
5918       if (j > 0)
5919         count = j;
5920
5921       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5922                count, after - before, count / (after - before));
5923     }
5924   else
5925     {
5926       /* Wait for a reply... */
5927       W;
5928     }
5929
5930   /* Return the good/bad news */
5931   return (vam->retval);
5932 }
5933
5934 static int
5935 api_proxy_arp_add_del (vat_main_t * vam)
5936 {
5937   unformat_input_t *i = vam->input;
5938   vl_api_proxy_arp_add_del_t *mp;
5939   f64 timeout;
5940   u32 vrf_id = 0;
5941   u8 is_add = 1;
5942   ip4_address_t lo, hi;
5943   u8 range_set = 0;
5944
5945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5946     {
5947       if (unformat (i, "vrf %d", &vrf_id))
5948         ;
5949       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5950                          unformat_ip4_address, &hi))
5951         range_set = 1;
5952       else if (unformat (i, "del"))
5953         is_add = 0;
5954       else
5955         {
5956           clib_warning ("parse error '%U'", format_unformat_error, i);
5957           return -99;
5958         }
5959     }
5960
5961   if (range_set == 0)
5962     {
5963       errmsg ("address range not set\n");
5964       return -99;
5965     }
5966
5967   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5968
5969   mp->vrf_id = ntohl (vrf_id);
5970   mp->is_add = is_add;
5971   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5972   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5973
5974   S;
5975   W;
5976   /* NOTREACHED */
5977   return 0;
5978 }
5979
5980 static int
5981 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5982 {
5983   unformat_input_t *i = vam->input;
5984   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5985   f64 timeout;
5986   u32 sw_if_index;
5987   u8 enable = 1;
5988   u8 sw_if_index_set = 0;
5989
5990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5991     {
5992       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5993         sw_if_index_set = 1;
5994       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5995         sw_if_index_set = 1;
5996       else if (unformat (i, "enable"))
5997         enable = 1;
5998       else if (unformat (i, "disable"))
5999         enable = 0;
6000       else
6001         {
6002           clib_warning ("parse error '%U'", format_unformat_error, i);
6003           return -99;
6004         }
6005     }
6006
6007   if (sw_if_index_set == 0)
6008     {
6009       errmsg ("missing interface name or sw_if_index\n");
6010       return -99;
6011     }
6012
6013   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6014
6015   mp->sw_if_index = ntohl (sw_if_index);
6016   mp->enable_disable = enable;
6017
6018   S;
6019   W;
6020   /* NOTREACHED */
6021   return 0;
6022 }
6023
6024 static int
6025 api_mpls_add_del_decap (vat_main_t * vam)
6026 {
6027   unformat_input_t *i = vam->input;
6028   vl_api_mpls_add_del_decap_t *mp;
6029   f64 timeout;
6030   u32 rx_vrf_id = 0;
6031   u32 tx_vrf_id = 0;
6032   u32 label = 0;
6033   u8 is_add = 1;
6034   u8 s_bit = 1;
6035   u32 next_index = 1;
6036
6037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6038     {
6039       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6040         ;
6041       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
6042         ;
6043       else if (unformat (i, "label %d", &label))
6044         ;
6045       else if (unformat (i, "next-index %d", &next_index))
6046         ;
6047       else if (unformat (i, "del"))
6048         is_add = 0;
6049       else if (unformat (i, "s-bit-clear"))
6050         s_bit = 0;
6051       else
6052         {
6053           clib_warning ("parse error '%U'", format_unformat_error, i);
6054           return -99;
6055         }
6056     }
6057
6058   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
6059
6060   mp->rx_vrf_id = ntohl (rx_vrf_id);
6061   mp->tx_vrf_id = ntohl (tx_vrf_id);
6062   mp->label = ntohl (label);
6063   mp->next_index = ntohl (next_index);
6064   mp->s_bit = s_bit;
6065   mp->is_add = is_add;
6066
6067   S;
6068   W;
6069   /* NOTREACHED */
6070   return 0;
6071 }
6072
6073 static int
6074 api_mpls_add_del_encap (vat_main_t * vam)
6075 {
6076   unformat_input_t *i = vam->input;
6077   vl_api_mpls_add_del_encap_t *mp;
6078   f64 timeout;
6079   u32 vrf_id = 0;
6080   u32 *labels = 0;
6081   u32 label;
6082   ip4_address_t dst_address;
6083   u8 is_add = 1;
6084
6085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6086     {
6087       if (unformat (i, "vrf %d", &vrf_id))
6088         ;
6089       else if (unformat (i, "label %d", &label))
6090         vec_add1 (labels, ntohl (label));
6091       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6092         ;
6093       else if (unformat (i, "del"))
6094         is_add = 0;
6095       else
6096         {
6097           clib_warning ("parse error '%U'", format_unformat_error, i);
6098           return -99;
6099         }
6100     }
6101
6102   if (vec_len (labels) == 0)
6103     {
6104       errmsg ("missing encap label stack\n");
6105       return -99;
6106     }
6107
6108   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6109       sizeof (u32) * vec_len (labels));
6110
6111   mp->vrf_id = ntohl (vrf_id);
6112   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6113   mp->is_add = is_add;
6114   mp->nlabels = vec_len (labels);
6115   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6116
6117   vec_free (labels);
6118
6119   S;
6120   W;
6121   /* NOTREACHED */
6122   return 0;
6123 }
6124
6125 static int
6126 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
6127 {
6128   unformat_input_t *i = vam->input;
6129   vl_api_mpls_gre_add_del_tunnel_t *mp;
6130   f64 timeout;
6131   u32 inner_vrf_id = 0;
6132   u32 outer_vrf_id = 0;
6133   ip4_address_t src_address;
6134   ip4_address_t dst_address;
6135   ip4_address_t intfc_address;
6136   u32 tmp;
6137   u8 intfc_address_length = 0;
6138   u8 is_add = 1;
6139   u8 l2_only = 0;
6140
6141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6142     {
6143       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6144         ;
6145       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6146         ;
6147       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
6148         ;
6149       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6150         ;
6151       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6152                          &intfc_address, &tmp))
6153         intfc_address_length = tmp;
6154       else if (unformat (i, "l2-only"))
6155         l2_only = 1;
6156       else if (unformat (i, "del"))
6157         is_add = 0;
6158       else
6159         {
6160           clib_warning ("parse error '%U'", format_unformat_error, i);
6161           return -99;
6162         }
6163     }
6164
6165   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
6166
6167   mp->inner_vrf_id = ntohl (inner_vrf_id);
6168   mp->outer_vrf_id = ntohl (outer_vrf_id);
6169   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
6170   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6171   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
6172   mp->intfc_address_length = intfc_address_length;
6173   mp->l2_only = l2_only;
6174   mp->is_add = is_add;
6175
6176   S;
6177   W;
6178   /* NOTREACHED */
6179   return 0;
6180 }
6181
6182 static int
6183 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6184 {
6185   unformat_input_t *i = vam->input;
6186   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6187   f64 timeout;
6188   u32 inner_vrf_id = 0;
6189   ip4_address_t intfc_address;
6190   u8 dst_mac_address[6];
6191   int dst_set = 1;
6192   u32 tmp;
6193   u8 intfc_address_length = 0;
6194   u8 is_add = 1;
6195   u8 l2_only = 0;
6196   u32 tx_sw_if_index;
6197   int tx_sw_if_index_set = 0;
6198
6199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6200     {
6201       if (unformat (i, "vrf %d", &inner_vrf_id))
6202         ;
6203       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6204                          &intfc_address, &tmp))
6205         intfc_address_length = tmp;
6206       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6207         tx_sw_if_index_set = 1;
6208       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6209         tx_sw_if_index_set = 1;
6210       else if (unformat (i, "dst %U", unformat_ethernet_address,
6211                          dst_mac_address))
6212         dst_set = 1;
6213       else if (unformat (i, "l2-only"))
6214         l2_only = 1;
6215       else if (unformat (i, "del"))
6216         is_add = 0;
6217       else
6218         {
6219           clib_warning ("parse error '%U'", format_unformat_error, i);
6220           return -99;
6221         }
6222     }
6223
6224   if (!dst_set)
6225     {
6226       errmsg ("dst (mac address) not set\n");
6227       return -99;
6228     }
6229   if (!tx_sw_if_index_set)
6230     {
6231       errmsg ("tx-intfc not set\n");
6232       return -99;
6233     }
6234
6235   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6236
6237   mp->vrf_id = ntohl (inner_vrf_id);
6238   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6239   mp->adj_address_length = intfc_address_length;
6240   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6241                sizeof (dst_mac_address));
6242   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6243   mp->l2_only = l2_only;
6244   mp->is_add = is_add;
6245
6246   S;
6247   W;
6248   /* NOTREACHED */
6249   return 0;
6250 }
6251
6252 static int
6253 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6254 {
6255   unformat_input_t *i = vam->input;
6256   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6257   f64 timeout;
6258   u32 inner_vrf_id = 0;
6259   u32 outer_vrf_id = 0;
6260   ip4_address_t adj_address;
6261   int adj_address_set = 0;
6262   ip4_address_t next_hop_address;
6263   int next_hop_address_set = 0;
6264   u32 tmp;
6265   u8 adj_address_length = 0;
6266   u8 l2_only = 0;
6267   u8 is_add = 1;
6268   u32 resolve_attempts = 5;
6269   u8 resolve_if_needed = 1;
6270
6271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6272     {
6273       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6274         ;
6275       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6276         ;
6277       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6278                          &adj_address, &tmp))
6279         {
6280           adj_address_length = tmp;
6281           adj_address_set = 1;
6282         }
6283       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6284                          &next_hop_address))
6285         next_hop_address_set = 1;
6286       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6287         ;
6288       else if (unformat (i, "resolve-if-needed %d", &tmp))
6289         resolve_if_needed = tmp;
6290       else if (unformat (i, "l2-only"))
6291         l2_only = 1;
6292       else if (unformat (i, "del"))
6293         is_add = 0;
6294       else
6295         {
6296           clib_warning ("parse error '%U'", format_unformat_error, i);
6297           return -99;
6298         }
6299     }
6300
6301   if (!adj_address_set)
6302     {
6303       errmsg ("adjacency address/mask not set\n");
6304       return -99;
6305     }
6306   if (!next_hop_address_set)
6307     {
6308       errmsg ("ip4 next hop address (in outer fib) not set\n");
6309       return -99;
6310     }
6311
6312   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6313
6314   mp->inner_vrf_id = ntohl (inner_vrf_id);
6315   mp->outer_vrf_id = ntohl (outer_vrf_id);
6316   mp->resolve_attempts = ntohl (resolve_attempts);
6317   mp->resolve_if_needed = resolve_if_needed;
6318   mp->is_add = is_add;
6319   mp->l2_only = l2_only;
6320   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6321   mp->adj_address_length = adj_address_length;
6322   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6323                sizeof (next_hop_address));
6324
6325   S;
6326   W;
6327   /* NOTREACHED */
6328   return 0;
6329 }
6330
6331 static int
6332 api_sw_interface_set_unnumbered (vat_main_t * vam)
6333 {
6334   unformat_input_t *i = vam->input;
6335   vl_api_sw_interface_set_unnumbered_t *mp;
6336   f64 timeout;
6337   u32 sw_if_index;
6338   u32 unnum_sw_index = ~0;
6339   u8 is_add = 1;
6340   u8 sw_if_index_set = 0;
6341
6342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6343     {
6344       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6345         sw_if_index_set = 1;
6346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6347         sw_if_index_set = 1;
6348       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6349         ;
6350       else if (unformat (i, "del"))
6351         is_add = 0;
6352       else
6353         {
6354           clib_warning ("parse error '%U'", format_unformat_error, i);
6355           return -99;
6356         }
6357     }
6358
6359   if (sw_if_index_set == 0)
6360     {
6361       errmsg ("missing interface name or sw_if_index\n");
6362       return -99;
6363     }
6364
6365   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6366
6367   mp->sw_if_index = ntohl (sw_if_index);
6368   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6369   mp->is_add = is_add;
6370
6371   S;
6372   W;
6373   /* NOTREACHED */
6374   return 0;
6375 }
6376
6377 static int
6378 api_ip_neighbor_add_del (vat_main_t * vam)
6379 {
6380   unformat_input_t *i = vam->input;
6381   vl_api_ip_neighbor_add_del_t *mp;
6382   f64 timeout;
6383   u32 sw_if_index;
6384   u8 sw_if_index_set = 0;
6385   u32 vrf_id = 0;
6386   u8 is_add = 1;
6387   u8 is_static = 0;
6388   u8 mac_address[6];
6389   u8 mac_set = 0;
6390   u8 v4_address_set = 0;
6391   u8 v6_address_set = 0;
6392   ip4_address_t v4address;
6393   ip6_address_t v6address;
6394
6395   memset (mac_address, 0, sizeof (mac_address));
6396
6397   /* Parse args required to build the message */
6398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6399     {
6400       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6401         {
6402           mac_set = 1;
6403         }
6404       else if (unformat (i, "del"))
6405         is_add = 0;
6406       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6407         sw_if_index_set = 1;
6408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6409         sw_if_index_set = 1;
6410       else if (unformat (i, "is_static"))
6411         is_static = 1;
6412       else if (unformat (i, "vrf %d", &vrf_id))
6413         ;
6414       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6415         v4_address_set = 1;
6416       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6417         v6_address_set = 1;
6418       else
6419         {
6420           clib_warning ("parse error '%U'", format_unformat_error, i);
6421           return -99;
6422         }
6423     }
6424
6425   if (sw_if_index_set == 0)
6426     {
6427       errmsg ("missing interface name or sw_if_index\n");
6428       return -99;
6429     }
6430   if (v4_address_set && v6_address_set)
6431     {
6432       errmsg ("both v4 and v6 addresses set\n");
6433       return -99;
6434     }
6435   if (!v4_address_set && !v6_address_set)
6436     {
6437       errmsg ("no address set\n");
6438       return -99;
6439     }
6440
6441   /* Construct the API message */
6442   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6443
6444   mp->sw_if_index = ntohl (sw_if_index);
6445   mp->is_add = is_add;
6446   mp->vrf_id = ntohl (vrf_id);
6447   mp->is_static = is_static;
6448   if (mac_set)
6449     clib_memcpy (mp->mac_address, mac_address, 6);
6450   if (v6_address_set)
6451     {
6452       mp->is_ipv6 = 1;
6453       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6454     }
6455   else
6456     {
6457       /* mp->is_ipv6 = 0; via memset in M macro above */
6458       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6459     }
6460
6461   /* send it... */
6462   S;
6463
6464   /* Wait for a reply, return good/bad news  */
6465   W;
6466
6467   /* NOTREACHED */
6468   return 0;
6469 }
6470
6471 static int
6472 api_reset_vrf (vat_main_t * vam)
6473 {
6474   unformat_input_t *i = vam->input;
6475   vl_api_reset_vrf_t *mp;
6476   f64 timeout;
6477   u32 vrf_id = 0;
6478   u8 is_ipv6 = 0;
6479   u8 vrf_id_set = 0;
6480
6481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6482     {
6483       if (unformat (i, "vrf %d", &vrf_id))
6484         vrf_id_set = 1;
6485       else if (unformat (i, "ipv6"))
6486         is_ipv6 = 1;
6487       else
6488         {
6489           clib_warning ("parse error '%U'", format_unformat_error, i);
6490           return -99;
6491         }
6492     }
6493
6494   if (vrf_id_set == 0)
6495     {
6496       errmsg ("missing vrf id\n");
6497       return -99;
6498     }
6499
6500   M (RESET_VRF, reset_vrf);
6501
6502   mp->vrf_id = ntohl (vrf_id);
6503   mp->is_ipv6 = is_ipv6;
6504
6505   S;
6506   W;
6507   /* NOTREACHED */
6508   return 0;
6509 }
6510
6511 static int
6512 api_create_vlan_subif (vat_main_t * vam)
6513 {
6514   unformat_input_t *i = vam->input;
6515   vl_api_create_vlan_subif_t *mp;
6516   f64 timeout;
6517   u32 sw_if_index;
6518   u8 sw_if_index_set = 0;
6519   u32 vlan_id;
6520   u8 vlan_id_set = 0;
6521
6522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6523     {
6524       if (unformat (i, "sw_if_index %d", &sw_if_index))
6525         sw_if_index_set = 1;
6526       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6527         sw_if_index_set = 1;
6528       else if (unformat (i, "vlan %d", &vlan_id))
6529         vlan_id_set = 1;
6530       else
6531         {
6532           clib_warning ("parse error '%U'", format_unformat_error, i);
6533           return -99;
6534         }
6535     }
6536
6537   if (sw_if_index_set == 0)
6538     {
6539       errmsg ("missing interface name or sw_if_index\n");
6540       return -99;
6541     }
6542
6543   if (vlan_id_set == 0)
6544     {
6545       errmsg ("missing vlan_id\n");
6546       return -99;
6547     }
6548   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6549
6550   mp->sw_if_index = ntohl (sw_if_index);
6551   mp->vlan_id = ntohl (vlan_id);
6552
6553   S;
6554   W;
6555   /* NOTREACHED */
6556   return 0;
6557 }
6558
6559 #define foreach_create_subif_bit                \
6560 _(no_tags)                                      \
6561 _(one_tag)                                      \
6562 _(two_tags)                                     \
6563 _(dot1ad)                                       \
6564 _(exact_match)                                  \
6565 _(default_sub)                                  \
6566 _(outer_vlan_id_any)                            \
6567 _(inner_vlan_id_any)
6568
6569 static int
6570 api_create_subif (vat_main_t * vam)
6571 {
6572   unformat_input_t *i = vam->input;
6573   vl_api_create_subif_t *mp;
6574   f64 timeout;
6575   u32 sw_if_index;
6576   u8 sw_if_index_set = 0;
6577   u32 sub_id;
6578   u8 sub_id_set = 0;
6579   u32 no_tags = 0;
6580   u32 one_tag = 0;
6581   u32 two_tags = 0;
6582   u32 dot1ad = 0;
6583   u32 exact_match = 0;
6584   u32 default_sub = 0;
6585   u32 outer_vlan_id_any = 0;
6586   u32 inner_vlan_id_any = 0;
6587   u32 tmp;
6588   u16 outer_vlan_id = 0;
6589   u16 inner_vlan_id = 0;
6590
6591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6592     {
6593       if (unformat (i, "sw_if_index %d", &sw_if_index))
6594         sw_if_index_set = 1;
6595       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "sub_id %d", &sub_id))
6598         sub_id_set = 1;
6599       else if (unformat (i, "outer_vlan_id %d", &tmp))
6600         outer_vlan_id = tmp;
6601       else if (unformat (i, "inner_vlan_id %d", &tmp))
6602         inner_vlan_id = tmp;
6603
6604 #define _(a) else if (unformat (i, #a)) a = 1 ;
6605       foreach_create_subif_bit
6606 #undef _
6607         else
6608         {
6609           clib_warning ("parse error '%U'", format_unformat_error, i);
6610           return -99;
6611         }
6612     }
6613
6614   if (sw_if_index_set == 0)
6615     {
6616       errmsg ("missing interface name or sw_if_index\n");
6617       return -99;
6618     }
6619
6620   if (sub_id_set == 0)
6621     {
6622       errmsg ("missing sub_id\n");
6623       return -99;
6624     }
6625   M (CREATE_SUBIF, create_subif);
6626
6627   mp->sw_if_index = ntohl (sw_if_index);
6628   mp->sub_id = ntohl (sub_id);
6629
6630 #define _(a) mp->a = a;
6631   foreach_create_subif_bit;
6632 #undef _
6633
6634   mp->outer_vlan_id = ntohs (outer_vlan_id);
6635   mp->inner_vlan_id = ntohs (inner_vlan_id);
6636
6637   S;
6638   W;
6639   /* NOTREACHED */
6640   return 0;
6641 }
6642
6643 static int
6644 api_oam_add_del (vat_main_t * vam)
6645 {
6646   unformat_input_t *i = vam->input;
6647   vl_api_oam_add_del_t *mp;
6648   f64 timeout;
6649   u32 vrf_id = 0;
6650   u8 is_add = 1;
6651   ip4_address_t src, dst;
6652   u8 src_set = 0;
6653   u8 dst_set = 0;
6654
6655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6656     {
6657       if (unformat (i, "vrf %d", &vrf_id))
6658         ;
6659       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6660         src_set = 1;
6661       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6662         dst_set = 1;
6663       else if (unformat (i, "del"))
6664         is_add = 0;
6665       else
6666         {
6667           clib_warning ("parse error '%U'", format_unformat_error, i);
6668           return -99;
6669         }
6670     }
6671
6672   if (src_set == 0)
6673     {
6674       errmsg ("missing src addr\n");
6675       return -99;
6676     }
6677
6678   if (dst_set == 0)
6679     {
6680       errmsg ("missing dst addr\n");
6681       return -99;
6682     }
6683
6684   M (OAM_ADD_DEL, oam_add_del);
6685
6686   mp->vrf_id = ntohl (vrf_id);
6687   mp->is_add = is_add;
6688   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6689   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6690
6691   S;
6692   W;
6693   /* NOTREACHED */
6694   return 0;
6695 }
6696
6697 static int
6698 api_reset_fib (vat_main_t * vam)
6699 {
6700   unformat_input_t *i = vam->input;
6701   vl_api_reset_fib_t *mp;
6702   f64 timeout;
6703   u32 vrf_id = 0;
6704   u8 is_ipv6 = 0;
6705   u8 vrf_id_set = 0;
6706
6707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6708     {
6709       if (unformat (i, "vrf %d", &vrf_id))
6710         vrf_id_set = 1;
6711       else if (unformat (i, "ipv6"))
6712         is_ipv6 = 1;
6713       else
6714         {
6715           clib_warning ("parse error '%U'", format_unformat_error, i);
6716           return -99;
6717         }
6718     }
6719
6720   if (vrf_id_set == 0)
6721     {
6722       errmsg ("missing vrf id\n");
6723       return -99;
6724     }
6725
6726   M (RESET_FIB, reset_fib);
6727
6728   mp->vrf_id = ntohl (vrf_id);
6729   mp->is_ipv6 = is_ipv6;
6730
6731   S;
6732   W;
6733   /* NOTREACHED */
6734   return 0;
6735 }
6736
6737 static int
6738 api_dhcp_proxy_config (vat_main_t * vam)
6739 {
6740   unformat_input_t *i = vam->input;
6741   vl_api_dhcp_proxy_config_t *mp;
6742   f64 timeout;
6743   u32 vrf_id = 0;
6744   u8 is_add = 1;
6745   u8 insert_cid = 1;
6746   u8 v4_address_set = 0;
6747   u8 v6_address_set = 0;
6748   ip4_address_t v4address;
6749   ip6_address_t v6address;
6750   u8 v4_src_address_set = 0;
6751   u8 v6_src_address_set = 0;
6752   ip4_address_t v4srcaddress;
6753   ip6_address_t v6srcaddress;
6754
6755   /* Parse args required to build the message */
6756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6757     {
6758       if (unformat (i, "del"))
6759         is_add = 0;
6760       else if (unformat (i, "vrf %d", &vrf_id))
6761         ;
6762       else if (unformat (i, "insert-cid %d", &insert_cid))
6763         ;
6764       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6765         v4_address_set = 1;
6766       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6767         v6_address_set = 1;
6768       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6769         v4_src_address_set = 1;
6770       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6771         v6_src_address_set = 1;
6772       else
6773         break;
6774     }
6775
6776   if (v4_address_set && v6_address_set)
6777     {
6778       errmsg ("both v4 and v6 server addresses set\n");
6779       return -99;
6780     }
6781   if (!v4_address_set && !v6_address_set)
6782     {
6783       errmsg ("no server addresses set\n");
6784       return -99;
6785     }
6786
6787   if (v4_src_address_set && v6_src_address_set)
6788     {
6789       errmsg ("both v4 and v6  src addresses set\n");
6790       return -99;
6791     }
6792   if (!v4_src_address_set && !v6_src_address_set)
6793     {
6794       errmsg ("no src addresses set\n");
6795       return -99;
6796     }
6797
6798   if (!(v4_src_address_set && v4_address_set) &&
6799       !(v6_src_address_set && v6_address_set))
6800     {
6801       errmsg ("no matching server and src addresses set\n");
6802       return -99;
6803     }
6804
6805   /* Construct the API message */
6806   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6807
6808   mp->insert_circuit_id = insert_cid;
6809   mp->is_add = is_add;
6810   mp->vrf_id = ntohl (vrf_id);
6811   if (v6_address_set)
6812     {
6813       mp->is_ipv6 = 1;
6814       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6815       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6816     }
6817   else
6818     {
6819       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6820       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6821     }
6822
6823   /* send it... */
6824   S;
6825
6826   /* Wait for a reply, return good/bad news  */
6827   W;
6828   /* NOTREACHED */
6829   return 0;
6830 }
6831
6832 static int
6833 api_dhcp_proxy_config_2 (vat_main_t * vam)
6834 {
6835   unformat_input_t *i = vam->input;
6836   vl_api_dhcp_proxy_config_2_t *mp;
6837   f64 timeout;
6838   u32 rx_vrf_id = 0;
6839   u32 server_vrf_id = 0;
6840   u8 is_add = 1;
6841   u8 insert_cid = 1;
6842   u8 v4_address_set = 0;
6843   u8 v6_address_set = 0;
6844   ip4_address_t v4address;
6845   ip6_address_t v6address;
6846   u8 v4_src_address_set = 0;
6847   u8 v6_src_address_set = 0;
6848   ip4_address_t v4srcaddress;
6849   ip6_address_t v6srcaddress;
6850
6851   /* Parse args required to build the message */
6852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6853     {
6854       if (unformat (i, "del"))
6855         is_add = 0;
6856       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6857         ;
6858       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6859         ;
6860       else if (unformat (i, "insert-cid %d", &insert_cid))
6861         ;
6862       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6863         v4_address_set = 1;
6864       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6865         v6_address_set = 1;
6866       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6867         v4_src_address_set = 1;
6868       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6869         v6_src_address_set = 1;
6870       else
6871         break;
6872     }
6873
6874   if (v4_address_set && v6_address_set)
6875     {
6876       errmsg ("both v4 and v6 server addresses set\n");
6877       return -99;
6878     }
6879   if (!v4_address_set && !v6_address_set)
6880     {
6881       errmsg ("no server addresses set\n");
6882       return -99;
6883     }
6884
6885   if (v4_src_address_set && v6_src_address_set)
6886     {
6887       errmsg ("both v4 and v6  src addresses set\n");
6888       return -99;
6889     }
6890   if (!v4_src_address_set && !v6_src_address_set)
6891     {
6892       errmsg ("no src addresses set\n");
6893       return -99;
6894     }
6895
6896   if (!(v4_src_address_set && v4_address_set) &&
6897       !(v6_src_address_set && v6_address_set))
6898     {
6899       errmsg ("no matching server and src addresses set\n");
6900       return -99;
6901     }
6902
6903   /* Construct the API message */
6904   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6905
6906   mp->insert_circuit_id = insert_cid;
6907   mp->is_add = is_add;
6908   mp->rx_vrf_id = ntohl (rx_vrf_id);
6909   mp->server_vrf_id = ntohl (server_vrf_id);
6910   if (v6_address_set)
6911     {
6912       mp->is_ipv6 = 1;
6913       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6914       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6915     }
6916   else
6917     {
6918       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6919       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6920     }
6921
6922   /* send it... */
6923   S;
6924
6925   /* Wait for a reply, return good/bad news  */
6926   W;
6927   /* NOTREACHED */
6928   return 0;
6929 }
6930
6931 static int
6932 api_dhcp_proxy_set_vss (vat_main_t * vam)
6933 {
6934   unformat_input_t *i = vam->input;
6935   vl_api_dhcp_proxy_set_vss_t *mp;
6936   f64 timeout;
6937   u8 is_ipv6 = 0;
6938   u8 is_add = 1;
6939   u32 tbl_id;
6940   u8 tbl_id_set = 0;
6941   u32 oui;
6942   u8 oui_set = 0;
6943   u32 fib_id;
6944   u8 fib_id_set = 0;
6945
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "tbl_id %d", &tbl_id))
6949         tbl_id_set = 1;
6950       if (unformat (i, "fib_id %d", &fib_id))
6951         fib_id_set = 1;
6952       if (unformat (i, "oui %d", &oui))
6953         oui_set = 1;
6954       else if (unformat (i, "ipv6"))
6955         is_ipv6 = 1;
6956       else if (unformat (i, "del"))
6957         is_add = 0;
6958       else
6959         {
6960           clib_warning ("parse error '%U'", format_unformat_error, i);
6961           return -99;
6962         }
6963     }
6964
6965   if (tbl_id_set == 0)
6966     {
6967       errmsg ("missing tbl id\n");
6968       return -99;
6969     }
6970
6971   if (fib_id_set == 0)
6972     {
6973       errmsg ("missing fib id\n");
6974       return -99;
6975     }
6976   if (oui_set == 0)
6977     {
6978       errmsg ("missing oui\n");
6979       return -99;
6980     }
6981
6982   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6983   mp->tbl_id = ntohl (tbl_id);
6984   mp->fib_id = ntohl (fib_id);
6985   mp->oui = ntohl (oui);
6986   mp->is_ipv6 = is_ipv6;
6987   mp->is_add = is_add;
6988
6989   S;
6990   W;
6991   /* NOTREACHED */
6992   return 0;
6993 }
6994
6995 static int
6996 api_dhcp_client_config (vat_main_t * vam)
6997 {
6998   unformat_input_t *i = vam->input;
6999   vl_api_dhcp_client_config_t *mp;
7000   f64 timeout;
7001   u32 sw_if_index;
7002   u8 sw_if_index_set = 0;
7003   u8 is_add = 1;
7004   u8 *hostname = 0;
7005   u8 disable_event = 0;
7006
7007   /* Parse args required to build the message */
7008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7009     {
7010       if (unformat (i, "del"))
7011         is_add = 0;
7012       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7013         sw_if_index_set = 1;
7014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7015         sw_if_index_set = 1;
7016       else if (unformat (i, "hostname %s", &hostname))
7017         ;
7018       else if (unformat (i, "disable_event"))
7019         disable_event = 1;
7020       else
7021         break;
7022     }
7023
7024   if (sw_if_index_set == 0)
7025     {
7026       errmsg ("missing interface name or sw_if_index\n");
7027       return -99;
7028     }
7029
7030   if (vec_len (hostname) > 63)
7031     {
7032       errmsg ("hostname too long\n");
7033     }
7034   vec_add1 (hostname, 0);
7035
7036   /* Construct the API message */
7037   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7038
7039   mp->sw_if_index = ntohl (sw_if_index);
7040   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7041   vec_free (hostname);
7042   mp->is_add = is_add;
7043   mp->want_dhcp_event = disable_event ? 0 : 1;
7044   mp->pid = getpid ();
7045
7046   /* send it... */
7047   S;
7048
7049   /* Wait for a reply, return good/bad news  */
7050   W;
7051   /* NOTREACHED */
7052   return 0;
7053 }
7054
7055 static int
7056 api_set_ip_flow_hash (vat_main_t * vam)
7057 {
7058   unformat_input_t *i = vam->input;
7059   vl_api_set_ip_flow_hash_t *mp;
7060   f64 timeout;
7061   u32 vrf_id = 0;
7062   u8 is_ipv6 = 0;
7063   u8 vrf_id_set = 0;
7064   u8 src = 0;
7065   u8 dst = 0;
7066   u8 sport = 0;
7067   u8 dport = 0;
7068   u8 proto = 0;
7069   u8 reverse = 0;
7070
7071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7072     {
7073       if (unformat (i, "vrf %d", &vrf_id))
7074         vrf_id_set = 1;
7075       else if (unformat (i, "ipv6"))
7076         is_ipv6 = 1;
7077       else if (unformat (i, "src"))
7078         src = 1;
7079       else if (unformat (i, "dst"))
7080         dst = 1;
7081       else if (unformat (i, "sport"))
7082         sport = 1;
7083       else if (unformat (i, "dport"))
7084         dport = 1;
7085       else if (unformat (i, "proto"))
7086         proto = 1;
7087       else if (unformat (i, "reverse"))
7088         reverse = 1;
7089
7090       else
7091         {
7092           clib_warning ("parse error '%U'", format_unformat_error, i);
7093           return -99;
7094         }
7095     }
7096
7097   if (vrf_id_set == 0)
7098     {
7099       errmsg ("missing vrf id\n");
7100       return -99;
7101     }
7102
7103   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7104   mp->src = src;
7105   mp->dst = dst;
7106   mp->sport = sport;
7107   mp->dport = dport;
7108   mp->proto = proto;
7109   mp->reverse = reverse;
7110   mp->vrf_id = ntohl (vrf_id);
7111   mp->is_ipv6 = is_ipv6;
7112
7113   S;
7114   W;
7115   /* NOTREACHED */
7116   return 0;
7117 }
7118
7119 static int
7120 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7121 {
7122   unformat_input_t *i = vam->input;
7123   vl_api_sw_interface_ip6_enable_disable_t *mp;
7124   f64 timeout;
7125   u32 sw_if_index;
7126   u8 sw_if_index_set = 0;
7127   u8 enable = 0;
7128
7129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7130     {
7131       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7132         sw_if_index_set = 1;
7133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7134         sw_if_index_set = 1;
7135       else if (unformat (i, "enable"))
7136         enable = 1;
7137       else if (unformat (i, "disable"))
7138         enable = 0;
7139       else
7140         {
7141           clib_warning ("parse error '%U'", format_unformat_error, i);
7142           return -99;
7143         }
7144     }
7145
7146   if (sw_if_index_set == 0)
7147     {
7148       errmsg ("missing interface name or sw_if_index\n");
7149       return -99;
7150     }
7151
7152   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7153
7154   mp->sw_if_index = ntohl (sw_if_index);
7155   mp->enable = enable;
7156
7157   S;
7158   W;
7159   /* NOTREACHED */
7160   return 0;
7161 }
7162
7163 static int
7164 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7165 {
7166   unformat_input_t *i = vam->input;
7167   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7168   f64 timeout;
7169   u32 sw_if_index;
7170   u8 sw_if_index_set = 0;
7171   u32 address_length = 0;
7172   u8 v6_address_set = 0;
7173   ip6_address_t v6address;
7174
7175   /* Parse args required to build the message */
7176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7177     {
7178       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7179         sw_if_index_set = 1;
7180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7181         sw_if_index_set = 1;
7182       else if (unformat (i, "%U/%d",
7183                          unformat_ip6_address, &v6address, &address_length))
7184         v6_address_set = 1;
7185       else
7186         break;
7187     }
7188
7189   if (sw_if_index_set == 0)
7190     {
7191       errmsg ("missing interface name or sw_if_index\n");
7192       return -99;
7193     }
7194   if (!v6_address_set)
7195     {
7196       errmsg ("no address set\n");
7197       return -99;
7198     }
7199
7200   /* Construct the API message */
7201   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7202      sw_interface_ip6_set_link_local_address);
7203
7204   mp->sw_if_index = ntohl (sw_if_index);
7205   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7206   mp->address_length = address_length;
7207
7208   /* send it... */
7209   S;
7210
7211   /* Wait for a reply, return good/bad news  */
7212   W;
7213
7214   /* NOTREACHED */
7215   return 0;
7216 }
7217
7218
7219 static int
7220 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7221 {
7222   unformat_input_t *i = vam->input;
7223   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7224   f64 timeout;
7225   u32 sw_if_index;
7226   u8 sw_if_index_set = 0;
7227   u32 address_length = 0;
7228   u8 v6_address_set = 0;
7229   ip6_address_t v6address;
7230   u8 use_default = 0;
7231   u8 no_advertise = 0;
7232   u8 off_link = 0;
7233   u8 no_autoconfig = 0;
7234   u8 no_onlink = 0;
7235   u8 is_no = 0;
7236   u32 val_lifetime = 0;
7237   u32 pref_lifetime = 0;
7238
7239   /* Parse args required to build the message */
7240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7241     {
7242       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7243         sw_if_index_set = 1;
7244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7245         sw_if_index_set = 1;
7246       else if (unformat (i, "%U/%d",
7247                          unformat_ip6_address, &v6address, &address_length))
7248         v6_address_set = 1;
7249       else if (unformat (i, "val_life %d", &val_lifetime))
7250         ;
7251       else if (unformat (i, "pref_life %d", &pref_lifetime))
7252         ;
7253       else if (unformat (i, "def"))
7254         use_default = 1;
7255       else if (unformat (i, "noadv"))
7256         no_advertise = 1;
7257       else if (unformat (i, "offl"))
7258         off_link = 1;
7259       else if (unformat (i, "noauto"))
7260         no_autoconfig = 1;
7261       else if (unformat (i, "nolink"))
7262         no_onlink = 1;
7263       else if (unformat (i, "isno"))
7264         is_no = 1;
7265       else
7266         {
7267           clib_warning ("parse error '%U'", format_unformat_error, i);
7268           return -99;
7269         }
7270     }
7271
7272   if (sw_if_index_set == 0)
7273     {
7274       errmsg ("missing interface name or sw_if_index\n");
7275       return -99;
7276     }
7277   if (!v6_address_set)
7278     {
7279       errmsg ("no address set\n");
7280       return -99;
7281     }
7282
7283   /* Construct the API message */
7284   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7285
7286   mp->sw_if_index = ntohl (sw_if_index);
7287   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7288   mp->address_length = address_length;
7289   mp->use_default = use_default;
7290   mp->no_advertise = no_advertise;
7291   mp->off_link = off_link;
7292   mp->no_autoconfig = no_autoconfig;
7293   mp->no_onlink = no_onlink;
7294   mp->is_no = is_no;
7295   mp->val_lifetime = ntohl (val_lifetime);
7296   mp->pref_lifetime = ntohl (pref_lifetime);
7297
7298   /* send it... */
7299   S;
7300
7301   /* Wait for a reply, return good/bad news  */
7302   W;
7303
7304   /* NOTREACHED */
7305   return 0;
7306 }
7307
7308 static int
7309 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7310 {
7311   unformat_input_t *i = vam->input;
7312   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7313   f64 timeout;
7314   u32 sw_if_index;
7315   u8 sw_if_index_set = 0;
7316   u8 suppress = 0;
7317   u8 managed = 0;
7318   u8 other = 0;
7319   u8 ll_option = 0;
7320   u8 send_unicast = 0;
7321   u8 cease = 0;
7322   u8 is_no = 0;
7323   u8 default_router = 0;
7324   u32 max_interval = 0;
7325   u32 min_interval = 0;
7326   u32 lifetime = 0;
7327   u32 initial_count = 0;
7328   u32 initial_interval = 0;
7329
7330
7331   /* Parse args required to build the message */
7332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7333     {
7334       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7335         sw_if_index_set = 1;
7336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7337         sw_if_index_set = 1;
7338       else if (unformat (i, "maxint %d", &max_interval))
7339         ;
7340       else if (unformat (i, "minint %d", &min_interval))
7341         ;
7342       else if (unformat (i, "life %d", &lifetime))
7343         ;
7344       else if (unformat (i, "count %d", &initial_count))
7345         ;
7346       else if (unformat (i, "interval %d", &initial_interval))
7347         ;
7348       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7349         suppress = 1;
7350       else if (unformat (i, "managed"))
7351         managed = 1;
7352       else if (unformat (i, "other"))
7353         other = 1;
7354       else if (unformat (i, "ll"))
7355         ll_option = 1;
7356       else if (unformat (i, "send"))
7357         send_unicast = 1;
7358       else if (unformat (i, "cease"))
7359         cease = 1;
7360       else if (unformat (i, "isno"))
7361         is_no = 1;
7362       else if (unformat (i, "def"))
7363         default_router = 1;
7364       else
7365         {
7366           clib_warning ("parse error '%U'", format_unformat_error, i);
7367           return -99;
7368         }
7369     }
7370
7371   if (sw_if_index_set == 0)
7372     {
7373       errmsg ("missing interface name or sw_if_index\n");
7374       return -99;
7375     }
7376
7377   /* Construct the API message */
7378   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7379
7380   mp->sw_if_index = ntohl (sw_if_index);
7381   mp->max_interval = ntohl (max_interval);
7382   mp->min_interval = ntohl (min_interval);
7383   mp->lifetime = ntohl (lifetime);
7384   mp->initial_count = ntohl (initial_count);
7385   mp->initial_interval = ntohl (initial_interval);
7386   mp->suppress = suppress;
7387   mp->managed = managed;
7388   mp->other = other;
7389   mp->ll_option = ll_option;
7390   mp->send_unicast = send_unicast;
7391   mp->cease = cease;
7392   mp->is_no = is_no;
7393   mp->default_router = default_router;
7394
7395   /* send it... */
7396   S;
7397
7398   /* Wait for a reply, return good/bad news  */
7399   W;
7400
7401   /* NOTREACHED */
7402   return 0;
7403 }
7404
7405 static int
7406 api_set_arp_neighbor_limit (vat_main_t * vam)
7407 {
7408   unformat_input_t *i = vam->input;
7409   vl_api_set_arp_neighbor_limit_t *mp;
7410   f64 timeout;
7411   u32 arp_nbr_limit;
7412   u8 limit_set = 0;
7413   u8 is_ipv6 = 0;
7414
7415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7416     {
7417       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7418         limit_set = 1;
7419       else if (unformat (i, "ipv6"))
7420         is_ipv6 = 1;
7421       else
7422         {
7423           clib_warning ("parse error '%U'", format_unformat_error, i);
7424           return -99;
7425         }
7426     }
7427
7428   if (limit_set == 0)
7429     {
7430       errmsg ("missing limit value\n");
7431       return -99;
7432     }
7433
7434   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7435
7436   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7437   mp->is_ipv6 = is_ipv6;
7438
7439   S;
7440   W;
7441   /* NOTREACHED */
7442   return 0;
7443 }
7444
7445 static int
7446 api_l2_patch_add_del (vat_main_t * vam)
7447 {
7448   unformat_input_t *i = vam->input;
7449   vl_api_l2_patch_add_del_t *mp;
7450   f64 timeout;
7451   u32 rx_sw_if_index;
7452   u8 rx_sw_if_index_set = 0;
7453   u32 tx_sw_if_index;
7454   u8 tx_sw_if_index_set = 0;
7455   u8 is_add = 1;
7456
7457   /* Parse args required to build the message */
7458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7459     {
7460       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7461         rx_sw_if_index_set = 1;
7462       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7463         tx_sw_if_index_set = 1;
7464       else if (unformat (i, "rx"))
7465         {
7466           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7467             {
7468               if (unformat (i, "%U", unformat_sw_if_index, vam,
7469                             &rx_sw_if_index))
7470                 rx_sw_if_index_set = 1;
7471             }
7472           else
7473             break;
7474         }
7475       else if (unformat (i, "tx"))
7476         {
7477           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7478             {
7479               if (unformat (i, "%U", unformat_sw_if_index, vam,
7480                             &tx_sw_if_index))
7481                 tx_sw_if_index_set = 1;
7482             }
7483           else
7484             break;
7485         }
7486       else if (unformat (i, "del"))
7487         is_add = 0;
7488       else
7489         break;
7490     }
7491
7492   if (rx_sw_if_index_set == 0)
7493     {
7494       errmsg ("missing rx interface name or rx_sw_if_index\n");
7495       return -99;
7496     }
7497
7498   if (tx_sw_if_index_set == 0)
7499     {
7500       errmsg ("missing tx interface name or tx_sw_if_index\n");
7501       return -99;
7502     }
7503
7504   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7505
7506   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7507   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7508   mp->is_add = is_add;
7509
7510   S;
7511   W;
7512   /* NOTREACHED */
7513   return 0;
7514 }
7515
7516 static int
7517 api_ioam_enable (vat_main_t * vam)
7518 {
7519   unformat_input_t *input = vam->input;
7520   vl_api_ioam_enable_t *mp;
7521   f64 timeout;
7522   u32 id = 0;
7523   int has_trace_option = 0;
7524   int has_pow_option = 0;
7525   int has_ppc_option = 0;
7526
7527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7528     {
7529       if (unformat (input, "trace"))
7530         has_trace_option = 1;
7531       else if (unformat (input, "pow"))
7532         has_pow_option = 1;
7533       else if (unformat (input, "ppc encap"))
7534         has_ppc_option = PPC_ENCAP;
7535       else if (unformat (input, "ppc decap"))
7536         has_ppc_option = PPC_DECAP;
7537       else if (unformat (input, "ppc none"))
7538         has_ppc_option = PPC_NONE;
7539       else
7540         break;
7541     }
7542   M (IOAM_ENABLE, ioam_enable);
7543   mp->id = htons (id);
7544   mp->trace_ppc = has_ppc_option;
7545   mp->pow_enable = has_pow_option;
7546   mp->trace_enable = has_trace_option;
7547
7548   S;
7549   W;
7550
7551   return (0);
7552
7553 }
7554
7555
7556 static int
7557 api_ioam_disable (vat_main_t * vam)
7558 {
7559   vl_api_ioam_disable_t *mp;
7560   f64 timeout;
7561
7562   M (IOAM_DISABLE, ioam_disable);
7563   S;
7564   W;
7565   return 0;
7566 }
7567
7568 static int
7569 api_sr_tunnel_add_del (vat_main_t * vam)
7570 {
7571   unformat_input_t *i = vam->input;
7572   vl_api_sr_tunnel_add_del_t *mp;
7573   f64 timeout;
7574   int is_del = 0;
7575   int pl_index;
7576   ip6_address_t src_address;
7577   int src_address_set = 0;
7578   ip6_address_t dst_address;
7579   u32 dst_mask_width;
7580   int dst_address_set = 0;
7581   u16 flags = 0;
7582   u32 rx_table_id = 0;
7583   u32 tx_table_id = 0;
7584   ip6_address_t *segments = 0;
7585   ip6_address_t *this_seg;
7586   ip6_address_t *tags = 0;
7587   ip6_address_t *this_tag;
7588   ip6_address_t next_address, tag;
7589   u8 *name = 0;
7590   u8 *policy_name = 0;
7591
7592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7593     {
7594       if (unformat (i, "del"))
7595         is_del = 1;
7596       else if (unformat (i, "name %s", &name))
7597         ;
7598       else if (unformat (i, "policy %s", &policy_name))
7599         ;
7600       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7601         ;
7602       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7603         ;
7604       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7605         src_address_set = 1;
7606       else if (unformat (i, "dst %U/%d",
7607                          unformat_ip6_address, &dst_address, &dst_mask_width))
7608         dst_address_set = 1;
7609       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7610         {
7611           vec_add2 (segments, this_seg, 1);
7612           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7613                        sizeof (*this_seg));
7614         }
7615       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7616         {
7617           vec_add2 (tags, this_tag, 1);
7618           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7619         }
7620       else if (unformat (i, "clean"))
7621         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7622       else if (unformat (i, "protected"))
7623         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7624       else if (unformat (i, "InPE %d", &pl_index))
7625         {
7626           if (pl_index <= 0 || pl_index > 4)
7627             {
7628             pl_index_range_error:
7629               errmsg ("pl index %d out of range\n", pl_index);
7630               return -99;
7631             }
7632           flags |=
7633             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7634         }
7635       else if (unformat (i, "EgPE %d", &pl_index))
7636         {
7637           if (pl_index <= 0 || pl_index > 4)
7638             goto pl_index_range_error;
7639           flags |=
7640             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7641         }
7642       else if (unformat (i, "OrgSrc %d", &pl_index))
7643         {
7644           if (pl_index <= 0 || pl_index > 4)
7645             goto pl_index_range_error;
7646           flags |=
7647             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7648         }
7649       else
7650         break;
7651     }
7652
7653   if (!src_address_set)
7654     {
7655       errmsg ("src address required\n");
7656       return -99;
7657     }
7658
7659   if (!dst_address_set)
7660     {
7661       errmsg ("dst address required\n");
7662       return -99;
7663     }
7664
7665   if (!segments)
7666     {
7667       errmsg ("at least one sr segment required\n");
7668       return -99;
7669     }
7670
7671   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7672       vec_len (segments) * sizeof (ip6_address_t)
7673       + vec_len (tags) * sizeof (ip6_address_t));
7674
7675   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7676   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7677   mp->dst_mask_width = dst_mask_width;
7678   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7679   mp->n_segments = vec_len (segments);
7680   mp->n_tags = vec_len (tags);
7681   mp->is_add = is_del == 0;
7682   clib_memcpy (mp->segs_and_tags, segments,
7683                vec_len (segments) * sizeof (ip6_address_t));
7684   clib_memcpy (mp->segs_and_tags +
7685                vec_len (segments) * sizeof (ip6_address_t), tags,
7686                vec_len (tags) * sizeof (ip6_address_t));
7687
7688   mp->outer_vrf_id = ntohl (rx_table_id);
7689   mp->inner_vrf_id = ntohl (tx_table_id);
7690   memcpy (mp->name, name, vec_len (name));
7691   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7692
7693   vec_free (segments);
7694   vec_free (tags);
7695
7696   S;
7697   W;
7698   /* NOTREACHED */
7699 }
7700
7701 static int
7702 api_sr_policy_add_del (vat_main_t * vam)
7703 {
7704   unformat_input_t *input = vam->input;
7705   vl_api_sr_policy_add_del_t *mp;
7706   f64 timeout;
7707   int is_del = 0;
7708   u8 *name = 0;
7709   u8 *tunnel_name = 0;
7710   u8 **tunnel_names = 0;
7711
7712   int name_set = 0;
7713   int tunnel_set = 0;
7714   int j = 0;
7715   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7716   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7717
7718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7719     {
7720       if (unformat (input, "del"))
7721         is_del = 1;
7722       else if (unformat (input, "name %s", &name))
7723         name_set = 1;
7724       else if (unformat (input, "tunnel %s", &tunnel_name))
7725         {
7726           if (tunnel_name)
7727             {
7728               vec_add1 (tunnel_names, tunnel_name);
7729               /* For serializer:
7730                  - length = #bytes to store in serial vector
7731                  - +1 = byte to store that length
7732                */
7733               tunnel_names_length += (vec_len (tunnel_name) + 1);
7734               tunnel_set = 1;
7735               tunnel_name = 0;
7736             }
7737         }
7738       else
7739         break;
7740     }
7741
7742   if (!name_set)
7743     {
7744       errmsg ("policy name required\n");
7745       return -99;
7746     }
7747
7748   if ((!tunnel_set) && (!is_del))
7749     {
7750       errmsg ("tunnel name required\n");
7751       return -99;
7752     }
7753
7754   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7755
7756
7757
7758   mp->is_add = !is_del;
7759
7760   memcpy (mp->name, name, vec_len (name));
7761   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7762   u8 *serial_orig = 0;
7763   vec_validate (serial_orig, tunnel_names_length);
7764   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7765   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7766
7767   for (j = 0; j < vec_len (tunnel_names); j++)
7768     {
7769       tun_name_len = vec_len (tunnel_names[j]);
7770       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7771       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7772       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7773       serial_orig += tun_name_len;      // Advance past the copy
7774     }
7775   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7776
7777   vec_free (tunnel_names);
7778   vec_free (tunnel_name);
7779
7780   S;
7781   W;
7782   /* NOTREACHED */
7783 }
7784
7785 static int
7786 api_sr_multicast_map_add_del (vat_main_t * vam)
7787 {
7788   unformat_input_t *input = vam->input;
7789   vl_api_sr_multicast_map_add_del_t *mp;
7790   f64 timeout;
7791   int is_del = 0;
7792   ip6_address_t multicast_address;
7793   u8 *policy_name = 0;
7794   int multicast_address_set = 0;
7795
7796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7797     {
7798       if (unformat (input, "del"))
7799         is_del = 1;
7800       else
7801         if (unformat
7802             (input, "address %U", unformat_ip6_address, &multicast_address))
7803         multicast_address_set = 1;
7804       else if (unformat (input, "sr-policy %s", &policy_name))
7805         ;
7806       else
7807         break;
7808     }
7809
7810   if (!is_del && !policy_name)
7811     {
7812       errmsg ("sr-policy name required\n");
7813       return -99;
7814     }
7815
7816
7817   if (!multicast_address_set)
7818     {
7819       errmsg ("address required\n");
7820       return -99;
7821     }
7822
7823   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7824
7825   mp->is_add = !is_del;
7826   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7827   clib_memcpy (mp->multicast_address, &multicast_address,
7828                sizeof (mp->multicast_address));
7829
7830
7831   vec_free (policy_name);
7832
7833   S;
7834   W;
7835   /* NOTREACHED */
7836 }
7837
7838
7839 #define foreach_ip4_proto_field                 \
7840 _(src_address)                                  \
7841 _(dst_address)                                  \
7842 _(tos)                                          \
7843 _(length)                                       \
7844 _(fragment_id)                                  \
7845 _(ttl)                                          \
7846 _(protocol)                                     \
7847 _(checksum)
7848
7849 uword
7850 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7851 {
7852   u8 **maskp = va_arg (*args, u8 **);
7853   u8 *mask = 0;
7854   u8 found_something = 0;
7855   ip4_header_t *ip;
7856
7857 #define _(a) u8 a=0;
7858   foreach_ip4_proto_field;
7859 #undef _
7860   u8 version = 0;
7861   u8 hdr_length = 0;
7862
7863
7864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7865     {
7866       if (unformat (input, "version"))
7867         version = 1;
7868       else if (unformat (input, "hdr_length"))
7869         hdr_length = 1;
7870       else if (unformat (input, "src"))
7871         src_address = 1;
7872       else if (unformat (input, "dst"))
7873         dst_address = 1;
7874       else if (unformat (input, "proto"))
7875         protocol = 1;
7876
7877 #define _(a) else if (unformat (input, #a)) a=1;
7878       foreach_ip4_proto_field
7879 #undef _
7880         else
7881         break;
7882     }
7883
7884 #define _(a) found_something += a;
7885   foreach_ip4_proto_field;
7886 #undef _
7887
7888   if (found_something == 0)
7889     return 0;
7890
7891   vec_validate (mask, sizeof (*ip) - 1);
7892
7893   ip = (ip4_header_t *) mask;
7894
7895 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7896   foreach_ip4_proto_field;
7897 #undef _
7898
7899   ip->ip_version_and_header_length = 0;
7900
7901   if (version)
7902     ip->ip_version_and_header_length |= 0xF0;
7903
7904   if (hdr_length)
7905     ip->ip_version_and_header_length |= 0x0F;
7906
7907   *maskp = mask;
7908   return 1;
7909 }
7910
7911 #define foreach_ip6_proto_field                 \
7912 _(src_address)                                  \
7913 _(dst_address)                                  \
7914 _(payload_length)                               \
7915 _(hop_limit)                                    \
7916 _(protocol)
7917
7918 uword
7919 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7920 {
7921   u8 **maskp = va_arg (*args, u8 **);
7922   u8 *mask = 0;
7923   u8 found_something = 0;
7924   ip6_header_t *ip;
7925   u32 ip_version_traffic_class_and_flow_label;
7926
7927 #define _(a) u8 a=0;
7928   foreach_ip6_proto_field;
7929 #undef _
7930   u8 version = 0;
7931   u8 traffic_class = 0;
7932   u8 flow_label = 0;
7933
7934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7935     {
7936       if (unformat (input, "version"))
7937         version = 1;
7938       else if (unformat (input, "traffic-class"))
7939         traffic_class = 1;
7940       else if (unformat (input, "flow-label"))
7941         flow_label = 1;
7942       else if (unformat (input, "src"))
7943         src_address = 1;
7944       else if (unformat (input, "dst"))
7945         dst_address = 1;
7946       else if (unformat (input, "proto"))
7947         protocol = 1;
7948
7949 #define _(a) else if (unformat (input, #a)) a=1;
7950       foreach_ip6_proto_field
7951 #undef _
7952         else
7953         break;
7954     }
7955
7956 #define _(a) found_something += a;
7957   foreach_ip6_proto_field;
7958 #undef _
7959
7960   if (found_something == 0)
7961     return 0;
7962
7963   vec_validate (mask, sizeof (*ip) - 1);
7964
7965   ip = (ip6_header_t *) mask;
7966
7967 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7968   foreach_ip6_proto_field;
7969 #undef _
7970
7971   ip_version_traffic_class_and_flow_label = 0;
7972
7973   if (version)
7974     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7975
7976   if (traffic_class)
7977     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7978
7979   if (flow_label)
7980     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7981
7982   ip->ip_version_traffic_class_and_flow_label =
7983     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7984
7985   *maskp = mask;
7986   return 1;
7987 }
7988
7989 uword
7990 unformat_l3_mask (unformat_input_t * input, va_list * args)
7991 {
7992   u8 **maskp = va_arg (*args, u8 **);
7993
7994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7995     {
7996       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7997         return 1;
7998       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7999         return 1;
8000       else
8001         break;
8002     }
8003   return 0;
8004 }
8005
8006 uword
8007 unformat_l2_mask (unformat_input_t * input, va_list * args)
8008 {
8009   u8 **maskp = va_arg (*args, u8 **);
8010   u8 *mask = 0;
8011   u8 src = 0;
8012   u8 dst = 0;
8013   u8 proto = 0;
8014   u8 tag1 = 0;
8015   u8 tag2 = 0;
8016   u8 ignore_tag1 = 0;
8017   u8 ignore_tag2 = 0;
8018   u8 cos1 = 0;
8019   u8 cos2 = 0;
8020   u8 dot1q = 0;
8021   u8 dot1ad = 0;
8022   int len = 14;
8023
8024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8025     {
8026       if (unformat (input, "src"))
8027         src = 1;
8028       else if (unformat (input, "dst"))
8029         dst = 1;
8030       else if (unformat (input, "proto"))
8031         proto = 1;
8032       else if (unformat (input, "tag1"))
8033         tag1 = 1;
8034       else if (unformat (input, "tag2"))
8035         tag2 = 1;
8036       else if (unformat (input, "ignore-tag1"))
8037         ignore_tag1 = 1;
8038       else if (unformat (input, "ignore-tag2"))
8039         ignore_tag2 = 1;
8040       else if (unformat (input, "cos1"))
8041         cos1 = 1;
8042       else if (unformat (input, "cos2"))
8043         cos2 = 1;
8044       else if (unformat (input, "dot1q"))
8045         dot1q = 1;
8046       else if (unformat (input, "dot1ad"))
8047         dot1ad = 1;
8048       else
8049         break;
8050     }
8051   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8052        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8053     return 0;
8054
8055   if (tag1 || ignore_tag1 || cos1 || dot1q)
8056     len = 18;
8057   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8058     len = 22;
8059
8060   vec_validate (mask, len - 1);
8061
8062   if (dst)
8063     memset (mask, 0xff, 6);
8064
8065   if (src)
8066     memset (mask + 6, 0xff, 6);
8067
8068   if (tag2 || dot1ad)
8069     {
8070       /* inner vlan tag */
8071       if (tag2)
8072         {
8073           mask[19] = 0xff;
8074           mask[18] = 0x0f;
8075         }
8076       if (cos2)
8077         mask[18] |= 0xe0;
8078       if (proto)
8079         mask[21] = mask[20] = 0xff;
8080       if (tag1)
8081         {
8082           mask[15] = 0xff;
8083           mask[14] = 0x0f;
8084         }
8085       if (cos1)
8086         mask[14] |= 0xe0;
8087       *maskp = mask;
8088       return 1;
8089     }
8090   if (tag1 | dot1q)
8091     {
8092       if (tag1)
8093         {
8094           mask[15] = 0xff;
8095           mask[14] = 0x0f;
8096         }
8097       if (cos1)
8098         mask[14] |= 0xe0;
8099       if (proto)
8100         mask[16] = mask[17] = 0xff;
8101
8102       *maskp = mask;
8103       return 1;
8104     }
8105   if (cos2)
8106     mask[18] |= 0xe0;
8107   if (cos1)
8108     mask[14] |= 0xe0;
8109   if (proto)
8110     mask[12] = mask[13] = 0xff;
8111
8112   *maskp = mask;
8113   return 1;
8114 }
8115
8116 uword
8117 unformat_classify_mask (unformat_input_t * input, va_list * args)
8118 {
8119   u8 **maskp = va_arg (*args, u8 **);
8120   u32 *skipp = va_arg (*args, u32 *);
8121   u32 *matchp = va_arg (*args, u32 *);
8122   u32 match;
8123   u8 *mask = 0;
8124   u8 *l2 = 0;
8125   u8 *l3 = 0;
8126   int i;
8127
8128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8129     {
8130       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8131         ;
8132       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8133         ;
8134       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8135         ;
8136       else
8137         break;
8138     }
8139
8140   if (mask || l2 || l3)
8141     {
8142       if (l2 || l3)
8143         {
8144           /* "With a free Ethernet header in every package" */
8145           if (l2 == 0)
8146             vec_validate (l2, 13);
8147           mask = l2;
8148           if (vec_len (l3))
8149             {
8150               vec_append (mask, l3);
8151               vec_free (l3);
8152             }
8153         }
8154
8155       /* Scan forward looking for the first significant mask octet */
8156       for (i = 0; i < vec_len (mask); i++)
8157         if (mask[i])
8158           break;
8159
8160       /* compute (skip, match) params */
8161       *skipp = i / sizeof (u32x4);
8162       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8163
8164       /* Pad mask to an even multiple of the vector size */
8165       while (vec_len (mask) % sizeof (u32x4))
8166         vec_add1 (mask, 0);
8167
8168       match = vec_len (mask) / sizeof (u32x4);
8169
8170       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8171         {
8172           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8173           if (*tmp || *(tmp + 1))
8174             break;
8175           match--;
8176         }
8177       if (match == 0)
8178         clib_warning ("BUG: match 0");
8179
8180       _vec_len (mask) = match * sizeof (u32x4);
8181
8182       *matchp = match;
8183       *maskp = mask;
8184
8185       return 1;
8186     }
8187
8188   return 0;
8189 }
8190
8191 #define foreach_l2_next                         \
8192 _(drop, DROP)                                   \
8193 _(ethernet, ETHERNET_INPUT)                     \
8194 _(ip4, IP4_INPUT)                               \
8195 _(ip6, IP6_INPUT)
8196
8197 uword
8198 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8199 {
8200   u32 *miss_next_indexp = va_arg (*args, u32 *);
8201   u32 next_index = 0;
8202   u32 tmp;
8203
8204 #define _(n,N) \
8205   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8206   foreach_l2_next;
8207 #undef _
8208
8209   if (unformat (input, "%d", &tmp))
8210     {
8211       next_index = tmp;
8212       goto out;
8213     }
8214
8215   return 0;
8216
8217 out:
8218   *miss_next_indexp = next_index;
8219   return 1;
8220 }
8221
8222 #define foreach_ip_next                         \
8223 _(drop, DROP)                                   \
8224 _(local, LOCAL)                                 \
8225 _(rewrite, REWRITE)
8226
8227 uword
8228 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8229 {
8230   u32 *miss_next_indexp = va_arg (*args, u32 *);
8231   u32 next_index = 0;
8232   u32 tmp;
8233
8234 #define _(n,N) \
8235   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8236   foreach_ip_next;
8237 #undef _
8238
8239   if (unformat (input, "%d", &tmp))
8240     {
8241       next_index = tmp;
8242       goto out;
8243     }
8244
8245   return 0;
8246
8247 out:
8248   *miss_next_indexp = next_index;
8249   return 1;
8250 }
8251
8252 #define foreach_acl_next                        \
8253 _(deny, DENY)
8254
8255 uword
8256 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8257 {
8258   u32 *miss_next_indexp = va_arg (*args, u32 *);
8259   u32 next_index = 0;
8260   u32 tmp;
8261
8262 #define _(n,N) \
8263   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8264   foreach_acl_next;
8265 #undef _
8266
8267   if (unformat (input, "permit"))
8268     {
8269       next_index = ~0;
8270       goto out;
8271     }
8272   else if (unformat (input, "%d", &tmp))
8273     {
8274       next_index = tmp;
8275       goto out;
8276     }
8277
8278   return 0;
8279
8280 out:
8281   *miss_next_indexp = next_index;
8282   return 1;
8283 }
8284
8285 uword
8286 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8287 {
8288   u32 *r = va_arg (*args, u32 *);
8289
8290   if (unformat (input, "conform-color"))
8291     *r = POLICE_CONFORM;
8292   else if (unformat (input, "exceed-color"))
8293     *r = POLICE_EXCEED;
8294   else
8295     return 0;
8296
8297   return 1;
8298 }
8299
8300 static int
8301 api_classify_add_del_table (vat_main_t * vam)
8302 {
8303   unformat_input_t *i = vam->input;
8304   vl_api_classify_add_del_table_t *mp;
8305
8306   u32 nbuckets = 2;
8307   u32 skip = ~0;
8308   u32 match = ~0;
8309   int is_add = 1;
8310   u32 table_index = ~0;
8311   u32 next_table_index = ~0;
8312   u32 miss_next_index = ~0;
8313   u32 memory_size = 32 << 20;
8314   u8 *mask = 0;
8315   f64 timeout;
8316
8317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8318     {
8319       if (unformat (i, "del"))
8320         is_add = 0;
8321       else if (unformat (i, "buckets %d", &nbuckets))
8322         ;
8323       else if (unformat (i, "memory_size %d", &memory_size))
8324         ;
8325       else if (unformat (i, "skip %d", &skip))
8326         ;
8327       else if (unformat (i, "match %d", &match))
8328         ;
8329       else if (unformat (i, "table %d", &table_index))
8330         ;
8331       else if (unformat (i, "mask %U", unformat_classify_mask,
8332                          &mask, &skip, &match))
8333         ;
8334       else if (unformat (i, "next-table %d", &next_table_index))
8335         ;
8336       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8337                          &miss_next_index))
8338         ;
8339       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8340                          &miss_next_index))
8341         ;
8342       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8343                          &miss_next_index))
8344         ;
8345       else
8346         break;
8347     }
8348
8349   if (is_add && mask == 0)
8350     {
8351       errmsg ("Mask required\n");
8352       return -99;
8353     }
8354
8355   if (is_add && skip == ~0)
8356     {
8357       errmsg ("skip count required\n");
8358       return -99;
8359     }
8360
8361   if (is_add && match == ~0)
8362     {
8363       errmsg ("match count required\n");
8364       return -99;
8365     }
8366
8367   if (!is_add && table_index == ~0)
8368     {
8369       errmsg ("table index required for delete\n");
8370       return -99;
8371     }
8372
8373   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8374
8375   mp->is_add = is_add;
8376   mp->table_index = ntohl (table_index);
8377   mp->nbuckets = ntohl (nbuckets);
8378   mp->memory_size = ntohl (memory_size);
8379   mp->skip_n_vectors = ntohl (skip);
8380   mp->match_n_vectors = ntohl (match);
8381   mp->next_table_index = ntohl (next_table_index);
8382   mp->miss_next_index = ntohl (miss_next_index);
8383   clib_memcpy (mp->mask, mask, vec_len (mask));
8384
8385   vec_free (mask);
8386
8387   S;
8388   W;
8389   /* NOTREACHED */
8390 }
8391
8392 uword
8393 unformat_ip4_match (unformat_input_t * input, va_list * args)
8394 {
8395   u8 **matchp = va_arg (*args, u8 **);
8396   u8 *match = 0;
8397   ip4_header_t *ip;
8398   int version = 0;
8399   u32 version_val;
8400   int hdr_length = 0;
8401   u32 hdr_length_val;
8402   int src = 0, dst = 0;
8403   ip4_address_t src_val, dst_val;
8404   int proto = 0;
8405   u32 proto_val;
8406   int tos = 0;
8407   u32 tos_val;
8408   int length = 0;
8409   u32 length_val;
8410   int fragment_id = 0;
8411   u32 fragment_id_val;
8412   int ttl = 0;
8413   int ttl_val;
8414   int checksum = 0;
8415   u32 checksum_val;
8416
8417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8418     {
8419       if (unformat (input, "version %d", &version_val))
8420         version = 1;
8421       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8422         hdr_length = 1;
8423       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8424         src = 1;
8425       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8426         dst = 1;
8427       else if (unformat (input, "proto %d", &proto_val))
8428         proto = 1;
8429       else if (unformat (input, "tos %d", &tos_val))
8430         tos = 1;
8431       else if (unformat (input, "length %d", &length_val))
8432         length = 1;
8433       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8434         fragment_id = 1;
8435       else if (unformat (input, "ttl %d", &ttl_val))
8436         ttl = 1;
8437       else if (unformat (input, "checksum %d", &checksum_val))
8438         checksum = 1;
8439       else
8440         break;
8441     }
8442
8443   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8444       + ttl + checksum == 0)
8445     return 0;
8446
8447   /*
8448    * Aligned because we use the real comparison functions
8449    */
8450   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8451
8452   ip = (ip4_header_t *) match;
8453
8454   /* These are realistically matched in practice */
8455   if (src)
8456     ip->src_address.as_u32 = src_val.as_u32;
8457
8458   if (dst)
8459     ip->dst_address.as_u32 = dst_val.as_u32;
8460
8461   if (proto)
8462     ip->protocol = proto_val;
8463
8464
8465   /* These are not, but they're included for completeness */
8466   if (version)
8467     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8468
8469   if (hdr_length)
8470     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8471
8472   if (tos)
8473     ip->tos = tos_val;
8474
8475   if (length)
8476     ip->length = length_val;
8477
8478   if (ttl)
8479     ip->ttl = ttl_val;
8480
8481   if (checksum)
8482     ip->checksum = checksum_val;
8483
8484   *matchp = match;
8485   return 1;
8486 }
8487
8488 uword
8489 unformat_ip6_match (unformat_input_t * input, va_list * args)
8490 {
8491   u8 **matchp = va_arg (*args, u8 **);
8492   u8 *match = 0;
8493   ip6_header_t *ip;
8494   int version = 0;
8495   u32 version_val;
8496   u8 traffic_class = 0;
8497   u32 traffic_class_val = 0;
8498   u8 flow_label = 0;
8499   u8 flow_label_val;
8500   int src = 0, dst = 0;
8501   ip6_address_t src_val, dst_val;
8502   int proto = 0;
8503   u32 proto_val;
8504   int payload_length = 0;
8505   u32 payload_length_val;
8506   int hop_limit = 0;
8507   int hop_limit_val;
8508   u32 ip_version_traffic_class_and_flow_label;
8509
8510   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8511     {
8512       if (unformat (input, "version %d", &version_val))
8513         version = 1;
8514       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8515         traffic_class = 1;
8516       else if (unformat (input, "flow_label %d", &flow_label_val))
8517         flow_label = 1;
8518       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8519         src = 1;
8520       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8521         dst = 1;
8522       else if (unformat (input, "proto %d", &proto_val))
8523         proto = 1;
8524       else if (unformat (input, "payload_length %d", &payload_length_val))
8525         payload_length = 1;
8526       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8527         hop_limit = 1;
8528       else
8529         break;
8530     }
8531
8532   if (version + traffic_class + flow_label + src + dst + proto +
8533       payload_length + hop_limit == 0)
8534     return 0;
8535
8536   /*
8537    * Aligned because we use the real comparison functions
8538    */
8539   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8540
8541   ip = (ip6_header_t *) match;
8542
8543   if (src)
8544     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8545
8546   if (dst)
8547     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8548
8549   if (proto)
8550     ip->protocol = proto_val;
8551
8552   ip_version_traffic_class_and_flow_label = 0;
8553
8554   if (version)
8555     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8556
8557   if (traffic_class)
8558     ip_version_traffic_class_and_flow_label |=
8559       (traffic_class_val & 0xFF) << 20;
8560
8561   if (flow_label)
8562     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8563
8564   ip->ip_version_traffic_class_and_flow_label =
8565     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8566
8567   if (payload_length)
8568     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8569
8570   if (hop_limit)
8571     ip->hop_limit = hop_limit_val;
8572
8573   *matchp = match;
8574   return 1;
8575 }
8576
8577 uword
8578 unformat_l3_match (unformat_input_t * input, va_list * args)
8579 {
8580   u8 **matchp = va_arg (*args, u8 **);
8581
8582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8583     {
8584       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8585         return 1;
8586       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8587         return 1;
8588       else
8589         break;
8590     }
8591   return 0;
8592 }
8593
8594 uword
8595 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8596 {
8597   u8 *tagp = va_arg (*args, u8 *);
8598   u32 tag;
8599
8600   if (unformat (input, "%d", &tag))
8601     {
8602       tagp[0] = (tag >> 8) & 0x0F;
8603       tagp[1] = tag & 0xFF;
8604       return 1;
8605     }
8606
8607   return 0;
8608 }
8609
8610 uword
8611 unformat_l2_match (unformat_input_t * input, va_list * args)
8612 {
8613   u8 **matchp = va_arg (*args, u8 **);
8614   u8 *match = 0;
8615   u8 src = 0;
8616   u8 src_val[6];
8617   u8 dst = 0;
8618   u8 dst_val[6];
8619   u8 proto = 0;
8620   u16 proto_val;
8621   u8 tag1 = 0;
8622   u8 tag1_val[2];
8623   u8 tag2 = 0;
8624   u8 tag2_val[2];
8625   int len = 14;
8626   u8 ignore_tag1 = 0;
8627   u8 ignore_tag2 = 0;
8628   u8 cos1 = 0;
8629   u8 cos2 = 0;
8630   u32 cos1_val = 0;
8631   u32 cos2_val = 0;
8632
8633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8634     {
8635       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8636         src = 1;
8637       else
8638         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8639         dst = 1;
8640       else if (unformat (input, "proto %U",
8641                          unformat_ethernet_type_host_byte_order, &proto_val))
8642         proto = 1;
8643       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8644         tag1 = 1;
8645       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8646         tag2 = 1;
8647       else if (unformat (input, "ignore-tag1"))
8648         ignore_tag1 = 1;
8649       else if (unformat (input, "ignore-tag2"))
8650         ignore_tag2 = 1;
8651       else if (unformat (input, "cos1 %d", &cos1_val))
8652         cos1 = 1;
8653       else if (unformat (input, "cos2 %d", &cos2_val))
8654         cos2 = 1;
8655       else
8656         break;
8657     }
8658   if ((src + dst + proto + tag1 + tag2 +
8659        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8660     return 0;
8661
8662   if (tag1 || ignore_tag1 || cos1)
8663     len = 18;
8664   if (tag2 || ignore_tag2 || cos2)
8665     len = 22;
8666
8667   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8668
8669   if (dst)
8670     clib_memcpy (match, dst_val, 6);
8671
8672   if (src)
8673     clib_memcpy (match + 6, src_val, 6);
8674
8675   if (tag2)
8676     {
8677       /* inner vlan tag */
8678       match[19] = tag2_val[1];
8679       match[18] = tag2_val[0];
8680       if (cos2)
8681         match[18] |= (cos2_val & 0x7) << 5;
8682       if (proto)
8683         {
8684           match[21] = proto_val & 0xff;
8685           match[20] = proto_val >> 8;
8686         }
8687       if (tag1)
8688         {
8689           match[15] = tag1_val[1];
8690           match[14] = tag1_val[0];
8691         }
8692       if (cos1)
8693         match[14] |= (cos1_val & 0x7) << 5;
8694       *matchp = match;
8695       return 1;
8696     }
8697   if (tag1)
8698     {
8699       match[15] = tag1_val[1];
8700       match[14] = tag1_val[0];
8701       if (proto)
8702         {
8703           match[17] = proto_val & 0xff;
8704           match[16] = proto_val >> 8;
8705         }
8706       if (cos1)
8707         match[14] |= (cos1_val & 0x7) << 5;
8708
8709       *matchp = match;
8710       return 1;
8711     }
8712   if (cos2)
8713     match[18] |= (cos2_val & 0x7) << 5;
8714   if (cos1)
8715     match[14] |= (cos1_val & 0x7) << 5;
8716   if (proto)
8717     {
8718       match[13] = proto_val & 0xff;
8719       match[12] = proto_val >> 8;
8720     }
8721
8722   *matchp = match;
8723   return 1;
8724 }
8725
8726
8727 uword
8728 unformat_classify_match (unformat_input_t * input, va_list * args)
8729 {
8730   u8 **matchp = va_arg (*args, u8 **);
8731   u32 skip_n_vectors = va_arg (*args, u32);
8732   u32 match_n_vectors = va_arg (*args, u32);
8733
8734   u8 *match = 0;
8735   u8 *l2 = 0;
8736   u8 *l3 = 0;
8737
8738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8739     {
8740       if (unformat (input, "hex %U", unformat_hex_string, &match))
8741         ;
8742       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8743         ;
8744       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8745         ;
8746       else
8747         break;
8748     }
8749
8750   if (match || l2 || l3)
8751     {
8752       if (l2 || l3)
8753         {
8754           /* "Win a free Ethernet header in every packet" */
8755           if (l2 == 0)
8756             vec_validate_aligned (l2, 13, sizeof (u32x4));
8757           match = l2;
8758           if (vec_len (l3))
8759             {
8760               vec_append_aligned (match, l3, sizeof (u32x4));
8761               vec_free (l3);
8762             }
8763         }
8764
8765       /* Make sure the vector is big enough even if key is all 0's */
8766       vec_validate_aligned
8767         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8768          sizeof (u32x4));
8769
8770       /* Set size, include skipped vectors */
8771       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8772
8773       *matchp = match;
8774
8775       return 1;
8776     }
8777
8778   return 0;
8779 }
8780
8781 static int
8782 api_classify_add_del_session (vat_main_t * vam)
8783 {
8784   unformat_input_t *i = vam->input;
8785   vl_api_classify_add_del_session_t *mp;
8786   int is_add = 1;
8787   u32 table_index = ~0;
8788   u32 hit_next_index = ~0;
8789   u32 opaque_index = ~0;
8790   u8 *match = 0;
8791   i32 advance = 0;
8792   f64 timeout;
8793   u32 skip_n_vectors = 0;
8794   u32 match_n_vectors = 0;
8795
8796   /*
8797    * Warning: you have to supply skip_n and match_n
8798    * because the API client cant simply look at the classify
8799    * table object.
8800    */
8801
8802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8803     {
8804       if (unformat (i, "del"))
8805         is_add = 0;
8806       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8807                          &hit_next_index))
8808         ;
8809       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8810                          &hit_next_index))
8811         ;
8812       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8813                          &hit_next_index))
8814         ;
8815       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8816         ;
8817       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8818         ;
8819       else if (unformat (i, "opaque-index %d", &opaque_index))
8820         ;
8821       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8822         ;
8823       else if (unformat (i, "match_n %d", &match_n_vectors))
8824         ;
8825       else if (unformat (i, "match %U", unformat_classify_match,
8826                          &match, skip_n_vectors, match_n_vectors))
8827         ;
8828       else if (unformat (i, "advance %d", &advance))
8829         ;
8830       else if (unformat (i, "table-index %d", &table_index))
8831         ;
8832       else
8833         break;
8834     }
8835
8836   if (table_index == ~0)
8837     {
8838       errmsg ("Table index required\n");
8839       return -99;
8840     }
8841
8842   if (is_add && match == 0)
8843     {
8844       errmsg ("Match value required\n");
8845       return -99;
8846     }
8847
8848   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8849
8850   mp->is_add = is_add;
8851   mp->table_index = ntohl (table_index);
8852   mp->hit_next_index = ntohl (hit_next_index);
8853   mp->opaque_index = ntohl (opaque_index);
8854   mp->advance = ntohl (advance);
8855   clib_memcpy (mp->match, match, vec_len (match));
8856   vec_free (match);
8857
8858   S;
8859   W;
8860   /* NOTREACHED */
8861 }
8862
8863 static int
8864 api_classify_set_interface_ip_table (vat_main_t * vam)
8865 {
8866   unformat_input_t *i = vam->input;
8867   vl_api_classify_set_interface_ip_table_t *mp;
8868   f64 timeout;
8869   u32 sw_if_index;
8870   int sw_if_index_set;
8871   u32 table_index = ~0;
8872   u8 is_ipv6 = 0;
8873
8874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8875     {
8876       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8877         sw_if_index_set = 1;
8878       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8879         sw_if_index_set = 1;
8880       else if (unformat (i, "table %d", &table_index))
8881         ;
8882       else
8883         {
8884           clib_warning ("parse error '%U'", format_unformat_error, i);
8885           return -99;
8886         }
8887     }
8888
8889   if (sw_if_index_set == 0)
8890     {
8891       errmsg ("missing interface name or sw_if_index\n");
8892       return -99;
8893     }
8894
8895
8896   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8897
8898   mp->sw_if_index = ntohl (sw_if_index);
8899   mp->table_index = ntohl (table_index);
8900   mp->is_ipv6 = is_ipv6;
8901
8902   S;
8903   W;
8904   /* NOTREACHED */
8905   return 0;
8906 }
8907
8908 static int
8909 api_classify_set_interface_l2_tables (vat_main_t * vam)
8910 {
8911   unformat_input_t *i = vam->input;
8912   vl_api_classify_set_interface_l2_tables_t *mp;
8913   f64 timeout;
8914   u32 sw_if_index;
8915   int sw_if_index_set;
8916   u32 ip4_table_index = ~0;
8917   u32 ip6_table_index = ~0;
8918   u32 other_table_index = ~0;
8919   u32 is_input = 1;
8920
8921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8922     {
8923       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8924         sw_if_index_set = 1;
8925       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8926         sw_if_index_set = 1;
8927       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8928         ;
8929       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8930         ;
8931       else if (unformat (i, "other-table %d", &other_table_index))
8932         ;
8933       else if (unformat (i, "is-input %d", &is_input))
8934         ;
8935       else
8936         {
8937           clib_warning ("parse error '%U'", format_unformat_error, i);
8938           return -99;
8939         }
8940     }
8941
8942   if (sw_if_index_set == 0)
8943     {
8944       errmsg ("missing interface name or sw_if_index\n");
8945       return -99;
8946     }
8947
8948
8949   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8950
8951   mp->sw_if_index = ntohl (sw_if_index);
8952   mp->ip4_table_index = ntohl (ip4_table_index);
8953   mp->ip6_table_index = ntohl (ip6_table_index);
8954   mp->other_table_index = ntohl (other_table_index);
8955   mp->is_input = (u8) is_input;
8956
8957   S;
8958   W;
8959   /* NOTREACHED */
8960   return 0;
8961 }
8962
8963 static int
8964 api_set_ipfix_exporter (vat_main_t * vam)
8965 {
8966   unformat_input_t *i = vam->input;
8967   vl_api_set_ipfix_exporter_t *mp;
8968   ip4_address_t collector_address;
8969   u8 collector_address_set = 0;
8970   u32 collector_port = ~0;
8971   ip4_address_t src_address;
8972   u8 src_address_set = 0;
8973   u32 vrf_id = ~0;
8974   u32 path_mtu = ~0;
8975   u32 template_interval = ~0;
8976   u8 udp_checksum = 0;
8977   f64 timeout;
8978
8979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8980     {
8981       if (unformat (i, "collector_address %U", unformat_ip4_address,
8982                     &collector_address))
8983         collector_address_set = 1;
8984       else if (unformat (i, "collector_port %d", &collector_port))
8985         ;
8986       else if (unformat (i, "src_address %U", unformat_ip4_address,
8987                          &src_address))
8988         src_address_set = 1;
8989       else if (unformat (i, "vrf_id %d", &vrf_id))
8990         ;
8991       else if (unformat (i, "path_mtu %d", &path_mtu))
8992         ;
8993       else if (unformat (i, "template_interval %d", &template_interval))
8994         ;
8995       else if (unformat (i, "udp_checksum"))
8996         udp_checksum = 1;
8997       else
8998         break;
8999     }
9000
9001   if (collector_address_set == 0)
9002     {
9003       errmsg ("collector_address required\n");
9004       return -99;
9005     }
9006
9007   if (src_address_set == 0)
9008     {
9009       errmsg ("src_address required\n");
9010       return -99;
9011     }
9012
9013   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9014
9015   memcpy (mp->collector_address, collector_address.data,
9016           sizeof (collector_address.data));
9017   mp->collector_port = htons ((u16) collector_port);
9018   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9019   mp->vrf_id = htonl (vrf_id);
9020   mp->path_mtu = htonl (path_mtu);
9021   mp->template_interval = htonl (template_interval);
9022   mp->udp_checksum = udp_checksum;
9023
9024   S;
9025   W;
9026   /* NOTREACHED */
9027 }
9028
9029 static int
9030 api_set_ipfix_classify_stream (vat_main_t * vam)
9031 {
9032   unformat_input_t *i = vam->input;
9033   vl_api_set_ipfix_classify_stream_t *mp;
9034   u32 domain_id = 0;
9035   u32 src_port = UDP_DST_PORT_ipfix;
9036   f64 timeout;
9037
9038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9039     {
9040       if (unformat (i, "domain %d", &domain_id))
9041         ;
9042       else if (unformat (i, "src_port %d", &src_port))
9043         ;
9044       else
9045         {
9046           errmsg ("unknown input `%U'", format_unformat_error, i);
9047           return -99;
9048         }
9049     }
9050
9051   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9052
9053   mp->domain_id = htonl (domain_id);
9054   mp->src_port = htons ((u16) src_port);
9055
9056   S;
9057   W;
9058   /* NOTREACHED */
9059 }
9060
9061 static int
9062 api_ipfix_classify_table_add_del (vat_main_t * vam)
9063 {
9064   unformat_input_t *i = vam->input;
9065   vl_api_ipfix_classify_table_add_del_t *mp;
9066   int is_add = -1;
9067   u32 classify_table_index = ~0;
9068   u8 ip_version = 0;
9069   u8 transport_protocol = 255;
9070   f64 timeout;
9071
9072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9073     {
9074       if (unformat (i, "add"))
9075         is_add = 1;
9076       else if (unformat (i, "del"))
9077         is_add = 0;
9078       else if (unformat (i, "table %d", &classify_table_index))
9079         ;
9080       else if (unformat (i, "ip4"))
9081         ip_version = 4;
9082       else if (unformat (i, "ip6"))
9083         ip_version = 6;
9084       else if (unformat (i, "tcp"))
9085         transport_protocol = 6;
9086       else if (unformat (i, "udp"))
9087         transport_protocol = 17;
9088       else
9089         {
9090           errmsg ("unknown input `%U'", format_unformat_error, i);
9091           return -99;
9092         }
9093     }
9094
9095   if (is_add == -1)
9096     {
9097       errmsg ("expecting: add|del");
9098       return -99;
9099     }
9100   if (classify_table_index == ~0)
9101     {
9102       errmsg ("classifier table not specified");
9103       return -99;
9104     }
9105   if (ip_version == 0)
9106     {
9107       errmsg ("IP version not specified");
9108       return -99;
9109     }
9110
9111   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9112
9113   mp->is_add = is_add;
9114   mp->table_id = htonl (classify_table_index);
9115   mp->ip_version = ip_version;
9116   mp->transport_protocol = transport_protocol;
9117
9118   S;
9119   W;
9120   /* NOTREACHED */
9121 }
9122
9123 static int
9124 api_get_node_index (vat_main_t * vam)
9125 {
9126   unformat_input_t *i = vam->input;
9127   vl_api_get_node_index_t *mp;
9128   f64 timeout;
9129   u8 *name = 0;
9130
9131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9132     {
9133       if (unformat (i, "node %s", &name))
9134         ;
9135       else
9136         break;
9137     }
9138   if (name == 0)
9139     {
9140       errmsg ("node name required\n");
9141       return -99;
9142     }
9143   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9144     {
9145       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9146       return -99;
9147     }
9148
9149   M (GET_NODE_INDEX, get_node_index);
9150   clib_memcpy (mp->node_name, name, vec_len (name));
9151   vec_free (name);
9152
9153   S;
9154   W;
9155   /* NOTREACHED */
9156   return 0;
9157 }
9158
9159 static int
9160 api_get_next_index (vat_main_t * vam)
9161 {
9162   unformat_input_t *i = vam->input;
9163   vl_api_get_next_index_t *mp;
9164   f64 timeout;
9165   u8 *node_name = 0, *next_node_name = 0;
9166
9167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9168     {
9169       if (unformat (i, "node-name %s", &node_name))
9170         ;
9171       else if (unformat (i, "next-node-name %s", &next_node_name))
9172         break;
9173     }
9174
9175   if (node_name == 0)
9176     {
9177       errmsg ("node name required\n");
9178       return -99;
9179     }
9180   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9181     {
9182       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9183       return -99;
9184     }
9185
9186   if (next_node_name == 0)
9187     {
9188       errmsg ("next node name required\n");
9189       return -99;
9190     }
9191   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9192     {
9193       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9194       return -99;
9195     }
9196
9197   M (GET_NEXT_INDEX, get_next_index);
9198   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9199   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9200   vec_free (node_name);
9201   vec_free (next_node_name);
9202
9203   S;
9204   W;
9205   /* NOTREACHED */
9206   return 0;
9207 }
9208
9209 static int
9210 api_add_node_next (vat_main_t * vam)
9211 {
9212   unformat_input_t *i = vam->input;
9213   vl_api_add_node_next_t *mp;
9214   f64 timeout;
9215   u8 *name = 0;
9216   u8 *next = 0;
9217
9218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9219     {
9220       if (unformat (i, "node %s", &name))
9221         ;
9222       else if (unformat (i, "next %s", &next))
9223         ;
9224       else
9225         break;
9226     }
9227   if (name == 0)
9228     {
9229       errmsg ("node name required\n");
9230       return -99;
9231     }
9232   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9233     {
9234       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9235       return -99;
9236     }
9237   if (next == 0)
9238     {
9239       errmsg ("next node required\n");
9240       return -99;
9241     }
9242   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9243     {
9244       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9245       return -99;
9246     }
9247
9248   M (ADD_NODE_NEXT, add_node_next);
9249   clib_memcpy (mp->node_name, name, vec_len (name));
9250   clib_memcpy (mp->next_name, next, vec_len (next));
9251   vec_free (name);
9252   vec_free (next);
9253
9254   S;
9255   W;
9256   /* NOTREACHED */
9257   return 0;
9258 }
9259
9260 static int
9261 api_l2tpv3_create_tunnel (vat_main_t * vam)
9262 {
9263   unformat_input_t *i = vam->input;
9264   ip6_address_t client_address, our_address;
9265   int client_address_set = 0;
9266   int our_address_set = 0;
9267   u32 local_session_id = 0;
9268   u32 remote_session_id = 0;
9269   u64 local_cookie = 0;
9270   u64 remote_cookie = 0;
9271   u8 l2_sublayer_present = 0;
9272   vl_api_l2tpv3_create_tunnel_t *mp;
9273   f64 timeout;
9274
9275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9276     {
9277       if (unformat (i, "client_address %U", unformat_ip6_address,
9278                     &client_address))
9279         client_address_set = 1;
9280       else if (unformat (i, "our_address %U", unformat_ip6_address,
9281                          &our_address))
9282         our_address_set = 1;
9283       else if (unformat (i, "local_session_id %d", &local_session_id))
9284         ;
9285       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9286         ;
9287       else if (unformat (i, "local_cookie %lld", &local_cookie))
9288         ;
9289       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9290         ;
9291       else if (unformat (i, "l2-sublayer-present"))
9292         l2_sublayer_present = 1;
9293       else
9294         break;
9295     }
9296
9297   if (client_address_set == 0)
9298     {
9299       errmsg ("client_address required\n");
9300       return -99;
9301     }
9302
9303   if (our_address_set == 0)
9304     {
9305       errmsg ("our_address required\n");
9306       return -99;
9307     }
9308
9309   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9310
9311   clib_memcpy (mp->client_address, client_address.as_u8,
9312                sizeof (mp->client_address));
9313
9314   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9315
9316   mp->local_session_id = ntohl (local_session_id);
9317   mp->remote_session_id = ntohl (remote_session_id);
9318   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9319   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9320   mp->l2_sublayer_present = l2_sublayer_present;
9321   mp->is_ipv6 = 1;
9322
9323   S;
9324   W;
9325   /* NOTREACHED */
9326   return 0;
9327 }
9328
9329 static int
9330 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9331 {
9332   unformat_input_t *i = vam->input;
9333   u32 sw_if_index;
9334   u8 sw_if_index_set = 0;
9335   u64 new_local_cookie = 0;
9336   u64 new_remote_cookie = 0;
9337   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9338   f64 timeout;
9339
9340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9341     {
9342       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9343         sw_if_index_set = 1;
9344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9345         sw_if_index_set = 1;
9346       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9347         ;
9348       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9349         ;
9350       else
9351         break;
9352     }
9353
9354   if (sw_if_index_set == 0)
9355     {
9356       errmsg ("missing interface name or sw_if_index\n");
9357       return -99;
9358     }
9359
9360   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9361
9362   mp->sw_if_index = ntohl (sw_if_index);
9363   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9364   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9365
9366   S;
9367   W;
9368   /* NOTREACHED */
9369   return 0;
9370 }
9371
9372 static int
9373 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9374 {
9375   unformat_input_t *i = vam->input;
9376   vl_api_l2tpv3_interface_enable_disable_t *mp;
9377   f64 timeout;
9378   u32 sw_if_index;
9379   u8 sw_if_index_set = 0;
9380   u8 enable_disable = 1;
9381
9382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9383     {
9384       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9385         sw_if_index_set = 1;
9386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9387         sw_if_index_set = 1;
9388       else if (unformat (i, "enable"))
9389         enable_disable = 1;
9390       else if (unformat (i, "disable"))
9391         enable_disable = 0;
9392       else
9393         break;
9394     }
9395
9396   if (sw_if_index_set == 0)
9397     {
9398       errmsg ("missing interface name or sw_if_index\n");
9399       return -99;
9400     }
9401
9402   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9403
9404   mp->sw_if_index = ntohl (sw_if_index);
9405   mp->enable_disable = enable_disable;
9406
9407   S;
9408   W;
9409   /* NOTREACHED */
9410   return 0;
9411 }
9412
9413 static int
9414 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9415 {
9416   unformat_input_t *i = vam->input;
9417   vl_api_l2tpv3_set_lookup_key_t *mp;
9418   f64 timeout;
9419   u8 key = ~0;
9420
9421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9422     {
9423       if (unformat (i, "lookup_v6_src"))
9424         key = L2T_LOOKUP_SRC_ADDRESS;
9425       else if (unformat (i, "lookup_v6_dst"))
9426         key = L2T_LOOKUP_DST_ADDRESS;
9427       else if (unformat (i, "lookup_session_id"))
9428         key = L2T_LOOKUP_SESSION_ID;
9429       else
9430         break;
9431     }
9432
9433   if (key == (u8) ~ 0)
9434     {
9435       errmsg ("l2tp session lookup key unset\n");
9436       return -99;
9437     }
9438
9439   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9440
9441   mp->key = key;
9442
9443   S;
9444   W;
9445   /* NOTREACHED */
9446   return 0;
9447 }
9448
9449 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9450   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9451 {
9452   vat_main_t *vam = &vat_main;
9453
9454   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9455            format_ip6_address, mp->our_address,
9456            format_ip6_address, mp->client_address,
9457            clib_net_to_host_u32 (mp->sw_if_index));
9458
9459   fformat (vam->ofp,
9460            "   local cookies %016llx %016llx remote cookie %016llx\n",
9461            clib_net_to_host_u64 (mp->local_cookie[0]),
9462            clib_net_to_host_u64 (mp->local_cookie[1]),
9463            clib_net_to_host_u64 (mp->remote_cookie));
9464
9465   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9466            clib_net_to_host_u32 (mp->local_session_id),
9467            clib_net_to_host_u32 (mp->remote_session_id));
9468
9469   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9470            mp->l2_sublayer_present ? "preset" : "absent");
9471
9472 }
9473
9474 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9475   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9476 {
9477   vat_main_t *vam = &vat_main;
9478   vat_json_node_t *node = NULL;
9479   struct in6_addr addr;
9480
9481   if (VAT_JSON_ARRAY != vam->json_tree.type)
9482     {
9483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9484       vat_json_init_array (&vam->json_tree);
9485     }
9486   node = vat_json_array_add (&vam->json_tree);
9487
9488   vat_json_init_object (node);
9489
9490   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9491   vat_json_object_add_ip6 (node, "our_address", addr);
9492   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9493   vat_json_object_add_ip6 (node, "client_address", addr);
9494
9495   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9496   vat_json_init_array (lc);
9497   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9498   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9499   vat_json_object_add_uint (node, "remote_cookie",
9500                             clib_net_to_host_u64 (mp->remote_cookie));
9501
9502   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9503   vat_json_object_add_uint (node, "local_session_id",
9504                             clib_net_to_host_u32 (mp->local_session_id));
9505   vat_json_object_add_uint (node, "remote_session_id",
9506                             clib_net_to_host_u32 (mp->remote_session_id));
9507   vat_json_object_add_string_copy (node, "l2_sublayer",
9508                                    mp->l2_sublayer_present ? (u8 *) "present"
9509                                    : (u8 *) "absent");
9510 }
9511
9512 static int
9513 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9514 {
9515   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9516   f64 timeout;
9517
9518   /* Get list of l2tpv3-tunnel interfaces */
9519   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9520   S;
9521
9522   /* Use a control ping for synchronization */
9523   {
9524     vl_api_control_ping_t *mp;
9525     M (CONTROL_PING, control_ping);
9526     S;
9527   }
9528   W;
9529 }
9530
9531
9532 static void vl_api_sw_interface_tap_details_t_handler
9533   (vl_api_sw_interface_tap_details_t * mp)
9534 {
9535   vat_main_t *vam = &vat_main;
9536
9537   fformat (vam->ofp, "%-16s %d\n",
9538            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9539 }
9540
9541 static void vl_api_sw_interface_tap_details_t_handler_json
9542   (vl_api_sw_interface_tap_details_t * mp)
9543 {
9544   vat_main_t *vam = &vat_main;
9545   vat_json_node_t *node = NULL;
9546
9547   if (VAT_JSON_ARRAY != vam->json_tree.type)
9548     {
9549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9550       vat_json_init_array (&vam->json_tree);
9551     }
9552   node = vat_json_array_add (&vam->json_tree);
9553
9554   vat_json_init_object (node);
9555   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9556   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9557 }
9558
9559 static int
9560 api_sw_interface_tap_dump (vat_main_t * vam)
9561 {
9562   vl_api_sw_interface_tap_dump_t *mp;
9563   f64 timeout;
9564
9565   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9566   /* Get list of tap interfaces */
9567   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9568   S;
9569
9570   /* Use a control ping for synchronization */
9571   {
9572     vl_api_control_ping_t *mp;
9573     M (CONTROL_PING, control_ping);
9574     S;
9575   }
9576   W;
9577 }
9578
9579 static uword unformat_vxlan_decap_next
9580   (unformat_input_t * input, va_list * args)
9581 {
9582   u32 *result = va_arg (*args, u32 *);
9583   u32 tmp;
9584
9585   if (unformat (input, "drop"))
9586     *result = VXLAN_INPUT_NEXT_DROP;
9587   else if (unformat (input, "ip4"))
9588     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9589   else if (unformat (input, "ip6"))
9590     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9591   else if (unformat (input, "l2"))
9592     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9593   else if (unformat (input, "%d", &tmp))
9594     *result = tmp;
9595   else
9596     return 0;
9597   return 1;
9598 }
9599
9600 static int
9601 api_vxlan_add_del_tunnel (vat_main_t * vam)
9602 {
9603   unformat_input_t *line_input = vam->input;
9604   vl_api_vxlan_add_del_tunnel_t *mp;
9605   f64 timeout;
9606   ip4_address_t src4, dst4;
9607   ip6_address_t src6, dst6;
9608   u8 is_add = 1;
9609   u8 ipv4_set = 0, ipv6_set = 0;
9610   u8 src_set = 0;
9611   u8 dst_set = 0;
9612   u32 encap_vrf_id = 0;
9613   u32 decap_next_index = ~0;
9614   u32 vni = 0;
9615
9616   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9617     {
9618       if (unformat (line_input, "del"))
9619         is_add = 0;
9620       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9621         {
9622           ipv4_set = 1;
9623           src_set = 1;
9624         }
9625       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9626         {
9627           ipv4_set = 1;
9628           dst_set = 1;
9629         }
9630       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9631         {
9632           ipv6_set = 1;
9633           src_set = 1;
9634         }
9635       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9636         {
9637           ipv6_set = 1;
9638           dst_set = 1;
9639         }
9640       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9641         ;
9642       else if (unformat (line_input, "decap-next %U",
9643                          unformat_vxlan_decap_next, &decap_next_index))
9644         ;
9645       else if (unformat (line_input, "vni %d", &vni))
9646         ;
9647       else
9648         {
9649           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9650           return -99;
9651         }
9652     }
9653
9654   if (src_set == 0)
9655     {
9656       errmsg ("tunnel src address not specified\n");
9657       return -99;
9658     }
9659   if (dst_set == 0)
9660     {
9661       errmsg ("tunnel dst address not specified\n");
9662       return -99;
9663     }
9664
9665   if (ipv4_set && ipv6_set)
9666     {
9667       errmsg ("both IPv4 and IPv6 addresses specified");
9668       return -99;
9669     }
9670
9671   if ((vni == 0) || (vni >> 24))
9672     {
9673       errmsg ("vni not specified or out of range\n");
9674       return -99;
9675     }
9676
9677   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9678
9679   if (ipv6_set)
9680     {
9681       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9682       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9683     }
9684   else
9685     {
9686       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9687       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9688     }
9689   mp->encap_vrf_id = ntohl (encap_vrf_id);
9690   mp->decap_next_index = ntohl (decap_next_index);
9691   mp->vni = ntohl (vni);
9692   mp->is_add = is_add;
9693   mp->is_ipv6 = ipv6_set;
9694
9695   S;
9696   W;
9697   /* NOTREACHED */
9698   return 0;
9699 }
9700
9701 static void vl_api_vxlan_tunnel_details_t_handler
9702   (vl_api_vxlan_tunnel_details_t * mp)
9703 {
9704   vat_main_t *vam = &vat_main;
9705
9706   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9707            ntohl (mp->sw_if_index),
9708            format_ip46_address, &(mp->src_address[0]),
9709            IP46_TYPE_ANY,
9710            format_ip46_address, &(mp->dst_address[0]),
9711            IP46_TYPE_ANY,
9712            ntohl (mp->encap_vrf_id),
9713            ntohl (mp->decap_next_index), ntohl (mp->vni));
9714 }
9715
9716 static void vl_api_vxlan_tunnel_details_t_handler_json
9717   (vl_api_vxlan_tunnel_details_t * mp)
9718 {
9719   vat_main_t *vam = &vat_main;
9720   vat_json_node_t *node = NULL;
9721   struct in_addr ip4;
9722   struct in6_addr ip6;
9723
9724   if (VAT_JSON_ARRAY != vam->json_tree.type)
9725     {
9726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9727       vat_json_init_array (&vam->json_tree);
9728     }
9729   node = vat_json_array_add (&vam->json_tree);
9730
9731   vat_json_init_object (node);
9732   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9733   if (mp->is_ipv6)
9734     {
9735       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9736       vat_json_object_add_ip6 (node, "src_address", ip6);
9737       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9738       vat_json_object_add_ip6 (node, "dst_address", ip6);
9739     }
9740   else
9741     {
9742       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9743       vat_json_object_add_ip4 (node, "src_address", ip4);
9744       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9745       vat_json_object_add_ip4 (node, "dst_address", ip4);
9746     }
9747   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9748   vat_json_object_add_uint (node, "decap_next_index",
9749                             ntohl (mp->decap_next_index));
9750   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9751   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9752 }
9753
9754 static int
9755 api_vxlan_tunnel_dump (vat_main_t * vam)
9756 {
9757   unformat_input_t *i = vam->input;
9758   vl_api_vxlan_tunnel_dump_t *mp;
9759   f64 timeout;
9760   u32 sw_if_index;
9761   u8 sw_if_index_set = 0;
9762
9763   /* Parse args required to build the message */
9764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9765     {
9766       if (unformat (i, "sw_if_index %d", &sw_if_index))
9767         sw_if_index_set = 1;
9768       else
9769         break;
9770     }
9771
9772   if (sw_if_index_set == 0)
9773     {
9774       sw_if_index = ~0;
9775     }
9776
9777   if (!vam->json_output)
9778     {
9779       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9780                "sw_if_index", "src_address", "dst_address",
9781                "encap_vrf_id", "decap_next_index", "vni");
9782     }
9783
9784   /* Get list of vxlan-tunnel interfaces */
9785   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9786
9787   mp->sw_if_index = htonl (sw_if_index);
9788
9789   S;
9790
9791   /* Use a control ping for synchronization */
9792   {
9793     vl_api_control_ping_t *mp;
9794     M (CONTROL_PING, control_ping);
9795     S;
9796   }
9797   W;
9798 }
9799
9800 static int
9801 api_gre_add_del_tunnel (vat_main_t * vam)
9802 {
9803   unformat_input_t *line_input = vam->input;
9804   vl_api_gre_add_del_tunnel_t *mp;
9805   f64 timeout;
9806   ip4_address_t src4, dst4;
9807   u8 is_add = 1;
9808   u8 teb = 0;
9809   u8 src_set = 0;
9810   u8 dst_set = 0;
9811   u32 outer_fib_id = 0;
9812
9813   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9814     {
9815       if (unformat (line_input, "del"))
9816         is_add = 0;
9817       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9818         src_set = 1;
9819       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9820         dst_set = 1;
9821       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9822         ;
9823       else if (unformat (line_input, "teb"))
9824         teb = 1;
9825       else
9826         {
9827           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9828           return -99;
9829         }
9830     }
9831
9832   if (src_set == 0)
9833     {
9834       errmsg ("tunnel src address not specified\n");
9835       return -99;
9836     }
9837   if (dst_set == 0)
9838     {
9839       errmsg ("tunnel dst address not specified\n");
9840       return -99;
9841     }
9842
9843
9844   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9845
9846   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9847   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9848   mp->outer_fib_id = ntohl (outer_fib_id);
9849   mp->is_add = is_add;
9850   mp->teb = teb;
9851
9852   S;
9853   W;
9854   /* NOTREACHED */
9855   return 0;
9856 }
9857
9858 static void vl_api_gre_tunnel_details_t_handler
9859   (vl_api_gre_tunnel_details_t * mp)
9860 {
9861   vat_main_t *vam = &vat_main;
9862
9863   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
9864            ntohl (mp->sw_if_index),
9865            format_ip4_address, &mp->src_address,
9866            format_ip4_address, &mp->dst_address,
9867            mp->teb, ntohl (mp->outer_fib_id));
9868 }
9869
9870 static void vl_api_gre_tunnel_details_t_handler_json
9871   (vl_api_gre_tunnel_details_t * mp)
9872 {
9873   vat_main_t *vam = &vat_main;
9874   vat_json_node_t *node = NULL;
9875   struct in_addr ip4;
9876
9877   if (VAT_JSON_ARRAY != vam->json_tree.type)
9878     {
9879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9880       vat_json_init_array (&vam->json_tree);
9881     }
9882   node = vat_json_array_add (&vam->json_tree);
9883
9884   vat_json_init_object (node);
9885   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9886   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9887   vat_json_object_add_ip4 (node, "src_address", ip4);
9888   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9889   vat_json_object_add_ip4 (node, "dst_address", ip4);
9890   vat_json_object_add_uint (node, "teb", mp->teb);
9891   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9892 }
9893
9894 static int
9895 api_gre_tunnel_dump (vat_main_t * vam)
9896 {
9897   unformat_input_t *i = vam->input;
9898   vl_api_gre_tunnel_dump_t *mp;
9899   f64 timeout;
9900   u32 sw_if_index;
9901   u8 sw_if_index_set = 0;
9902
9903   /* Parse args required to build the message */
9904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9905     {
9906       if (unformat (i, "sw_if_index %d", &sw_if_index))
9907         sw_if_index_set = 1;
9908       else
9909         break;
9910     }
9911
9912   if (sw_if_index_set == 0)
9913     {
9914       sw_if_index = ~0;
9915     }
9916
9917   if (!vam->json_output)
9918     {
9919       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
9920                "sw_if_index", "src_address", "dst_address", "teb",
9921                "outer_fib_id");
9922     }
9923
9924   /* Get list of gre-tunnel interfaces */
9925   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9926
9927   mp->sw_if_index = htonl (sw_if_index);
9928
9929   S;
9930
9931   /* Use a control ping for synchronization */
9932   {
9933     vl_api_control_ping_t *mp;
9934     M (CONTROL_PING, control_ping);
9935     S;
9936   }
9937   W;
9938 }
9939
9940 static int
9941 api_l2_fib_clear_table (vat_main_t * vam)
9942 {
9943 //  unformat_input_t * i = vam->input;
9944   vl_api_l2_fib_clear_table_t *mp;
9945   f64 timeout;
9946
9947   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9948
9949   S;
9950   W;
9951   /* NOTREACHED */
9952   return 0;
9953 }
9954
9955 static int
9956 api_l2_interface_efp_filter (vat_main_t * vam)
9957 {
9958   unformat_input_t *i = vam->input;
9959   vl_api_l2_interface_efp_filter_t *mp;
9960   f64 timeout;
9961   u32 sw_if_index;
9962   u8 enable = 1;
9963   u8 sw_if_index_set = 0;
9964
9965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9966     {
9967       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9968         sw_if_index_set = 1;
9969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9970         sw_if_index_set = 1;
9971       else if (unformat (i, "enable"))
9972         enable = 1;
9973       else if (unformat (i, "disable"))
9974         enable = 0;
9975       else
9976         {
9977           clib_warning ("parse error '%U'", format_unformat_error, i);
9978           return -99;
9979         }
9980     }
9981
9982   if (sw_if_index_set == 0)
9983     {
9984       errmsg ("missing sw_if_index\n");
9985       return -99;
9986     }
9987
9988   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9989
9990   mp->sw_if_index = ntohl (sw_if_index);
9991   mp->enable_disable = enable;
9992
9993   S;
9994   W;
9995   /* NOTREACHED */
9996   return 0;
9997 }
9998
9999 #define foreach_vtr_op                          \
10000 _("disable",  L2_VTR_DISABLED)                  \
10001 _("push-1",  L2_VTR_PUSH_1)                     \
10002 _("push-2",  L2_VTR_PUSH_2)                     \
10003 _("pop-1",  L2_VTR_POP_1)                       \
10004 _("pop-2",  L2_VTR_POP_2)                       \
10005 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10006 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10007 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10008 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10009
10010 static int
10011 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10012 {
10013   unformat_input_t *i = vam->input;
10014   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10015   f64 timeout;
10016   u32 sw_if_index;
10017   u8 sw_if_index_set = 0;
10018   u8 vtr_op_set = 0;
10019   u32 vtr_op = 0;
10020   u32 push_dot1q = 1;
10021   u32 tag1 = ~0;
10022   u32 tag2 = ~0;
10023
10024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10025     {
10026       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10027         sw_if_index_set = 1;
10028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10029         sw_if_index_set = 1;
10030       else if (unformat (i, "vtr_op %d", &vtr_op))
10031         vtr_op_set = 1;
10032 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10033       foreach_vtr_op
10034 #undef _
10035         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10036         ;
10037       else if (unformat (i, "tag1 %d", &tag1))
10038         ;
10039       else if (unformat (i, "tag2 %d", &tag2))
10040         ;
10041       else
10042         {
10043           clib_warning ("parse error '%U'", format_unformat_error, i);
10044           return -99;
10045         }
10046     }
10047
10048   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10049     {
10050       errmsg ("missing vtr operation or sw_if_index\n");
10051       return -99;
10052     }
10053
10054   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10055     mp->sw_if_index = ntohl (sw_if_index);
10056   mp->vtr_op = ntohl (vtr_op);
10057   mp->push_dot1q = ntohl (push_dot1q);
10058   mp->tag1 = ntohl (tag1);
10059   mp->tag2 = ntohl (tag2);
10060
10061   S;
10062   W;
10063   /* NOTREACHED */
10064   return 0;
10065 }
10066
10067 static int
10068 api_create_vhost_user_if (vat_main_t * vam)
10069 {
10070   unformat_input_t *i = vam->input;
10071   vl_api_create_vhost_user_if_t *mp;
10072   f64 timeout;
10073   u8 *file_name;
10074   u8 is_server = 0;
10075   u8 file_name_set = 0;
10076   u32 custom_dev_instance = ~0;
10077   u8 hwaddr[6];
10078   u8 use_custom_mac = 0;
10079
10080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10081     {
10082       if (unformat (i, "socket %s", &file_name))
10083         {
10084           file_name_set = 1;
10085         }
10086       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10087         ;
10088       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10089         use_custom_mac = 1;
10090       else if (unformat (i, "server"))
10091         is_server = 1;
10092       else
10093         break;
10094     }
10095
10096   if (file_name_set == 0)
10097     {
10098       errmsg ("missing socket file name\n");
10099       return -99;
10100     }
10101
10102   if (vec_len (file_name) > 255)
10103     {
10104       errmsg ("socket file name too long\n");
10105       return -99;
10106     }
10107   vec_add1 (file_name, 0);
10108
10109   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10110
10111   mp->is_server = is_server;
10112   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10113   vec_free (file_name);
10114   if (custom_dev_instance != ~0)
10115     {
10116       mp->renumber = 1;
10117       mp->custom_dev_instance = ntohl (custom_dev_instance);
10118     }
10119   mp->use_custom_mac = use_custom_mac;
10120   clib_memcpy (mp->mac_address, hwaddr, 6);
10121
10122   S;
10123   W;
10124   /* NOTREACHED */
10125   return 0;
10126 }
10127
10128 static int
10129 api_modify_vhost_user_if (vat_main_t * vam)
10130 {
10131   unformat_input_t *i = vam->input;
10132   vl_api_modify_vhost_user_if_t *mp;
10133   f64 timeout;
10134   u8 *file_name;
10135   u8 is_server = 0;
10136   u8 file_name_set = 0;
10137   u32 custom_dev_instance = ~0;
10138   u8 sw_if_index_set = 0;
10139   u32 sw_if_index = (u32) ~ 0;
10140
10141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10142     {
10143       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10144         sw_if_index_set = 1;
10145       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10146         sw_if_index_set = 1;
10147       else if (unformat (i, "socket %s", &file_name))
10148         {
10149           file_name_set = 1;
10150         }
10151       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10152         ;
10153       else if (unformat (i, "server"))
10154         is_server = 1;
10155       else
10156         break;
10157     }
10158
10159   if (sw_if_index_set == 0)
10160     {
10161       errmsg ("missing sw_if_index or interface name\n");
10162       return -99;
10163     }
10164
10165   if (file_name_set == 0)
10166     {
10167       errmsg ("missing socket file name\n");
10168       return -99;
10169     }
10170
10171   if (vec_len (file_name) > 255)
10172     {
10173       errmsg ("socket file name too long\n");
10174       return -99;
10175     }
10176   vec_add1 (file_name, 0);
10177
10178   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10179
10180   mp->sw_if_index = ntohl (sw_if_index);
10181   mp->is_server = is_server;
10182   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10183   vec_free (file_name);
10184   if (custom_dev_instance != ~0)
10185     {
10186       mp->renumber = 1;
10187       mp->custom_dev_instance = ntohl (custom_dev_instance);
10188     }
10189
10190   S;
10191   W;
10192   /* NOTREACHED */
10193   return 0;
10194 }
10195
10196 static int
10197 api_delete_vhost_user_if (vat_main_t * vam)
10198 {
10199   unformat_input_t *i = vam->input;
10200   vl_api_delete_vhost_user_if_t *mp;
10201   f64 timeout;
10202   u32 sw_if_index = ~0;
10203   u8 sw_if_index_set = 0;
10204
10205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10206     {
10207       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10208         sw_if_index_set = 1;
10209       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10210         sw_if_index_set = 1;
10211       else
10212         break;
10213     }
10214
10215   if (sw_if_index_set == 0)
10216     {
10217       errmsg ("missing sw_if_index or interface name\n");
10218       return -99;
10219     }
10220
10221
10222   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10223
10224   mp->sw_if_index = ntohl (sw_if_index);
10225
10226   S;
10227   W;
10228   /* NOTREACHED */
10229   return 0;
10230 }
10231
10232 static void vl_api_sw_interface_vhost_user_details_t_handler
10233   (vl_api_sw_interface_vhost_user_details_t * mp)
10234 {
10235   vat_main_t *vam = &vat_main;
10236
10237   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10238            (char *) mp->interface_name,
10239            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10240            clib_net_to_host_u64 (mp->features), mp->is_server,
10241            ntohl (mp->num_regions), (char *) mp->sock_filename);
10242   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10243 }
10244
10245 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10246   (vl_api_sw_interface_vhost_user_details_t * mp)
10247 {
10248   vat_main_t *vam = &vat_main;
10249   vat_json_node_t *node = NULL;
10250
10251   if (VAT_JSON_ARRAY != vam->json_tree.type)
10252     {
10253       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10254       vat_json_init_array (&vam->json_tree);
10255     }
10256   node = vat_json_array_add (&vam->json_tree);
10257
10258   vat_json_init_object (node);
10259   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10260   vat_json_object_add_string_copy (node, "interface_name",
10261                                    mp->interface_name);
10262   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10263                             ntohl (mp->virtio_net_hdr_sz));
10264   vat_json_object_add_uint (node, "features",
10265                             clib_net_to_host_u64 (mp->features));
10266   vat_json_object_add_uint (node, "is_server", mp->is_server);
10267   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10268   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10269   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10270 }
10271
10272 static int
10273 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10274 {
10275   vl_api_sw_interface_vhost_user_dump_t *mp;
10276   f64 timeout;
10277   fformat (vam->ofp,
10278            "Interface name           idx hdr_sz features server regions filename\n");
10279
10280   /* Get list of vhost-user interfaces */
10281   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10282   S;
10283
10284   /* Use a control ping for synchronization */
10285   {
10286     vl_api_control_ping_t *mp;
10287     M (CONTROL_PING, control_ping);
10288     S;
10289   }
10290   W;
10291 }
10292
10293 static int
10294 api_show_version (vat_main_t * vam)
10295 {
10296   vl_api_show_version_t *mp;
10297   f64 timeout;
10298
10299   M (SHOW_VERSION, show_version);
10300
10301   S;
10302   W;
10303   /* NOTREACHED */
10304   return 0;
10305 }
10306
10307
10308 static int
10309 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10310 {
10311   unformat_input_t *line_input = vam->input;
10312   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10313   f64 timeout;
10314   ip4_address_t local4, remote4;
10315   ip6_address_t local6, remote6;
10316   u8 is_add = 1;
10317   u8 ipv4_set = 0, ipv6_set = 0;
10318   u8 local_set = 0;
10319   u8 remote_set = 0;
10320   u32 encap_vrf_id = 0;
10321   u32 decap_vrf_id = 0;
10322   u8 protocol = ~0;
10323   u32 vni;
10324   u8 vni_set = 0;
10325
10326   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10327     {
10328       if (unformat (line_input, "del"))
10329         is_add = 0;
10330       else if (unformat (line_input, "local %U",
10331                          unformat_ip4_address, &local4))
10332         {
10333           local_set = 1;
10334           ipv4_set = 1;
10335         }
10336       else if (unformat (line_input, "remote %U",
10337                          unformat_ip4_address, &remote4))
10338         {
10339           remote_set = 1;
10340           ipv4_set = 1;
10341         }
10342       else if (unformat (line_input, "local %U",
10343                          unformat_ip6_address, &local6))
10344         {
10345           local_set = 1;
10346           ipv6_set = 1;
10347         }
10348       else if (unformat (line_input, "remote %U",
10349                          unformat_ip6_address, &remote6))
10350         {
10351           remote_set = 1;
10352           ipv6_set = 1;
10353         }
10354       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10355         ;
10356       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10357         ;
10358       else if (unformat (line_input, "vni %d", &vni))
10359         vni_set = 1;
10360       else if (unformat (line_input, "next-ip4"))
10361         protocol = 1;
10362       else if (unformat (line_input, "next-ip6"))
10363         protocol = 2;
10364       else if (unformat (line_input, "next-ethernet"))
10365         protocol = 3;
10366       else if (unformat (line_input, "next-nsh"))
10367         protocol = 4;
10368       else
10369         {
10370           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10371           return -99;
10372         }
10373     }
10374
10375   if (local_set == 0)
10376     {
10377       errmsg ("tunnel local address not specified\n");
10378       return -99;
10379     }
10380   if (remote_set == 0)
10381     {
10382       errmsg ("tunnel remote address not specified\n");
10383       return -99;
10384     }
10385   if (ipv4_set && ipv6_set)
10386     {
10387       errmsg ("both IPv4 and IPv6 addresses specified");
10388       return -99;
10389     }
10390
10391   if (vni_set == 0)
10392     {
10393       errmsg ("vni not specified\n");
10394       return -99;
10395     }
10396
10397   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10398
10399
10400   if (ipv6_set)
10401     {
10402       clib_memcpy (&mp->local, &local6, sizeof (local6));
10403       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10404     }
10405   else
10406     {
10407       clib_memcpy (&mp->local, &local4, sizeof (local4));
10408       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10409     }
10410
10411   mp->encap_vrf_id = ntohl (encap_vrf_id);
10412   mp->decap_vrf_id = ntohl (decap_vrf_id);
10413   mp->protocol = ntohl (protocol);
10414   mp->vni = ntohl (vni);
10415   mp->is_add = is_add;
10416   mp->is_ipv6 = ipv6_set;
10417
10418   S;
10419   W;
10420   /* NOTREACHED */
10421   return 0;
10422 }
10423
10424 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10425   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10426 {
10427   vat_main_t *vam = &vat_main;
10428
10429   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10430            ntohl (mp->sw_if_index),
10431            format_ip46_address, &(mp->local[0]),
10432            format_ip46_address, &(mp->remote[0]),
10433            ntohl (mp->vni),
10434            ntohl (mp->protocol),
10435            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10436 }
10437
10438 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10439   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10440 {
10441   vat_main_t *vam = &vat_main;
10442   vat_json_node_t *node = NULL;
10443   struct in_addr ip4;
10444   struct in6_addr ip6;
10445
10446   if (VAT_JSON_ARRAY != vam->json_tree.type)
10447     {
10448       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10449       vat_json_init_array (&vam->json_tree);
10450     }
10451   node = vat_json_array_add (&vam->json_tree);
10452
10453   vat_json_init_object (node);
10454   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10455   if (mp->is_ipv6)
10456     {
10457       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10458       vat_json_object_add_ip6 (node, "local", ip6);
10459       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10460       vat_json_object_add_ip6 (node, "remote", ip6);
10461     }
10462   else
10463     {
10464       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10465       vat_json_object_add_ip4 (node, "local", ip4);
10466       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10467       vat_json_object_add_ip4 (node, "remote", ip4);
10468     }
10469   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10470   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10471   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10472   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10473   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10474 }
10475
10476 static int
10477 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10478 {
10479   unformat_input_t *i = vam->input;
10480   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10481   f64 timeout;
10482   u32 sw_if_index;
10483   u8 sw_if_index_set = 0;
10484
10485   /* Parse args required to build the message */
10486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10487     {
10488       if (unformat (i, "sw_if_index %d", &sw_if_index))
10489         sw_if_index_set = 1;
10490       else
10491         break;
10492     }
10493
10494   if (sw_if_index_set == 0)
10495     {
10496       sw_if_index = ~0;
10497     }
10498
10499   if (!vam->json_output)
10500     {
10501       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10502                "sw_if_index", "local", "remote", "vni",
10503                "protocol", "encap_vrf_id", "decap_vrf_id");
10504     }
10505
10506   /* Get list of vxlan-tunnel interfaces */
10507   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10508
10509   mp->sw_if_index = htonl (sw_if_index);
10510
10511   S;
10512
10513   /* Use a control ping for synchronization */
10514   {
10515     vl_api_control_ping_t *mp;
10516     M (CONTROL_PING, control_ping);
10517     S;
10518   }
10519   W;
10520 }
10521
10522 u8 *
10523 format_l2_fib_mac_address (u8 * s, va_list * args)
10524 {
10525   u8 *a = va_arg (*args, u8 *);
10526
10527   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10528                  a[2], a[3], a[4], a[5], a[6], a[7]);
10529 }
10530
10531 static void vl_api_l2_fib_table_entry_t_handler
10532   (vl_api_l2_fib_table_entry_t * mp)
10533 {
10534   vat_main_t *vam = &vat_main;
10535
10536   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10537            "       %d       %d     %d\n",
10538            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10539            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10540            mp->bvi_mac);
10541 }
10542
10543 static void vl_api_l2_fib_table_entry_t_handler_json
10544   (vl_api_l2_fib_table_entry_t * mp)
10545 {
10546   vat_main_t *vam = &vat_main;
10547   vat_json_node_t *node = NULL;
10548
10549   if (VAT_JSON_ARRAY != vam->json_tree.type)
10550     {
10551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10552       vat_json_init_array (&vam->json_tree);
10553     }
10554   node = vat_json_array_add (&vam->json_tree);
10555
10556   vat_json_init_object (node);
10557   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10558   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10559   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10560   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10561   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10562   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10563 }
10564
10565 static int
10566 api_l2_fib_table_dump (vat_main_t * vam)
10567 {
10568   unformat_input_t *i = vam->input;
10569   vl_api_l2_fib_table_dump_t *mp;
10570   f64 timeout;
10571   u32 bd_id;
10572   u8 bd_id_set = 0;
10573
10574   /* Parse args required to build the message */
10575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10576     {
10577       if (unformat (i, "bd_id %d", &bd_id))
10578         bd_id_set = 1;
10579       else
10580         break;
10581     }
10582
10583   if (bd_id_set == 0)
10584     {
10585       errmsg ("missing bridge domain\n");
10586       return -99;
10587     }
10588
10589   fformat (vam->ofp,
10590            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10591
10592   /* Get list of l2 fib entries */
10593   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10594
10595   mp->bd_id = ntohl (bd_id);
10596   S;
10597
10598   /* Use a control ping for synchronization */
10599   {
10600     vl_api_control_ping_t *mp;
10601     M (CONTROL_PING, control_ping);
10602     S;
10603   }
10604   W;
10605 }
10606
10607
10608 static int
10609 api_interface_name_renumber (vat_main_t * vam)
10610 {
10611   unformat_input_t *line_input = vam->input;
10612   vl_api_interface_name_renumber_t *mp;
10613   u32 sw_if_index = ~0;
10614   f64 timeout;
10615   u32 new_show_dev_instance = ~0;
10616
10617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10618     {
10619       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10620                     &sw_if_index))
10621         ;
10622       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10623         ;
10624       else if (unformat (line_input, "new_show_dev_instance %d",
10625                          &new_show_dev_instance))
10626         ;
10627       else
10628         break;
10629     }
10630
10631   if (sw_if_index == ~0)
10632     {
10633       errmsg ("missing interface name or sw_if_index\n");
10634       return -99;
10635     }
10636
10637   if (new_show_dev_instance == ~0)
10638     {
10639       errmsg ("missing new_show_dev_instance\n");
10640       return -99;
10641     }
10642
10643   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10644
10645   mp->sw_if_index = ntohl (sw_if_index);
10646   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10647
10648   S;
10649   W;
10650 }
10651
10652 static int
10653 api_want_ip4_arp_events (vat_main_t * vam)
10654 {
10655   unformat_input_t *line_input = vam->input;
10656   vl_api_want_ip4_arp_events_t *mp;
10657   f64 timeout;
10658   ip4_address_t address;
10659   int address_set = 0;
10660   u32 enable_disable = 1;
10661
10662   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10663     {
10664       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10665         address_set = 1;
10666       else if (unformat (line_input, "del"))
10667         enable_disable = 0;
10668       else
10669         break;
10670     }
10671
10672   if (address_set == 0)
10673     {
10674       errmsg ("missing addresses\n");
10675       return -99;
10676     }
10677
10678   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10679   mp->enable_disable = enable_disable;
10680   mp->pid = getpid ();
10681   mp->address = address.as_u32;
10682
10683   S;
10684   W;
10685 }
10686
10687 static int
10688 api_want_ip6_nd_events (vat_main_t * vam)
10689 {
10690   unformat_input_t *line_input = vam->input;
10691   vl_api_want_ip6_nd_events_t *mp;
10692   f64 timeout;
10693   ip6_address_t address;
10694   int address_set = 0;
10695   u32 enable_disable = 1;
10696
10697   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10698     {
10699       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10700         address_set = 1;
10701       else if (unformat (line_input, "del"))
10702         enable_disable = 0;
10703       else
10704         break;
10705     }
10706
10707   if (address_set == 0)
10708     {
10709       errmsg ("missing addresses\n");
10710       return -99;
10711     }
10712
10713   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10714   mp->enable_disable = enable_disable;
10715   mp->pid = getpid ();
10716   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10717
10718   S;
10719   W;
10720 }
10721
10722 static int
10723 api_input_acl_set_interface (vat_main_t * vam)
10724 {
10725   unformat_input_t *i = vam->input;
10726   vl_api_input_acl_set_interface_t *mp;
10727   f64 timeout;
10728   u32 sw_if_index;
10729   int sw_if_index_set;
10730   u32 ip4_table_index = ~0;
10731   u32 ip6_table_index = ~0;
10732   u32 l2_table_index = ~0;
10733   u8 is_add = 1;
10734
10735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10736     {
10737       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10738         sw_if_index_set = 1;
10739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10740         sw_if_index_set = 1;
10741       else if (unformat (i, "del"))
10742         is_add = 0;
10743       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10744         ;
10745       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10746         ;
10747       else if (unformat (i, "l2-table %d", &l2_table_index))
10748         ;
10749       else
10750         {
10751           clib_warning ("parse error '%U'", format_unformat_error, i);
10752           return -99;
10753         }
10754     }
10755
10756   if (sw_if_index_set == 0)
10757     {
10758       errmsg ("missing interface name or sw_if_index\n");
10759       return -99;
10760     }
10761
10762   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10763
10764   mp->sw_if_index = ntohl (sw_if_index);
10765   mp->ip4_table_index = ntohl (ip4_table_index);
10766   mp->ip6_table_index = ntohl (ip6_table_index);
10767   mp->l2_table_index = ntohl (l2_table_index);
10768   mp->is_add = is_add;
10769
10770   S;
10771   W;
10772   /* NOTREACHED */
10773   return 0;
10774 }
10775
10776 static int
10777 api_ip_address_dump (vat_main_t * vam)
10778 {
10779   unformat_input_t *i = vam->input;
10780   vl_api_ip_address_dump_t *mp;
10781   u32 sw_if_index = ~0;
10782   u8 sw_if_index_set = 0;
10783   u8 ipv4_set = 0;
10784   u8 ipv6_set = 0;
10785   f64 timeout;
10786
10787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10788     {
10789       if (unformat (i, "sw_if_index %d", &sw_if_index))
10790         sw_if_index_set = 1;
10791       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10792         sw_if_index_set = 1;
10793       else if (unformat (i, "ipv4"))
10794         ipv4_set = 1;
10795       else if (unformat (i, "ipv6"))
10796         ipv6_set = 1;
10797       else
10798         break;
10799     }
10800
10801   if (ipv4_set && ipv6_set)
10802     {
10803       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10804       return -99;
10805     }
10806
10807   if ((!ipv4_set) && (!ipv6_set))
10808     {
10809       errmsg ("no ipv4 nor ipv6 flag set\n");
10810       return -99;
10811     }
10812
10813   if (sw_if_index_set == 0)
10814     {
10815       errmsg ("missing interface name or sw_if_index\n");
10816       return -99;
10817     }
10818
10819   vam->current_sw_if_index = sw_if_index;
10820   vam->is_ipv6 = ipv6_set;
10821
10822   M (IP_ADDRESS_DUMP, ip_address_dump);
10823   mp->sw_if_index = ntohl (sw_if_index);
10824   mp->is_ipv6 = ipv6_set;
10825   S;
10826
10827   /* Use a control ping for synchronization */
10828   {
10829     vl_api_control_ping_t *mp;
10830     M (CONTROL_PING, control_ping);
10831     S;
10832   }
10833   W;
10834 }
10835
10836 static int
10837 api_ip_dump (vat_main_t * vam)
10838 {
10839   vl_api_ip_dump_t *mp;
10840   unformat_input_t *in = vam->input;
10841   int ipv4_set = 0;
10842   int ipv6_set = 0;
10843   int is_ipv6;
10844   f64 timeout;
10845   int i;
10846
10847   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10848     {
10849       if (unformat (in, "ipv4"))
10850         ipv4_set = 1;
10851       else if (unformat (in, "ipv6"))
10852         ipv6_set = 1;
10853       else
10854         break;
10855     }
10856
10857   if (ipv4_set && ipv6_set)
10858     {
10859       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10860       return -99;
10861     }
10862
10863   if ((!ipv4_set) && (!ipv6_set))
10864     {
10865       errmsg ("no ipv4 nor ipv6 flag set\n");
10866       return -99;
10867     }
10868
10869   is_ipv6 = ipv6_set;
10870   vam->is_ipv6 = is_ipv6;
10871
10872   /* free old data */
10873   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10874     {
10875       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10876     }
10877   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10878
10879   M (IP_DUMP, ip_dump);
10880   mp->is_ipv6 = ipv6_set;
10881   S;
10882
10883   /* Use a control ping for synchronization */
10884   {
10885     vl_api_control_ping_t *mp;
10886     M (CONTROL_PING, control_ping);
10887     S;
10888   }
10889   W;
10890 }
10891
10892 static int
10893 api_ipsec_spd_add_del (vat_main_t * vam)
10894 {
10895 #if DPDK > 0
10896   unformat_input_t *i = vam->input;
10897   vl_api_ipsec_spd_add_del_t *mp;
10898   f64 timeout;
10899   u32 spd_id = ~0;
10900   u8 is_add = 1;
10901
10902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10903     {
10904       if (unformat (i, "spd_id %d", &spd_id))
10905         ;
10906       else if (unformat (i, "del"))
10907         is_add = 0;
10908       else
10909         {
10910           clib_warning ("parse error '%U'", format_unformat_error, i);
10911           return -99;
10912         }
10913     }
10914   if (spd_id == ~0)
10915     {
10916       errmsg ("spd_id must be set\n");
10917       return -99;
10918     }
10919
10920   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10921
10922   mp->spd_id = ntohl (spd_id);
10923   mp->is_add = is_add;
10924
10925   S;
10926   W;
10927   /* NOTREACHED */
10928   return 0;
10929 #else
10930   clib_warning ("unsupported (no dpdk)");
10931   return -99;
10932 #endif
10933 }
10934
10935 static int
10936 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10937 {
10938 #if DPDK > 0
10939   unformat_input_t *i = vam->input;
10940   vl_api_ipsec_interface_add_del_spd_t *mp;
10941   f64 timeout;
10942   u32 sw_if_index;
10943   u8 sw_if_index_set = 0;
10944   u32 spd_id = (u32) ~ 0;
10945   u8 is_add = 1;
10946
10947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10948     {
10949       if (unformat (i, "del"))
10950         is_add = 0;
10951       else if (unformat (i, "spd_id %d", &spd_id))
10952         ;
10953       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10954         sw_if_index_set = 1;
10955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10956         sw_if_index_set = 1;
10957       else
10958         {
10959           clib_warning ("parse error '%U'", format_unformat_error, i);
10960           return -99;
10961         }
10962
10963     }
10964
10965   if (spd_id == (u32) ~ 0)
10966     {
10967       errmsg ("spd_id must be set\n");
10968       return -99;
10969     }
10970
10971   if (sw_if_index_set == 0)
10972     {
10973       errmsg ("missing interface name or sw_if_index\n");
10974       return -99;
10975     }
10976
10977   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10978
10979   mp->spd_id = ntohl (spd_id);
10980   mp->sw_if_index = ntohl (sw_if_index);
10981   mp->is_add = is_add;
10982
10983   S;
10984   W;
10985   /* NOTREACHED */
10986   return 0;
10987 #else
10988   clib_warning ("unsupported (no dpdk)");
10989   return -99;
10990 #endif
10991 }
10992
10993 static int
10994 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10995 {
10996 #if DPDK > 0
10997   unformat_input_t *i = vam->input;
10998   vl_api_ipsec_spd_add_del_entry_t *mp;
10999   f64 timeout;
11000   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11001   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11002   i32 priority = 0;
11003   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11004   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11005   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11006   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11007
11008   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11009   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11010   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11011   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11012   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11013   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11014
11015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11016     {
11017       if (unformat (i, "del"))
11018         is_add = 0;
11019       if (unformat (i, "outbound"))
11020         is_outbound = 1;
11021       if (unformat (i, "inbound"))
11022         is_outbound = 0;
11023       else if (unformat (i, "spd_id %d", &spd_id))
11024         ;
11025       else if (unformat (i, "sa_id %d", &sa_id))
11026         ;
11027       else if (unformat (i, "priority %d", &priority))
11028         ;
11029       else if (unformat (i, "protocol %d", &protocol))
11030         ;
11031       else if (unformat (i, "lport_start %d", &lport_start))
11032         ;
11033       else if (unformat (i, "lport_stop %d", &lport_stop))
11034         ;
11035       else if (unformat (i, "rport_start %d", &rport_start))
11036         ;
11037       else if (unformat (i, "rport_stop %d", &rport_stop))
11038         ;
11039       else
11040         if (unformat
11041             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11042         {
11043           is_ipv6 = 0;
11044           is_ip_any = 0;
11045         }
11046       else
11047         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11048         {
11049           is_ipv6 = 0;
11050           is_ip_any = 0;
11051         }
11052       else
11053         if (unformat
11054             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11055         {
11056           is_ipv6 = 0;
11057           is_ip_any = 0;
11058         }
11059       else
11060         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11061         {
11062           is_ipv6 = 0;
11063           is_ip_any = 0;
11064         }
11065       else
11066         if (unformat
11067             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11068         {
11069           is_ipv6 = 1;
11070           is_ip_any = 0;
11071         }
11072       else
11073         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11074         {
11075           is_ipv6 = 1;
11076           is_ip_any = 0;
11077         }
11078       else
11079         if (unformat
11080             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11081         {
11082           is_ipv6 = 1;
11083           is_ip_any = 0;
11084         }
11085       else
11086         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11087         {
11088           is_ipv6 = 1;
11089           is_ip_any = 0;
11090         }
11091       else
11092         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11093         {
11094           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11095             {
11096               clib_warning ("unsupported action: 'resolve'");
11097               return -99;
11098             }
11099         }
11100       else
11101         {
11102           clib_warning ("parse error '%U'", format_unformat_error, i);
11103           return -99;
11104         }
11105
11106     }
11107
11108   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11109
11110   mp->spd_id = ntohl (spd_id);
11111   mp->priority = ntohl (priority);
11112   mp->is_outbound = is_outbound;
11113
11114   mp->is_ipv6 = is_ipv6;
11115   if (is_ipv6 || is_ip_any)
11116     {
11117       clib_memcpy (mp->remote_address_start, &raddr6_start,
11118                    sizeof (ip6_address_t));
11119       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11120                    sizeof (ip6_address_t));
11121       clib_memcpy (mp->local_address_start, &laddr6_start,
11122                    sizeof (ip6_address_t));
11123       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11124                    sizeof (ip6_address_t));
11125     }
11126   else
11127     {
11128       clib_memcpy (mp->remote_address_start, &raddr4_start,
11129                    sizeof (ip4_address_t));
11130       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11131                    sizeof (ip4_address_t));
11132       clib_memcpy (mp->local_address_start, &laddr4_start,
11133                    sizeof (ip4_address_t));
11134       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11135                    sizeof (ip4_address_t));
11136     }
11137   mp->protocol = (u8) protocol;
11138   mp->local_port_start = ntohs ((u16) lport_start);
11139   mp->local_port_stop = ntohs ((u16) lport_stop);
11140   mp->remote_port_start = ntohs ((u16) rport_start);
11141   mp->remote_port_stop = ntohs ((u16) rport_stop);
11142   mp->policy = (u8) policy;
11143   mp->sa_id = ntohl (sa_id);
11144   mp->is_add = is_add;
11145   mp->is_ip_any = is_ip_any;
11146   S;
11147   W;
11148   /* NOTREACHED */
11149   return 0;
11150 #else
11151   clib_warning ("unsupported (no dpdk)");
11152   return -99;
11153 #endif
11154 }
11155
11156 static int
11157 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11158 {
11159 #if DPDK > 0
11160   unformat_input_t *i = vam->input;
11161   vl_api_ipsec_sad_add_del_entry_t *mp;
11162   f64 timeout;
11163   u32 sad_id = 0, spi = 0;
11164   u8 *ck = 0, *ik = 0;
11165   u8 is_add = 1;
11166
11167   u8 protocol = IPSEC_PROTOCOL_AH;
11168   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11169   u32 crypto_alg = 0, integ_alg = 0;
11170   ip4_address_t tun_src4;
11171   ip4_address_t tun_dst4;
11172   ip6_address_t tun_src6;
11173   ip6_address_t tun_dst6;
11174
11175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11176     {
11177       if (unformat (i, "del"))
11178         is_add = 0;
11179       else if (unformat (i, "sad_id %d", &sad_id))
11180         ;
11181       else if (unformat (i, "spi %d", &spi))
11182         ;
11183       else if (unformat (i, "esp"))
11184         protocol = IPSEC_PROTOCOL_ESP;
11185       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11186         {
11187           is_tunnel = 1;
11188           is_tunnel_ipv6 = 0;
11189         }
11190       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11191         {
11192           is_tunnel = 1;
11193           is_tunnel_ipv6 = 0;
11194         }
11195       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11196         {
11197           is_tunnel = 1;
11198           is_tunnel_ipv6 = 1;
11199         }
11200       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11201         {
11202           is_tunnel = 1;
11203           is_tunnel_ipv6 = 1;
11204         }
11205       else
11206         if (unformat
11207             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11208         {
11209           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11210               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11211             {
11212               clib_warning ("unsupported crypto-alg: '%U'",
11213                             format_ipsec_crypto_alg, crypto_alg);
11214               return -99;
11215             }
11216         }
11217       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11218         ;
11219       else
11220         if (unformat
11221             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11222         {
11223           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11224               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11225             {
11226               clib_warning ("unsupported integ-alg: '%U'",
11227                             format_ipsec_integ_alg, integ_alg);
11228               return -99;
11229             }
11230         }
11231       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11232         ;
11233       else
11234         {
11235           clib_warning ("parse error '%U'", format_unformat_error, i);
11236           return -99;
11237         }
11238
11239     }
11240
11241   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11242
11243   mp->sad_id = ntohl (sad_id);
11244   mp->is_add = is_add;
11245   mp->protocol = protocol;
11246   mp->spi = ntohl (spi);
11247   mp->is_tunnel = is_tunnel;
11248   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11249   mp->crypto_algorithm = crypto_alg;
11250   mp->integrity_algorithm = integ_alg;
11251   mp->crypto_key_length = vec_len (ck);
11252   mp->integrity_key_length = vec_len (ik);
11253
11254   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11255     mp->crypto_key_length = sizeof (mp->crypto_key);
11256
11257   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11258     mp->integrity_key_length = sizeof (mp->integrity_key);
11259
11260   if (ck)
11261     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11262   if (ik)
11263     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11264
11265   if (is_tunnel)
11266     {
11267       if (is_tunnel_ipv6)
11268         {
11269           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11270                        sizeof (ip6_address_t));
11271           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11272                        sizeof (ip6_address_t));
11273         }
11274       else
11275         {
11276           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11277                        sizeof (ip4_address_t));
11278           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11279                        sizeof (ip4_address_t));
11280         }
11281     }
11282
11283   S;
11284   W;
11285   /* NOTREACHED */
11286   return 0;
11287 #else
11288   clib_warning ("unsupported (no dpdk)");
11289   return -99;
11290 #endif
11291 }
11292
11293 static int
11294 api_ipsec_sa_set_key (vat_main_t * vam)
11295 {
11296 #if DPDK > 0
11297   unformat_input_t *i = vam->input;
11298   vl_api_ipsec_sa_set_key_t *mp;
11299   f64 timeout;
11300   u32 sa_id;
11301   u8 *ck = 0, *ik = 0;
11302
11303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11304     {
11305       if (unformat (i, "sa_id %d", &sa_id))
11306         ;
11307       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11308         ;
11309       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11310         ;
11311       else
11312         {
11313           clib_warning ("parse error '%U'", format_unformat_error, i);
11314           return -99;
11315         }
11316     }
11317
11318   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11319
11320   mp->sa_id = ntohl (sa_id);
11321   mp->crypto_key_length = vec_len (ck);
11322   mp->integrity_key_length = vec_len (ik);
11323
11324   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11325     mp->crypto_key_length = sizeof (mp->crypto_key);
11326
11327   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11328     mp->integrity_key_length = sizeof (mp->integrity_key);
11329
11330   if (ck)
11331     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11332   if (ik)
11333     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11334
11335   S;
11336   W;
11337   /* NOTREACHED */
11338   return 0;
11339 #else
11340   clib_warning ("unsupported (no dpdk)");
11341   return -99;
11342 #endif
11343 }
11344
11345 static int
11346 api_ikev2_profile_add_del (vat_main_t * vam)
11347 {
11348 #if DPDK > 0
11349   unformat_input_t *i = vam->input;
11350   vl_api_ikev2_profile_add_del_t *mp;
11351   f64 timeout;
11352   u8 is_add = 1;
11353   u8 *name = 0;
11354
11355   const char *valid_chars = "a-zA-Z0-9_";
11356
11357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11358     {
11359       if (unformat (i, "del"))
11360         is_add = 0;
11361       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11362         vec_add1 (name, 0);
11363       else
11364         {
11365           errmsg ("parse error '%U'", format_unformat_error, i);
11366           return -99;
11367         }
11368     }
11369
11370   if (!vec_len (name))
11371     {
11372       errmsg ("profile name must be specified");
11373       return -99;
11374     }
11375
11376   if (vec_len (name) > 64)
11377     {
11378       errmsg ("profile name too long");
11379       return -99;
11380     }
11381
11382   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11383
11384   clib_memcpy (mp->name, name, vec_len (name));
11385   mp->is_add = is_add;
11386   vec_free (name);
11387
11388   S;
11389   W;
11390   /* NOTREACHED */
11391   return 0;
11392 #else
11393   clib_warning ("unsupported (no dpdk)");
11394   return -99;
11395 #endif
11396 }
11397
11398 static int
11399 api_ikev2_profile_set_auth (vat_main_t * vam)
11400 {
11401 #if DPDK > 0
11402   unformat_input_t *i = vam->input;
11403   vl_api_ikev2_profile_set_auth_t *mp;
11404   f64 timeout;
11405   u8 *name = 0;
11406   u8 *data = 0;
11407   u32 auth_method = 0;
11408   u8 is_hex = 0;
11409
11410   const char *valid_chars = "a-zA-Z0-9_";
11411
11412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11413     {
11414       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11415         vec_add1 (name, 0);
11416       else if (unformat (i, "auth_method %U",
11417                          unformat_ikev2_auth_method, &auth_method))
11418         ;
11419       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11420         is_hex = 1;
11421       else if (unformat (i, "auth_data %v", &data))
11422         ;
11423       else
11424         {
11425           errmsg ("parse error '%U'", format_unformat_error, i);
11426           return -99;
11427         }
11428     }
11429
11430   if (!vec_len (name))
11431     {
11432       errmsg ("profile name must be specified");
11433       return -99;
11434     }
11435
11436   if (vec_len (name) > 64)
11437     {
11438       errmsg ("profile name too long");
11439       return -99;
11440     }
11441
11442   if (!vec_len (data))
11443     {
11444       errmsg ("auth_data must be specified");
11445       return -99;
11446     }
11447
11448   if (!auth_method)
11449     {
11450       errmsg ("auth_method must be specified");
11451       return -99;
11452     }
11453
11454   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11455
11456   mp->is_hex = is_hex;
11457   mp->auth_method = (u8) auth_method;
11458   mp->data_len = vec_len (data);
11459   clib_memcpy (mp->name, name, vec_len (name));
11460   clib_memcpy (mp->data, data, vec_len (data));
11461   vec_free (name);
11462   vec_free (data);
11463
11464   S;
11465   W;
11466   /* NOTREACHED */
11467   return 0;
11468 #else
11469   clib_warning ("unsupported (no dpdk)");
11470   return -99;
11471 #endif
11472 }
11473
11474 static int
11475 api_ikev2_profile_set_id (vat_main_t * vam)
11476 {
11477 #if DPDK > 0
11478   unformat_input_t *i = vam->input;
11479   vl_api_ikev2_profile_set_id_t *mp;
11480   f64 timeout;
11481   u8 *name = 0;
11482   u8 *data = 0;
11483   u8 is_local = 0;
11484   u32 id_type = 0;
11485   ip4_address_t ip4;
11486
11487   const char *valid_chars = "a-zA-Z0-9_";
11488
11489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11490     {
11491       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11492         vec_add1 (name, 0);
11493       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11494         ;
11495       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11496         {
11497           data = vec_new (u8, 4);
11498           clib_memcpy (data, ip4.as_u8, 4);
11499         }
11500       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11501         ;
11502       else if (unformat (i, "id_data %v", &data))
11503         ;
11504       else if (unformat (i, "local"))
11505         is_local = 1;
11506       else if (unformat (i, "remote"))
11507         is_local = 0;
11508       else
11509         {
11510           errmsg ("parse error '%U'", format_unformat_error, i);
11511           return -99;
11512         }
11513     }
11514
11515   if (!vec_len (name))
11516     {
11517       errmsg ("profile name must be specified");
11518       return -99;
11519     }
11520
11521   if (vec_len (name) > 64)
11522     {
11523       errmsg ("profile name too long");
11524       return -99;
11525     }
11526
11527   if (!vec_len (data))
11528     {
11529       errmsg ("id_data must be specified");
11530       return -99;
11531     }
11532
11533   if (!id_type)
11534     {
11535       errmsg ("id_type must be specified");
11536       return -99;
11537     }
11538
11539   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11540
11541   mp->is_local = is_local;
11542   mp->id_type = (u8) id_type;
11543   mp->data_len = vec_len (data);
11544   clib_memcpy (mp->name, name, vec_len (name));
11545   clib_memcpy (mp->data, data, vec_len (data));
11546   vec_free (name);
11547   vec_free (data);
11548
11549   S;
11550   W;
11551   /* NOTREACHED */
11552   return 0;
11553 #else
11554   clib_warning ("unsupported (no dpdk)");
11555   return -99;
11556 #endif
11557 }
11558
11559 static int
11560 api_ikev2_profile_set_ts (vat_main_t * vam)
11561 {
11562 #if DPDK > 0
11563   unformat_input_t *i = vam->input;
11564   vl_api_ikev2_profile_set_ts_t *mp;
11565   f64 timeout;
11566   u8 *name = 0;
11567   u8 is_local = 0;
11568   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11569   ip4_address_t start_addr, end_addr;
11570
11571   const char *valid_chars = "a-zA-Z0-9_";
11572
11573   start_addr.as_u32 = 0;
11574   end_addr.as_u32 = (u32) ~ 0;
11575
11576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11577     {
11578       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11579         vec_add1 (name, 0);
11580       else if (unformat (i, "protocol %d", &proto))
11581         ;
11582       else if (unformat (i, "start_port %d", &start_port))
11583         ;
11584       else if (unformat (i, "end_port %d", &end_port))
11585         ;
11586       else
11587         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11588         ;
11589       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11590         ;
11591       else if (unformat (i, "local"))
11592         is_local = 1;
11593       else if (unformat (i, "remote"))
11594         is_local = 0;
11595       else
11596         {
11597           errmsg ("parse error '%U'", format_unformat_error, i);
11598           return -99;
11599         }
11600     }
11601
11602   if (!vec_len (name))
11603     {
11604       errmsg ("profile name must be specified");
11605       return -99;
11606     }
11607
11608   if (vec_len (name) > 64)
11609     {
11610       errmsg ("profile name too long");
11611       return -99;
11612     }
11613
11614   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11615
11616   mp->is_local = is_local;
11617   mp->proto = (u8) proto;
11618   mp->start_port = (u16) start_port;
11619   mp->end_port = (u16) end_port;
11620   mp->start_addr = start_addr.as_u32;
11621   mp->end_addr = end_addr.as_u32;
11622   clib_memcpy (mp->name, name, vec_len (name));
11623   vec_free (name);
11624
11625   S;
11626   W;
11627   /* NOTREACHED */
11628   return 0;
11629 #else
11630   clib_warning ("unsupported (no dpdk)");
11631   return -99;
11632 #endif
11633 }
11634
11635 static int
11636 api_ikev2_set_local_key (vat_main_t * vam)
11637 {
11638 #if DPDK > 0
11639   unformat_input_t *i = vam->input;
11640   vl_api_ikev2_set_local_key_t *mp;
11641   f64 timeout;
11642   u8 *file = 0;
11643
11644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11645     {
11646       if (unformat (i, "file %v", &file))
11647         vec_add1 (file, 0);
11648       else
11649         {
11650           errmsg ("parse error '%U'", format_unformat_error, i);
11651           return -99;
11652         }
11653     }
11654
11655   if (!vec_len (file))
11656     {
11657       errmsg ("RSA key file must be specified");
11658       return -99;
11659     }
11660
11661   if (vec_len (file) > 256)
11662     {
11663       errmsg ("file name too long");
11664       return -99;
11665     }
11666
11667   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11668
11669   clib_memcpy (mp->key_file, file, vec_len (file));
11670   vec_free (file);
11671
11672   S;
11673   W;
11674   /* NOTREACHED */
11675   return 0;
11676 #else
11677   clib_warning ("unsupported (no dpdk)");
11678   return -99;
11679 #endif
11680 }
11681
11682 /*
11683  * MAP
11684  */
11685 static int
11686 api_map_add_domain (vat_main_t * vam)
11687 {
11688   unformat_input_t *i = vam->input;
11689   vl_api_map_add_domain_t *mp;
11690   f64 timeout;
11691
11692   ip4_address_t ip4_prefix;
11693   ip6_address_t ip6_prefix;
11694   ip6_address_t ip6_src;
11695   u32 num_m_args = 0;
11696   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11697     0, psid_length = 0;
11698   u8 is_translation = 0;
11699   u32 mtu = 0;
11700   u32 ip6_src_len = 128;
11701
11702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11703     {
11704       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11705                     &ip4_prefix, &ip4_prefix_len))
11706         num_m_args++;
11707       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11708                          &ip6_prefix, &ip6_prefix_len))
11709         num_m_args++;
11710       else
11711         if (unformat
11712             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11713              &ip6_src_len))
11714         num_m_args++;
11715       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11716         num_m_args++;
11717       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11718         num_m_args++;
11719       else if (unformat (i, "psid-offset %d", &psid_offset))
11720         num_m_args++;
11721       else if (unformat (i, "psid-len %d", &psid_length))
11722         num_m_args++;
11723       else if (unformat (i, "mtu %d", &mtu))
11724         num_m_args++;
11725       else if (unformat (i, "map-t"))
11726         is_translation = 1;
11727       else
11728         {
11729           clib_warning ("parse error '%U'", format_unformat_error, i);
11730           return -99;
11731         }
11732     }
11733
11734   if (num_m_args < 3)
11735     {
11736       errmsg ("mandatory argument(s) missing\n");
11737       return -99;
11738     }
11739
11740   /* Construct the API message */
11741   M (MAP_ADD_DOMAIN, map_add_domain);
11742
11743   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11744   mp->ip4_prefix_len = ip4_prefix_len;
11745
11746   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11747   mp->ip6_prefix_len = ip6_prefix_len;
11748
11749   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11750   mp->ip6_src_prefix_len = ip6_src_len;
11751
11752   mp->ea_bits_len = ea_bits_len;
11753   mp->psid_offset = psid_offset;
11754   mp->psid_length = psid_length;
11755   mp->is_translation = is_translation;
11756   mp->mtu = htons (mtu);
11757
11758   /* send it... */
11759   S;
11760
11761   /* Wait for a reply, return good/bad news  */
11762   W;
11763 }
11764
11765 static int
11766 api_map_del_domain (vat_main_t * vam)
11767 {
11768   unformat_input_t *i = vam->input;
11769   vl_api_map_del_domain_t *mp;
11770   f64 timeout;
11771
11772   u32 num_m_args = 0;
11773   u32 index;
11774
11775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11776     {
11777       if (unformat (i, "index %d", &index))
11778         num_m_args++;
11779       else
11780         {
11781           clib_warning ("parse error '%U'", format_unformat_error, i);
11782           return -99;
11783         }
11784     }
11785
11786   if (num_m_args != 1)
11787     {
11788       errmsg ("mandatory argument(s) missing\n");
11789       return -99;
11790     }
11791
11792   /* Construct the API message */
11793   M (MAP_DEL_DOMAIN, map_del_domain);
11794
11795   mp->index = ntohl (index);
11796
11797   /* send it... */
11798   S;
11799
11800   /* Wait for a reply, return good/bad news  */
11801   W;
11802 }
11803
11804 static int
11805 api_map_add_del_rule (vat_main_t * vam)
11806 {
11807   unformat_input_t *i = vam->input;
11808   vl_api_map_add_del_rule_t *mp;
11809   f64 timeout;
11810   u8 is_add = 1;
11811   ip6_address_t ip6_dst;
11812   u32 num_m_args = 0, index, psid = 0;
11813
11814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11815     {
11816       if (unformat (i, "index %d", &index))
11817         num_m_args++;
11818       else if (unformat (i, "psid %d", &psid))
11819         num_m_args++;
11820       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11821         num_m_args++;
11822       else if (unformat (i, "del"))
11823         {
11824           is_add = 0;
11825         }
11826       else
11827         {
11828           clib_warning ("parse error '%U'", format_unformat_error, i);
11829           return -99;
11830         }
11831     }
11832
11833   /* Construct the API message */
11834   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11835
11836   mp->index = ntohl (index);
11837   mp->is_add = is_add;
11838   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11839   mp->psid = ntohs (psid);
11840
11841   /* send it... */
11842   S;
11843
11844   /* Wait for a reply, return good/bad news  */
11845   W;
11846 }
11847
11848 static int
11849 api_map_domain_dump (vat_main_t * vam)
11850 {
11851   vl_api_map_domain_dump_t *mp;
11852   f64 timeout;
11853
11854   /* Construct the API message */
11855   M (MAP_DOMAIN_DUMP, map_domain_dump);
11856
11857   /* send it... */
11858   S;
11859
11860   /* Use a control ping for synchronization */
11861   {
11862     vl_api_control_ping_t *mp;
11863     M (CONTROL_PING, control_ping);
11864     S;
11865   }
11866   W;
11867 }
11868
11869 static int
11870 api_map_rule_dump (vat_main_t * vam)
11871 {
11872   unformat_input_t *i = vam->input;
11873   vl_api_map_rule_dump_t *mp;
11874   f64 timeout;
11875   u32 domain_index = ~0;
11876
11877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11878     {
11879       if (unformat (i, "index %u", &domain_index))
11880         ;
11881       else
11882         break;
11883     }
11884
11885   if (domain_index == ~0)
11886     {
11887       clib_warning ("parse error: domain index expected");
11888       return -99;
11889     }
11890
11891   /* Construct the API message */
11892   M (MAP_RULE_DUMP, map_rule_dump);
11893
11894   mp->domain_index = htonl (domain_index);
11895
11896   /* send it... */
11897   S;
11898
11899   /* Use a control ping for synchronization */
11900   {
11901     vl_api_control_ping_t *mp;
11902     M (CONTROL_PING, control_ping);
11903     S;
11904   }
11905   W;
11906 }
11907
11908 static void vl_api_map_add_domain_reply_t_handler
11909   (vl_api_map_add_domain_reply_t * mp)
11910 {
11911   vat_main_t *vam = &vat_main;
11912   i32 retval = ntohl (mp->retval);
11913
11914   if (vam->async_mode)
11915     {
11916       vam->async_errors += (retval < 0);
11917     }
11918   else
11919     {
11920       vam->retval = retval;
11921       vam->result_ready = 1;
11922     }
11923 }
11924
11925 static void vl_api_map_add_domain_reply_t_handler_json
11926   (vl_api_map_add_domain_reply_t * mp)
11927 {
11928   vat_main_t *vam = &vat_main;
11929   vat_json_node_t node;
11930
11931   vat_json_init_object (&node);
11932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11933   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11934
11935   vat_json_print (vam->ofp, &node);
11936   vat_json_free (&node);
11937
11938   vam->retval = ntohl (mp->retval);
11939   vam->result_ready = 1;
11940 }
11941
11942 static int
11943 api_get_first_msg_id (vat_main_t * vam)
11944 {
11945   vl_api_get_first_msg_id_t *mp;
11946   f64 timeout;
11947   unformat_input_t *i = vam->input;
11948   u8 *name;
11949   u8 name_set = 0;
11950
11951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11952     {
11953       if (unformat (i, "client %s", &name))
11954         name_set = 1;
11955       else
11956         break;
11957     }
11958
11959   if (name_set == 0)
11960     {
11961       errmsg ("missing client name\n");
11962       return -99;
11963     }
11964   vec_add1 (name, 0);
11965
11966   if (vec_len (name) > 63)
11967     {
11968       errmsg ("client name too long\n");
11969       return -99;
11970     }
11971
11972   M (GET_FIRST_MSG_ID, get_first_msg_id);
11973   clib_memcpy (mp->name, name, vec_len (name));
11974   S;
11975   W;
11976   /* NOTREACHED */
11977   return 0;
11978 }
11979
11980 static int
11981 api_cop_interface_enable_disable (vat_main_t * vam)
11982 {
11983   unformat_input_t *line_input = vam->input;
11984   vl_api_cop_interface_enable_disable_t *mp;
11985   f64 timeout;
11986   u32 sw_if_index = ~0;
11987   u8 enable_disable = 1;
11988
11989   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11990     {
11991       if (unformat (line_input, "disable"))
11992         enable_disable = 0;
11993       if (unformat (line_input, "enable"))
11994         enable_disable = 1;
11995       else if (unformat (line_input, "%U", unformat_sw_if_index,
11996                          vam, &sw_if_index))
11997         ;
11998       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11999         ;
12000       else
12001         break;
12002     }
12003
12004   if (sw_if_index == ~0)
12005     {
12006       errmsg ("missing interface name or sw_if_index\n");
12007       return -99;
12008     }
12009
12010   /* Construct the API message */
12011   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12012   mp->sw_if_index = ntohl (sw_if_index);
12013   mp->enable_disable = enable_disable;
12014
12015   /* send it... */
12016   S;
12017   /* Wait for the reply */
12018   W;
12019 }
12020
12021 static int
12022 api_cop_whitelist_enable_disable (vat_main_t * vam)
12023 {
12024   unformat_input_t *line_input = vam->input;
12025   vl_api_cop_whitelist_enable_disable_t *mp;
12026   f64 timeout;
12027   u32 sw_if_index = ~0;
12028   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12029   u32 fib_id = 0;
12030
12031   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12032     {
12033       if (unformat (line_input, "ip4"))
12034         ip4 = 1;
12035       else if (unformat (line_input, "ip6"))
12036         ip6 = 1;
12037       else if (unformat (line_input, "default"))
12038         default_cop = 1;
12039       else if (unformat (line_input, "%U", unformat_sw_if_index,
12040                          vam, &sw_if_index))
12041         ;
12042       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12043         ;
12044       else if (unformat (line_input, "fib-id %d", &fib_id))
12045         ;
12046       else
12047         break;
12048     }
12049
12050   if (sw_if_index == ~0)
12051     {
12052       errmsg ("missing interface name or sw_if_index\n");
12053       return -99;
12054     }
12055
12056   /* Construct the API message */
12057   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12058   mp->sw_if_index = ntohl (sw_if_index);
12059   mp->fib_id = ntohl (fib_id);
12060   mp->ip4 = ip4;
12061   mp->ip6 = ip6;
12062   mp->default_cop = default_cop;
12063
12064   /* send it... */
12065   S;
12066   /* Wait for the reply */
12067   W;
12068 }
12069
12070 static int
12071 api_get_node_graph (vat_main_t * vam)
12072 {
12073   vl_api_get_node_graph_t *mp;
12074   f64 timeout;
12075
12076   M (GET_NODE_GRAPH, get_node_graph);
12077
12078   /* send it... */
12079   S;
12080   /* Wait for the reply */
12081   W;
12082 }
12083
12084 /* *INDENT-OFF* */
12085 /** Used for parsing LISP eids */
12086 typedef CLIB_PACKED(struct{
12087   u8 addr[16];   /**< eid address */
12088   u32 len;       /**< prefix length if IP */
12089   u8 type;      /**< type of eid */
12090 }) lisp_eid_vat_t;
12091 /* *INDENT-ON* */
12092
12093 static uword
12094 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12095 {
12096   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12097
12098   memset (a, 0, sizeof (a[0]));
12099
12100   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12101     {
12102       a->type = 0;              /* ipv4 type */
12103     }
12104   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12105     {
12106       a->type = 1;              /* ipv6 type */
12107     }
12108   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12109     {
12110       a->type = 2;              /* mac type */
12111     }
12112   else
12113     {
12114       return 0;
12115     }
12116
12117   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12118     {
12119       return 0;
12120     }
12121
12122   return 1;
12123 }
12124
12125 static int
12126 lisp_eid_size_vat (u8 type)
12127 {
12128   switch (type)
12129     {
12130     case 0:
12131       return 4;
12132     case 1:
12133       return 16;
12134     case 2:
12135       return 6;
12136     }
12137   return 0;
12138 }
12139
12140 static void
12141 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12142 {
12143   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12144 }
12145
12146 /* *INDENT-OFF* */
12147 /** Used for transferring locators via VPP API */
12148 typedef CLIB_PACKED(struct
12149 {
12150   u32 sw_if_index; /**< locator sw_if_index */
12151   u8 priority; /**< locator priority */
12152   u8 weight;   /**< locator weight */
12153 }) ls_locator_t;
12154 /* *INDENT-ON* */
12155
12156 static int
12157 api_lisp_add_del_locator_set (vat_main_t * vam)
12158 {
12159   unformat_input_t *input = vam->input;
12160   vl_api_lisp_add_del_locator_set_t *mp;
12161   f64 timeout = ~0;
12162   u8 is_add = 1;
12163   u8 *locator_set_name = NULL;
12164   u8 locator_set_name_set = 0;
12165   ls_locator_t locator, *locators = 0;
12166   u32 sw_if_index, priority, weight;
12167   u32 data_len = 0;
12168
12169   /* Parse args required to build the message */
12170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12171     {
12172       if (unformat (input, "del"))
12173         {
12174           is_add = 0;
12175         }
12176       else if (unformat (input, "locator-set %s", &locator_set_name))
12177         {
12178           locator_set_name_set = 1;
12179         }
12180       else if (unformat (input, "sw_if_index %u p %u w %u",
12181                          &sw_if_index, &priority, &weight))
12182         {
12183           locator.sw_if_index = htonl (sw_if_index);
12184           locator.priority = priority;
12185           locator.weight = weight;
12186           vec_add1 (locators, locator);
12187         }
12188       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12189                          vam, &sw_if_index, &priority, &weight))
12190         {
12191           locator.sw_if_index = htonl (sw_if_index);
12192           locator.priority = priority;
12193           locator.weight = weight;
12194           vec_add1 (locators, locator);
12195         }
12196       else
12197         break;
12198     }
12199
12200   if (locator_set_name_set == 0)
12201     {
12202       errmsg ("missing locator-set name");
12203       vec_free (locators);
12204       return -99;
12205     }
12206
12207   if (vec_len (locator_set_name) > 64)
12208     {
12209       errmsg ("locator-set name too long\n");
12210       vec_free (locator_set_name);
12211       vec_free (locators);
12212       return -99;
12213     }
12214   vec_add1 (locator_set_name, 0);
12215
12216   data_len = sizeof (ls_locator_t) * vec_len (locators);
12217
12218   /* Construct the API message */
12219   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12220
12221   mp->is_add = is_add;
12222   clib_memcpy (mp->locator_set_name, locator_set_name,
12223                vec_len (locator_set_name));
12224   vec_free (locator_set_name);
12225
12226   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12227   if (locators)
12228     clib_memcpy (mp->locators, locators, data_len);
12229   vec_free (locators);
12230
12231   /* send it... */
12232   S;
12233
12234   /* Wait for a reply... */
12235   W;
12236
12237   /* NOTREACHED */
12238   return 0;
12239 }
12240
12241 static int
12242 api_lisp_add_del_locator (vat_main_t * vam)
12243 {
12244   unformat_input_t *input = vam->input;
12245   vl_api_lisp_add_del_locator_t *mp;
12246   f64 timeout = ~0;
12247   u32 tmp_if_index = ~0;
12248   u32 sw_if_index = ~0;
12249   u8 sw_if_index_set = 0;
12250   u8 sw_if_index_if_name_set = 0;
12251   u32 priority = ~0;
12252   u8 priority_set = 0;
12253   u32 weight = ~0;
12254   u8 weight_set = 0;
12255   u8 is_add = 1;
12256   u8 *locator_set_name = NULL;
12257   u8 locator_set_name_set = 0;
12258
12259   /* Parse args required to build the message */
12260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12261     {
12262       if (unformat (input, "del"))
12263         {
12264           is_add = 0;
12265         }
12266       else if (unformat (input, "locator-set %s", &locator_set_name))
12267         {
12268           locator_set_name_set = 1;
12269         }
12270       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12271                          &tmp_if_index))
12272         {
12273           sw_if_index_if_name_set = 1;
12274           sw_if_index = tmp_if_index;
12275         }
12276       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12277         {
12278           sw_if_index_set = 1;
12279           sw_if_index = tmp_if_index;
12280         }
12281       else if (unformat (input, "p %d", &priority))
12282         {
12283           priority_set = 1;
12284         }
12285       else if (unformat (input, "w %d", &weight))
12286         {
12287           weight_set = 1;
12288         }
12289       else
12290         break;
12291     }
12292
12293   if (locator_set_name_set == 0)
12294     {
12295       errmsg ("missing locator-set name");
12296       return -99;
12297     }
12298
12299   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12300     {
12301       errmsg ("missing sw_if_index");
12302       vec_free (locator_set_name);
12303       return -99;
12304     }
12305
12306   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12307     {
12308       errmsg ("cannot use both params interface name and sw_if_index");
12309       vec_free (locator_set_name);
12310       return -99;
12311     }
12312
12313   if (priority_set == 0)
12314     {
12315       errmsg ("missing locator-set priority\n");
12316       vec_free (locator_set_name);
12317       return -99;
12318     }
12319
12320   if (weight_set == 0)
12321     {
12322       errmsg ("missing locator-set weight\n");
12323       vec_free (locator_set_name);
12324       return -99;
12325     }
12326
12327   if (vec_len (locator_set_name) > 64)
12328     {
12329       errmsg ("locator-set name too long\n");
12330       vec_free (locator_set_name);
12331       return -99;
12332     }
12333   vec_add1 (locator_set_name, 0);
12334
12335   /* Construct the API message */
12336   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12337
12338   mp->is_add = is_add;
12339   mp->sw_if_index = ntohl (sw_if_index);
12340   mp->priority = priority;
12341   mp->weight = weight;
12342   clib_memcpy (mp->locator_set_name, locator_set_name,
12343                vec_len (locator_set_name));
12344   vec_free (locator_set_name);
12345
12346   /* send it... */
12347   S;
12348
12349   /* Wait for a reply... */
12350   W;
12351
12352   /* NOTREACHED */
12353   return 0;
12354 }
12355
12356 static int
12357 api_lisp_add_del_local_eid (vat_main_t * vam)
12358 {
12359   unformat_input_t *input = vam->input;
12360   vl_api_lisp_add_del_local_eid_t *mp;
12361   f64 timeout = ~0;
12362   u8 is_add = 1;
12363   u8 eid_set = 0;
12364   lisp_eid_vat_t _eid, *eid = &_eid;
12365   u8 *locator_set_name = 0;
12366   u8 locator_set_name_set = 0;
12367   u32 vni = 0;
12368
12369   /* Parse args required to build the message */
12370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12371     {
12372       if (unformat (input, "del"))
12373         {
12374           is_add = 0;
12375         }
12376       else if (unformat (input, "vni %d", &vni))
12377         {
12378           ;
12379         }
12380       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12381         {
12382           eid_set = 1;
12383         }
12384       else if (unformat (input, "locator-set %s", &locator_set_name))
12385         {
12386           locator_set_name_set = 1;
12387         }
12388       else
12389         break;
12390     }
12391
12392   if (locator_set_name_set == 0)
12393     {
12394       errmsg ("missing locator-set name\n");
12395       return -99;
12396     }
12397
12398   if (0 == eid_set)
12399     {
12400       errmsg ("EID address not set!");
12401       vec_free (locator_set_name);
12402       return -99;
12403     }
12404
12405   if (vec_len (locator_set_name) > 64)
12406     {
12407       errmsg ("locator-set name too long\n");
12408       vec_free (locator_set_name);
12409       return -99;
12410     }
12411   vec_add1 (locator_set_name, 0);
12412
12413   /* Construct the API message */
12414   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12415
12416   mp->is_add = is_add;
12417   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12418   mp->eid_type = eid->type;
12419   mp->prefix_len = eid->len;
12420   mp->vni = clib_host_to_net_u32 (vni);
12421   clib_memcpy (mp->locator_set_name, locator_set_name,
12422                vec_len (locator_set_name));
12423
12424   vec_free (locator_set_name);
12425
12426   /* send it... */
12427   S;
12428
12429   /* Wait for a reply... */
12430   W;
12431
12432   /* NOTREACHED */
12433   return 0;
12434 }
12435
12436 /* *INDENT-OFF* */
12437 /** Used for transferring locators via VPP API */
12438 typedef CLIB_PACKED(struct
12439 {
12440   u8 is_ip4; /**< is locator an IPv4 address? */
12441   u8 priority; /**< locator priority */
12442   u8 weight;   /**< locator weight */
12443   u8 addr[16]; /**< IPv4/IPv6 address */
12444 }) rloc_t;
12445 /* *INDENT-ON* */
12446
12447 static int
12448 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12449 {
12450   unformat_input_t *input = vam->input;
12451   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12452   f64 timeout = ~0;
12453   u8 is_add = 1;
12454   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12455   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12456   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12457   u32 action = ~0, p, w;
12458   ip4_address_t rmt_rloc4, lcl_rloc4;
12459   ip6_address_t rmt_rloc6, lcl_rloc6;
12460   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12461
12462   memset (&rloc, 0, sizeof (rloc));
12463
12464   /* Parse args required to build the message */
12465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12466     {
12467       if (unformat (input, "del"))
12468         {
12469           is_add = 0;
12470         }
12471       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12472         {
12473           rmt_eid_set = 1;
12474         }
12475       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12476         {
12477           lcl_eid_set = 1;
12478         }
12479       else if (unformat (input, "p %d w %d", &p, &w))
12480         {
12481           if (!curr_rloc)
12482             {
12483               errmsg ("No RLOC configured for setting priority/weight!");
12484               return -99;
12485             }
12486           curr_rloc->priority = p;
12487           curr_rloc->weight = w;
12488         }
12489       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12490                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12491         {
12492           rloc.is_ip4 = 1;
12493
12494           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12495           rloc.priority = rloc.weight = 0;
12496           vec_add1 (lcl_locs, rloc);
12497
12498           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12499           vec_add1 (rmt_locs, rloc);
12500           /* priority and weight saved in rmt loc */
12501           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12502         }
12503       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12504                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12505         {
12506           rloc.is_ip4 = 0;
12507           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12508           rloc.priority = rloc.weight = 0;
12509           vec_add1 (lcl_locs, rloc);
12510
12511           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12512           vec_add1 (rmt_locs, rloc);
12513           /* priority and weight saved in rmt loc */
12514           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12515         }
12516       else if (unformat (input, "action %d", &action))
12517         {
12518           ;
12519         }
12520       else
12521         {
12522           clib_warning ("parse error '%U'", format_unformat_error, input);
12523           return -99;
12524         }
12525     }
12526
12527   if (!rmt_eid_set)
12528     {
12529       errmsg ("remote eid addresses not set\n");
12530       return -99;
12531     }
12532
12533   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12534     {
12535       errmsg ("eid types don't match\n");
12536       return -99;
12537     }
12538
12539   if (0 == rmt_locs && (u32) ~ 0 == action)
12540     {
12541       errmsg ("action not set for negative mapping\n");
12542       return -99;
12543     }
12544
12545   /* Construct the API message */
12546   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12547
12548   mp->is_add = is_add;
12549   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12550   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12551   mp->eid_type = rmt_eid->type;
12552   mp->rmt_len = rmt_eid->len;
12553   mp->lcl_len = lcl_eid->len;
12554   mp->action = action;
12555
12556   if (0 != rmt_locs && 0 != lcl_locs)
12557     {
12558       mp->loc_num = vec_len (rmt_locs);
12559       clib_memcpy (mp->lcl_locs, lcl_locs,
12560                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12561       clib_memcpy (mp->rmt_locs, rmt_locs,
12562                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12563     }
12564   vec_free (lcl_locs);
12565   vec_free (rmt_locs);
12566
12567   /* send it... */
12568   S;
12569
12570   /* Wait for a reply... */
12571   W;
12572
12573   /* NOTREACHED */
12574   return 0;
12575 }
12576
12577 static int
12578 api_lisp_add_del_map_resolver (vat_main_t * vam)
12579 {
12580   unformat_input_t *input = vam->input;
12581   vl_api_lisp_add_del_map_resolver_t *mp;
12582   f64 timeout = ~0;
12583   u8 is_add = 1;
12584   u8 ipv4_set = 0;
12585   u8 ipv6_set = 0;
12586   ip4_address_t ipv4;
12587   ip6_address_t ipv6;
12588
12589   /* Parse args required to build the message */
12590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12591     {
12592       if (unformat (input, "del"))
12593         {
12594           is_add = 0;
12595         }
12596       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12597         {
12598           ipv4_set = 1;
12599         }
12600       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12601         {
12602           ipv6_set = 1;
12603         }
12604       else
12605         break;
12606     }
12607
12608   if (ipv4_set && ipv6_set)
12609     {
12610       errmsg ("both eid v4 and v6 addresses set\n");
12611       return -99;
12612     }
12613
12614   if (!ipv4_set && !ipv6_set)
12615     {
12616       errmsg ("eid addresses not set\n");
12617       return -99;
12618     }
12619
12620   /* Construct the API message */
12621   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12622
12623   mp->is_add = is_add;
12624   if (ipv6_set)
12625     {
12626       mp->is_ipv6 = 1;
12627       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12628     }
12629   else
12630     {
12631       mp->is_ipv6 = 0;
12632       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12633     }
12634
12635   /* send it... */
12636   S;
12637
12638   /* Wait for a reply... */
12639   W;
12640
12641   /* NOTREACHED */
12642   return 0;
12643 }
12644
12645 static int
12646 api_lisp_gpe_enable_disable (vat_main_t * vam)
12647 {
12648   unformat_input_t *input = vam->input;
12649   vl_api_lisp_gpe_enable_disable_t *mp;
12650   f64 timeout = ~0;
12651   u8 is_set = 0;
12652   u8 is_en = 1;
12653
12654   /* Parse args required to build the message */
12655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12656     {
12657       if (unformat (input, "enable"))
12658         {
12659           is_set = 1;
12660           is_en = 1;
12661         }
12662       else if (unformat (input, "disable"))
12663         {
12664           is_set = 1;
12665           is_en = 0;
12666         }
12667       else
12668         break;
12669     }
12670
12671   if (is_set == 0)
12672     {
12673       errmsg ("Value not set\n");
12674       return -99;
12675     }
12676
12677   /* Construct the API message */
12678   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12679
12680   mp->is_en = is_en;
12681
12682   /* send it... */
12683   S;
12684
12685   /* Wait for a reply... */
12686   W;
12687
12688   /* NOTREACHED */
12689   return 0;
12690 }
12691
12692 static int
12693 api_lisp_enable_disable (vat_main_t * vam)
12694 {
12695   unformat_input_t *input = vam->input;
12696   vl_api_lisp_enable_disable_t *mp;
12697   f64 timeout = ~0;
12698   u8 is_set = 0;
12699   u8 is_en = 0;
12700
12701   /* Parse args required to build the message */
12702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12703     {
12704       if (unformat (input, "enable"))
12705         {
12706           is_set = 1;
12707           is_en = 1;
12708         }
12709       else if (unformat (input, "disable"))
12710         {
12711           is_set = 1;
12712         }
12713       else
12714         break;
12715     }
12716
12717   if (!is_set)
12718     {
12719       errmsg ("Value not set\n");
12720       return -99;
12721     }
12722
12723   /* Construct the API message */
12724   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12725
12726   mp->is_en = is_en;
12727
12728   /* send it... */
12729   S;
12730
12731   /* Wait for a reply... */
12732   W;
12733
12734   /* NOTREACHED */
12735   return 0;
12736 }
12737
12738 static int
12739 api_show_lisp_map_request_mode (vat_main_t * vam)
12740 {
12741   f64 timeout = ~0;
12742   vl_api_show_lisp_map_request_mode_t *mp;
12743
12744   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
12745
12746   /* send */
12747   S;
12748
12749   /* wait for reply */
12750   W;
12751
12752   return 0;
12753 }
12754
12755 static int
12756 api_lisp_map_request_mode (vat_main_t * vam)
12757 {
12758   f64 timeout = ~0;
12759   unformat_input_t *input = vam->input;
12760   vl_api_lisp_map_request_mode_t *mp;
12761   u8 mode = 0;
12762
12763   /* Parse args required to build the message */
12764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12765     {
12766       if (unformat (input, "dst-only"))
12767         mode = 0;
12768       else if (unformat (input, "src-dst"))
12769         mode = 1;
12770       else
12771         {
12772           errmsg ("parse error '%U'", format_unformat_error, input);
12773           return -99;
12774         }
12775     }
12776
12777   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
12778
12779   mp->mode = mode;
12780
12781   /* send */
12782   S;
12783
12784   /* wait for reply */
12785   W;
12786
12787   /* notreached */
12788   return 0;
12789 }
12790
12791 /**
12792  * Enable/disable LISP proxy ITR.
12793  *
12794  * @param vam vpp API test context
12795  * @return return code
12796  */
12797 static int
12798 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12799 {
12800   f64 timeout = ~0;
12801   u8 ls_name_set = 0;
12802   unformat_input_t *input = vam->input;
12803   vl_api_lisp_pitr_set_locator_set_t *mp;
12804   u8 is_add = 1;
12805   u8 *ls_name = 0;
12806
12807   /* Parse args required to build the message */
12808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12809     {
12810       if (unformat (input, "del"))
12811         is_add = 0;
12812       else if (unformat (input, "locator-set %s", &ls_name))
12813         ls_name_set = 1;
12814       else
12815         {
12816           errmsg ("parse error '%U'", format_unformat_error, input);
12817           return -99;
12818         }
12819     }
12820
12821   if (!ls_name_set)
12822     {
12823       errmsg ("locator-set name not set!");
12824       return -99;
12825     }
12826
12827   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12828
12829   mp->is_add = is_add;
12830   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12831   vec_free (ls_name);
12832
12833   /* send */
12834   S;
12835
12836   /* wait for reply */
12837   W;
12838
12839   /* notreached */
12840   return 0;
12841 }
12842
12843 static int
12844 api_show_lisp_pitr (vat_main_t * vam)
12845 {
12846   vl_api_show_lisp_pitr_t *mp;
12847   f64 timeout = ~0;
12848
12849   if (!vam->json_output)
12850     {
12851       fformat (vam->ofp, "%=20s\n", "lisp status:");
12852     }
12853
12854   M (SHOW_LISP_PITR, show_lisp_pitr);
12855   /* send it... */
12856   S;
12857
12858   /* Wait for a reply... */
12859   W;
12860
12861   /* NOTREACHED */
12862   return 0;
12863 }
12864
12865 /**
12866  * Add/delete mapping between vni and vrf
12867  */
12868 static int
12869 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12870 {
12871   f64 timeout = ~0;
12872   unformat_input_t *input = vam->input;
12873   vl_api_lisp_eid_table_add_del_map_t *mp;
12874   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12875   u32 vni, vrf, bd_index;
12876
12877   /* Parse args required to build the message */
12878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12879     {
12880       if (unformat (input, "del"))
12881         is_add = 0;
12882       else if (unformat (input, "vrf %d", &vrf))
12883         vrf_set = 1;
12884       else if (unformat (input, "bd_index %d", &bd_index))
12885         bd_index_set = 1;
12886       else if (unformat (input, "vni %d", &vni))
12887         vni_set = 1;
12888       else
12889         break;
12890     }
12891
12892   if (!vni_set || (!vrf_set && !bd_index_set))
12893     {
12894       errmsg ("missing arguments!");
12895       return -99;
12896     }
12897
12898   if (vrf_set && bd_index_set)
12899     {
12900       errmsg ("error: both vrf and bd entered!");
12901       return -99;
12902     }
12903
12904   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12905
12906   mp->is_add = is_add;
12907   mp->vni = htonl (vni);
12908   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12909   mp->is_l2 = bd_index_set;
12910
12911   /* send */
12912   S;
12913
12914   /* wait for reply */
12915   W;
12916
12917   /* notreached */
12918   return 0;
12919 }
12920
12921 uword
12922 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
12923 {
12924   u32 *action = va_arg (*args, u32 *);
12925   u8 *s = 0;
12926
12927   if (unformat (input, "%s", &s))
12928     {
12929       if (!strcmp ((char *) s, "no-action"))
12930         action[0] = 0;
12931       else if (!strcmp ((char *) s, "natively-forward"))
12932         action[0] = 1;
12933       else if (!strcmp ((char *) s, "send-map-request"))
12934         action[0] = 2;
12935       else if (!strcmp ((char *) s, "drop"))
12936         action[0] = 3;
12937       else
12938         {
12939           clib_warning ("invalid action: '%s'", s);
12940           action[0] = 3;
12941         }
12942     }
12943   else
12944     return 0;
12945
12946   vec_free (s);
12947   return 1;
12948 }
12949
12950 /**
12951  * Add/del remote mapping to/from LISP control plane
12952  *
12953  * @param vam vpp API test context
12954  * @return return code
12955  */
12956 static int
12957 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12958 {
12959   unformat_input_t *input = vam->input;
12960   vl_api_lisp_add_del_remote_mapping_t *mp;
12961   f64 timeout = ~0;
12962   u32 vni = 0;
12963   lisp_eid_vat_t _eid, *eid = &_eid;
12964   lisp_eid_vat_t _seid, *seid = &_seid;
12965   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
12966   u32 action = ~0, p, w, data_len;
12967   ip4_address_t rloc4;
12968   ip6_address_t rloc6;
12969   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12970
12971   memset (&rloc, 0, sizeof (rloc));
12972
12973   /* Parse args required to build the message */
12974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12975     {
12976       if (unformat (input, "del-all"))
12977         {
12978           del_all = 1;
12979         }
12980       else if (unformat (input, "del"))
12981         {
12982           is_add = 0;
12983         }
12984       else if (unformat (input, "add"))
12985         {
12986           is_add = 1;
12987         }
12988       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12989         {
12990           eid_set = 1;
12991         }
12992       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
12993         {
12994           seid_set = 1;
12995         }
12996       else if (unformat (input, "vni %d", &vni))
12997         {
12998           ;
12999         }
13000       else if (unformat (input, "p %d w %d", &p, &w))
13001         {
13002           if (!curr_rloc)
13003             {
13004               errmsg ("No RLOC configured for setting priority/weight!");
13005               return -99;
13006             }
13007           curr_rloc->priority = p;
13008           curr_rloc->weight = w;
13009         }
13010       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13011         {
13012           rloc.is_ip4 = 1;
13013           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13014           vec_add1 (rlocs, rloc);
13015           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13016         }
13017       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13018         {
13019           rloc.is_ip4 = 0;
13020           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13021           vec_add1 (rlocs, rloc);
13022           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13023         }
13024       else if (unformat (input, "action %U",
13025                          unformat_negative_mapping_action, &action))
13026         {
13027           ;
13028         }
13029       else
13030         {
13031           clib_warning ("parse error '%U'", format_unformat_error, input);
13032           return -99;
13033         }
13034     }
13035
13036   if (0 == eid_set)
13037     {
13038       errmsg ("missing params!");
13039       return -99;
13040     }
13041
13042   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13043     {
13044       errmsg ("no action set for negative map-reply!");
13045       return -99;
13046     }
13047
13048   data_len = vec_len (rlocs) * sizeof (rloc_t);
13049
13050   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13051   mp->is_add = is_add;
13052   mp->vni = htonl (vni);
13053   mp->action = (u8) action;
13054   mp->is_src_dst = seid_set;
13055   mp->eid_len = eid->len;
13056   mp->seid_len = seid->len;
13057   mp->del_all = del_all;
13058   mp->eid_type = eid->type;
13059   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13060   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13061
13062   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13063   clib_memcpy (mp->rlocs, rlocs, data_len);
13064   vec_free (rlocs);
13065
13066   /* send it... */
13067   S;
13068
13069   /* Wait for a reply... */
13070   W;
13071
13072   /* NOTREACHED */
13073   return 0;
13074 }
13075
13076 /**
13077  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13078  * forwarding entries in data-plane accordingly.
13079  *
13080  * @param vam vpp API test context
13081  * @return return code
13082  */
13083 static int
13084 api_lisp_add_del_adjacency (vat_main_t * vam)
13085 {
13086   unformat_input_t *input = vam->input;
13087   vl_api_lisp_add_del_adjacency_t *mp;
13088   f64 timeout = ~0;
13089   u32 vni = 0;
13090   ip4_address_t leid4, reid4;
13091   ip6_address_t leid6, reid6;
13092   u8 reid_mac[6] = { 0 };
13093   u8 leid_mac[6] = { 0 };
13094   u8 reid_type, leid_type;
13095   u32 leid_len = 0, reid_len = 0, len;
13096   u8 is_add = 1;
13097
13098   leid_type = reid_type = (u8) ~ 0;
13099
13100   /* Parse args required to build the message */
13101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13102     {
13103       if (unformat (input, "del"))
13104         {
13105           is_add = 0;
13106         }
13107       else if (unformat (input, "add"))
13108         {
13109           is_add = 1;
13110         }
13111       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13112                          &reid4, &len))
13113         {
13114           reid_type = 0;        /* ipv4 */
13115           reid_len = len;
13116         }
13117       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13118                          &reid6, &len))
13119         {
13120           reid_type = 1;        /* ipv6 */
13121           reid_len = len;
13122         }
13123       else if (unformat (input, "reid %U", unformat_ethernet_address,
13124                          reid_mac))
13125         {
13126           reid_type = 2;        /* mac */
13127         }
13128       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13129                          &leid4, &len))
13130         {
13131           leid_type = 0;        /* ipv4 */
13132           leid_len = len;
13133         }
13134       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13135                          &leid6, &len))
13136         {
13137           leid_type = 1;        /* ipv6 */
13138           leid_len = len;
13139         }
13140       else if (unformat (input, "leid %U", unformat_ethernet_address,
13141                          leid_mac))
13142         {
13143           leid_type = 2;        /* mac */
13144         }
13145       else if (unformat (input, "vni %d", &vni))
13146         {
13147           ;
13148         }
13149       else
13150         {
13151           errmsg ("parse error '%U'", format_unformat_error, input);
13152           return -99;
13153         }
13154     }
13155
13156   if ((u8) ~ 0 == reid_type)
13157     {
13158       errmsg ("missing params!");
13159       return -99;
13160     }
13161
13162   if (leid_type != reid_type)
13163     {
13164       errmsg ("remote and local EIDs are of different types!");
13165       return -99;
13166     }
13167
13168   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13169   mp->is_add = is_add;
13170   mp->vni = htonl (vni);
13171   mp->leid_len = leid_len;
13172   mp->reid_len = reid_len;
13173   mp->eid_type = reid_type;
13174
13175   switch (mp->eid_type)
13176     {
13177     case 0:
13178       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13179       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13180       break;
13181     case 1:
13182       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13183       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13184       break;
13185     case 2:
13186       clib_memcpy (mp->leid, leid_mac, 6);
13187       clib_memcpy (mp->reid, reid_mac, 6);
13188       break;
13189     default:
13190       errmsg ("unknown EID type %d!", mp->eid_type);
13191       return 0;
13192     }
13193
13194   /* send it... */
13195   S;
13196
13197   /* Wait for a reply... */
13198   W;
13199
13200   /* NOTREACHED */
13201   return 0;
13202 }
13203
13204 static int
13205 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13206 {
13207   unformat_input_t *input = vam->input;
13208   vl_api_lisp_gpe_add_del_iface_t *mp;
13209   f64 timeout = ~0;
13210   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13211   u32 dp_table = 0, vni = 0;
13212
13213   /* Parse args required to build the message */
13214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13215     {
13216       if (unformat (input, "up"))
13217         {
13218           action_set = 1;
13219           is_add = 1;
13220         }
13221       else if (unformat (input, "down"))
13222         {
13223           action_set = 1;
13224           is_add = 0;
13225         }
13226       else if (unformat (input, "table_id %d", &dp_table))
13227         {
13228           dp_table_set = 1;
13229         }
13230       else if (unformat (input, "bd_id %d", &dp_table))
13231         {
13232           dp_table_set = 1;
13233           is_l2 = 1;
13234         }
13235       else if (unformat (input, "vni %d", &vni))
13236         {
13237           vni_set = 1;
13238         }
13239       else
13240         break;
13241     }
13242
13243   if (action_set == 0)
13244     {
13245       errmsg ("Action not set\n");
13246       return -99;
13247     }
13248   if (dp_table_set == 0 || vni_set == 0)
13249     {
13250       errmsg ("vni and dp_table must be set\n");
13251       return -99;
13252     }
13253
13254   /* Construct the API message */
13255   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13256
13257   mp->is_add = is_add;
13258   mp->dp_table = dp_table;
13259   mp->is_l2 = is_l2;
13260   mp->vni = vni;
13261
13262   /* send it... */
13263   S;
13264
13265   /* Wait for a reply... */
13266   W;
13267
13268   /* NOTREACHED */
13269   return 0;
13270 }
13271
13272 /**
13273  * Add/del map request itr rlocs from LISP control plane and updates
13274  *
13275  * @param vam vpp API test context
13276  * @return return code
13277  */
13278 static int
13279 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13280 {
13281   unformat_input_t *input = vam->input;
13282   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13283   f64 timeout = ~0;
13284   u8 *locator_set_name = 0;
13285   u8 locator_set_name_set = 0;
13286   u8 is_add = 1;
13287
13288   /* Parse args required to build the message */
13289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13290     {
13291       if (unformat (input, "del"))
13292         {
13293           is_add = 0;
13294         }
13295       else if (unformat (input, "%_%v%_", &locator_set_name))
13296         {
13297           locator_set_name_set = 1;
13298         }
13299       else
13300         {
13301           clib_warning ("parse error '%U'", format_unformat_error, input);
13302           return -99;
13303         }
13304     }
13305
13306   if (is_add && !locator_set_name_set)
13307     {
13308       errmsg ("itr-rloc is not set!");
13309       return -99;
13310     }
13311
13312   if (is_add && vec_len (locator_set_name) > 64)
13313     {
13314       errmsg ("itr-rloc locator-set name too long\n");
13315       vec_free (locator_set_name);
13316       return -99;
13317     }
13318
13319   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13320   mp->is_add = is_add;
13321   if (is_add)
13322     {
13323       clib_memcpy (mp->locator_set_name, locator_set_name,
13324                    vec_len (locator_set_name));
13325     }
13326   else
13327     {
13328       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13329     }
13330   vec_free (locator_set_name);
13331
13332   /* send it... */
13333   S;
13334
13335   /* Wait for a reply... */
13336   W;
13337
13338   /* NOTREACHED */
13339   return 0;
13340 }
13341
13342 static int
13343 api_lisp_locator_dump (vat_main_t * vam)
13344 {
13345   unformat_input_t *input = vam->input;
13346   vl_api_lisp_locator_dump_t *mp;
13347   f64 timeout = ~0;
13348   u8 is_index_set = 0, is_name_set = 0;
13349   u8 *ls_name = 0;
13350   u32 ls_index = ~0;
13351
13352   /* Parse args required to build the message */
13353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13354     {
13355       if (unformat (input, "ls_name %_%v%_", &ls_name))
13356         {
13357           is_name_set = 1;
13358         }
13359       else if (unformat (input, "ls_index %d", &ls_index))
13360         {
13361           is_index_set = 1;
13362         }
13363       else
13364         {
13365           errmsg ("parse error '%U'", format_unformat_error, input);
13366           return -99;
13367         }
13368     }
13369
13370   if (!is_index_set && !is_name_set)
13371     {
13372       errmsg ("error: expected one of index or name!\n");
13373       return -99;
13374     }
13375
13376   if (is_index_set && is_name_set)
13377     {
13378       errmsg ("error: only one param expected!\n");
13379       return -99;
13380     }
13381
13382   if (vec_len (ls_name) > 62)
13383     {
13384       errmsg ("error: locator set name too long!");
13385       return -99;
13386     }
13387
13388   if (!vam->json_output)
13389     {
13390       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13391                "weight");
13392     }
13393
13394   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13395   mp->is_index_set = is_index_set;
13396
13397   if (is_index_set)
13398     mp->ls_index = clib_host_to_net_u32 (ls_index);
13399   else
13400     {
13401       vec_add1 (ls_name, 0);
13402       strncpy ((char *) mp->ls_name, (char *) ls_name,
13403                sizeof (mp->ls_name) - 1);
13404     }
13405
13406   /* send it... */
13407   S;
13408
13409   /* Use a control ping for synchronization */
13410   {
13411     vl_api_control_ping_t *mp;
13412     M (CONTROL_PING, control_ping);
13413     S;
13414   }
13415   /* Wait for a reply... */
13416   W;
13417
13418   /* NOTREACHED */
13419   return 0;
13420 }
13421
13422 static int
13423 api_lisp_locator_set_dump (vat_main_t * vam)
13424 {
13425   vl_api_lisp_locator_set_dump_t *mp;
13426   unformat_input_t *input = vam->input;
13427   f64 timeout = ~0;
13428   u8 filter = 0;
13429
13430   /* Parse args required to build the message */
13431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13432     {
13433       if (unformat (input, "local"))
13434         {
13435           filter = 1;
13436         }
13437       else if (unformat (input, "remote"))
13438         {
13439           filter = 2;
13440         }
13441       else
13442         {
13443           errmsg ("parse error '%U'", format_unformat_error, input);
13444           return -99;
13445         }
13446     }
13447
13448   if (!vam->json_output)
13449     {
13450       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13451     }
13452
13453   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13454
13455   mp->filter = filter;
13456
13457   /* send it... */
13458   S;
13459
13460   /* Use a control ping for synchronization */
13461   {
13462     vl_api_control_ping_t *mp;
13463     M (CONTROL_PING, control_ping);
13464     S;
13465   }
13466   /* Wait for a reply... */
13467   W;
13468
13469   /* NOTREACHED */
13470   return 0;
13471 }
13472
13473 static int
13474 api_lisp_eid_table_map_dump (vat_main_t * vam)
13475 {
13476   u8 is_l2 = 0;
13477   u8 mode_set = 0;
13478   unformat_input_t *input = vam->input;
13479   vl_api_lisp_eid_table_map_dump_t *mp;
13480   f64 timeout = ~0;
13481
13482   /* Parse args required to build the message */
13483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13484     {
13485       if (unformat (input, "l2"))
13486         {
13487           is_l2 = 1;
13488           mode_set = 1;
13489         }
13490       else if (unformat (input, "l3"))
13491         {
13492           is_l2 = 0;
13493           mode_set = 1;
13494         }
13495       else
13496         {
13497           errmsg ("parse error '%U'", format_unformat_error, input);
13498           return -99;
13499         }
13500     }
13501
13502   if (!mode_set)
13503     {
13504       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13505       return -99;
13506     }
13507
13508   if (!vam->json_output)
13509     {
13510       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13511     }
13512
13513   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13514   mp->is_l2 = is_l2;
13515
13516   /* send it... */
13517   S;
13518
13519   /* Use a control ping for synchronization */
13520   {
13521     vl_api_control_ping_t *mp;
13522     M (CONTROL_PING, control_ping);
13523     S;
13524   }
13525   /* Wait for a reply... */
13526   W;
13527
13528   /* NOTREACHED */
13529   return 0;
13530 }
13531
13532 static int
13533 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13534 {
13535   vl_api_lisp_eid_table_vni_dump_t *mp;
13536   f64 timeout = ~0;
13537
13538   if (!vam->json_output)
13539     {
13540       fformat (vam->ofp, "VNI\n");
13541     }
13542
13543   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13544
13545   /* send it... */
13546   S;
13547
13548   /* Use a control ping for synchronization */
13549   {
13550     vl_api_control_ping_t *mp;
13551     M (CONTROL_PING, control_ping);
13552     S;
13553   }
13554   /* Wait for a reply... */
13555   W;
13556
13557   /* NOTREACHED */
13558   return 0;
13559 }
13560
13561 static int
13562 api_lisp_eid_table_dump (vat_main_t * vam)
13563 {
13564   unformat_input_t *i = vam->input;
13565   vl_api_lisp_eid_table_dump_t *mp;
13566   f64 timeout = ~0;
13567   struct in_addr ip4;
13568   struct in6_addr ip6;
13569   u8 mac[6];
13570   u8 eid_type = ~0, eid_set = 0;
13571   u32 prefix_length = ~0, t, vni = 0;
13572   u8 filter = 0;
13573
13574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13575     {
13576       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13577         {
13578           eid_set = 1;
13579           eid_type = 0;
13580           prefix_length = t;
13581         }
13582       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13583         {
13584           eid_set = 1;
13585           eid_type = 1;
13586           prefix_length = t;
13587         }
13588       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13589         {
13590           eid_set = 1;
13591           eid_type = 2;
13592         }
13593       else if (unformat (i, "vni %d", &t))
13594         {
13595           vni = t;
13596         }
13597       else if (unformat (i, "local"))
13598         {
13599           filter = 1;
13600         }
13601       else if (unformat (i, "remote"))
13602         {
13603           filter = 2;
13604         }
13605       else
13606         {
13607           errmsg ("parse error '%U'", format_unformat_error, i);
13608           return -99;
13609         }
13610     }
13611
13612   if (!vam->json_output)
13613     {
13614       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13615                "ls_index", "ttl", "authoritative");
13616     }
13617
13618   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13619
13620   mp->filter = filter;
13621   if (eid_set)
13622     {
13623       mp->eid_set = 1;
13624       mp->vni = htonl (vni);
13625       mp->eid_type = eid_type;
13626       switch (eid_type)
13627         {
13628         case 0:
13629           mp->prefix_length = prefix_length;
13630           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13631           break;
13632         case 1:
13633           mp->prefix_length = prefix_length;
13634           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13635           break;
13636         case 2:
13637           clib_memcpy (mp->eid, mac, sizeof (mac));
13638           break;
13639         default:
13640           errmsg ("unknown EID type %d!", eid_type);
13641           return -99;
13642         }
13643     }
13644
13645   /* send it... */
13646   S;
13647
13648   /* Use a control ping for synchronization */
13649   {
13650     vl_api_control_ping_t *mp;
13651     M (CONTROL_PING, control_ping);
13652     S;
13653   }
13654
13655   /* Wait for a reply... */
13656   W;
13657
13658   /* NOTREACHED */
13659   return 0;
13660 }
13661
13662 static int
13663 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13664 {
13665   vl_api_lisp_gpe_tunnel_dump_t *mp;
13666   f64 timeout = ~0;
13667
13668   if (!vam->json_output)
13669     {
13670       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13671                "%=16s%=16s%=16s%=16s%=16s\n",
13672                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13673                "Decap next", "Lisp version", "Flags", "Next protocol",
13674                "ver_res", "res", "iid");
13675     }
13676
13677   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13678   /* send it... */
13679   S;
13680
13681   /* Use a control ping for synchronization */
13682   {
13683     vl_api_control_ping_t *mp;
13684     M (CONTROL_PING, control_ping);
13685     S;
13686   }
13687   /* Wait for a reply... */
13688   W;
13689
13690   /* NOTREACHED */
13691   return 0;
13692 }
13693
13694 static int
13695 api_lisp_map_resolver_dump (vat_main_t * vam)
13696 {
13697   vl_api_lisp_map_resolver_dump_t *mp;
13698   f64 timeout = ~0;
13699
13700   if (!vam->json_output)
13701     {
13702       fformat (vam->ofp, "%=20s\n", "Map resolver");
13703     }
13704
13705   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13706   /* send it... */
13707   S;
13708
13709   /* Use a control ping for synchronization */
13710   {
13711     vl_api_control_ping_t *mp;
13712     M (CONTROL_PING, control_ping);
13713     S;
13714   }
13715   /* Wait for a reply... */
13716   W;
13717
13718   /* NOTREACHED */
13719   return 0;
13720 }
13721
13722 static int
13723 api_show_lisp_status (vat_main_t * vam)
13724 {
13725   vl_api_show_lisp_status_t *mp;
13726   f64 timeout = ~0;
13727
13728   if (!vam->json_output)
13729     {
13730       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13731     }
13732
13733   M (SHOW_LISP_STATUS, show_lisp_status);
13734   /* send it... */
13735   S;
13736   /* Wait for a reply... */
13737   W;
13738
13739   /* NOTREACHED */
13740   return 0;
13741 }
13742
13743 static int
13744 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13745 {
13746   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13747   f64 timeout = ~0;
13748
13749   if (!vam->json_output)
13750     {
13751       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13752     }
13753
13754   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13755   /* send it... */
13756   S;
13757   /* Wait for a reply... */
13758   W;
13759
13760   /* NOTREACHED */
13761   return 0;
13762 }
13763
13764 static int
13765 api_af_packet_create (vat_main_t * vam)
13766 {
13767   unformat_input_t *i = vam->input;
13768   vl_api_af_packet_create_t *mp;
13769   f64 timeout;
13770   u8 *host_if_name = 0;
13771   u8 hw_addr[6];
13772   u8 random_hw_addr = 1;
13773
13774   memset (hw_addr, 0, sizeof (hw_addr));
13775
13776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13777     {
13778       if (unformat (i, "name %s", &host_if_name))
13779         vec_add1 (host_if_name, 0);
13780       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13781         random_hw_addr = 0;
13782       else
13783         break;
13784     }
13785
13786   if (!vec_len (host_if_name))
13787     {
13788       errmsg ("host-interface name must be specified");
13789       return -99;
13790     }
13791
13792   if (vec_len (host_if_name) > 64)
13793     {
13794       errmsg ("host-interface name too long");
13795       return -99;
13796     }
13797
13798   M (AF_PACKET_CREATE, af_packet_create);
13799
13800   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13801   clib_memcpy (mp->hw_addr, hw_addr, 6);
13802   mp->use_random_hw_addr = random_hw_addr;
13803   vec_free (host_if_name);
13804
13805   S;
13806   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13807   /* NOTREACHED */
13808   return 0;
13809 }
13810
13811 static int
13812 api_af_packet_delete (vat_main_t * vam)
13813 {
13814   unformat_input_t *i = vam->input;
13815   vl_api_af_packet_delete_t *mp;
13816   f64 timeout;
13817   u8 *host_if_name = 0;
13818
13819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13820     {
13821       if (unformat (i, "name %s", &host_if_name))
13822         vec_add1 (host_if_name, 0);
13823       else
13824         break;
13825     }
13826
13827   if (!vec_len (host_if_name))
13828     {
13829       errmsg ("host-interface name must be specified");
13830       return -99;
13831     }
13832
13833   if (vec_len (host_if_name) > 64)
13834     {
13835       errmsg ("host-interface name too long");
13836       return -99;
13837     }
13838
13839   M (AF_PACKET_DELETE, af_packet_delete);
13840
13841   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13842   vec_free (host_if_name);
13843
13844   S;
13845   W;
13846   /* NOTREACHED */
13847   return 0;
13848 }
13849
13850 static int
13851 api_policer_add_del (vat_main_t * vam)
13852 {
13853   unformat_input_t *i = vam->input;
13854   vl_api_policer_add_del_t *mp;
13855   f64 timeout;
13856   u8 is_add = 1;
13857   u8 *name = 0;
13858   u32 cir = 0;
13859   u32 eir = 0;
13860   u64 cb = 0;
13861   u64 eb = 0;
13862   u8 rate_type = 0;
13863   u8 round_type = 0;
13864   u8 type = 0;
13865   u8 color_aware = 0;
13866   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13867
13868   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13869   conform_action.dscp = 0;
13870   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13871   exceed_action.dscp = 0;
13872   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13873   violate_action.dscp = 0;
13874
13875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13876     {
13877       if (unformat (i, "del"))
13878         is_add = 0;
13879       else if (unformat (i, "name %s", &name))
13880         vec_add1 (name, 0);
13881       else if (unformat (i, "cir %u", &cir))
13882         ;
13883       else if (unformat (i, "eir %u", &eir))
13884         ;
13885       else if (unformat (i, "cb %u", &cb))
13886         ;
13887       else if (unformat (i, "eb %u", &eb))
13888         ;
13889       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13890                          &rate_type))
13891         ;
13892       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13893                          &round_type))
13894         ;
13895       else if (unformat (i, "type %U", unformat_policer_type, &type))
13896         ;
13897       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13898                          &conform_action))
13899         ;
13900       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13901                          &exceed_action))
13902         ;
13903       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13904                          &violate_action))
13905         ;
13906       else if (unformat (i, "color-aware"))
13907         color_aware = 1;
13908       else
13909         break;
13910     }
13911
13912   if (!vec_len (name))
13913     {
13914       errmsg ("policer name must be specified");
13915       return -99;
13916     }
13917
13918   if (vec_len (name) > 64)
13919     {
13920       errmsg ("policer name too long");
13921       return -99;
13922     }
13923
13924   M (POLICER_ADD_DEL, policer_add_del);
13925
13926   clib_memcpy (mp->name, name, vec_len (name));
13927   vec_free (name);
13928   mp->is_add = is_add;
13929   mp->cir = cir;
13930   mp->eir = eir;
13931   mp->cb = cb;
13932   mp->eb = eb;
13933   mp->rate_type = rate_type;
13934   mp->round_type = round_type;
13935   mp->type = type;
13936   mp->conform_action_type = conform_action.action_type;
13937   mp->conform_dscp = conform_action.dscp;
13938   mp->exceed_action_type = exceed_action.action_type;
13939   mp->exceed_dscp = exceed_action.dscp;
13940   mp->violate_action_type = violate_action.action_type;
13941   mp->violate_dscp = violate_action.dscp;
13942   mp->color_aware = color_aware;
13943
13944   S;
13945   W;
13946   /* NOTREACHED */
13947   return 0;
13948 }
13949
13950 static int
13951 api_policer_dump (vat_main_t * vam)
13952 {
13953   unformat_input_t *i = vam->input;
13954   vl_api_policer_dump_t *mp;
13955   f64 timeout = ~0;
13956   u8 *match_name = 0;
13957   u8 match_name_valid = 0;
13958
13959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13960     {
13961       if (unformat (i, "name %s", &match_name))
13962         {
13963           vec_add1 (match_name, 0);
13964           match_name_valid = 1;
13965         }
13966       else
13967         break;
13968     }
13969
13970   M (POLICER_DUMP, policer_dump);
13971   mp->match_name_valid = match_name_valid;
13972   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13973   vec_free (match_name);
13974   /* send it... */
13975   S;
13976
13977   /* Use a control ping for synchronization */
13978   {
13979     vl_api_control_ping_t *mp;
13980     M (CONTROL_PING, control_ping);
13981     S;
13982   }
13983   /* Wait for a reply... */
13984   W;
13985
13986   /* NOTREACHED */
13987   return 0;
13988 }
13989
13990 static int
13991 api_policer_classify_set_interface (vat_main_t * vam)
13992 {
13993   unformat_input_t *i = vam->input;
13994   vl_api_policer_classify_set_interface_t *mp;
13995   f64 timeout;
13996   u32 sw_if_index;
13997   int sw_if_index_set;
13998   u32 ip4_table_index = ~0;
13999   u32 ip6_table_index = ~0;
14000   u32 l2_table_index = ~0;
14001   u8 is_add = 1;
14002
14003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14004     {
14005       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14006         sw_if_index_set = 1;
14007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14008         sw_if_index_set = 1;
14009       else if (unformat (i, "del"))
14010         is_add = 0;
14011       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14012         ;
14013       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14014         ;
14015       else if (unformat (i, "l2-table %d", &l2_table_index))
14016         ;
14017       else
14018         {
14019           clib_warning ("parse error '%U'", format_unformat_error, i);
14020           return -99;
14021         }
14022     }
14023
14024   if (sw_if_index_set == 0)
14025     {
14026       errmsg ("missing interface name or sw_if_index\n");
14027       return -99;
14028     }
14029
14030   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14031
14032   mp->sw_if_index = ntohl (sw_if_index);
14033   mp->ip4_table_index = ntohl (ip4_table_index);
14034   mp->ip6_table_index = ntohl (ip6_table_index);
14035   mp->l2_table_index = ntohl (l2_table_index);
14036   mp->is_add = is_add;
14037
14038   S;
14039   W;
14040   /* NOTREACHED */
14041   return 0;
14042 }
14043
14044 static int
14045 api_policer_classify_dump (vat_main_t * vam)
14046 {
14047   unformat_input_t *i = vam->input;
14048   vl_api_policer_classify_dump_t *mp;
14049   f64 timeout = ~0;
14050   u8 type = POLICER_CLASSIFY_N_TABLES;
14051
14052   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14053     ;
14054   else
14055     {
14056       errmsg ("classify table type must be specified\n");
14057       return -99;
14058     }
14059
14060   if (!vam->json_output)
14061     {
14062       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14063     }
14064
14065   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14066   mp->type = type;
14067   /* send it... */
14068   S;
14069
14070   /* Use a control ping for synchronization */
14071   {
14072     vl_api_control_ping_t *mp;
14073     M (CONTROL_PING, control_ping);
14074     S;
14075   }
14076   /* Wait for a reply... */
14077   W;
14078
14079   /* NOTREACHED */
14080   return 0;
14081 }
14082
14083 static int
14084 api_netmap_create (vat_main_t * vam)
14085 {
14086   unformat_input_t *i = vam->input;
14087   vl_api_netmap_create_t *mp;
14088   f64 timeout;
14089   u8 *if_name = 0;
14090   u8 hw_addr[6];
14091   u8 random_hw_addr = 1;
14092   u8 is_pipe = 0;
14093   u8 is_master = 0;
14094
14095   memset (hw_addr, 0, sizeof (hw_addr));
14096
14097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14098     {
14099       if (unformat (i, "name %s", &if_name))
14100         vec_add1 (if_name, 0);
14101       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14102         random_hw_addr = 0;
14103       else if (unformat (i, "pipe"))
14104         is_pipe = 1;
14105       else if (unformat (i, "master"))
14106         is_master = 1;
14107       else if (unformat (i, "slave"))
14108         is_master = 0;
14109       else
14110         break;
14111     }
14112
14113   if (!vec_len (if_name))
14114     {
14115       errmsg ("interface name must be specified");
14116       return -99;
14117     }
14118
14119   if (vec_len (if_name) > 64)
14120     {
14121       errmsg ("interface name too long");
14122       return -99;
14123     }
14124
14125   M (NETMAP_CREATE, netmap_create);
14126
14127   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14128   clib_memcpy (mp->hw_addr, hw_addr, 6);
14129   mp->use_random_hw_addr = random_hw_addr;
14130   mp->is_pipe = is_pipe;
14131   mp->is_master = is_master;
14132   vec_free (if_name);
14133
14134   S;
14135   W;
14136   /* NOTREACHED */
14137   return 0;
14138 }
14139
14140 static int
14141 api_netmap_delete (vat_main_t * vam)
14142 {
14143   unformat_input_t *i = vam->input;
14144   vl_api_netmap_delete_t *mp;
14145   f64 timeout;
14146   u8 *if_name = 0;
14147
14148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14149     {
14150       if (unformat (i, "name %s", &if_name))
14151         vec_add1 (if_name, 0);
14152       else
14153         break;
14154     }
14155
14156   if (!vec_len (if_name))
14157     {
14158       errmsg ("interface name must be specified");
14159       return -99;
14160     }
14161
14162   if (vec_len (if_name) > 64)
14163     {
14164       errmsg ("interface name too long");
14165       return -99;
14166     }
14167
14168   M (NETMAP_DELETE, netmap_delete);
14169
14170   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14171   vec_free (if_name);
14172
14173   S;
14174   W;
14175   /* NOTREACHED */
14176   return 0;
14177 }
14178
14179 static void vl_api_mpls_gre_tunnel_details_t_handler
14180   (vl_api_mpls_gre_tunnel_details_t * mp)
14181 {
14182   vat_main_t *vam = &vat_main;
14183   i32 i;
14184   i32 len = ntohl (mp->nlabels);
14185
14186   if (mp->l2_only == 0)
14187     {
14188       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14189                ntohl (mp->tunnel_index),
14190                format_ip4_address, &mp->tunnel_src,
14191                format_ip4_address, &mp->tunnel_dst,
14192                format_ip4_address, &mp->intfc_address,
14193                ntohl (mp->mask_width));
14194       for (i = 0; i < len; i++)
14195         {
14196           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14197         }
14198       fformat (vam->ofp, "\n");
14199       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14200                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14201     }
14202   else
14203     {
14204       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14205                ntohl (mp->tunnel_index),
14206                format_ip4_address, &mp->tunnel_src,
14207                format_ip4_address, &mp->tunnel_dst,
14208                format_ip4_address, &mp->intfc_address);
14209       for (i = 0; i < len; i++)
14210         {
14211           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14212         }
14213       fformat (vam->ofp, "\n");
14214       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14215                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14216     }
14217 }
14218
14219 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14220   (vl_api_mpls_gre_tunnel_details_t * mp)
14221 {
14222   vat_main_t *vam = &vat_main;
14223   vat_json_node_t *node = NULL;
14224   struct in_addr ip4;
14225   i32 i;
14226   i32 len = ntohl (mp->nlabels);
14227
14228   if (VAT_JSON_ARRAY != vam->json_tree.type)
14229     {
14230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14231       vat_json_init_array (&vam->json_tree);
14232     }
14233   node = vat_json_array_add (&vam->json_tree);
14234
14235   vat_json_init_object (node);
14236   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14237   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14238   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14239   vat_json_object_add_uint (node, "inner_fib_index",
14240                             ntohl (mp->inner_fib_index));
14241   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14242   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14243   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14244   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14245   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14246   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14247   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14248   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14249   vat_json_object_add_uint (node, "outer_fib_index",
14250                             ntohl (mp->outer_fib_index));
14251   vat_json_object_add_uint (node, "label_count", len);
14252   for (i = 0; i < len; i++)
14253     {
14254       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14255     }
14256 }
14257
14258 static int
14259 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14260 {
14261   vl_api_mpls_gre_tunnel_dump_t *mp;
14262   f64 timeout;
14263   i32 index = -1;
14264
14265   /* Parse args required to build the message */
14266   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14267     {
14268       if (!unformat (vam->input, "tunnel_index %d", &index))
14269         {
14270           index = -1;
14271           break;
14272         }
14273     }
14274
14275   fformat (vam->ofp, "  tunnel_index %d\n", index);
14276
14277   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14278   mp->tunnel_index = htonl (index);
14279   S;
14280
14281   /* Use a control ping for synchronization */
14282   {
14283     vl_api_control_ping_t *mp;
14284     M (CONTROL_PING, control_ping);
14285     S;
14286   }
14287   W;
14288 }
14289
14290 static void vl_api_mpls_eth_tunnel_details_t_handler
14291   (vl_api_mpls_eth_tunnel_details_t * mp)
14292 {
14293   vat_main_t *vam = &vat_main;
14294   i32 i;
14295   i32 len = ntohl (mp->nlabels);
14296
14297   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14298            ntohl (mp->tunnel_index),
14299            format_ethernet_address, &mp->tunnel_dst_mac,
14300            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14301   for (i = 0; i < len; i++)
14302     {
14303       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14304     }
14305   fformat (vam->ofp, "\n");
14306   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14307            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14308 }
14309
14310 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14311   (vl_api_mpls_eth_tunnel_details_t * mp)
14312 {
14313   vat_main_t *vam = &vat_main;
14314   vat_json_node_t *node = NULL;
14315   struct in_addr ip4;
14316   i32 i;
14317   i32 len = ntohl (mp->nlabels);
14318
14319   if (VAT_JSON_ARRAY != vam->json_tree.type)
14320     {
14321       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14322       vat_json_init_array (&vam->json_tree);
14323     }
14324   node = vat_json_array_add (&vam->json_tree);
14325
14326   vat_json_init_object (node);
14327   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14328   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14329   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14330   vat_json_object_add_uint (node, "inner_fib_index",
14331                             ntohl (mp->inner_fib_index));
14332   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14333   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14334   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14335   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14336   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14337                                    format (0, "%U", format_ethernet_address,
14338                                            &mp->tunnel_dst_mac));
14339   vat_json_object_add_uint (node, "tx_sw_if_index",
14340                             ntohl (mp->tx_sw_if_index));
14341   vat_json_object_add_uint (node, "label_count", len);
14342   for (i = 0; i < len; i++)
14343     {
14344       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14345     }
14346 }
14347
14348 static int
14349 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14350 {
14351   vl_api_mpls_eth_tunnel_dump_t *mp;
14352   f64 timeout;
14353   i32 index = -1;
14354
14355   /* Parse args required to build the message */
14356   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14357     {
14358       if (!unformat (vam->input, "tunnel_index %d", &index))
14359         {
14360           index = -1;
14361           break;
14362         }
14363     }
14364
14365   fformat (vam->ofp, "  tunnel_index %d\n", index);
14366
14367   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14368   mp->tunnel_index = htonl (index);
14369   S;
14370
14371   /* Use a control ping for synchronization */
14372   {
14373     vl_api_control_ping_t *mp;
14374     M (CONTROL_PING, control_ping);
14375     S;
14376   }
14377   W;
14378 }
14379
14380 static void vl_api_mpls_fib_encap_details_t_handler
14381   (vl_api_mpls_fib_encap_details_t * mp)
14382 {
14383   vat_main_t *vam = &vat_main;
14384   i32 i;
14385   i32 len = ntohl (mp->nlabels);
14386
14387   fformat (vam->ofp, "table %d, dest %U, label ",
14388            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14389   for (i = 0; i < len; i++)
14390     {
14391       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14392     }
14393   fformat (vam->ofp, "\n");
14394 }
14395
14396 static void vl_api_mpls_fib_encap_details_t_handler_json
14397   (vl_api_mpls_fib_encap_details_t * mp)
14398 {
14399   vat_main_t *vam = &vat_main;
14400   vat_json_node_t *node = NULL;
14401   i32 i;
14402   i32 len = ntohl (mp->nlabels);
14403   struct in_addr ip4;
14404
14405   if (VAT_JSON_ARRAY != vam->json_tree.type)
14406     {
14407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14408       vat_json_init_array (&vam->json_tree);
14409     }
14410   node = vat_json_array_add (&vam->json_tree);
14411
14412   vat_json_init_object (node);
14413   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14414   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14415   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14416   vat_json_object_add_ip4 (node, "dest", ip4);
14417   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14418   vat_json_object_add_uint (node, "label_count", len);
14419   for (i = 0; i < len; i++)
14420     {
14421       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14422     }
14423 }
14424
14425 static int
14426 api_mpls_fib_encap_dump (vat_main_t * vam)
14427 {
14428   vl_api_mpls_fib_encap_dump_t *mp;
14429   f64 timeout;
14430
14431   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14432   S;
14433
14434   /* Use a control ping for synchronization */
14435   {
14436     vl_api_control_ping_t *mp;
14437     M (CONTROL_PING, control_ping);
14438     S;
14439   }
14440   W;
14441 }
14442
14443 static void vl_api_mpls_fib_decap_details_t_handler
14444   (vl_api_mpls_fib_decap_details_t * mp)
14445 {
14446   vat_main_t *vam = &vat_main;
14447
14448   fformat (vam->ofp,
14449            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14450            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14451            ntohl (mp->label), ntohl (mp->s_bit));
14452 }
14453
14454 static void vl_api_mpls_fib_decap_details_t_handler_json
14455   (vl_api_mpls_fib_decap_details_t * mp)
14456 {
14457   vat_main_t *vam = &vat_main;
14458   vat_json_node_t *node = NULL;
14459   struct in_addr ip4;
14460
14461   if (VAT_JSON_ARRAY != vam->json_tree.type)
14462     {
14463       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14464       vat_json_init_array (&vam->json_tree);
14465     }
14466   node = vat_json_array_add (&vam->json_tree);
14467
14468   vat_json_init_object (node);
14469   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14470   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14471   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14472   vat_json_object_add_ip4 (node, "dest", ip4);
14473   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14474   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14475   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14476   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14477   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14478 }
14479
14480 static int
14481 api_mpls_fib_decap_dump (vat_main_t * vam)
14482 {
14483   vl_api_mpls_fib_decap_dump_t *mp;
14484   f64 timeout;
14485
14486   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14487   S;
14488
14489   /* Use a control ping for synchronization */
14490   {
14491     vl_api_control_ping_t *mp;
14492     M (CONTROL_PING, control_ping);
14493     S;
14494   }
14495   W;
14496 }
14497
14498 int
14499 api_classify_table_ids (vat_main_t * vam)
14500 {
14501   vl_api_classify_table_ids_t *mp;
14502   f64 timeout;
14503
14504   /* Construct the API message */
14505   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14506   mp->context = 0;
14507
14508   S;
14509   W;
14510   /* NOTREACHED */
14511   return 0;
14512 }
14513
14514 int
14515 api_classify_table_by_interface (vat_main_t * vam)
14516 {
14517   unformat_input_t *input = vam->input;
14518   vl_api_classify_table_by_interface_t *mp;
14519   f64 timeout;
14520
14521   u32 sw_if_index = ~0;
14522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14523     {
14524       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14525         ;
14526       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14527         ;
14528       else
14529         break;
14530     }
14531   if (sw_if_index == ~0)
14532     {
14533       errmsg ("missing interface name or sw_if_index\n");
14534       return -99;
14535     }
14536
14537   /* Construct the API message */
14538   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14539   mp->context = 0;
14540   mp->sw_if_index = ntohl (sw_if_index);
14541
14542   S;
14543   W;
14544   /* NOTREACHED */
14545   return 0;
14546 }
14547
14548 int
14549 api_classify_table_info (vat_main_t * vam)
14550 {
14551   unformat_input_t *input = vam->input;
14552   vl_api_classify_table_info_t *mp;
14553   f64 timeout;
14554
14555   u32 table_id = ~0;
14556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14557     {
14558       if (unformat (input, "table_id %d", &table_id))
14559         ;
14560       else
14561         break;
14562     }
14563   if (table_id == ~0)
14564     {
14565       errmsg ("missing table id\n");
14566       return -99;
14567     }
14568
14569   /* Construct the API message */
14570   M (CLASSIFY_TABLE_INFO, classify_table_info);
14571   mp->context = 0;
14572   mp->table_id = ntohl (table_id);
14573
14574   S;
14575   W;
14576   /* NOTREACHED */
14577   return 0;
14578 }
14579
14580 int
14581 api_classify_session_dump (vat_main_t * vam)
14582 {
14583   unformat_input_t *input = vam->input;
14584   vl_api_classify_session_dump_t *mp;
14585   f64 timeout;
14586
14587   u32 table_id = ~0;
14588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14589     {
14590       if (unformat (input, "table_id %d", &table_id))
14591         ;
14592       else
14593         break;
14594     }
14595   if (table_id == ~0)
14596     {
14597       errmsg ("missing table id\n");
14598       return -99;
14599     }
14600
14601   /* Construct the API message */
14602   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14603   mp->context = 0;
14604   mp->table_id = ntohl (table_id);
14605   S;
14606
14607   /* Use a control ping for synchronization */
14608   {
14609     vl_api_control_ping_t *mp;
14610     M (CONTROL_PING, control_ping);
14611     S;
14612   }
14613   W;
14614   /* NOTREACHED */
14615   return 0;
14616 }
14617
14618 static void
14619 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14620 {
14621   vat_main_t *vam = &vat_main;
14622
14623   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14624            "src_address %U, vrf_id %d, path_mtu %u, "
14625            "template_interval %u, udp_checksum %d\n",
14626            format_ip4_address, mp->collector_address,
14627            ntohs (mp->collector_port),
14628            format_ip4_address, mp->src_address,
14629            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14630            ntohl (mp->template_interval), mp->udp_checksum);
14631
14632   vam->retval = 0;
14633   vam->result_ready = 1;
14634 }
14635
14636 static void
14637   vl_api_ipfix_exporter_details_t_handler_json
14638   (vl_api_ipfix_exporter_details_t * mp)
14639 {
14640   vat_main_t *vam = &vat_main;
14641   vat_json_node_t node;
14642   struct in_addr collector_address;
14643   struct in_addr src_address;
14644
14645   vat_json_init_object (&node);
14646   clib_memcpy (&collector_address, &mp->collector_address,
14647                sizeof (collector_address));
14648   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14649   vat_json_object_add_uint (&node, "collector_port",
14650                             ntohs (mp->collector_port));
14651   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14652   vat_json_object_add_ip4 (&node, "src_address", src_address);
14653   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14654   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14655   vat_json_object_add_uint (&node, "template_interval",
14656                             ntohl (mp->template_interval));
14657   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14658
14659   vat_json_print (vam->ofp, &node);
14660   vat_json_free (&node);
14661   vam->retval = 0;
14662   vam->result_ready = 1;
14663 }
14664
14665 int
14666 api_ipfix_exporter_dump (vat_main_t * vam)
14667 {
14668   vl_api_ipfix_exporter_dump_t *mp;
14669   f64 timeout;
14670
14671   /* Construct the API message */
14672   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14673   mp->context = 0;
14674
14675   S;
14676   W;
14677   /* NOTREACHED */
14678   return 0;
14679 }
14680
14681 static int
14682 api_ipfix_classify_stream_dump (vat_main_t * vam)
14683 {
14684   vl_api_ipfix_classify_stream_dump_t *mp;
14685   f64 timeout;
14686
14687   /* Construct the API message */
14688   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14689   mp->context = 0;
14690
14691   S;
14692   W;
14693   /* NOTREACHED */
14694   return 0;
14695 }
14696
14697 static void
14698   vl_api_ipfix_classify_stream_details_t_handler
14699   (vl_api_ipfix_classify_stream_details_t * mp)
14700 {
14701   vat_main_t *vam = &vat_main;
14702   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14703            ntohl (mp->domain_id), ntohs (mp->src_port));
14704   vam->retval = 0;
14705   vam->result_ready = 1;
14706 }
14707
14708 static void
14709   vl_api_ipfix_classify_stream_details_t_handler_json
14710   (vl_api_ipfix_classify_stream_details_t * mp)
14711 {
14712   vat_main_t *vam = &vat_main;
14713   vat_json_node_t node;
14714
14715   vat_json_init_object (&node);
14716   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14717   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14718
14719   vat_json_print (vam->ofp, &node);
14720   vat_json_free (&node);
14721   vam->retval = 0;
14722   vam->result_ready = 1;
14723 }
14724
14725 static int
14726 api_ipfix_classify_table_dump (vat_main_t * vam)
14727 {
14728   vl_api_ipfix_classify_table_dump_t *mp;
14729   f64 timeout;
14730
14731   if (!vam->json_output)
14732     {
14733       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14734                "transport_protocol");
14735     }
14736
14737   /* Construct the API message */
14738   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14739
14740   /* send it... */
14741   S;
14742
14743   /* Use a control ping for synchronization */
14744   {
14745     vl_api_control_ping_t *mp;
14746     M (CONTROL_PING, control_ping);
14747     S;
14748   }
14749   W;
14750 }
14751
14752 static void
14753   vl_api_ipfix_classify_table_details_t_handler
14754   (vl_api_ipfix_classify_table_details_t * mp)
14755 {
14756   vat_main_t *vam = &vat_main;
14757   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14758            mp->transport_protocol);
14759 }
14760
14761 static void
14762   vl_api_ipfix_classify_table_details_t_handler_json
14763   (vl_api_ipfix_classify_table_details_t * mp)
14764 {
14765   vat_json_node_t *node = NULL;
14766   vat_main_t *vam = &vat_main;
14767
14768   if (VAT_JSON_ARRAY != vam->json_tree.type)
14769     {
14770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14771       vat_json_init_array (&vam->json_tree);
14772     }
14773
14774   node = vat_json_array_add (&vam->json_tree);
14775   vat_json_init_object (node);
14776
14777   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
14778   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
14779   vat_json_object_add_uint (node, "transport_protocol",
14780                             mp->transport_protocol);
14781 }
14782
14783 int
14784 api_pg_create_interface (vat_main_t * vam)
14785 {
14786   unformat_input_t *input = vam->input;
14787   vl_api_pg_create_interface_t *mp;
14788   f64 timeout;
14789
14790   u32 if_id = ~0;
14791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14792     {
14793       if (unformat (input, "if_id %d", &if_id))
14794         ;
14795       else
14796         break;
14797     }
14798   if (if_id == ~0)
14799     {
14800       errmsg ("missing pg interface index\n");
14801       return -99;
14802     }
14803
14804   /* Construct the API message */
14805   M (PG_CREATE_INTERFACE, pg_create_interface);
14806   mp->context = 0;
14807   mp->interface_id = ntohl (if_id);
14808
14809   S;
14810   W;
14811   /* NOTREACHED */
14812   return 0;
14813 }
14814
14815 int
14816 api_pg_capture (vat_main_t * vam)
14817 {
14818   unformat_input_t *input = vam->input;
14819   vl_api_pg_capture_t *mp;
14820   f64 timeout;
14821
14822   u32 if_id = ~0;
14823   u8 enable = 1;
14824   u32 count = 1;
14825   u8 pcap_file_set = 0;
14826   u8 *pcap_file = 0;
14827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14828     {
14829       if (unformat (input, "if_id %d", &if_id))
14830         ;
14831       else if (unformat (input, "pcap %s", &pcap_file))
14832         pcap_file_set = 1;
14833       else if (unformat (input, "count %d", &count))
14834         ;
14835       else if (unformat (input, "disable"))
14836         enable = 0;
14837       else
14838         break;
14839     }
14840   if (if_id == ~0)
14841     {
14842       errmsg ("missing pg interface index\n");
14843       return -99;
14844     }
14845   if (pcap_file_set > 0)
14846     {
14847       if (vec_len (pcap_file) > 255)
14848         {
14849           errmsg ("pcap file name is too long\n");
14850           return -99;
14851         }
14852     }
14853
14854   u32 name_len = vec_len (pcap_file);
14855   /* Construct the API message */
14856   M (PG_CAPTURE, pg_capture);
14857   mp->context = 0;
14858   mp->interface_id = ntohl (if_id);
14859   mp->is_enabled = enable;
14860   mp->count = ntohl (count);
14861   mp->pcap_name_length = ntohl (name_len);
14862   if (pcap_file_set != 0)
14863     {
14864       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14865     }
14866   vec_free (pcap_file);
14867
14868   S;
14869   W;
14870   /* NOTREACHED */
14871   return 0;
14872 }
14873
14874 int
14875 api_pg_enable_disable (vat_main_t * vam)
14876 {
14877   unformat_input_t *input = vam->input;
14878   vl_api_pg_enable_disable_t *mp;
14879   f64 timeout;
14880
14881   u8 enable = 1;
14882   u8 stream_name_set = 0;
14883   u8 *stream_name = 0;
14884   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14885     {
14886       if (unformat (input, "stream %s", &stream_name))
14887         stream_name_set = 1;
14888       else if (unformat (input, "disable"))
14889         enable = 0;
14890       else
14891         break;
14892     }
14893
14894   if (stream_name_set > 0)
14895     {
14896       if (vec_len (stream_name) > 255)
14897         {
14898           errmsg ("stream name too long\n");
14899           return -99;
14900         }
14901     }
14902
14903   u32 name_len = vec_len (stream_name);
14904   /* Construct the API message */
14905   M (PG_ENABLE_DISABLE, pg_enable_disable);
14906   mp->context = 0;
14907   mp->is_enabled = enable;
14908   if (stream_name_set != 0)
14909     {
14910       mp->stream_name_length = ntohl (name_len);
14911       clib_memcpy (mp->stream_name, stream_name, name_len);
14912     }
14913   vec_free (stream_name);
14914
14915   S;
14916   W;
14917   /* NOTREACHED */
14918   return 0;
14919 }
14920
14921 int
14922 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14923 {
14924   unformat_input_t *input = vam->input;
14925   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14926   f64 timeout;
14927
14928   u16 *low_ports = 0;
14929   u16 *high_ports = 0;
14930   u16 this_low;
14931   u16 this_hi;
14932   ip4_address_t ip4_addr;
14933   ip6_address_t ip6_addr;
14934   u32 length;
14935   u32 tmp, tmp2;
14936   u8 prefix_set = 0;
14937   u32 vrf_id = ~0;
14938   u8 is_add = 1;
14939   u8 is_ipv6 = 0;
14940
14941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14942     {
14943       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14944         {
14945           prefix_set = 1;
14946         }
14947       else
14948         if (unformat
14949             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14950         {
14951           prefix_set = 1;
14952           is_ipv6 = 1;
14953         }
14954       else if (unformat (input, "vrf %d", &vrf_id))
14955         ;
14956       else if (unformat (input, "del"))
14957         is_add = 0;
14958       else if (unformat (input, "port %d", &tmp))
14959         {
14960           if (tmp == 0 || tmp > 65535)
14961             {
14962               errmsg ("port %d out of range", tmp);
14963               return -99;
14964             }
14965           this_low = tmp;
14966           this_hi = this_low + 1;
14967           vec_add1 (low_ports, this_low);
14968           vec_add1 (high_ports, this_hi);
14969         }
14970       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14971         {
14972           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14973             {
14974               errmsg ("incorrect range parameters\n");
14975               return -99;
14976             }
14977           this_low = tmp;
14978           /* Note: in debug CLI +1 is added to high before
14979              passing to real fn that does "the work"
14980              (ip_source_and_port_range_check_add_del).
14981              This fn is a wrapper around the binary API fn a
14982              control plane will call, which expects this increment
14983              to have occurred. Hence letting the binary API control
14984              plane fn do the increment for consistency between VAT
14985              and other control planes.
14986            */
14987           this_hi = tmp2;
14988           vec_add1 (low_ports, this_low);
14989           vec_add1 (high_ports, this_hi);
14990         }
14991       else
14992         break;
14993     }
14994
14995   if (prefix_set == 0)
14996     {
14997       errmsg ("<address>/<mask> not specified\n");
14998       return -99;
14999     }
15000
15001   if (vrf_id == ~0)
15002     {
15003       errmsg ("VRF ID required, not specified\n");
15004       return -99;
15005     }
15006
15007   if (vrf_id == 0)
15008     {
15009       errmsg
15010         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15011       return -99;
15012     }
15013
15014   if (vec_len (low_ports) == 0)
15015     {
15016       errmsg ("At least one port or port range required\n");
15017       return -99;
15018     }
15019
15020   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15021      ip_source_and_port_range_check_add_del);
15022
15023   mp->is_add = is_add;
15024
15025   if (is_ipv6)
15026     {
15027       mp->is_ipv6 = 1;
15028       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15029     }
15030   else
15031     {
15032       mp->is_ipv6 = 0;
15033       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15034     }
15035
15036   mp->mask_length = length;
15037   mp->number_of_ranges = vec_len (low_ports);
15038
15039   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15040   vec_free (low_ports);
15041
15042   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15043   vec_free (high_ports);
15044
15045   mp->vrf_id = ntohl (vrf_id);
15046
15047   S;
15048   W;
15049   /* NOTREACHED */
15050   return 0;
15051 }
15052
15053 int
15054 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15055 {
15056   unformat_input_t *input = vam->input;
15057   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15058   f64 timeout;
15059   u32 sw_if_index = ~0;
15060   int vrf_set = 0;
15061   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15062   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15063   u8 is_add = 1;
15064
15065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15066     {
15067       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15068         ;
15069       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15070         ;
15071       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15072         vrf_set = 1;
15073       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15074         vrf_set = 1;
15075       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15076         vrf_set = 1;
15077       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15078         vrf_set = 1;
15079       else if (unformat (input, "del"))
15080         is_add = 0;
15081       else
15082         break;
15083     }
15084
15085   if (sw_if_index == ~0)
15086     {
15087       errmsg ("Interface required but not specified\n");
15088       return -99;
15089     }
15090
15091   if (vrf_set == 0)
15092     {
15093       errmsg ("VRF ID required but not specified\n");
15094       return -99;
15095     }
15096
15097   if (tcp_out_vrf_id == 0
15098       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15099     {
15100       errmsg
15101         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15102       return -99;
15103     }
15104
15105   /* Construct the API message */
15106   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15107      ip_source_and_port_range_check_interface_add_del);
15108
15109   mp->sw_if_index = ntohl (sw_if_index);
15110   mp->is_add = is_add;
15111   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15112   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15113   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15114   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15115
15116   /* send it... */
15117   S;
15118
15119   /* Wait for a reply... */
15120   W;
15121 }
15122
15123 static int
15124 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15125 {
15126   unformat_input_t *i = vam->input;
15127   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15128   f64 timeout;
15129   u32 local_sa_id = 0;
15130   u32 remote_sa_id = 0;
15131   ip4_address_t src_address;
15132   ip4_address_t dst_address;
15133   u8 is_add = 1;
15134
15135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15136     {
15137       if (unformat (i, "local_sa %d", &local_sa_id))
15138         ;
15139       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15140         ;
15141       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15142         ;
15143       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15144         ;
15145       else if (unformat (i, "del"))
15146         is_add = 0;
15147       else
15148         {
15149           clib_warning ("parse error '%U'", format_unformat_error, i);
15150           return -99;
15151         }
15152     }
15153
15154   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15155
15156   mp->local_sa_id = ntohl (local_sa_id);
15157   mp->remote_sa_id = ntohl (remote_sa_id);
15158   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15159   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15160   mp->is_add = is_add;
15161
15162   S;
15163   W;
15164   /* NOTREACHED */
15165   return 0;
15166 }
15167
15168 static int
15169 api_punt (vat_main_t * vam)
15170 {
15171   unformat_input_t *i = vam->input;
15172   vl_api_punt_t *mp;
15173   f64 timeout;
15174   u32 ipv = ~0;
15175   u32 protocol = ~0;
15176   u32 port = ~0;
15177   int is_add = 1;
15178
15179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15180     {
15181       if (unformat (i, "ip %d", &ipv))
15182         ;
15183       else if (unformat (i, "protocol %d", &protocol))
15184         ;
15185       else if (unformat (i, "port %d", &port))
15186         ;
15187       else if (unformat (i, "del"))
15188         is_add = 0;
15189       else
15190         {
15191           clib_warning ("parse error '%U'", format_unformat_error, i);
15192           return -99;
15193         }
15194     }
15195
15196   M (PUNT, punt);
15197
15198   mp->is_add = (u8) is_add;
15199   mp->ipv = (u8) ipv;
15200   mp->l4_protocol = (u8) protocol;
15201   mp->l4_port = htons ((u16) port);
15202
15203   S;
15204   W;
15205   /* NOTREACHED */
15206   return 0;
15207 }
15208
15209 static void vl_api_ipsec_gre_tunnel_details_t_handler
15210   (vl_api_ipsec_gre_tunnel_details_t * mp)
15211 {
15212   vat_main_t *vam = &vat_main;
15213
15214   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15215            ntohl (mp->sw_if_index),
15216            format_ip4_address, &mp->src_address,
15217            format_ip4_address, &mp->dst_address,
15218            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15219 }
15220
15221 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15222   (vl_api_ipsec_gre_tunnel_details_t * mp)
15223 {
15224   vat_main_t *vam = &vat_main;
15225   vat_json_node_t *node = NULL;
15226   struct in_addr ip4;
15227
15228   if (VAT_JSON_ARRAY != vam->json_tree.type)
15229     {
15230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15231       vat_json_init_array (&vam->json_tree);
15232     }
15233   node = vat_json_array_add (&vam->json_tree);
15234
15235   vat_json_init_object (node);
15236   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15237   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15238   vat_json_object_add_ip4 (node, "src_address", ip4);
15239   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15240   vat_json_object_add_ip4 (node, "dst_address", ip4);
15241   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15242   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15243 }
15244
15245 static int
15246 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15247 {
15248   unformat_input_t *i = vam->input;
15249   vl_api_ipsec_gre_tunnel_dump_t *mp;
15250   f64 timeout;
15251   u32 sw_if_index;
15252   u8 sw_if_index_set = 0;
15253
15254   /* Parse args required to build the message */
15255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15256     {
15257       if (unformat (i, "sw_if_index %d", &sw_if_index))
15258         sw_if_index_set = 1;
15259       else
15260         break;
15261     }
15262
15263   if (sw_if_index_set == 0)
15264     {
15265       sw_if_index = ~0;
15266     }
15267
15268   if (!vam->json_output)
15269     {
15270       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15271                "sw_if_index", "src_address", "dst_address",
15272                "local_sa_id", "remote_sa_id");
15273     }
15274
15275   /* Get list of gre-tunnel interfaces */
15276   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15277
15278   mp->sw_if_index = htonl (sw_if_index);
15279
15280   S;
15281
15282   /* Use a control ping for synchronization */
15283   {
15284     vl_api_control_ping_t *mp;
15285     M (CONTROL_PING, control_ping);
15286     S;
15287   }
15288   W;
15289 }
15290
15291 static int
15292 api_delete_subif (vat_main_t * vam)
15293 {
15294   unformat_input_t *i = vam->input;
15295   vl_api_delete_subif_t *mp;
15296   f64 timeout;
15297   u32 sw_if_index = ~0;
15298
15299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15300     {
15301       if (unformat (i, "sw_if_index %d", &sw_if_index))
15302         ;
15303       else
15304         break;
15305     }
15306
15307   if (sw_if_index == ~0)
15308     {
15309       errmsg ("missing sw_if_index\n");
15310       return -99;
15311     }
15312
15313   /* Construct the API message */
15314   M (DELETE_SUBIF, delete_subif);
15315   mp->sw_if_index = ntohl (sw_if_index);
15316
15317   S;
15318   W;
15319 }
15320
15321 #define foreach_pbb_vtr_op      \
15322 _("disable",  L2_VTR_DISABLED)  \
15323 _("pop",  L2_VTR_POP_2)         \
15324 _("push",  L2_VTR_PUSH_2)
15325
15326 static int
15327 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15328 {
15329   unformat_input_t *i = vam->input;
15330   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15331   f64 timeout;
15332   u32 sw_if_index = ~0, vtr_op = ~0;
15333   u16 outer_tag = ~0;
15334   u8 dmac[6], smac[6];
15335   u8 dmac_set = 0, smac_set = 0;
15336   u16 vlanid = 0;
15337   u32 sid = ~0;
15338   u32 tmp;
15339
15340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15341     {
15342       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15343         ;
15344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15345         ;
15346       else if (unformat (i, "vtr_op %d", &vtr_op))
15347         ;
15348 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15349       foreach_pbb_vtr_op
15350 #undef _
15351         else if (unformat (i, "translate_pbb_stag"))
15352         {
15353           if (unformat (i, "%d", &tmp))
15354             {
15355               vtr_op = L2_VTR_TRANSLATE_2_1;
15356               outer_tag = tmp;
15357             }
15358           else
15359             {
15360               errmsg
15361                 ("translate_pbb_stag operation requires outer tag definition\n");
15362               return -99;
15363             }
15364         }
15365       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15366         dmac_set++;
15367       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15368         smac_set++;
15369       else if (unformat (i, "sid %d", &sid))
15370         ;
15371       else if (unformat (i, "vlanid %d", &tmp))
15372         vlanid = tmp;
15373       else
15374         {
15375           clib_warning ("parse error '%U'", format_unformat_error, i);
15376           return -99;
15377         }
15378     }
15379
15380   if ((sw_if_index == ~0) || (vtr_op == ~0))
15381     {
15382       errmsg ("missing sw_if_index or vtr operation\n");
15383       return -99;
15384     }
15385   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15386       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15387     {
15388       errmsg
15389         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15390       return -99;
15391     }
15392
15393   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15394   mp->sw_if_index = ntohl (sw_if_index);
15395   mp->vtr_op = ntohl (vtr_op);
15396   mp->outer_tag = ntohs (outer_tag);
15397   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15398   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15399   mp->b_vlanid = ntohs (vlanid);
15400   mp->i_sid = ntohl (sid);
15401
15402   S;
15403   W;
15404   /* NOTREACHED */
15405   return 0;
15406 }
15407
15408 static int
15409 api_flow_classify_set_interface (vat_main_t * vam)
15410 {
15411   unformat_input_t *i = vam->input;
15412   vl_api_flow_classify_set_interface_t *mp;
15413   f64 timeout;
15414   u32 sw_if_index;
15415   int sw_if_index_set;
15416   u32 ip4_table_index = ~0;
15417   u32 ip6_table_index = ~0;
15418   u8 is_add = 1;
15419
15420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15421     {
15422       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15423         sw_if_index_set = 1;
15424       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15425         sw_if_index_set = 1;
15426       else if (unformat (i, "del"))
15427         is_add = 0;
15428       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15429         ;
15430       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15431         ;
15432       else
15433         {
15434           clib_warning ("parse error '%U'", format_unformat_error, i);
15435           return -99;
15436         }
15437     }
15438
15439   if (sw_if_index_set == 0)
15440     {
15441       errmsg ("missing interface name or sw_if_index\n");
15442       return -99;
15443     }
15444
15445   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
15446
15447   mp->sw_if_index = ntohl (sw_if_index);
15448   mp->ip4_table_index = ntohl (ip4_table_index);
15449   mp->ip6_table_index = ntohl (ip6_table_index);
15450   mp->is_add = is_add;
15451
15452   S;
15453   W;
15454   /* NOTREACHED */
15455   return 0;
15456 }
15457
15458 static int
15459 api_flow_classify_dump (vat_main_t * vam)
15460 {
15461   unformat_input_t *i = vam->input;
15462   vl_api_flow_classify_dump_t *mp;
15463   f64 timeout = ~0;
15464   u8 type = FLOW_CLASSIFY_N_TABLES;
15465
15466   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
15467     ;
15468   else
15469     {
15470       errmsg ("classify table type must be specified\n");
15471       return -99;
15472     }
15473
15474   if (!vam->json_output)
15475     {
15476       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15477     }
15478
15479   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
15480   mp->type = type;
15481   /* send it... */
15482   S;
15483
15484   /* Use a control ping for synchronization */
15485   {
15486     vl_api_control_ping_t *mp;
15487     M (CONTROL_PING, control_ping);
15488     S;
15489   }
15490   /* Wait for a reply... */
15491   W;
15492
15493   /* NOTREACHED */
15494   return 0;
15495 }
15496
15497 static int
15498 q_or_quit (vat_main_t * vam)
15499 {
15500   longjmp (vam->jump_buf, 1);
15501   return 0;                     /* not so much */
15502 }
15503
15504 static int
15505 q (vat_main_t * vam)
15506 {
15507   return q_or_quit (vam);
15508 }
15509
15510 static int
15511 quit (vat_main_t * vam)
15512 {
15513   return q_or_quit (vam);
15514 }
15515
15516 static int
15517 comment (vat_main_t * vam)
15518 {
15519   return 0;
15520 }
15521
15522 static int
15523 cmd_cmp (void *a1, void *a2)
15524 {
15525   u8 **c1 = a1;
15526   u8 **c2 = a2;
15527
15528   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15529 }
15530
15531 static int
15532 help (vat_main_t * vam)
15533 {
15534   u8 **cmds = 0;
15535   u8 *name = 0;
15536   hash_pair_t *p;
15537   unformat_input_t *i = vam->input;
15538   int j;
15539
15540   if (unformat (i, "%s", &name))
15541     {
15542       uword *hs;
15543
15544       vec_add1 (name, 0);
15545
15546       hs = hash_get_mem (vam->help_by_name, name);
15547       if (hs)
15548         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15549       else
15550         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15551       vec_free (name);
15552       return 0;
15553     }
15554
15555   fformat (vam->ofp, "Help is available for the following:\n");
15556
15557     /* *INDENT-OFF* */
15558     hash_foreach_pair (p, vam->function_by_name,
15559     ({
15560       vec_add1 (cmds, (u8 *)(p->key));
15561     }));
15562     /* *INDENT-ON* */
15563
15564   vec_sort_with_function (cmds, cmd_cmp);
15565
15566   for (j = 0; j < vec_len (cmds); j++)
15567     fformat (vam->ofp, "%s\n", cmds[j]);
15568
15569   vec_free (cmds);
15570   return 0;
15571 }
15572
15573 static int
15574 set (vat_main_t * vam)
15575 {
15576   u8 *name = 0, *value = 0;
15577   unformat_input_t *i = vam->input;
15578
15579   if (unformat (i, "%s", &name))
15580     {
15581       /* The input buffer is a vector, not a string. */
15582       value = vec_dup (i->buffer);
15583       vec_delete (value, i->index, 0);
15584       /* Almost certainly has a trailing newline */
15585       if (value[vec_len (value) - 1] == '\n')
15586         value[vec_len (value) - 1] = 0;
15587       /* Make sure it's a proper string, one way or the other */
15588       vec_add1 (value, 0);
15589       (void) clib_macro_set_value (&vam->macro_main,
15590                                    (char *) name, (char *) value);
15591     }
15592   else
15593     errmsg ("usage: set <name> <value>\n");
15594
15595   vec_free (name);
15596   vec_free (value);
15597   return 0;
15598 }
15599
15600 static int
15601 unset (vat_main_t * vam)
15602 {
15603   u8 *name = 0;
15604
15605   if (unformat (vam->input, "%s", &name))
15606     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15607       errmsg ("unset: %s wasn't set\n", name);
15608   vec_free (name);
15609   return 0;
15610 }
15611
15612 typedef struct
15613 {
15614   u8 *name;
15615   u8 *value;
15616 } macro_sort_t;
15617
15618
15619 static int
15620 macro_sort_cmp (void *a1, void *a2)
15621 {
15622   macro_sort_t *s1 = a1;
15623   macro_sort_t *s2 = a2;
15624
15625   return strcmp ((char *) (s1->name), (char *) (s2->name));
15626 }
15627
15628 static int
15629 dump_macro_table (vat_main_t * vam)
15630 {
15631   macro_sort_t *sort_me = 0, *sm;
15632   int i;
15633   hash_pair_t *p;
15634
15635     /* *INDENT-OFF* */
15636     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15637     ({
15638       vec_add2 (sort_me, sm, 1);
15639       sm->name = (u8 *)(p->key);
15640       sm->value = (u8 *) (p->value[0]);
15641     }));
15642     /* *INDENT-ON* */
15643
15644   vec_sort_with_function (sort_me, macro_sort_cmp);
15645
15646   if (vec_len (sort_me))
15647     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15648   else
15649     fformat (vam->ofp, "The macro table is empty...\n");
15650
15651   for (i = 0; i < vec_len (sort_me); i++)
15652     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15653   return 0;
15654 }
15655
15656 static int
15657 dump_node_table (vat_main_t * vam)
15658 {
15659   int i, j;
15660   vlib_node_t *node, *next_node;
15661
15662   if (vec_len (vam->graph_nodes) == 0)
15663     {
15664       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15665       return 0;
15666     }
15667
15668   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15669     {
15670       node = vam->graph_nodes[i];
15671       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15672       for (j = 0; j < vec_len (node->next_nodes); j++)
15673         {
15674           if (node->next_nodes[j] != ~0)
15675             {
15676               next_node = vam->graph_nodes[node->next_nodes[j]];
15677               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15678             }
15679         }
15680     }
15681   return 0;
15682 }
15683
15684 static int
15685 search_node_table (vat_main_t * vam)
15686 {
15687   unformat_input_t *line_input = vam->input;
15688   u8 *node_to_find;
15689   int j;
15690   vlib_node_t *node, *next_node;
15691   uword *p;
15692
15693   if (vam->graph_node_index_by_name == 0)
15694     {
15695       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15696       return 0;
15697     }
15698
15699   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15700     {
15701       if (unformat (line_input, "%s", &node_to_find))
15702         {
15703           vec_add1 (node_to_find, 0);
15704           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15705           if (p == 0)
15706             {
15707               fformat (vam->ofp, "%s not found...\n", node_to_find);
15708               goto out;
15709             }
15710           node = vam->graph_nodes[p[0]];
15711           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15712           for (j = 0; j < vec_len (node->next_nodes); j++)
15713             {
15714               if (node->next_nodes[j] != ~0)
15715                 {
15716                   next_node = vam->graph_nodes[node->next_nodes[j]];
15717                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15718                 }
15719             }
15720         }
15721
15722       else
15723         {
15724           clib_warning ("parse error '%U'", format_unformat_error,
15725                         line_input);
15726           return -99;
15727         }
15728
15729     out:
15730       vec_free (node_to_find);
15731
15732     }
15733
15734   return 0;
15735 }
15736
15737
15738 static int
15739 script (vat_main_t * vam)
15740 {
15741   u8 *s = 0;
15742   char *save_current_file;
15743   unformat_input_t save_input;
15744   jmp_buf save_jump_buf;
15745   u32 save_line_number;
15746
15747   FILE *new_fp, *save_ifp;
15748
15749   if (unformat (vam->input, "%s", &s))
15750     {
15751       new_fp = fopen ((char *) s, "r");
15752       if (new_fp == 0)
15753         {
15754           errmsg ("Couldn't open script file %s\n", s);
15755           vec_free (s);
15756           return -99;
15757         }
15758     }
15759   else
15760     {
15761       errmsg ("Missing script name\n");
15762       return -99;
15763     }
15764
15765   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15766   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15767   save_ifp = vam->ifp;
15768   save_line_number = vam->input_line_number;
15769   save_current_file = (char *) vam->current_file;
15770
15771   vam->input_line_number = 0;
15772   vam->ifp = new_fp;
15773   vam->current_file = s;
15774   do_one_file (vam);
15775
15776   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15777   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15778   vam->ifp = save_ifp;
15779   vam->input_line_number = save_line_number;
15780   vam->current_file = (u8 *) save_current_file;
15781   vec_free (s);
15782
15783   return 0;
15784 }
15785
15786 static int
15787 echo (vat_main_t * vam)
15788 {
15789   fformat (vam->ofp, "%v", vam->input->buffer);
15790   return 0;
15791 }
15792
15793 /* List of API message constructors, CLI names map to api_xxx */
15794 #define foreach_vpe_api_msg                                             \
15795 _(create_loopback,"[mac <mac-addr>]")                                   \
15796 _(sw_interface_dump,"")                                                 \
15797 _(sw_interface_set_flags,                                               \
15798   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15799 _(sw_interface_add_del_address,                                         \
15800   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15801 _(sw_interface_set_table,                                               \
15802   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15803 _(sw_interface_set_vpath,                                               \
15804   "<intfc> | sw_if_index <id> enable | disable")                        \
15805 _(sw_interface_set_l2_xconnect,                                         \
15806   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15807   "enable | disable")                                                   \
15808 _(sw_interface_set_l2_bridge,                                           \
15809   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15810   "[shg <split-horizon-group>] [bvi]\n"                                 \
15811   "enable | disable")                                                   \
15812 _(sw_interface_set_dpdk_hqos_pipe,                                      \
15813   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
15814   "profile <profile-id>\n")                                             \
15815 _(sw_interface_set_dpdk_hqos_subport,                                   \
15816   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
15817   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
15818 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
15819   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
15820 _(bridge_domain_add_del,                                                \
15821   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15822 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15823 _(l2fib_add_del,                                                        \
15824   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15825 _(l2_flags,                                                             \
15826   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15827 _(bridge_flags,                                                         \
15828   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15829 _(tap_connect,                                                          \
15830   "tapname <name> mac <mac-addr> | random-mac")                         \
15831 _(tap_modify,                                                           \
15832   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15833 _(tap_delete,                                                           \
15834   "<vpp-if-name> | sw_if_index <id>")                                   \
15835 _(sw_interface_tap_dump, "")                                            \
15836 _(ip_add_del_route,                                                     \
15837   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15838   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15839   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15840   "[multipath] [count <n>]")                                            \
15841 _(proxy_arp_add_del,                                                    \
15842   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15843 _(proxy_arp_intfc_enable_disable,                                       \
15844   "<intfc> | sw_if_index <id> enable | disable")                        \
15845 _(mpls_add_del_encap,                                                   \
15846   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15847 _(mpls_add_del_decap,                                                   \
15848   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15849 _(mpls_gre_add_del_tunnel,                                              \
15850   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15851   "adj <ip4-address>/<mask-width> [del]")                               \
15852 _(sw_interface_set_unnumbered,                                          \
15853   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15854 _(ip_neighbor_add_del,                                                  \
15855   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15856   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15857 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15858 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15859 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15860   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15861   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15862   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15863 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15864 _(reset_fib, "vrf <n> [ipv6]")                                          \
15865 _(dhcp_proxy_config,                                                    \
15866   "svr <v46-address> src <v46-address>\n"                               \
15867    "insert-cid <n> [del]")                                              \
15868 _(dhcp_proxy_config_2,                                                  \
15869   "svr <v46-address> src <v46-address>\n"                               \
15870    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15871 _(dhcp_proxy_set_vss,                                                   \
15872   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15873 _(dhcp_client_config,                                                   \
15874   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15875 _(set_ip_flow_hash,                                                     \
15876   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15877 _(sw_interface_ip6_enable_disable,                                      \
15878   "<intfc> | sw_if_index <id> enable | disable")                        \
15879 _(sw_interface_ip6_set_link_local_address,                              \
15880   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15881 _(sw_interface_ip6nd_ra_prefix,                                         \
15882   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15883   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15884   "[nolink] [isno]")                                                    \
15885 _(sw_interface_ip6nd_ra_config,                                         \
15886   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15887   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15888   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15889 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15890 _(l2_patch_add_del,                                                     \
15891   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15892   "enable | disable")                                                   \
15893 _(mpls_ethernet_add_del_tunnel,                                         \
15894   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15895   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15896 _(mpls_ethernet_add_del_tunnel_2,                                       \
15897   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15898   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15899 _(sr_tunnel_add_del,                                                    \
15900   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15901   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15902   "[policy <policy_name>]")                                             \
15903 _(sr_policy_add_del,                                                    \
15904   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15905 _(sr_multicast_map_add_del,                                             \
15906   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15907 _(classify_add_del_table,                                               \
15908   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15909   "[del] mask <mask-value>\n"                                           \
15910   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15911 _(classify_add_del_session,                                             \
15912   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15913   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15914   "  [l3 [ip4|ip6]]")                                                   \
15915 _(classify_set_interface_ip_table,                                      \
15916   "<intfc> | sw_if_index <nn> table <nn>")                              \
15917 _(classify_set_interface_l2_tables,                                     \
15918   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15919   "  [other-table <nn>]")                                               \
15920 _(get_node_index, "node <node-name")                                    \
15921 _(add_node_next, "node <node-name> next <next-node-name>")              \
15922 _(l2tpv3_create_tunnel,                                                 \
15923   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15924   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15925   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15926 _(l2tpv3_set_tunnel_cookies,                                            \
15927   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15928   "[new_remote_cookie <nn>]\n")                                         \
15929 _(l2tpv3_interface_enable_disable,                                      \
15930   "<intfc> | sw_if_index <nn> enable | disable")                        \
15931 _(l2tpv3_set_lookup_key,                                                \
15932   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15933 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15934 _(vxlan_add_del_tunnel,                                                 \
15935   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15936   " [decap-next l2|ip4|ip6] [del]")                                     \
15937 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15938 _(gre_add_del_tunnel,                                                   \
15939   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
15940 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15941 _(l2_fib_clear_table, "")                                               \
15942 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15943 _(l2_interface_vlan_tag_rewrite,                                        \
15944   "<intfc> | sw_if_index <nn> \n"                                       \
15945   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15946   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15947 _(create_vhost_user_if,                                                 \
15948         "socket <filename> [server] [renumber <dev_instance>] "         \
15949         "[mac <mac_address>]")                                          \
15950 _(modify_vhost_user_if,                                                 \
15951         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15952         "[server] [renumber <dev_instance>]")                           \
15953 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15954 _(sw_interface_vhost_user_dump, "")                                     \
15955 _(show_version, "")                                                     \
15956 _(vxlan_gpe_add_del_tunnel,                                             \
15957   "local <addr> remote <addr> vni <nn>\n"                               \
15958     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15959   "[next-ethernet] [next-nsh]\n")                                       \
15960 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15961 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15962 _(interface_name_renumber,                                              \
15963   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15964 _(input_acl_set_interface,                                              \
15965   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15966   "  [l2-table <nn>] [del]")                                            \
15967 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15968 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15969 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15970 _(ip_dump, "ipv4 | ipv6")                                               \
15971 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15972 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15973   "  spid_id <n> ")                                                     \
15974 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15975   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15976   "  integ_alg <alg> integ_key <hex>")                                  \
15977 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15978   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15979   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15980   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15981 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15982 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15983 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15984   "(auth_data 0x<data> | auth_data <data>)")                            \
15985 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15986   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15987 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15988   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15989   "(local|remote)")                                                     \
15990 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15991 _(delete_loopback,"sw_if_index <nn>")                                   \
15992 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15993 _(map_add_domain,                                                       \
15994   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15995   "ip6-src <ip6addr> "                                                  \
15996   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15997 _(map_del_domain, "index <n>")                                          \
15998 _(map_add_del_rule,                                                     \
15999   "index <n> psid <n> dst <ip6addr> [del]")                             \
16000 _(map_domain_dump, "")                                                  \
16001 _(map_rule_dump, "index <map-domain>")                                  \
16002 _(want_interface_events,  "enable|disable")                             \
16003 _(want_stats,"enable|disable")                                          \
16004 _(get_first_msg_id, "client <name>")                                    \
16005 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16006 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16007   "fib-id <nn> [ip4][ip6][default]")                                    \
16008 _(get_node_graph, " ")                                                  \
16009 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16010 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16011 _(ioam_disable, "")                                                \
16012 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16013                             " sw_if_index <sw_if_index> p <priority> "  \
16014                             "w <weight>] [del]")                        \
16015 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16016                         "iface <intf> | sw_if_index <sw_if_index> "     \
16017                         "p <priority> w <weight> [del]")                \
16018 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16019                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16020                           "locator-set <locator_name> [del]")           \
16021 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16022   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16023 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16024 _(lisp_gpe_enable_disable, "enable|disable")                            \
16025 _(lisp_enable_disable, "enable|disable")                                \
16026 _(lisp_gpe_add_del_iface, "up|down")                                    \
16027 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16028                                "[seid <seid>] "                         \
16029                                "rloc <locator> p <prio> "               \
16030                                "w <weight> [rloc <loc> ... ] "          \
16031                                "action <action> [del-all]")             \
16032 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16033                           "<local-eid>")                                \
16034 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16035 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16036 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16037 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16038 _(lisp_locator_set_dump, "[local | remote]")                            \
16039 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16040 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16041                        "[local] | [remote]")                            \
16042 _(lisp_eid_table_vni_dump, "")                                          \
16043 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16044 _(lisp_gpe_tunnel_dump, "")                                             \
16045 _(lisp_map_resolver_dump, "")                                           \
16046 _(show_lisp_status, "")                                                 \
16047 _(lisp_get_map_request_itr_rlocs, "")                                   \
16048 _(show_lisp_pitr, "")                                                   \
16049 _(show_lisp_map_request_mode, "")                                       \
16050 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16051 _(af_packet_delete, "name <host interface name>")                       \
16052 _(policer_add_del, "name <policer name> <params> [del]")                \
16053 _(policer_dump, "[name <policer name>]")                                \
16054 _(policer_classify_set_interface,                                       \
16055   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16056   "  [l2-table <nn>] [del]")                                            \
16057 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16058 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16059     "[master|slave]")                                                   \
16060 _(netmap_delete, "name <interface name>")                               \
16061 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16062 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16063 _(mpls_fib_encap_dump, "")                                              \
16064 _(mpls_fib_decap_dump, "")                                              \
16065 _(classify_table_ids, "")                                               \
16066 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16067 _(classify_table_info, "table_id <nn>")                                 \
16068 _(classify_session_dump, "table_id <nn>")                               \
16069 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16070     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16071     "[template_interval <nn>] [udp_checksum]")                          \
16072 _(ipfix_exporter_dump, "")                                              \
16073 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16074 _(ipfix_classify_stream_dump, "")                                       \
16075 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16076 _(ipfix_classify_table_dump, "")                                        \
16077 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16078 _(pg_create_interface, "if_id <nn>")                                    \
16079 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16080 _(pg_enable_disable, "[stream <id>] disable")                           \
16081 _(ip_source_and_port_range_check_add_del,                               \
16082   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16083 _(ip_source_and_port_range_check_interface_add_del,                     \
16084   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16085   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16086 _(ipsec_gre_add_del_tunnel,                                             \
16087   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16088 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16089 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
16090 _(l2_interface_pbb_tag_rewrite,                                         \
16091   "<intfc> | sw_if_index <nn> \n"                                       \
16092   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16093   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16094 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16095 _(flow_classify_set_interface,                                          \
16096   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16097 _(flow_classify_dump, "type [ip4|ip6]")
16098
16099 /* List of command functions, CLI names map directly to functions */
16100 #define foreach_cli_function                                    \
16101 _(comment, "usage: comment <ignore-rest-of-line>")              \
16102 _(dump_interface_table, "usage: dump_interface_table")          \
16103 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16104 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16105 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16106 _(dump_stats_table, "usage: dump_stats_table")                  \
16107 _(dump_macro_table, "usage: dump_macro_table ")                 \
16108 _(dump_node_table, "usage: dump_node_table")                    \
16109 _(echo, "usage: echo <message>")                                \
16110 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16111 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16112 _(help, "usage: help")                                          \
16113 _(q, "usage: quit")                                             \
16114 _(quit, "usage: quit")                                          \
16115 _(search_node_table, "usage: search_node_table <name>...")      \
16116 _(set, "usage: set <variable-name> <value>")                    \
16117 _(script, "usage: script <file-name>")                          \
16118 _(unset, "usage: unset <variable-name>")
16119
16120 #define _(N,n)                                  \
16121     static void vl_api_##n##_t_handler_uni      \
16122     (vl_api_##n##_t * mp)                       \
16123     {                                           \
16124         vat_main_t * vam = &vat_main;           \
16125         if (vam->json_output) {                 \
16126             vl_api_##n##_t_handler_json(mp);    \
16127         } else {                                \
16128             vl_api_##n##_t_handler(mp);         \
16129         }                                       \
16130     }
16131 foreach_vpe_api_reply_msg;
16132 #undef _
16133
16134 void
16135 vat_api_hookup (vat_main_t * vam)
16136 {
16137 #define _(N,n)                                                  \
16138     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16139                            vl_api_##n##_t_handler_uni,          \
16140                            vl_noop_handler,                     \
16141                            vl_api_##n##_t_endian,               \
16142                            vl_api_##n##_t_print,                \
16143                            sizeof(vl_api_##n##_t), 1);
16144   foreach_vpe_api_reply_msg;
16145 #undef _
16146
16147   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16148
16149   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16150
16151   vam->function_by_name = hash_create_string (0, sizeof (uword));
16152
16153   vam->help_by_name = hash_create_string (0, sizeof (uword));
16154
16155   /* API messages we can send */
16156 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16157   foreach_vpe_api_msg;
16158 #undef _
16159
16160   /* Help strings */
16161 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16162   foreach_vpe_api_msg;
16163 #undef _
16164
16165   /* CLI functions */
16166 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16167   foreach_cli_function;
16168 #undef _
16169
16170   /* Help strings */
16171 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16172   foreach_cli_function;
16173 #undef _
16174 }
16175
16176 #undef vl_api_version
16177 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16178 #include <vpp-api/vpe.api.h>
16179 #undef vl_api_version
16180
16181 void
16182 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16183 {
16184   /*
16185    * Send the main API signature in slot 0. This bit of code must
16186    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16187    */
16188   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16189 }
16190
16191 /*
16192  * fd.io coding-style-patch-verification: ON
16193  *
16194  * Local Variables:
16195  * eval: (c-set-style "gnu")
16196  * End:
16197  */