c77571a7357f11cfcf9db17b034c298febad2e15
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53
54 #include "vat/json_format.h"
55
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp-api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp-api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp-api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 uword
75 unformat_sw_if_index (unformat_input_t * input, va_list * args)
76 {
77   vat_main_t *vam = va_arg (*args, vat_main_t *);
78   u32 *result = va_arg (*args, u32 *);
79   u8 *if_name;
80   uword *p;
81
82   if (!unformat (input, "%s", &if_name))
83     return 0;
84
85   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
86   if (p == 0)
87     return 0;
88   *result = p[0];
89   return 1;
90 }
91
92 /* Parse an IP4 address %d.%d.%d.%d. */
93 uword
94 unformat_ip4_address (unformat_input_t * input, va_list * args)
95 {
96   u8 *result = va_arg (*args, u8 *);
97   unsigned a[4];
98
99   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
100     return 0;
101
102   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
103     return 0;
104
105   result[0] = a[0];
106   result[1] = a[1];
107   result[2] = a[2];
108   result[3] = a[3];
109
110   return 1;
111 }
112
113
114 uword
115 unformat_ethernet_address (unformat_input_t * input, va_list * args)
116 {
117   u8 *result = va_arg (*args, u8 *);
118   u32 i, a[6];
119
120   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
121                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
122     return 0;
123
124   /* Check range. */
125   for (i = 0; i < 6; i++)
126     if (a[i] >= (1 << 8))
127       return 0;
128
129   for (i = 0; i < 6; i++)
130     result[i] = a[i];
131
132   return 1;
133 }
134
135 /* Returns ethernet type as an int in host byte order. */
136 uword
137 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
138                                         va_list * args)
139 {
140   u16 *result = va_arg (*args, u16 *);
141   int type;
142
143   /* Numeric type. */
144   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
145     {
146       if (type >= (1 << 16))
147         return 0;
148       *result = type;
149       return 1;
150     }
151   return 0;
152 }
153
154 /* Parse an IP6 address. */
155 uword
156 unformat_ip6_address (unformat_input_t * input, va_list * args)
157 {
158   ip6_address_t *result = va_arg (*args, ip6_address_t *);
159   u16 hex_quads[8];
160   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
161   uword c, n_colon, double_colon_index;
162
163   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
164   double_colon_index = ARRAY_LEN (hex_quads);
165   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
166     {
167       hex_digit = 16;
168       if (c >= '0' && c <= '9')
169         hex_digit = c - '0';
170       else if (c >= 'a' && c <= 'f')
171         hex_digit = c + 10 - 'a';
172       else if (c >= 'A' && c <= 'F')
173         hex_digit = c + 10 - 'A';
174       else if (c == ':' && n_colon < 2)
175         n_colon++;
176       else
177         {
178           unformat_put_input (input);
179           break;
180         }
181
182       /* Too many hex quads. */
183       if (n_hex_quads >= ARRAY_LEN (hex_quads))
184         return 0;
185
186       if (hex_digit < 16)
187         {
188           hex_quad = (hex_quad << 4) | hex_digit;
189
190           /* Hex quad must fit in 16 bits. */
191           if (n_hex_digits >= 4)
192             return 0;
193
194           n_colon = 0;
195           n_hex_digits++;
196         }
197
198       /* Save position of :: */
199       if (n_colon == 2)
200         {
201           /* More than one :: ? */
202           if (double_colon_index < ARRAY_LEN (hex_quads))
203             return 0;
204           double_colon_index = n_hex_quads;
205         }
206
207       if (n_colon > 0 && n_hex_digits > 0)
208         {
209           hex_quads[n_hex_quads++] = hex_quad;
210           hex_quad = 0;
211           n_hex_digits = 0;
212         }
213     }
214
215   if (n_hex_digits > 0)
216     hex_quads[n_hex_quads++] = hex_quad;
217
218   {
219     word i;
220
221     /* Expand :: to appropriate number of zero hex quads. */
222     if (double_colon_index < ARRAY_LEN (hex_quads))
223       {
224         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
225
226         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
227           hex_quads[n_zero + i] = hex_quads[i];
228
229         for (i = 0; i < n_zero; i++)
230           hex_quads[double_colon_index + i] = 0;
231
232         n_hex_quads = ARRAY_LEN (hex_quads);
233       }
234
235     /* Too few hex quads given. */
236     if (n_hex_quads < ARRAY_LEN (hex_quads))
237       return 0;
238
239     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
240       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
241
242     return 1;
243   }
244 }
245
246 uword
247 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
248 {
249 #if DPDK > 0
250   u32 *r = va_arg (*args, u32 *);
251
252   if (0);
253 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254   foreach_ipsec_policy_action
255 #undef _
256     else
257     return 0;
258   return 1;
259 #else
260   return 0;
261 #endif
262 }
263
264 uword
265 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
266 {
267 #if DPDK > 0
268   u32 *r = va_arg (*args, u32 *);
269
270   if (0);
271 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
272   foreach_ipsec_crypto_alg
273 #undef _
274     else
275     return 0;
276   return 1;
277 #else
278   return 0;
279 #endif
280 }
281
282 u8 *
283 format_ipsec_crypto_alg (u8 * s, va_list * args)
284 {
285 #if DPDK > 0
286   u32 i = va_arg (*args, u32);
287   u8 *t = 0;
288
289   switch (i)
290     {
291 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
292       foreach_ipsec_crypto_alg
293 #undef _
294     default:
295       return format (s, "unknown");
296     }
297   return format (s, "%s", t);
298 #else
299   return format (s, "Unimplemented");
300 #endif
301 }
302
303 uword
304 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
305 {
306 #if DPDK > 0
307   u32 *r = va_arg (*args, u32 *);
308
309   if (0);
310 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
311   foreach_ipsec_integ_alg
312 #undef _
313     else
314     return 0;
315   return 1;
316 #else
317   return 0;
318 #endif
319 }
320
321 u8 *
322 format_ipsec_integ_alg (u8 * s, va_list * args)
323 {
324 #if DPDK > 0
325   u32 i = va_arg (*args, u32);
326   u8 *t = 0;
327
328   switch (i)
329     {
330 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
331       foreach_ipsec_integ_alg
332 #undef _
333     default:
334       return format (s, "unknown");
335     }
336   return format (s, "%s", t);
337 #else
338   return format (s, "Unsupported");
339 #endif
340 }
341
342 uword
343 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
344 {
345 #if DPDK > 0
346   u32 *r = va_arg (*args, u32 *);
347
348   if (0);
349 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
350   foreach_ikev2_auth_method
351 #undef _
352     else
353     return 0;
354   return 1;
355 #else
356   return 0;
357 #endif
358 }
359
360 uword
361 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
362 {
363 #if DPDK > 0
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
368   foreach_ikev2_id_type
369 #undef _
370     else
371     return 0;
372   return 1;
373 #else
374   return 0;
375 #endif
376 }
377
378 uword
379 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
380 {
381   u8 *r = va_arg (*args, u8 *);
382
383   if (unformat (input, "kbps"))
384     *r = SSE2_QOS_RATE_KBPS;
385   else if (unformat (input, "pps"))
386     *r = SSE2_QOS_RATE_PPS;
387   else
388     return 0;
389   return 1;
390 }
391
392 uword
393 unformat_policer_round_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "closest"))
398     *r = SSE2_QOS_ROUND_TO_CLOSEST;
399   else if (unformat (input, "up"))
400     *r = SSE2_QOS_ROUND_TO_UP;
401   else if (unformat (input, "down"))
402     *r = SSE2_QOS_ROUND_TO_DOWN;
403   else
404     return 0;
405   return 1;
406 }
407
408 uword
409 unformat_policer_type (unformat_input_t * input, va_list * args)
410 {
411   u8 *r = va_arg (*args, u8 *);
412
413   if (unformat (input, "1r2c"))
414     *r = SSE2_QOS_POLICER_TYPE_1R2C;
415   else if (unformat (input, "1r3c"))
416     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
417   else if (unformat (input, "2r3c-2698"))
418     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
419   else if (unformat (input, "2r3c-4115"))
420     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
421   else if (unformat (input, "2r3c-mef5cf1"))
422     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
423   else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_dscp (unformat_input_t * input, va_list * va)
430 {
431   u8 *r = va_arg (*va, u8 *);
432
433   if (0);
434 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
435   foreach_vnet_dscp
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_policer_action_type (unformat_input_t * input, va_list * va)
444 {
445   sse2_qos_pol_action_params_st *a
446     = va_arg (*va, sse2_qos_pol_action_params_st *);
447
448   if (unformat (input, "drop"))
449     a->action_type = SSE2_QOS_ACTION_DROP;
450   else if (unformat (input, "transmit"))
451     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
452   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
453     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
454   else
455     return 0;
456   return 1;
457 }
458
459 uword
460 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
461 {
462   u32 *r = va_arg (*va, u32 *);
463   u32 tid;
464
465   if (unformat (input, "ip4"))
466     tid = POLICER_CLASSIFY_TABLE_IP4;
467   else if (unformat (input, "ip6"))
468     tid = POLICER_CLASSIFY_TABLE_IP6;
469   else if (unformat (input, "l2"))
470     tid = POLICER_CLASSIFY_TABLE_L2;
471   else
472     return 0;
473
474   *r = tid;
475   return 1;
476 }
477
478 uword
479 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
480 {
481   u32 *r = va_arg (*va, u32 *);
482   u32 tid;
483
484   if (unformat (input, "ip4"))
485     tid = FLOW_CLASSIFY_TABLE_IP4;
486   else if (unformat (input, "ip6"))
487     tid = FLOW_CLASSIFY_TABLE_IP6;
488   else
489     return 0;
490
491   *r = tid;
492   return 1;
493 }
494
495 u8 *
496 format_ip4_address (u8 * s, va_list * args)
497 {
498   u8 *a = va_arg (*args, u8 *);
499   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
500 }
501
502 u8 *
503 format_ip6_address (u8 * s, va_list * args)
504 {
505   ip6_address_t *a = va_arg (*args, ip6_address_t *);
506   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
507
508   i_max_n_zero = ARRAY_LEN (a->as_u16);
509   max_n_zeros = 0;
510   i_first_zero = i_max_n_zero;
511   n_zeros = 0;
512   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
513     {
514       u32 is_zero = a->as_u16[i] == 0;
515       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
516         {
517           i_first_zero = i;
518           n_zeros = 0;
519         }
520       n_zeros += is_zero;
521       if ((!is_zero && n_zeros > max_n_zeros)
522           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
523         {
524           i_max_n_zero = i_first_zero;
525           max_n_zeros = n_zeros;
526           i_first_zero = ARRAY_LEN (a->as_u16);
527           n_zeros = 0;
528         }
529     }
530
531   last_double_colon = 0;
532   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
533     {
534       if (i == i_max_n_zero && max_n_zeros > 1)
535         {
536           s = format (s, "::");
537           i += max_n_zeros - 1;
538           last_double_colon = 1;
539         }
540       else
541         {
542           s = format (s, "%s%x",
543                       (last_double_colon || i == 0) ? "" : ":",
544                       clib_net_to_host_u16 (a->as_u16[i]));
545           last_double_colon = 0;
546         }
547     }
548
549   return s;
550 }
551
552 /* Format an IP46 address. */
553 u8 *
554 format_ip46_address (u8 * s, va_list * args)
555 {
556   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
557   ip46_type_t type = va_arg (*args, ip46_type_t);
558   int is_ip4 = 1;
559
560   switch (type)
561     {
562     case IP46_TYPE_ANY:
563       is_ip4 = ip46_address_is_ip4 (ip46);
564       break;
565     case IP46_TYPE_IP4:
566       is_ip4 = 1;
567       break;
568     case IP46_TYPE_IP6:
569       is_ip4 = 0;
570       break;
571     }
572
573   return is_ip4 ?
574     format (s, "%U", format_ip4_address, &ip46->ip4) :
575     format (s, "%U", format_ip6_address, &ip46->ip6);
576 }
577
578 u8 *
579 format_ethernet_address (u8 * s, va_list * args)
580 {
581   u8 *a = va_arg (*args, u8 *);
582
583   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
584                  a[0], a[1], a[2], a[3], a[4], a[5]);
585 }
586
587 void
588 increment_v4_address (ip4_address_t * a)
589 {
590   u32 v;
591
592   v = ntohl (a->as_u32) + 1;
593   a->as_u32 = ntohl (v);
594 }
595
596 void
597 increment_v6_address (ip6_address_t * a)
598 {
599   u64 v0, v1;
600
601   v0 = clib_net_to_host_u64 (a->as_u64[0]);
602   v1 = clib_net_to_host_u64 (a->as_u64[1]);
603
604   v1 += 1;
605   if (v1 == 0)
606     v0 += 1;
607   a->as_u64[0] = clib_net_to_host_u64 (v0);
608   a->as_u64[1] = clib_net_to_host_u64 (v1);
609 }
610
611 void
612 increment_mac_address (u64 * mac)
613 {
614   u64 tmp = *mac;
615
616   tmp = clib_net_to_host_u64 (tmp);
617   tmp += 1 << 16;               /* skip unused (least significant) octets */
618   tmp = clib_host_to_net_u64 (tmp);
619   *mac = tmp;
620 }
621
622 static void vl_api_create_loopback_reply_t_handler
623   (vl_api_create_loopback_reply_t * mp)
624 {
625   vat_main_t *vam = &vat_main;
626   i32 retval = ntohl (mp->retval);
627
628   vam->retval = retval;
629   vam->regenerate_interface_table = 1;
630   vam->sw_if_index = ntohl (mp->sw_if_index);
631   vam->result_ready = 1;
632 }
633
634 static void vl_api_create_loopback_reply_t_handler_json
635   (vl_api_create_loopback_reply_t * mp)
636 {
637   vat_main_t *vam = &vat_main;
638   vat_json_node_t node;
639
640   vat_json_init_object (&node);
641   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
642   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
643
644   vat_json_print (vam->ofp, &node);
645   vat_json_free (&node);
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_af_packet_create_reply_t_handler
651   (vl_api_af_packet_create_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_af_packet_create_reply_t_handler_json
663   (vl_api_af_packet_create_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_vlan_subif_reply_t_handler
680   (vl_api_create_vlan_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_vlan_subif_reply_t_handler_json
692   (vl_api_create_vlan_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_create_subif_reply_t_handler
709   (vl_api_create_subif_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->sw_if_index = ntohl (mp->sw_if_index);
717   vam->result_ready = 1;
718 }
719
720 static void vl_api_create_subif_reply_t_handler_json
721   (vl_api_create_subif_reply_t * mp)
722 {
723   vat_main_t *vam = &vat_main;
724   vat_json_node_t node;
725
726   vat_json_init_object (&node);
727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
729
730   vat_json_print (vam->ofp, &node);
731   vat_json_free (&node);
732
733   vam->retval = ntohl (mp->retval);
734   vam->result_ready = 1;
735 }
736
737 static void vl_api_interface_name_renumber_reply_t_handler
738   (vl_api_interface_name_renumber_reply_t * mp)
739 {
740   vat_main_t *vam = &vat_main;
741   i32 retval = ntohl (mp->retval);
742
743   vam->retval = retval;
744   vam->regenerate_interface_table = 1;
745   vam->result_ready = 1;
746 }
747
748 static void vl_api_interface_name_renumber_reply_t_handler_json
749   (vl_api_interface_name_renumber_reply_t * mp)
750 {
751   vat_main_t *vam = &vat_main;
752   vat_json_node_t node;
753
754   vat_json_init_object (&node);
755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
756
757   vat_json_print (vam->ofp, &node);
758   vat_json_free (&node);
759
760   vam->retval = ntohl (mp->retval);
761   vam->result_ready = 1;
762 }
763
764 /*
765  * Special-case: build the interface table, maintain
766  * the next loopback sw_if_index vbl.
767  */
768 static void vl_api_sw_interface_details_t_handler
769   (vl_api_sw_interface_details_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   u8 *s = format (0, "%s%c", mp->interface_name, 0);
773
774   hash_set_mem (vam->sw_if_index_by_interface_name, s,
775                 ntohl (mp->sw_if_index));
776
777   /* In sub interface case, fill the sub interface table entry */
778   if (mp->sw_if_index != mp->sup_sw_if_index)
779     {
780       sw_interface_subif_t *sub = NULL;
781
782       vec_add2 (vam->sw_if_subif_table, sub, 1);
783
784       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
785       strncpy ((char *) sub->interface_name, (char *) s,
786                vec_len (sub->interface_name));
787       sub->sw_if_index = ntohl (mp->sw_if_index);
788       sub->sub_id = ntohl (mp->sub_id);
789
790       sub->sub_dot1ad = mp->sub_dot1ad;
791       sub->sub_number_of_tags = mp->sub_number_of_tags;
792       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
793       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
794       sub->sub_exact_match = mp->sub_exact_match;
795       sub->sub_default = mp->sub_default;
796       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
797       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
798
799       /* vlan tag rewrite */
800       sub->vtr_op = ntohl (mp->vtr_op);
801       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
802       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
803       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
804     }
805 }
806
807 static void vl_api_sw_interface_details_t_handler_json
808   (vl_api_sw_interface_details_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t *node = NULL;
812
813   if (VAT_JSON_ARRAY != vam->json_tree.type)
814     {
815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
816       vat_json_init_array (&vam->json_tree);
817     }
818   node = vat_json_array_add (&vam->json_tree);
819
820   vat_json_init_object (node);
821   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
822   vat_json_object_add_uint (node, "sup_sw_if_index",
823                             ntohl (mp->sup_sw_if_index));
824   vat_json_object_add_uint (node, "l2_address_length",
825                             ntohl (mp->l2_address_length));
826   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
827                              sizeof (mp->l2_address));
828   vat_json_object_add_string_copy (node, "interface_name",
829                                    mp->interface_name);
830   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
831   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
832   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
833   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
834   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
835   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
836   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
837   vat_json_object_add_uint (node, "sub_number_of_tags",
838                             mp->sub_number_of_tags);
839   vat_json_object_add_uint (node, "sub_outer_vlan_id",
840                             ntohs (mp->sub_outer_vlan_id));
841   vat_json_object_add_uint (node, "sub_inner_vlan_id",
842                             ntohs (mp->sub_inner_vlan_id));
843   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
844   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
845   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
846                             mp->sub_outer_vlan_id_any);
847   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
848                             mp->sub_inner_vlan_id_any);
849   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
850   vat_json_object_add_uint (node, "vtr_push_dot1q",
851                             ntohl (mp->vtr_push_dot1q));
852   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
853   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
854 }
855
856 static void vl_api_sw_interface_set_flags_t_handler
857   (vl_api_sw_interface_set_flags_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   if (vam->interface_event_display)
861     errmsg ("interface flags: sw_if_index %d %s %s\n",
862             ntohl (mp->sw_if_index),
863             mp->admin_up_down ? "admin-up" : "admin-down",
864             mp->link_up_down ? "link-up" : "link-down");
865 }
866
867 static void vl_api_sw_interface_set_flags_t_handler_json
868   (vl_api_sw_interface_set_flags_t * mp)
869 {
870   /* JSON output not supported */
871 }
872
873 static void
874 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   i32 retval = ntohl (mp->retval);
878
879   vam->retval = retval;
880   vam->shmem_result = (u8 *) mp->reply_in_shmem;
881   vam->result_ready = 1;
882 }
883
884 static void
885 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   vat_json_node_t node;
889   api_main_t *am = &api_main;
890   void *oldheap;
891   u8 *reply;
892
893   vat_json_init_object (&node);
894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
895   vat_json_object_add_uint (&node, "reply_in_shmem",
896                             ntohl (mp->reply_in_shmem));
897   /* Toss the shared-memory original... */
898   pthread_mutex_lock (&am->vlib_rp->mutex);
899   oldheap = svm_push_data_heap (am->vlib_rp);
900
901   reply = (u8 *) (mp->reply_in_shmem);
902   vec_free (reply);
903
904   svm_pop_heap (oldheap);
905   pthread_mutex_unlock (&am->vlib_rp->mutex);
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 static void
915 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   i32 retval = ntohl (mp->retval);
919
920   vam->retval = retval;
921   vam->cmd_reply = mp->reply;
922   vam->result_ready = 1;
923 }
924
925 static void
926 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_string_copy (&node, "reply", mp->reply);
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_classify_add_del_table_reply_t_handler
943   (vl_api_classify_add_del_table_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947   if (vam->async_mode)
948     {
949       vam->async_errors += (retval < 0);
950     }
951   else
952     {
953       vam->retval = retval;
954       if (retval == 0 &&
955           ((mp->new_table_index != 0xFFFFFFFF) ||
956            (mp->skip_n_vectors != 0xFFFFFFFF) ||
957            (mp->match_n_vectors != 0xFFFFFFFF)))
958         /*
959          * Note: this is just barely thread-safe, depends on
960          * the main thread spinning waiting for an answer...
961          */
962         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
963                 ntohl (mp->new_table_index),
964                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
965       vam->result_ready = 1;
966     }
967 }
968
969 static void vl_api_classify_add_del_table_reply_t_handler_json
970   (vl_api_classify_add_del_table_reply_t * mp)
971 {
972   vat_main_t *vam = &vat_main;
973   vat_json_node_t node;
974
975   vat_json_init_object (&node);
976   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
977   vat_json_object_add_uint (&node, "new_table_index",
978                             ntohl (mp->new_table_index));
979   vat_json_object_add_uint (&node, "skip_n_vectors",
980                             ntohl (mp->skip_n_vectors));
981   vat_json_object_add_uint (&node, "match_n_vectors",
982                             ntohl (mp->match_n_vectors));
983
984   vat_json_print (vam->ofp, &node);
985   vat_json_free (&node);
986
987   vam->retval = ntohl (mp->retval);
988   vam->result_ready = 1;
989 }
990
991 static void vl_api_get_node_index_reply_t_handler
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   i32 retval = ntohl (mp->retval);
996   if (vam->async_mode)
997     {
998       vam->async_errors += (retval < 0);
999     }
1000   else
1001     {
1002       vam->retval = retval;
1003       if (retval == 0)
1004         errmsg ("node index %d\n", ntohl (mp->node_index));
1005       vam->result_ready = 1;
1006     }
1007 }
1008
1009 static void vl_api_get_node_index_reply_t_handler_json
1010   (vl_api_get_node_index_reply_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t node;
1014
1015   vat_json_init_object (&node);
1016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1017   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1018
1019   vat_json_print (vam->ofp, &node);
1020   vat_json_free (&node);
1021
1022   vam->retval = ntohl (mp->retval);
1023   vam->result_ready = 1;
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031   if (vam->async_mode)
1032     {
1033       vam->async_errors += (retval < 0);
1034     }
1035   else
1036     {
1037       vam->retval = retval;
1038       if (retval == 0)
1039         errmsg ("next node index %d\n", ntohl (mp->next_index));
1040       vam->result_ready = 1;
1041     }
1042 }
1043
1044 static void vl_api_get_next_index_reply_t_handler_json
1045   (vl_api_get_next_index_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049
1050   vat_json_init_object (&node);
1051   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1052   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1053
1054   vat_json_print (vam->ofp, &node);
1055   vat_json_free (&node);
1056
1057   vam->retval = ntohl (mp->retval);
1058   vam->result_ready = 1;
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   i32 retval = ntohl (mp->retval);
1066   if (vam->async_mode)
1067     {
1068       vam->async_errors += (retval < 0);
1069     }
1070   else
1071     {
1072       vam->retval = retval;
1073       if (retval == 0)
1074         errmsg ("next index %d\n", ntohl (mp->next_index));
1075       vam->result_ready = 1;
1076     }
1077 }
1078
1079 static void vl_api_add_node_next_reply_t_handler_json
1080   (vl_api_add_node_next_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   vat_json_node_t node;
1084
1085   vat_json_init_object (&node);
1086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1087   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1088
1089   vat_json_print (vam->ofp, &node);
1090   vat_json_free (&node);
1091
1092   vam->retval = ntohl (mp->retval);
1093   vam->result_ready = 1;
1094 }
1095
1096 static void vl_api_show_version_reply_t_handler
1097   (vl_api_show_version_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   i32 retval = ntohl (mp->retval);
1101
1102   if (retval >= 0)
1103     {
1104       errmsg ("        program: %s\n", mp->program);
1105       errmsg ("        version: %s\n", mp->version);
1106       errmsg ("     build date: %s\n", mp->build_date);
1107       errmsg ("build directory: %s\n", mp->build_directory);
1108     }
1109   vam->retval = retval;
1110   vam->result_ready = 1;
1111 }
1112
1113 static void vl_api_show_version_reply_t_handler_json
1114   (vl_api_show_version_reply_t * mp)
1115 {
1116   vat_main_t *vam = &vat_main;
1117   vat_json_node_t node;
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "program", mp->program);
1122   vat_json_object_add_string_copy (&node, "version", mp->version);
1123   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1124   vat_json_object_add_string_copy (&node, "build_directory",
1125                                    mp->build_directory);
1126
1127   vat_json_print (vam->ofp, &node);
1128   vat_json_free (&node);
1129
1130   vam->retval = ntohl (mp->retval);
1131   vam->result_ready = 1;
1132 }
1133
1134 static void
1135 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1136 {
1137   vat_main_t *vam = &vat_main;
1138   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1139           mp->mac_ip ? "mac/ip binding" : "address resolution",
1140           format_ip4_address, &mp->address,
1141           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1142 }
1143
1144 static void
1145 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1146 {
1147   /* JSON output not supported */
1148 }
1149
1150 static void
1151 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip6_address, mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 /*
1167  * Special-case: build the bridge domain table, maintain
1168  * the next bd id vbl.
1169  */
1170 static void vl_api_bridge_domain_details_t_handler
1171   (vl_api_bridge_domain_details_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1175
1176   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1177            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1178
1179   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1180            ntohl (mp->bd_id), mp->learn, mp->forward,
1181            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1182
1183   if (n_sw_ifs)
1184     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1185              "Interface Name");
1186 }
1187
1188 static void vl_api_bridge_domain_details_t_handler_json
1189   (vl_api_bridge_domain_details_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   vat_json_node_t *node, *array = NULL;
1193
1194   if (VAT_JSON_ARRAY != vam->json_tree.type)
1195     {
1196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1197       vat_json_init_array (&vam->json_tree);
1198     }
1199   node = vat_json_array_add (&vam->json_tree);
1200
1201   vat_json_init_object (node);
1202   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1203   vat_json_object_add_uint (node, "flood", mp->flood);
1204   vat_json_object_add_uint (node, "forward", mp->forward);
1205   vat_json_object_add_uint (node, "learn", mp->learn);
1206   vat_json_object_add_uint (node, "bvi_sw_if_index",
1207                             ntohl (mp->bvi_sw_if_index));
1208   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1209   array = vat_json_object_add (node, "sw_if");
1210   vat_json_init_array (array);
1211 }
1212
1213 /*
1214  * Special-case: build the bridge domain sw if table.
1215  */
1216 static void vl_api_bridge_domain_sw_if_details_t_handler
1217   (vl_api_bridge_domain_sw_if_details_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   hash_pair_t *p;
1221   u8 *sw_if_name = 0;
1222   u32 sw_if_index;
1223
1224   sw_if_index = ntohl (mp->sw_if_index);
1225   /* *INDENT-OFF* */
1226   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1227   ({
1228     if ((u32) p->value[0] == sw_if_index)
1229       {
1230         sw_if_name = (u8 *)(p->key);
1231         break;
1232       }
1233   }));
1234   /* *INDENT-ON* */
1235
1236   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1237            mp->shg, sw_if_name ? (char *) sw_if_name :
1238            "sw_if_index not found!");
1239 }
1240
1241 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1242   (vl_api_bridge_domain_sw_if_details_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t *node = NULL;
1246   uword last_index = 0;
1247
1248   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1249   ASSERT (vec_len (vam->json_tree.array) >= 1);
1250   last_index = vec_len (vam->json_tree.array) - 1;
1251   node = &vam->json_tree.array[last_index];
1252   node = vat_json_object_get_element (node, "sw_if");
1253   ASSERT (NULL != node);
1254   node = vat_json_array_add (node);
1255
1256   vat_json_init_object (node);
1257   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1258   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1259   vat_json_object_add_uint (node, "shg", mp->shg);
1260 }
1261
1262 static void vl_api_control_ping_reply_t_handler
1263   (vl_api_control_ping_reply_t * mp)
1264 {
1265   vat_main_t *vam = &vat_main;
1266   i32 retval = ntohl (mp->retval);
1267   if (vam->async_mode)
1268     {
1269       vam->async_errors += (retval < 0);
1270     }
1271   else
1272     {
1273       vam->retval = retval;
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler_json
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283
1284   if (VAT_JSON_NONE != vam->json_tree.type)
1285     {
1286       vat_json_print (vam->ofp, &vam->json_tree);
1287       vat_json_free (&vam->json_tree);
1288       vam->json_tree.type = VAT_JSON_NONE;
1289     }
1290   else
1291     {
1292       /* just print [] */
1293       vat_json_init_array (&vam->json_tree);
1294       vat_json_print (vam->ofp, &vam->json_tree);
1295       vam->json_tree.type = VAT_JSON_NONE;
1296     }
1297
1298   vam->retval = retval;
1299   vam->result_ready = 1;
1300 }
1301
1302 static void
1303 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   i32 retval = ntohl (mp->retval);
1307   if (vam->async_mode)
1308     {
1309       vam->async_errors += (retval < 0);
1310     }
1311   else
1312     {
1313       vam->retval = retval;
1314       vam->result_ready = 1;
1315     }
1316 }
1317
1318 static void vl_api_l2_flags_reply_t_handler_json
1319   (vl_api_l2_flags_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   vat_json_node_t node;
1323
1324   vat_json_init_object (&node);
1325   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1326   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1327                             ntohl (mp->resulting_feature_bitmap));
1328
1329   vat_json_print (vam->ofp, &node);
1330   vat_json_free (&node);
1331
1332   vam->retval = ntohl (mp->retval);
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_bridge_flags_reply_t_handler
1337   (vl_api_bridge_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   i32 retval = ntohl (mp->retval);
1341   if (vam->async_mode)
1342     {
1343       vam->async_errors += (retval < 0);
1344     }
1345   else
1346     {
1347       vam->retval = retval;
1348       vam->result_ready = 1;
1349     }
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler_json
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   vat_json_node_t node;
1357
1358   vat_json_init_object (&node);
1359   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1360   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1361                             ntohl (mp->resulting_feature_bitmap));
1362
1363   vat_json_print (vam->ofp, &node);
1364   vat_json_free (&node);
1365
1366   vam->retval = ntohl (mp->retval);
1367   vam->result_ready = 1;
1368 }
1369
1370 static void vl_api_tap_connect_reply_t_handler
1371   (vl_api_tap_connect_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   i32 retval = ntohl (mp->retval);
1375   if (vam->async_mode)
1376     {
1377       vam->async_errors += (retval < 0);
1378     }
1379   else
1380     {
1381       vam->retval = retval;
1382       vam->sw_if_index = ntohl (mp->sw_if_index);
1383       vam->result_ready = 1;
1384     }
1385
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler_json
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   vat_json_node_t node;
1393
1394   vat_json_init_object (&node);
1395   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1396   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1397
1398   vat_json_print (vam->ofp, &node);
1399   vat_json_free (&node);
1400
1401   vam->retval = ntohl (mp->retval);
1402   vam->result_ready = 1;
1403
1404 }
1405
1406 static void
1407 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   i32 retval = ntohl (mp->retval);
1411   if (vam->async_mode)
1412     {
1413       vam->async_errors += (retval < 0);
1414     }
1415   else
1416     {
1417       vam->retval = retval;
1418       vam->sw_if_index = ntohl (mp->sw_if_index);
1419       vam->result_ready = 1;
1420     }
1421 }
1422
1423 static void vl_api_tap_modify_reply_t_handler_json
1424   (vl_api_tap_modify_reply_t * mp)
1425 {
1426   vat_main_t *vam = &vat_main;
1427   vat_json_node_t node;
1428
1429   vat_json_init_object (&node);
1430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1431   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1432
1433   vat_json_print (vam->ofp, &node);
1434   vat_json_free (&node);
1435
1436   vam->retval = ntohl (mp->retval);
1437   vam->result_ready = 1;
1438 }
1439
1440 static void
1441 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   i32 retval = ntohl (mp->retval);
1445   if (vam->async_mode)
1446     {
1447       vam->async_errors += (retval < 0);
1448     }
1449   else
1450     {
1451       vam->retval = retval;
1452       vam->result_ready = 1;
1453     }
1454 }
1455
1456 static void vl_api_tap_delete_reply_t_handler_json
1457   (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   vat_json_node_t node;
1461
1462   vat_json_init_object (&node);
1463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1464
1465   vat_json_print (vam->ofp, &node);
1466   vat_json_free (&node);
1467
1468   vam->retval = ntohl (mp->retval);
1469   vam->result_ready = 1;
1470 }
1471
1472 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1473   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   i32 retval = ntohl (mp->retval);
1477   if (vam->async_mode)
1478     {
1479       vam->async_errors += (retval < 0);
1480     }
1481   else
1482     {
1483       vam->retval = retval;
1484       vam->result_ready = 1;
1485     }
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   vat_json_node_t node;
1493
1494   vat_json_init_object (&node);
1495   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1496   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1497                             ntohl (mp->tunnel_sw_if_index));
1498
1499   vat_json_print (vam->ofp, &node);
1500   vat_json_free (&node);
1501
1502   vam->retval = ntohl (mp->retval);
1503   vam->result_ready = 1;
1504 }
1505
1506 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1507   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   i32 retval = ntohl (mp->retval);
1511   if (vam->async_mode)
1512     {
1513       vam->async_errors += (retval < 0);
1514     }
1515   else
1516     {
1517       vam->retval = retval;
1518       vam->sw_if_index = ntohl (mp->sw_if_index);
1519       vam->result_ready = 1;
1520     }
1521 }
1522
1523 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1524   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1525 {
1526   vat_main_t *vam = &vat_main;
1527   vat_json_node_t node;
1528
1529   vat_json_init_object (&node);
1530   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1531   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540
1541 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1542   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   i32 retval = ntohl (mp->retval);
1546   if (vam->async_mode)
1547     {
1548       vam->async_errors += (retval < 0);
1549     }
1550   else
1551     {
1552       vam->retval = retval;
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   vat_json_node_t node;
1562
1563   vat_json_init_object (&node);
1564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1565   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1575   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->sw_if_index = ntohl (mp->sw_if_index);
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1592   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   vat_json_node_t node;
1596
1597   vat_json_init_object (&node);
1598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1599   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_gre_add_del_tunnel_reply_t_handler
1609   (vl_api_gre_add_del_tunnel_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623 }
1624
1625 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1626   (vl_api_gre_add_del_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   vat_json_node_t node;
1630
1631   vat_json_init_object (&node);
1632   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1633   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1634
1635   vat_json_print (vam->ofp, &node);
1636   vat_json_free (&node);
1637
1638   vam->retval = ntohl (mp->retval);
1639   vam->result_ready = 1;
1640 }
1641
1642 static void vl_api_create_vhost_user_if_reply_t_handler
1643   (vl_api_create_vhost_user_if_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   i32 retval = ntohl (mp->retval);
1647   if (vam->async_mode)
1648     {
1649       vam->async_errors += (retval < 0);
1650     }
1651   else
1652     {
1653       vam->retval = retval;
1654       vam->sw_if_index = ntohl (mp->sw_if_index);
1655       vam->result_ready = 1;
1656     }
1657 }
1658
1659 static void vl_api_create_vhost_user_if_reply_t_handler_json
1660   (vl_api_create_vhost_user_if_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   vat_json_node_t node;
1664
1665   vat_json_init_object (&node);
1666   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1667   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1668
1669   vat_json_print (vam->ofp, &node);
1670   vat_json_free (&node);
1671
1672   vam->retval = ntohl (mp->retval);
1673   vam->result_ready = 1;
1674 }
1675
1676 static void vl_api_ip_address_details_t_handler
1677   (vl_api_ip_address_details_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   static ip_address_details_t empty_ip_address_details = { {0} };
1681   ip_address_details_t *address = NULL;
1682   ip_details_t *current_ip_details = NULL;
1683   ip_details_t *details = NULL;
1684
1685   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1686
1687   if (!details || vam->current_sw_if_index >= vec_len (details)
1688       || !details[vam->current_sw_if_index].present)
1689     {
1690       errmsg ("ip address details arrived but not stored\n");
1691       errmsg ("ip_dump should be called first\n");
1692       return;
1693     }
1694
1695   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1696
1697 #define addresses (current_ip_details->addr)
1698
1699   vec_validate_init_empty (addresses, vec_len (addresses),
1700                            empty_ip_address_details);
1701
1702   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1703
1704   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1705   address->prefix_length = mp->prefix_length;
1706 #undef addresses
1707 }
1708
1709 static void vl_api_ip_address_details_t_handler_json
1710   (vl_api_ip_address_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   vat_json_node_t *node = NULL;
1714   struct in6_addr ip6;
1715   struct in_addr ip4;
1716
1717   if (VAT_JSON_ARRAY != vam->json_tree.type)
1718     {
1719       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1720       vat_json_init_array (&vam->json_tree);
1721     }
1722   node = vat_json_array_add (&vam->json_tree);
1723
1724   vat_json_init_object (node);
1725   if (vam->is_ipv6)
1726     {
1727       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1728       vat_json_object_add_ip6 (node, "ip", ip6);
1729     }
1730   else
1731     {
1732       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1733       vat_json_object_add_ip4 (node, "ip", ip4);
1734     }
1735   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1736 }
1737
1738 static void
1739 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   static ip_details_t empty_ip_details = { 0 };
1743   ip_details_t *ip = NULL;
1744   u32 sw_if_index = ~0;
1745
1746   sw_if_index = ntohl (mp->sw_if_index);
1747
1748   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1749                            sw_if_index, empty_ip_details);
1750
1751   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1752                          sw_if_index);
1753
1754   ip->present = 1;
1755 }
1756
1757 static void
1758 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1759 {
1760   vat_main_t *vam = &vat_main;
1761
1762   if (VAT_JSON_ARRAY != vam->json_tree.type)
1763     {
1764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1765       vat_json_init_array (&vam->json_tree);
1766     }
1767   vat_json_array_add_uint (&vam->json_tree,
1768                            clib_net_to_host_u32 (mp->sw_if_index));
1769 }
1770
1771 static void vl_api_map_domain_details_t_handler_json
1772   (vl_api_map_domain_details_t * mp)
1773 {
1774   vat_json_node_t *node = NULL;
1775   vat_main_t *vam = &vat_main;
1776   struct in6_addr ip6;
1777   struct in_addr ip4;
1778
1779   if (VAT_JSON_ARRAY != vam->json_tree.type)
1780     {
1781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1782       vat_json_init_array (&vam->json_tree);
1783     }
1784
1785   node = vat_json_array_add (&vam->json_tree);
1786   vat_json_init_object (node);
1787
1788   vat_json_object_add_uint (node, "domain_index",
1789                             clib_net_to_host_u32 (mp->domain_index));
1790   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1791   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1792   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1793   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1794   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1795   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1796   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1797   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1798   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1799   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1800   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1801   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1802   vat_json_object_add_uint (node, "flags", mp->flags);
1803   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1804   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1805 }
1806
1807 static void vl_api_map_domain_details_t_handler
1808   (vl_api_map_domain_details_t * mp)
1809 {
1810   vat_main_t *vam = &vat_main;
1811
1812   if (mp->is_translation)
1813     {
1814       fformat (vam->ofp,
1815                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1816                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1817                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1818                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1819                clib_net_to_host_u32 (mp->domain_index));
1820     }
1821   else
1822     {
1823       fformat (vam->ofp,
1824                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1825                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1826                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1827                format_ip6_address, mp->ip6_src,
1828                clib_net_to_host_u32 (mp->domain_index));
1829     }
1830   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1831            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1832            mp->is_translation ? "map-t" : "");
1833 }
1834
1835 static void vl_api_map_rule_details_t_handler_json
1836   (vl_api_map_rule_details_t * mp)
1837 {
1838   struct in6_addr ip6;
1839   vat_json_node_t *node = NULL;
1840   vat_main_t *vam = &vat_main;
1841
1842   if (VAT_JSON_ARRAY != vam->json_tree.type)
1843     {
1844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1845       vat_json_init_array (&vam->json_tree);
1846     }
1847
1848   node = vat_json_array_add (&vam->json_tree);
1849   vat_json_init_object (node);
1850
1851   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1852   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1853   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1854 }
1855
1856 static void
1857 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1861            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1862 }
1863
1864 static void
1865 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1869           "router_addr %U host_mac %U\n",
1870           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1871           format_ip4_address, &mp->host_address,
1872           format_ip4_address, &mp->router_address,
1873           format_ethernet_address, mp->host_mac);
1874 }
1875
1876 static void vl_api_dhcp_compl_event_t_handler_json
1877   (vl_api_dhcp_compl_event_t * mp)
1878 {
1879   /* JSON output not supported */
1880 }
1881
1882 static void
1883 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1884                               u32 counter)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   static u64 default_counter = 0;
1888
1889   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1890                            NULL);
1891   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1892                            sw_if_index, default_counter);
1893   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1894 }
1895
1896 static void
1897 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1898                                 interface_counter_t counter)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   static interface_counter_t default_counter = { 0, };
1902
1903   vec_validate_init_empty (vam->combined_interface_counters,
1904                            vnet_counter_type, NULL);
1905   vec_validate_init_empty (vam->combined_interface_counters
1906                            [vnet_counter_type], sw_if_index, default_counter);
1907   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1908 }
1909
1910 static void vl_api_vnet_interface_counters_t_handler
1911   (vl_api_vnet_interface_counters_t * mp)
1912 {
1913   /* not supported */
1914 }
1915
1916 static void vl_api_vnet_interface_counters_t_handler_json
1917   (vl_api_vnet_interface_counters_t * mp)
1918 {
1919   interface_counter_t counter;
1920   vlib_counter_t *v;
1921   u64 *v_packets;
1922   u64 packets;
1923   u32 count;
1924   u32 first_sw_if_index;
1925   int i;
1926
1927   count = ntohl (mp->count);
1928   first_sw_if_index = ntohl (mp->first_sw_if_index);
1929
1930   if (!mp->is_combined)
1931     {
1932       v_packets = (u64 *) & mp->data;
1933       for (i = 0; i < count; i++)
1934         {
1935           packets =
1936             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1937           set_simple_interface_counter (mp->vnet_counter_type,
1938                                         first_sw_if_index + i, packets);
1939           v_packets++;
1940         }
1941     }
1942   else
1943     {
1944       v = (vlib_counter_t *) & mp->data;
1945       for (i = 0; i < count; i++)
1946         {
1947           counter.packets =
1948             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1949           counter.bytes =
1950             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1951           set_combined_interface_counter (mp->vnet_counter_type,
1952                                           first_sw_if_index + i, counter);
1953           v++;
1954         }
1955     }
1956 }
1957
1958 static u32
1959 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   u32 i;
1963
1964   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1965     {
1966       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1967         {
1968           return i;
1969         }
1970     }
1971   return ~0;
1972 }
1973
1974 static u32
1975 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static void vl_api_vnet_ip4_fib_counters_t_handler
1991   (vl_api_vnet_ip4_fib_counters_t * mp)
1992 {
1993   /* not supported */
1994 }
1995
1996 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1997   (vl_api_vnet_ip4_fib_counters_t * mp)
1998 {
1999   vat_main_t *vam = &vat_main;
2000   vl_api_ip4_fib_counter_t *v;
2001   ip4_fib_counter_t *counter;
2002   struct in_addr ip4;
2003   u32 vrf_id;
2004   u32 vrf_index;
2005   u32 count;
2006   int i;
2007
2008   vrf_id = ntohl (mp->vrf_id);
2009   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2010   if (~0 == vrf_index)
2011     {
2012       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2013       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2014       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2015       vec_validate (vam->ip4_fib_counters, vrf_index);
2016       vam->ip4_fib_counters[vrf_index] = NULL;
2017     }
2018
2019   vec_free (vam->ip4_fib_counters[vrf_index]);
2020   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2021   count = ntohl (mp->count);
2022   for (i = 0; i < count; i++)
2023     {
2024       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2025       counter = &vam->ip4_fib_counters[vrf_index][i];
2026       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2027       counter->address = ip4;
2028       counter->address_length = v->address_length;
2029       counter->packets = clib_net_to_host_u64 (v->packets);
2030       counter->bytes = clib_net_to_host_u64 (v->bytes);
2031       v++;
2032     }
2033 }
2034
2035 static void vl_api_vnet_ip6_fib_counters_t_handler
2036   (vl_api_vnet_ip6_fib_counters_t * mp)
2037 {
2038   /* not supported */
2039 }
2040
2041 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2042   (vl_api_vnet_ip6_fib_counters_t * mp)
2043 {
2044   vat_main_t *vam = &vat_main;
2045   vl_api_ip6_fib_counter_t *v;
2046   ip6_fib_counter_t *counter;
2047   struct in6_addr ip6;
2048   u32 vrf_id;
2049   u32 vrf_index;
2050   u32 count;
2051   int i;
2052
2053   vrf_id = ntohl (mp->vrf_id);
2054   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2055   if (~0 == vrf_index)
2056     {
2057       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2058       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2059       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2060       vec_validate (vam->ip6_fib_counters, vrf_index);
2061       vam->ip6_fib_counters[vrf_index] = NULL;
2062     }
2063
2064   vec_free (vam->ip6_fib_counters[vrf_index]);
2065   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2066   count = ntohl (mp->count);
2067   for (i = 0; i < count; i++)
2068     {
2069       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2070       counter = &vam->ip6_fib_counters[vrf_index][i];
2071       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2072       counter->address = ip6;
2073       counter->address_length = v->address_length;
2074       counter->packets = clib_net_to_host_u64 (v->packets);
2075       counter->bytes = clib_net_to_host_u64 (v->bytes);
2076       v++;
2077     }
2078 }
2079
2080 static void vl_api_get_first_msg_id_reply_t_handler
2081   (vl_api_get_first_msg_id_reply_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   i32 retval = ntohl (mp->retval);
2085
2086   if (vam->async_mode)
2087     {
2088       vam->async_errors += (retval < 0);
2089     }
2090   else
2091     {
2092       vam->retval = retval;
2093       vam->result_ready = 1;
2094     }
2095   if (retval >= 0)
2096     {
2097       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2098     }
2099 }
2100
2101 static void vl_api_get_first_msg_id_reply_t_handler_json
2102   (vl_api_get_first_msg_id_reply_t * mp)
2103 {
2104   vat_main_t *vam = &vat_main;
2105   vat_json_node_t node;
2106
2107   vat_json_init_object (&node);
2108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2109   vat_json_object_add_uint (&node, "first_msg_id",
2110                             (uint) ntohs (mp->first_msg_id));
2111
2112   vat_json_print (vam->ofp, &node);
2113   vat_json_free (&node);
2114
2115   vam->retval = ntohl (mp->retval);
2116   vam->result_ready = 1;
2117 }
2118
2119 static void vl_api_get_node_graph_reply_t_handler
2120   (vl_api_get_node_graph_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   api_main_t *am = &api_main;
2124   i32 retval = ntohl (mp->retval);
2125   u8 *pvt_copy, *reply;
2126   void *oldheap;
2127   vlib_node_t *node;
2128   int i;
2129
2130   if (vam->async_mode)
2131     {
2132       vam->async_errors += (retval < 0);
2133     }
2134   else
2135     {
2136       vam->retval = retval;
2137       vam->result_ready = 1;
2138     }
2139
2140   /* "Should never happen..." */
2141   if (retval != 0)
2142     return;
2143
2144   reply = (u8 *) (mp->reply_in_shmem);
2145   pvt_copy = vec_dup (reply);
2146
2147   /* Toss the shared-memory original... */
2148   pthread_mutex_lock (&am->vlib_rp->mutex);
2149   oldheap = svm_push_data_heap (am->vlib_rp);
2150
2151   vec_free (reply);
2152
2153   svm_pop_heap (oldheap);
2154   pthread_mutex_unlock (&am->vlib_rp->mutex);
2155
2156   if (vam->graph_nodes)
2157     {
2158       hash_free (vam->graph_node_index_by_name);
2159
2160       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2161         {
2162           node = vam->graph_nodes[i];
2163           vec_free (node->name);
2164           vec_free (node->next_nodes);
2165           vec_free (node);
2166         }
2167       vec_free (vam->graph_nodes);
2168     }
2169
2170   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2171   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2172   vec_free (pvt_copy);
2173
2174   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2175     {
2176       node = vam->graph_nodes[i];
2177       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2178     }
2179 }
2180
2181 static void vl_api_get_node_graph_reply_t_handler_json
2182   (vl_api_get_node_graph_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   api_main_t *am = &api_main;
2186   void *oldheap;
2187   vat_json_node_t node;
2188   u8 *reply;
2189
2190   /* $$$$ make this real? */
2191   vat_json_init_object (&node);
2192   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2193   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2194
2195   reply = (u8 *) (mp->reply_in_shmem);
2196
2197   /* Toss the shared-memory original... */
2198   pthread_mutex_lock (&am->vlib_rp->mutex);
2199   oldheap = svm_push_data_heap (am->vlib_rp);
2200
2201   vec_free (reply);
2202
2203   svm_pop_heap (oldheap);
2204   pthread_mutex_unlock (&am->vlib_rp->mutex);
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void
2214 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   u8 *s = 0;
2218
2219   if (mp->local)
2220     {
2221       s = format (s, "%=16d%=16d%=16d\n",
2222                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2223     }
2224   else
2225     {
2226       s = format (s, "%=16U%=16d%=16d\n",
2227                   mp->is_ipv6 ? format_ip6_address :
2228                   format_ip4_address,
2229                   mp->ip_address, mp->priority, mp->weight);
2230     }
2231
2232   fformat (vam->ofp, "%v", s);
2233   vec_free (s);
2234 }
2235
2236 static void
2237 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2238                                             mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   vat_json_node_t *node = NULL;
2242   struct in6_addr ip6;
2243   struct in_addr ip4;
2244
2245   if (VAT_JSON_ARRAY != vam->json_tree.type)
2246     {
2247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2248       vat_json_init_array (&vam->json_tree);
2249     }
2250   node = vat_json_array_add (&vam->json_tree);
2251   vat_json_init_object (node);
2252
2253   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2254   vat_json_object_add_uint (node, "priority", mp->priority);
2255   vat_json_object_add_uint (node, "weight", mp->weight);
2256
2257   if (mp->local)
2258     vat_json_object_add_uint (node, "sw_if_index",
2259                               clib_net_to_host_u32 (mp->sw_if_index));
2260   else
2261     {
2262       if (mp->is_ipv6)
2263         {
2264           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2265           vat_json_object_add_ip6 (node, "address", ip6);
2266         }
2267       else
2268         {
2269           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2270           vat_json_object_add_ip4 (node, "address", ip4);
2271         }
2272     }
2273 }
2274
2275 static void
2276 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2277                                            mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   u8 *ls_name = 0;
2281
2282   ls_name = format (0, "%s", mp->ls_name);
2283
2284   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2285            ls_name);
2286   vec_free (ls_name);
2287 }
2288
2289 static void
2290   vl_api_lisp_locator_set_details_t_handler_json
2291   (vl_api_lisp_locator_set_details_t * mp)
2292 {
2293   vat_main_t *vam = &vat_main;
2294   vat_json_node_t *node = 0;
2295   u8 *ls_name = 0;
2296
2297   ls_name = format (0, "%s", mp->ls_name);
2298   vec_add1 (ls_name, 0);
2299
2300   if (VAT_JSON_ARRAY != vam->json_tree.type)
2301     {
2302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2303       vat_json_init_array (&vam->json_tree);
2304     }
2305   node = vat_json_array_add (&vam->json_tree);
2306
2307   vat_json_init_object (node);
2308   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2309   vat_json_object_add_uint (node, "ls_index",
2310                             clib_net_to_host_u32 (mp->ls_index));
2311   vec_free (ls_name);
2312 }
2313
2314 static u8 *
2315 format_lisp_flat_eid (u8 * s, va_list * args)
2316 {
2317   u32 type = va_arg (*args, u32);
2318   u8 *eid = va_arg (*args, u8 *);
2319   u32 eid_len = va_arg (*args, u32);
2320
2321   switch (type)
2322     {
2323     case 0:
2324       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2325     case 1:
2326       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2327     case 2:
2328       return format (s, "%U", format_ethernet_address, eid);
2329     }
2330   return 0;
2331 }
2332
2333 static u8 *
2334 format_lisp_eid_vat (u8 * s, va_list * args)
2335 {
2336   u32 type = va_arg (*args, u32);
2337   u8 *eid = va_arg (*args, u8 *);
2338   u32 eid_len = va_arg (*args, u32);
2339   u8 *seid = va_arg (*args, u8 *);
2340   u32 seid_len = va_arg (*args, u32);
2341   u32 is_src_dst = va_arg (*args, u32);
2342
2343   if (is_src_dst)
2344     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2345
2346   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2347
2348   return s;
2349 }
2350
2351 static void
2352 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   u8 *s = 0, *eid = 0;
2356
2357   if (~0 == mp->locator_set_index)
2358     s = format (0, "action: %d", mp->action);
2359   else
2360     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2361
2362   eid = format (0, "%U", format_lisp_eid_vat,
2363                 mp->eid_type,
2364                 mp->eid,
2365                 mp->eid_prefix_len,
2366                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2367   vec_add1 (eid, 0);
2368
2369   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2370            clib_net_to_host_u32 (mp->vni),
2371            eid,
2372            mp->is_local ? "local" : "remote",
2373            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2374   vec_free (s);
2375   vec_free (eid);
2376 }
2377
2378 static void
2379 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2380                                               * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   vat_json_node_t *node = 0;
2384   u8 *eid = 0;
2385
2386   if (VAT_JSON_ARRAY != vam->json_tree.type)
2387     {
2388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2389       vat_json_init_array (&vam->json_tree);
2390     }
2391   node = vat_json_array_add (&vam->json_tree);
2392
2393   vat_json_init_object (node);
2394   if (~0 == mp->locator_set_index)
2395     vat_json_object_add_uint (node, "action", mp->action);
2396   else
2397     vat_json_object_add_uint (node, "locator_set_index",
2398                               clib_net_to_host_u32 (mp->locator_set_index));
2399
2400   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2401   eid = format (0, "%U", format_lisp_eid_vat,
2402                 mp->eid_type,
2403                 mp->eid,
2404                 mp->eid_prefix_len,
2405                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2406   vec_add1 (eid, 0);
2407   vat_json_object_add_string_copy (node, "eid", eid);
2408   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2409   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2410   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2411   vec_free (eid);
2412 }
2413
2414 static void
2415   vl_api_lisp_eid_table_map_details_t_handler
2416   (vl_api_lisp_eid_table_map_details_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419
2420   u8 *line = format (0, "%=10d%=10d",
2421                      clib_net_to_host_u32 (mp->vni),
2422                      clib_net_to_host_u32 (mp->dp_table));
2423   fformat (vam->ofp, "%v\n", line);
2424   vec_free (line);
2425 }
2426
2427 static void
2428   vl_api_lisp_eid_table_map_details_t_handler_json
2429   (vl_api_lisp_eid_table_map_details_t * mp)
2430 {
2431   vat_main_t *vam = &vat_main;
2432   vat_json_node_t *node = NULL;
2433
2434   if (VAT_JSON_ARRAY != vam->json_tree.type)
2435     {
2436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2437       vat_json_init_array (&vam->json_tree);
2438     }
2439   node = vat_json_array_add (&vam->json_tree);
2440   vat_json_init_object (node);
2441   vat_json_object_add_uint (node, "dp_table",
2442                             clib_net_to_host_u32 (mp->dp_table));
2443   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2444 }
2445
2446 static void
2447   vl_api_lisp_eid_table_vni_details_t_handler
2448   (vl_api_lisp_eid_table_vni_details_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451
2452   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2453   fformat (vam->ofp, "%v\n", line);
2454   vec_free (line);
2455 }
2456
2457 static void
2458   vl_api_lisp_eid_table_vni_details_t_handler_json
2459   (vl_api_lisp_eid_table_vni_details_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   vat_json_node_t *node = NULL;
2463
2464   if (VAT_JSON_ARRAY != vam->json_tree.type)
2465     {
2466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2467       vat_json_init_array (&vam->json_tree);
2468     }
2469   node = vat_json_array_add (&vam->json_tree);
2470   vat_json_init_object (node);
2471   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2472 }
2473
2474 static u8 *
2475 format_decap_next (u8 * s, va_list * args)
2476 {
2477   u32 next_index = va_arg (*args, u32);
2478
2479   switch (next_index)
2480     {
2481     case LISP_GPE_INPUT_NEXT_DROP:
2482       return format (s, "drop");
2483     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2484       return format (s, "ip4");
2485     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2486       return format (s, "ip6");
2487     default:
2488       return format (s, "unknown %d", next_index);
2489     }
2490   return s;
2491 }
2492
2493 static void
2494 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2495                                           mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   u8 *iid_str;
2499   u8 *flag_str = NULL;
2500
2501   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2502
2503 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2504   foreach_lisp_gpe_flag_bit;
2505 #undef _
2506
2507   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2508            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2509            mp->tunnels,
2510            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2511            mp->source_ip,
2512            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2513            mp->destination_ip,
2514            ntohl (mp->encap_fib_id),
2515            ntohl (mp->decap_fib_id),
2516            format_decap_next, ntohl (mp->dcap_next),
2517            mp->ver_res >> 6,
2518            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2519
2520   vec_free (iid_str);
2521 }
2522
2523 static void
2524   vl_api_lisp_gpe_tunnel_details_t_handler_json
2525   (vl_api_lisp_gpe_tunnel_details_t * mp)
2526 {
2527   vat_main_t *vam = &vat_main;
2528   vat_json_node_t *node = NULL;
2529   struct in6_addr ip6;
2530   struct in_addr ip4;
2531   u8 *next_decap_str;
2532
2533   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2534
2535   if (VAT_JSON_ARRAY != vam->json_tree.type)
2536     {
2537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2538       vat_json_init_array (&vam->json_tree);
2539     }
2540   node = vat_json_array_add (&vam->json_tree);
2541
2542   vat_json_init_object (node);
2543   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2544   if (mp->is_ipv6)
2545     {
2546       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2547       vat_json_object_add_ip6 (node, "source address", ip6);
2548       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2549       vat_json_object_add_ip6 (node, "destination address", ip6);
2550     }
2551   else
2552     {
2553       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2554       vat_json_object_add_ip4 (node, "source address", ip4);
2555       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2556       vat_json_object_add_ip4 (node, "destination address", ip4);
2557     }
2558   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2559   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2560   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2561   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2562   vat_json_object_add_uint (node, "flags", mp->flags);
2563   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2564   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2565   vat_json_object_add_uint (node, "res", mp->res);
2566   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2567
2568   vec_free (next_decap_str);
2569 }
2570
2571 static void
2572   vl_api_lisp_adjacencies_get_reply_t_handler
2573   (vl_api_lisp_adjacencies_get_reply_t * mp)
2574 {
2575   vat_main_t *vam = &vat_main;
2576   u32 i, n;
2577   int retval = clib_net_to_host_u32 (mp->retval);
2578   vl_api_lisp_adjacency_t *a;
2579
2580   if (retval)
2581     goto end;
2582
2583   n = clib_net_to_host_u32 (mp->count);
2584
2585   for (i = 0; i < n; i++)
2586     {
2587       a = &mp->adjacencies[i];
2588       fformat (vam->ofp, "%U %40U\n",
2589                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2590                format_lisp_flat_eid, a->eid_type, a->reid,
2591                a->reid_prefix_len);
2592     }
2593
2594 end:
2595   vam->retval = retval;
2596   vam->result_ready = 1;
2597 }
2598
2599 static void
2600   vl_api_lisp_adjacencies_get_reply_t_handler_json
2601   (vl_api_lisp_adjacencies_get_reply_t * mp)
2602 {
2603   u8 *s = 0;
2604   vat_main_t *vam = &vat_main;
2605   vat_json_node_t *e = 0, root;
2606   u32 i, n;
2607   int retval = clib_net_to_host_u32 (mp->retval);
2608   vl_api_lisp_adjacency_t *a;
2609
2610   if (retval)
2611     goto end;
2612
2613   n = clib_net_to_host_u32 (mp->count);
2614   vat_json_init_array (&root);
2615
2616   for (i = 0; i < n; i++)
2617     {
2618       e = vat_json_array_add (&root);
2619       a = &mp->adjacencies[i];
2620
2621       vat_json_init_object (e);
2622       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2623                   a->leid_prefix_len);
2624       vec_add1 (s, 0);
2625       vat_json_object_add_string_copy (e, "leid", s);
2626       vec_free (s);
2627
2628       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2629                   a->reid_prefix_len);
2630       vec_add1 (s, 0);
2631       vat_json_object_add_string_copy (e, "reid", s);
2632       vec_free (s);
2633     }
2634
2635   vat_json_print (vam->ofp, &root);
2636   vat_json_free (&root);
2637
2638 end:
2639   vam->retval = retval;
2640   vam->result_ready = 1;
2641 }
2642
2643 static void
2644 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2645                                             * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648
2649   fformat (vam->ofp, "%=20U\n",
2650            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2651            mp->ip_address);
2652 }
2653
2654 static void
2655   vl_api_lisp_map_resolver_details_t_handler_json
2656   (vl_api_lisp_map_resolver_details_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   vat_json_node_t *node = NULL;
2660   struct in6_addr ip6;
2661   struct in_addr ip4;
2662
2663   if (VAT_JSON_ARRAY != vam->json_tree.type)
2664     {
2665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2666       vat_json_init_array (&vam->json_tree);
2667     }
2668   node = vat_json_array_add (&vam->json_tree);
2669
2670   vat_json_init_object (node);
2671   if (mp->is_ipv6)
2672     {
2673       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2674       vat_json_object_add_ip6 (node, "map resolver", ip6);
2675     }
2676   else
2677     {
2678       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2679       vat_json_object_add_ip4 (node, "map resolver", ip4);
2680     }
2681 }
2682
2683 static void
2684   vl_api_show_lisp_status_reply_t_handler
2685   (vl_api_show_lisp_status_reply_t * mp)
2686 {
2687   vat_main_t *vam = &vat_main;
2688   i32 retval = ntohl (mp->retval);
2689
2690   if (0 <= retval)
2691     {
2692       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2693                mp->feature_status ? "enabled" : "disabled",
2694                mp->gpe_status ? "enabled" : "disabled");
2695     }
2696
2697   vam->retval = retval;
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_show_lisp_status_reply_t_handler_json
2703   (vl_api_show_lisp_status_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   vat_json_node_t node;
2707   u8 *gpe_status = NULL;
2708   u8 *feature_status = NULL;
2709
2710   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2711   feature_status = format (0, "%s",
2712                            mp->feature_status ? "enabled" : "disabled");
2713   vec_add1 (gpe_status, 0);
2714   vec_add1 (feature_status, 0);
2715
2716   vat_json_init_object (&node);
2717   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2718   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2719
2720   vec_free (gpe_status);
2721   vec_free (feature_status);
2722
2723   vat_json_print (vam->ofp, &node);
2724   vat_json_free (&node);
2725
2726   vam->retval = ntohl (mp->retval);
2727   vam->result_ready = 1;
2728 }
2729
2730 static void
2731   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2732   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2733 {
2734   vat_main_t *vam = &vat_main;
2735   i32 retval = ntohl (mp->retval);
2736
2737   if (retval >= 0)
2738     {
2739       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2740     }
2741
2742   vam->retval = retval;
2743   vam->result_ready = 1;
2744 }
2745
2746 static void
2747   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2748   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2749 {
2750   vat_main_t *vam = &vat_main;
2751   vat_json_node_t *node = NULL;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2762
2763   vat_json_print (vam->ofp, node);
2764   vat_json_free (node);
2765
2766   vam->retval = ntohl (mp->retval);
2767   vam->result_ready = 1;
2768 }
2769
2770 static u8 *
2771 format_lisp_map_request_mode (u8 * s, va_list * args)
2772 {
2773   u32 mode = va_arg (*args, u32);
2774
2775   switch (mode)
2776     {
2777     case 0:
2778       return format (0, "dst-only");
2779     case 1:
2780       return format (0, "src-dst");
2781     }
2782   return 0;
2783 }
2784
2785 static void
2786   vl_api_show_lisp_map_request_mode_reply_t_handler
2787   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   i32 retval = ntohl (mp->retval);
2791
2792   if (0 <= retval)
2793     {
2794       u32 mode = mp->mode;
2795       fformat (vam->ofp, "map_request_mode: %U\n",
2796                format_lisp_map_request_mode, mode);
2797     }
2798
2799   vam->retval = retval;
2800   vam->result_ready = 1;
2801 }
2802
2803 static void
2804   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2805   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   vat_json_node_t node;
2809   u8 *s = 0;
2810   u32 mode;
2811
2812   mode = mp->mode;
2813   s = format (0, "%U", format_lisp_map_request_mode, mode);
2814   vec_add1 (s, 0);
2815
2816   vat_json_init_object (&node);
2817   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2818   vat_json_print (vam->ofp, &node);
2819   vat_json_free (&node);
2820
2821   vec_free (s);
2822   vam->retval = ntohl (mp->retval);
2823   vam->result_ready = 1;
2824 }
2825
2826 static void
2827 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   i32 retval = ntohl (mp->retval);
2831
2832   if (0 <= retval)
2833     {
2834       fformat (vam->ofp, "%-20s%-16s\n",
2835                mp->status ? "enabled" : "disabled",
2836                mp->status ? (char *) mp->locator_set_name : "");
2837     }
2838
2839   vam->retval = retval;
2840   vam->result_ready = 1;
2841 }
2842
2843 static void
2844 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2845                                             mp)
2846 {
2847   vat_main_t *vam = &vat_main;
2848   vat_json_node_t node;
2849   u8 *status = 0;
2850
2851   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2852   vec_add1 (status, 0);
2853
2854   vat_json_init_object (&node);
2855   vat_json_object_add_string_copy (&node, "status", status);
2856   if (mp->status)
2857     {
2858       vat_json_object_add_string_copy (&node, "locator_set",
2859                                        mp->locator_set_name);
2860     }
2861
2862   vec_free (status);
2863
2864   vat_json_print (vam->ofp, &node);
2865   vat_json_free (&node);
2866
2867   vam->retval = ntohl (mp->retval);
2868   vam->result_ready = 1;
2869 }
2870
2871 static u8 *
2872 format_policer_type (u8 * s, va_list * va)
2873 {
2874   u32 i = va_arg (*va, u32);
2875
2876   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2877     s = format (s, "1r2c");
2878   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2879     s = format (s, "1r3c");
2880   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2881     s = format (s, "2r3c-2698");
2882   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2883     s = format (s, "2r3c-4115");
2884   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2885     s = format (s, "2r3c-mef5cf1");
2886   else
2887     s = format (s, "ILLEGAL");
2888   return s;
2889 }
2890
2891 static u8 *
2892 format_policer_rate_type (u8 * s, va_list * va)
2893 {
2894   u32 i = va_arg (*va, u32);
2895
2896   if (i == SSE2_QOS_RATE_KBPS)
2897     s = format (s, "kbps");
2898   else if (i == SSE2_QOS_RATE_PPS)
2899     s = format (s, "pps");
2900   else
2901     s = format (s, "ILLEGAL");
2902   return s;
2903 }
2904
2905 static u8 *
2906 format_policer_round_type (u8 * s, va_list * va)
2907 {
2908   u32 i = va_arg (*va, u32);
2909
2910   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2911     s = format (s, "closest");
2912   else if (i == SSE2_QOS_ROUND_TO_UP)
2913     s = format (s, "up");
2914   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2915     s = format (s, "down");
2916   else
2917     s = format (s, "ILLEGAL");
2918   return s;
2919 }
2920
2921 static u8 *
2922 format_policer_action_type (u8 * s, va_list * va)
2923 {
2924   u32 i = va_arg (*va, u32);
2925
2926   if (i == SSE2_QOS_ACTION_DROP)
2927     s = format (s, "drop");
2928   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2929     s = format (s, "transmit");
2930   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2931     s = format (s, "mark-and-transmit");
2932   else
2933     s = format (s, "ILLEGAL");
2934   return s;
2935 }
2936
2937 static u8 *
2938 format_dscp (u8 * s, va_list * va)
2939 {
2940   u32 i = va_arg (*va, u32);
2941   char *t = 0;
2942
2943   switch (i)
2944     {
2945 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2946       foreach_vnet_dscp
2947 #undef _
2948     default:
2949       return format (s, "ILLEGAL");
2950     }
2951   s = format (s, "%s", t);
2952   return s;
2953 }
2954
2955 static void
2956 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2957 {
2958   vat_main_t *vam = &vat_main;
2959   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2960
2961   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2962     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2963   else
2964     conform_dscp_str = format (0, "");
2965
2966   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2967     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2968   else
2969     exceed_dscp_str = format (0, "");
2970
2971   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2972     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2973   else
2974     violate_dscp_str = format (0, "");
2975
2976   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2977            "rate type %U, round type %U, %s rate, %s color-aware, "
2978            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2979            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2980            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2981            mp->name,
2982            format_policer_type, mp->type,
2983            ntohl (mp->cir),
2984            ntohl (mp->eir),
2985            clib_net_to_host_u64 (mp->cb),
2986            clib_net_to_host_u64 (mp->eb),
2987            format_policer_rate_type, mp->rate_type,
2988            format_policer_round_type, mp->round_type,
2989            mp->single_rate ? "single" : "dual",
2990            mp->color_aware ? "is" : "not",
2991            ntohl (mp->cir_tokens_per_period),
2992            ntohl (mp->pir_tokens_per_period),
2993            ntohl (mp->scale),
2994            ntohl (mp->current_limit),
2995            ntohl (mp->current_bucket),
2996            ntohl (mp->extended_limit),
2997            ntohl (mp->extended_bucket),
2998            clib_net_to_host_u64 (mp->last_update_time),
2999            format_policer_action_type, mp->conform_action_type,
3000            conform_dscp_str,
3001            format_policer_action_type, mp->exceed_action_type,
3002            exceed_dscp_str,
3003            format_policer_action_type, mp->violate_action_type,
3004            violate_dscp_str);
3005
3006   vec_free (conform_dscp_str);
3007   vec_free (exceed_dscp_str);
3008   vec_free (violate_dscp_str);
3009 }
3010
3011 static void vl_api_policer_details_t_handler_json
3012   (vl_api_policer_details_t * mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   vat_json_node_t *node;
3016   u8 *rate_type_str, *round_type_str, *type_str;
3017   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3018
3019   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3020   round_type_str =
3021     format (0, "%U", format_policer_round_type, mp->round_type);
3022   type_str = format (0, "%U", format_policer_type, mp->type);
3023   conform_action_str = format (0, "%U", format_policer_action_type,
3024                                mp->conform_action_type);
3025   exceed_action_str = format (0, "%U", format_policer_action_type,
3026                               mp->exceed_action_type);
3027   violate_action_str = format (0, "%U", format_policer_action_type,
3028                                mp->violate_action_type);
3029
3030   if (VAT_JSON_ARRAY != vam->json_tree.type)
3031     {
3032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3033       vat_json_init_array (&vam->json_tree);
3034     }
3035   node = vat_json_array_add (&vam->json_tree);
3036
3037   vat_json_init_object (node);
3038   vat_json_object_add_string_copy (node, "name", mp->name);
3039   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3040   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3041   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3042   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3043   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3044   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3045   vat_json_object_add_string_copy (node, "type", type_str);
3046   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3047   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3048   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3049   vat_json_object_add_uint (node, "cir_tokens_per_period",
3050                             ntohl (mp->cir_tokens_per_period));
3051   vat_json_object_add_uint (node, "eir_tokens_per_period",
3052                             ntohl (mp->pir_tokens_per_period));
3053   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3054   vat_json_object_add_uint (node, "current_bucket",
3055                             ntohl (mp->current_bucket));
3056   vat_json_object_add_uint (node, "extended_limit",
3057                             ntohl (mp->extended_limit));
3058   vat_json_object_add_uint (node, "extended_bucket",
3059                             ntohl (mp->extended_bucket));
3060   vat_json_object_add_uint (node, "last_update_time",
3061                             ntohl (mp->last_update_time));
3062   vat_json_object_add_string_copy (node, "conform_action",
3063                                    conform_action_str);
3064   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3065     {
3066       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3067       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3068       vec_free (dscp_str);
3069     }
3070   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3071   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3072     {
3073       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3074       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3075       vec_free (dscp_str);
3076     }
3077   vat_json_object_add_string_copy (node, "violate_action",
3078                                    violate_action_str);
3079   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3080     {
3081       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3082       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3083       vec_free (dscp_str);
3084     }
3085
3086   vec_free (rate_type_str);
3087   vec_free (round_type_str);
3088   vec_free (type_str);
3089   vec_free (conform_action_str);
3090   vec_free (exceed_action_str);
3091   vec_free (violate_action_str);
3092 }
3093
3094 static void
3095 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3096                                            mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   int i, count = ntohl (mp->count);
3100
3101   if (count > 0)
3102     fformat (vam->ofp, "classify table ids (%d) : ", count);
3103   for (i = 0; i < count; i++)
3104     {
3105       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3106       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3107     }
3108   vam->retval = ntohl (mp->retval);
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_classify_table_ids_reply_t_handler_json
3114   (vl_api_classify_table_ids_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   int i, count = ntohl (mp->count);
3118
3119   if (count > 0)
3120     {
3121       vat_json_node_t node;
3122
3123       vat_json_init_object (&node);
3124       for (i = 0; i < count; i++)
3125         {
3126           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3127         }
3128       vat_json_print (vam->ofp, &node);
3129       vat_json_free (&node);
3130     }
3131   vam->retval = ntohl (mp->retval);
3132   vam->result_ready = 1;
3133 }
3134
3135 static void
3136   vl_api_classify_table_by_interface_reply_t_handler
3137   (vl_api_classify_table_by_interface_reply_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   u32 table_id;
3141
3142   table_id = ntohl (mp->l2_table_id);
3143   if (table_id != ~0)
3144     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3145   else
3146     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3147   table_id = ntohl (mp->ip4_table_id);
3148   if (table_id != ~0)
3149     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3150   else
3151     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3152   table_id = ntohl (mp->ip6_table_id);
3153   if (table_id != ~0)
3154     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3155   else
3156     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3157   vam->retval = ntohl (mp->retval);
3158   vam->result_ready = 1;
3159 }
3160
3161 static void
3162   vl_api_classify_table_by_interface_reply_t_handler_json
3163   (vl_api_classify_table_by_interface_reply_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   vat_json_node_t node;
3167
3168   vat_json_init_object (&node);
3169
3170   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3171   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3172   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3173
3174   vat_json_print (vam->ofp, &node);
3175   vat_json_free (&node);
3176
3177   vam->retval = ntohl (mp->retval);
3178   vam->result_ready = 1;
3179 }
3180
3181 static void vl_api_policer_add_del_reply_t_handler
3182   (vl_api_policer_add_del_reply_t * mp)
3183 {
3184   vat_main_t *vam = &vat_main;
3185   i32 retval = ntohl (mp->retval);
3186   if (vam->async_mode)
3187     {
3188       vam->async_errors += (retval < 0);
3189     }
3190   else
3191     {
3192       vam->retval = retval;
3193       vam->result_ready = 1;
3194       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3195         /*
3196          * Note: this is just barely thread-safe, depends on
3197          * the main thread spinning waiting for an answer...
3198          */
3199         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3200     }
3201 }
3202
3203 static void vl_api_policer_add_del_reply_t_handler_json
3204   (vl_api_policer_add_del_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t node;
3208
3209   vat_json_init_object (&node);
3210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3211   vat_json_object_add_uint (&node, "policer_index",
3212                             ntohl (mp->policer_index));
3213
3214   vat_json_print (vam->ofp, &node);
3215   vat_json_free (&node);
3216
3217   vam->retval = ntohl (mp->retval);
3218   vam->result_ready = 1;
3219 }
3220
3221 /* Format hex dump. */
3222 u8 *
3223 format_hex_bytes (u8 * s, va_list * va)
3224 {
3225   u8 *bytes = va_arg (*va, u8 *);
3226   int n_bytes = va_arg (*va, int);
3227   uword i;
3228
3229   /* Print short or long form depending on byte count. */
3230   uword short_form = n_bytes <= 32;
3231   uword indent = format_get_indent (s);
3232
3233   if (n_bytes == 0)
3234     return s;
3235
3236   for (i = 0; i < n_bytes; i++)
3237     {
3238       if (!short_form && (i % 32) == 0)
3239         s = format (s, "%08x: ", i);
3240       s = format (s, "%02x", bytes[i]);
3241       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3242         s = format (s, "\n%U", format_white_space, indent);
3243     }
3244
3245   return s;
3246 }
3247
3248 static void
3249 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3250                                             * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   i32 retval = ntohl (mp->retval);
3254   if (retval == 0)
3255     {
3256       fformat (vam->ofp, "classify table info :\n");
3257       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3258                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3259                ntohl (mp->miss_next_index));
3260       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3261                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3262                ntohl (mp->match_n_vectors));
3263       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3264                ntohl (mp->mask_length));
3265     }
3266   vam->retval = retval;
3267   vam->result_ready = 1;
3268 }
3269
3270 static void
3271   vl_api_classify_table_info_reply_t_handler_json
3272   (vl_api_classify_table_info_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   vat_json_node_t node;
3276
3277   i32 retval = ntohl (mp->retval);
3278   if (retval == 0)
3279     {
3280       vat_json_init_object (&node);
3281
3282       vat_json_object_add_int (&node, "sessions",
3283                                ntohl (mp->active_sessions));
3284       vat_json_object_add_int (&node, "nexttbl",
3285                                ntohl (mp->next_table_index));
3286       vat_json_object_add_int (&node, "nextnode",
3287                                ntohl (mp->miss_next_index));
3288       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3289       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3290       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3291       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3292                       ntohl (mp->mask_length), 0);
3293       vat_json_object_add_string_copy (&node, "mask", s);
3294
3295       vat_json_print (vam->ofp, &node);
3296       vat_json_free (&node);
3297     }
3298   vam->retval = ntohl (mp->retval);
3299   vam->result_ready = 1;
3300 }
3301
3302 static void
3303 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3304                                            mp)
3305 {
3306   vat_main_t *vam = &vat_main;
3307
3308   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3309            ntohl (mp->hit_next_index), ntohl (mp->advance),
3310            ntohl (mp->opaque_index));
3311   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3312            ntohl (mp->match_length));
3313 }
3314
3315 static void
3316   vl_api_classify_session_details_t_handler_json
3317   (vl_api_classify_session_details_t * mp)
3318 {
3319   vat_main_t *vam = &vat_main;
3320   vat_json_node_t *node = NULL;
3321
3322   if (VAT_JSON_ARRAY != vam->json_tree.type)
3323     {
3324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3325       vat_json_init_array (&vam->json_tree);
3326     }
3327   node = vat_json_array_add (&vam->json_tree);
3328
3329   vat_json_init_object (node);
3330   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3331   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3332   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3333   u8 *s =
3334     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3335             0);
3336   vat_json_object_add_string_copy (node, "match", s);
3337 }
3338
3339 static void vl_api_pg_create_interface_reply_t_handler
3340   (vl_api_pg_create_interface_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   vam->retval = ntohl (mp->retval);
3345   vam->result_ready = 1;
3346 }
3347
3348 static void vl_api_pg_create_interface_reply_t_handler_json
3349   (vl_api_pg_create_interface_reply_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t node;
3353
3354   i32 retval = ntohl (mp->retval);
3355   if (retval == 0)
3356     {
3357       vat_json_init_object (&node);
3358
3359       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3360
3361       vat_json_print (vam->ofp, &node);
3362       vat_json_free (&node);
3363     }
3364   vam->retval = ntohl (mp->retval);
3365   vam->result_ready = 1;
3366 }
3367
3368 static void vl_api_policer_classify_details_t_handler
3369   (vl_api_policer_classify_details_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372
3373   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3374            ntohl (mp->table_index));
3375 }
3376
3377 static void vl_api_policer_classify_details_t_handler_json
3378   (vl_api_policer_classify_details_t * mp)
3379 {
3380   vat_main_t *vam = &vat_main;
3381   vat_json_node_t *node;
3382
3383   if (VAT_JSON_ARRAY != vam->json_tree.type)
3384     {
3385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3386       vat_json_init_array (&vam->json_tree);
3387     }
3388   node = vat_json_array_add (&vam->json_tree);
3389
3390   vat_json_init_object (node);
3391   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3392   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3393 }
3394
3395 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3396   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399   i32 retval = ntohl (mp->retval);
3400   if (vam->async_mode)
3401     {
3402       vam->async_errors += (retval < 0);
3403     }
3404   else
3405     {
3406       vam->retval = retval;
3407       vam->sw_if_index = ntohl (mp->sw_if_index);
3408       vam->result_ready = 1;
3409     }
3410 }
3411
3412 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3413   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3414 {
3415   vat_main_t *vam = &vat_main;
3416   vat_json_node_t node;
3417
3418   vat_json_init_object (&node);
3419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3420   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3421
3422   vat_json_print (vam->ofp, &node);
3423   vat_json_free (&node);
3424
3425   vam->retval = ntohl (mp->retval);
3426   vam->result_ready = 1;
3427 }
3428
3429 static void vl_api_flow_classify_details_t_handler
3430   (vl_api_flow_classify_details_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3435            ntohl (mp->table_index));
3436 }
3437
3438 static void vl_api_flow_classify_details_t_handler_json
3439   (vl_api_flow_classify_details_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t *node;
3443
3444   if (VAT_JSON_ARRAY != vam->json_tree.type)
3445     {
3446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3447       vat_json_init_array (&vam->json_tree);
3448     }
3449   node = vat_json_array_add (&vam->json_tree);
3450
3451   vat_json_init_object (node);
3452   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3453   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3454 }
3455
3456
3457
3458 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3459 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3460 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3461 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3462 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3463 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3464
3465 /*
3466  * Generate boilerplate reply handlers, which
3467  * dig the return value out of the xxx_reply_t API message,
3468  * stick it into vam->retval, and set vam->result_ready
3469  *
3470  * Could also do this by pointing N message decode slots at
3471  * a single function, but that could break in subtle ways.
3472  */
3473
3474 #define foreach_standard_reply_retval_handler           \
3475 _(sw_interface_set_flags_reply)                         \
3476 _(sw_interface_add_del_address_reply)                   \
3477 _(sw_interface_set_table_reply)                         \
3478 _(sw_interface_set_mpls_enable_reply)                   \
3479 _(sw_interface_set_vpath_reply)                         \
3480 _(sw_interface_set_l2_bridge_reply)                     \
3481 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3482 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3483 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3484 _(bridge_domain_add_del_reply)                          \
3485 _(sw_interface_set_l2_xconnect_reply)                   \
3486 _(l2fib_add_del_reply)                                  \
3487 _(ip_add_del_route_reply)                               \
3488 _(mpls_route_add_del_reply)                             \
3489 _(mpls_ip_bind_unbind_reply)                            \
3490 _(proxy_arp_add_del_reply)                              \
3491 _(proxy_arp_intfc_enable_disable_reply)                 \
3492 _(mpls_add_del_encap_reply)                             \
3493 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3494 _(sw_interface_set_unnumbered_reply)                    \
3495 _(ip_neighbor_add_del_reply)                            \
3496 _(reset_vrf_reply)                                      \
3497 _(oam_add_del_reply)                                    \
3498 _(reset_fib_reply)                                      \
3499 _(dhcp_proxy_config_reply)                              \
3500 _(dhcp_proxy_config_2_reply)                            \
3501 _(dhcp_proxy_set_vss_reply)                             \
3502 _(dhcp_client_config_reply)                             \
3503 _(set_ip_flow_hash_reply)                               \
3504 _(sw_interface_ip6_enable_disable_reply)                \
3505 _(sw_interface_ip6_set_link_local_address_reply)        \
3506 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3507 _(sw_interface_ip6nd_ra_config_reply)                   \
3508 _(set_arp_neighbor_limit_reply)                         \
3509 _(l2_patch_add_del_reply)                               \
3510 _(sr_tunnel_add_del_reply)                              \
3511 _(sr_policy_add_del_reply)                              \
3512 _(sr_multicast_map_add_del_reply)                       \
3513 _(classify_add_del_session_reply)                       \
3514 _(classify_set_interface_ip_table_reply)                \
3515 _(classify_set_interface_l2_tables_reply)               \
3516 _(l2tpv3_set_tunnel_cookies_reply)                      \
3517 _(l2tpv3_interface_enable_disable_reply)                \
3518 _(l2tpv3_set_lookup_key_reply)                          \
3519 _(l2_fib_clear_table_reply)                             \
3520 _(l2_interface_efp_filter_reply)                        \
3521 _(l2_interface_vlan_tag_rewrite_reply)                  \
3522 _(modify_vhost_user_if_reply)                           \
3523 _(delete_vhost_user_if_reply)                           \
3524 _(want_ip4_arp_events_reply)                            \
3525 _(want_ip6_nd_events_reply)                             \
3526 _(input_acl_set_interface_reply)                        \
3527 _(ipsec_spd_add_del_reply)                              \
3528 _(ipsec_interface_add_del_spd_reply)                    \
3529 _(ipsec_spd_add_del_entry_reply)                        \
3530 _(ipsec_sad_add_del_entry_reply)                        \
3531 _(ipsec_sa_set_key_reply)                               \
3532 _(ikev2_profile_add_del_reply)                          \
3533 _(ikev2_profile_set_auth_reply)                         \
3534 _(ikev2_profile_set_id_reply)                           \
3535 _(ikev2_profile_set_ts_reply)                           \
3536 _(ikev2_set_local_key_reply)                            \
3537 _(delete_loopback_reply)                                \
3538 _(bd_ip_mac_add_del_reply)                              \
3539 _(map_del_domain_reply)                                 \
3540 _(map_add_del_rule_reply)                               \
3541 _(want_interface_events_reply)                          \
3542 _(want_stats_reply)                                     \
3543 _(cop_interface_enable_disable_reply)                   \
3544 _(cop_whitelist_enable_disable_reply)                   \
3545 _(sw_interface_clear_stats_reply)                       \
3546 _(ioam_enable_reply)                              \
3547 _(ioam_disable_reply)                              \
3548 _(lisp_add_del_locator_reply)                           \
3549 _(lisp_add_del_local_eid_reply)                         \
3550 _(lisp_add_del_remote_mapping_reply)                    \
3551 _(lisp_add_del_adjacency_reply)                         \
3552 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3553 _(lisp_add_del_map_resolver_reply)                      \
3554 _(lisp_gpe_enable_disable_reply)                        \
3555 _(lisp_gpe_add_del_iface_reply)                         \
3556 _(lisp_enable_disable_reply)                            \
3557 _(lisp_pitr_set_locator_set_reply)                      \
3558 _(lisp_map_request_mode_reply)                          \
3559 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3560 _(lisp_eid_table_add_del_map_reply)                     \
3561 _(vxlan_gpe_add_del_tunnel_reply)                       \
3562 _(af_packet_delete_reply)                               \
3563 _(policer_classify_set_interface_reply)                 \
3564 _(netmap_create_reply)                                  \
3565 _(netmap_delete_reply)                                  \
3566 _(set_ipfix_exporter_reply)                             \
3567 _(set_ipfix_classify_stream_reply)                      \
3568 _(ipfix_classify_table_add_del_reply)                   \
3569 _(flow_classify_set_interface_reply)                    \
3570 _(pg_capture_reply)                                     \
3571 _(pg_enable_disable_reply)                              \
3572 _(ip_source_and_port_range_check_add_del_reply)         \
3573 _(ip_source_and_port_range_check_interface_add_del_reply)\
3574 _(delete_subif_reply)                                   \
3575 _(l2_interface_pbb_tag_rewrite_reply)                   \
3576 _(punt_reply)
3577
3578 #define _(n)                                    \
3579     static void vl_api_##n##_t_handler          \
3580     (vl_api_##n##_t * mp)                       \
3581     {                                           \
3582         vat_main_t * vam = &vat_main;           \
3583         i32 retval = ntohl(mp->retval);         \
3584         if (vam->async_mode) {                  \
3585             vam->async_errors += (retval < 0);  \
3586         } else {                                \
3587             vam->retval = retval;               \
3588             vam->result_ready = 1;              \
3589         }                                       \
3590     }
3591 foreach_standard_reply_retval_handler;
3592 #undef _
3593
3594 #define _(n)                                    \
3595     static void vl_api_##n##_t_handler_json     \
3596     (vl_api_##n##_t * mp)                       \
3597     {                                           \
3598         vat_main_t * vam = &vat_main;           \
3599         vat_json_node_t node;                   \
3600         vat_json_init_object(&node);            \
3601         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3602         vat_json_print(vam->ofp, &node);        \
3603         vam->retval = ntohl(mp->retval);        \
3604         vam->result_ready = 1;                  \
3605     }
3606 foreach_standard_reply_retval_handler;
3607 #undef _
3608
3609 /*
3610  * Table of message reply handlers, must include boilerplate handlers
3611  * we just generated
3612  */
3613
3614 #define foreach_vpe_api_reply_msg                                       \
3615 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3616 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3617 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3618 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3619 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3620 _(CLI_REPLY, cli_reply)                                                 \
3621 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3622 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3623   sw_interface_add_del_address_reply)                                   \
3624 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3625 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3626 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3627 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3628   sw_interface_set_l2_xconnect_reply)                                   \
3629 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3630   sw_interface_set_l2_bridge_reply)                                     \
3631 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3632   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3633 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3634   sw_interface_set_dpdk_hqos_subport_reply)                             \
3635 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3636   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3637 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3638 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3639 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3640 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3641 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3642 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3643 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3644 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3645 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3646 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3647 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3648 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3649 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3650 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3651 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3652   proxy_arp_intfc_enable_disable_reply)                                 \
3653 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3654 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3655   mpls_ethernet_add_del_tunnel_reply)                                   \
3656 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3657   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3658 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3659   sw_interface_set_unnumbered_reply)                                    \
3660 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3661 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3662 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3663 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3664 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3665 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3666 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3667 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3668 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3669 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3670 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3671 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3672   sw_interface_ip6_enable_disable_reply)                                \
3673 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3674   sw_interface_ip6_set_link_local_address_reply)                        \
3675 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3676   sw_interface_ip6nd_ra_prefix_reply)                                   \
3677 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3678   sw_interface_ip6nd_ra_config_reply)                                   \
3679 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3680 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3681 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3682 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3683 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3684 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3685 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3686 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3687 classify_set_interface_ip_table_reply)                                  \
3688 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3689   classify_set_interface_l2_tables_reply)                               \
3690 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3691 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3692 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3693 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3694 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3695   l2tpv3_interface_enable_disable_reply)                                \
3696 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3697 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3698 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3699 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3700 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3701 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3702 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3703 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3704 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3705 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3706 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3707 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3708 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3709 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3710 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3711 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3712 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3713 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3714 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3715 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3716 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3717 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3718 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3719 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3720 _(IP_DETAILS, ip_details)                                               \
3721 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3722 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3723 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3724 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3725 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3726 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3727 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3728 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3729 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3730 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3731 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3732 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3733 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3734 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3735 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3736 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3737 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3738 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3739 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3740 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3741 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3742 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3743 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3744 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3745 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3746 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3747 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3748 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3749 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3750 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3751 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3752 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3753 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3754 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3755 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3756 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3757 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3758 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3759 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3760 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3761 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3762 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3763 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3764 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3765 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3766 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3767 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3768 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3769 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3770 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3771 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3772 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3773 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3774   lisp_add_del_map_request_itr_rlocs_reply)                             \
3775 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3776   lisp_get_map_request_itr_rlocs_reply)                                 \
3777 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3778 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3779 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3780 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3781 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3782 _(POLICER_DETAILS, policer_details)                                     \
3783 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3784 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3785 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3786 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3787 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3788 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3789 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3790 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3791 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3792 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3793 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3794 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3795 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3796 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3797 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3798 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3799 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3800 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3801 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3802 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3803 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3804 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3805 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3806 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3807  ip_source_and_port_range_check_add_del_reply)                          \
3808 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3809  ip_source_and_port_range_check_interface_add_del_reply)                \
3810 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3811 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3812 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3813 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3814 _(PUNT_REPLY, punt_reply)                                               \
3815 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3816 _(IP6_FIB_DETAILS, ip6_fib_details)
3817
3818 /* M: construct, but don't yet send a message */
3819
3820 #define M(T,t)                                  \
3821 do {                                            \
3822     vam->result_ready = 0;                      \
3823     mp = vl_msg_api_alloc(sizeof(*mp));         \
3824     memset (mp, 0, sizeof (*mp));               \
3825     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3826     mp->client_index = vam->my_client_index;    \
3827 } while(0);
3828
3829 #define M2(T,t,n)                               \
3830 do {                                            \
3831     vam->result_ready = 0;                      \
3832     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3833     memset (mp, 0, sizeof (*mp));               \
3834     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3835     mp->client_index = vam->my_client_index;    \
3836 } while(0);
3837
3838
3839 /* S: send a message */
3840 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3841
3842 /* W: wait for results, with timeout */
3843 #define W                                       \
3844 do {                                            \
3845     timeout = vat_time_now (vam) + 1.0;         \
3846                                                 \
3847     while (vat_time_now (vam) < timeout) {      \
3848         if (vam->result_ready == 1) {           \
3849             return (vam->retval);               \
3850         }                                       \
3851     }                                           \
3852     return -99;                                 \
3853 } while(0);
3854
3855 /* W2: wait for results, with timeout */
3856 #define W2(body)                                \
3857 do {                                            \
3858     timeout = vat_time_now (vam) + 1.0;         \
3859                                                 \
3860     while (vat_time_now (vam) < timeout) {      \
3861         if (vam->result_ready == 1) {           \
3862           (body);                               \
3863           return (vam->retval);                 \
3864         }                                       \
3865     }                                           \
3866     return -99;                                 \
3867 } while(0);
3868
3869 typedef struct
3870 {
3871   u8 *name;
3872   u32 value;
3873 } name_sort_t;
3874
3875
3876 #define STR_VTR_OP_CASE(op)     \
3877     case L2_VTR_ ## op:         \
3878         return "" # op;
3879
3880 static const char *
3881 str_vtr_op (u32 vtr_op)
3882 {
3883   switch (vtr_op)
3884     {
3885       STR_VTR_OP_CASE (DISABLED);
3886       STR_VTR_OP_CASE (PUSH_1);
3887       STR_VTR_OP_CASE (PUSH_2);
3888       STR_VTR_OP_CASE (POP_1);
3889       STR_VTR_OP_CASE (POP_2);
3890       STR_VTR_OP_CASE (TRANSLATE_1_1);
3891       STR_VTR_OP_CASE (TRANSLATE_1_2);
3892       STR_VTR_OP_CASE (TRANSLATE_2_1);
3893       STR_VTR_OP_CASE (TRANSLATE_2_2);
3894     }
3895
3896   return "UNKNOWN";
3897 }
3898
3899 static int
3900 dump_sub_interface_table (vat_main_t * vam)
3901 {
3902   const sw_interface_subif_t *sub = NULL;
3903
3904   if (vam->json_output)
3905     {
3906       clib_warning
3907         ("JSON output supported only for VPE API calls and dump_stats_table");
3908       return -99;
3909     }
3910
3911   fformat (vam->ofp,
3912            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3913            "Interface", "sw_if_index",
3914            "sub id", "dot1ad", "tags", "outer id",
3915            "inner id", "exact", "default", "outer any", "inner any");
3916
3917   vec_foreach (sub, vam->sw_if_subif_table)
3918   {
3919     fformat (vam->ofp,
3920              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3921              sub->interface_name,
3922              sub->sw_if_index,
3923              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3924              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3925              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3926              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3927     if (sub->vtr_op != L2_VTR_DISABLED)
3928       {
3929         fformat (vam->ofp,
3930                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3931                  "tag1: %d tag2: %d ]\n",
3932                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3933                  sub->vtr_tag1, sub->vtr_tag2);
3934       }
3935   }
3936
3937   return 0;
3938 }
3939
3940 static int
3941 name_sort_cmp (void *a1, void *a2)
3942 {
3943   name_sort_t *n1 = a1;
3944   name_sort_t *n2 = a2;
3945
3946   return strcmp ((char *) n1->name, (char *) n2->name);
3947 }
3948
3949 static int
3950 dump_interface_table (vat_main_t * vam)
3951 {
3952   hash_pair_t *p;
3953   name_sort_t *nses = 0, *ns;
3954
3955   if (vam->json_output)
3956     {
3957       clib_warning
3958         ("JSON output supported only for VPE API calls and dump_stats_table");
3959       return -99;
3960     }
3961
3962   /* *INDENT-OFF* */
3963   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3964   ({
3965     vec_add2 (nses, ns, 1);
3966     ns->name = (u8 *)(p->key);
3967     ns->value = (u32) p->value[0];
3968   }));
3969   /* *INDENT-ON* */
3970
3971   vec_sort_with_function (nses, name_sort_cmp);
3972
3973   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3974   vec_foreach (ns, nses)
3975   {
3976     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3977   }
3978   vec_free (nses);
3979   return 0;
3980 }
3981
3982 static int
3983 dump_ip_table (vat_main_t * vam, int is_ipv6)
3984 {
3985   const ip_details_t *det = NULL;
3986   const ip_address_details_t *address = NULL;
3987   u32 i = ~0;
3988
3989   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3990
3991   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3992   {
3993     i++;
3994     if (!det->present)
3995       {
3996         continue;
3997       }
3998     fformat (vam->ofp, "%-12d\n", i);
3999     fformat (vam->ofp,
4000              "            %-30s%-13s\n", "Address", "Prefix length");
4001     if (!det->addr)
4002       {
4003         continue;
4004       }
4005     vec_foreach (address, det->addr)
4006     {
4007       fformat (vam->ofp,
4008                "            %-30U%-13d\n",
4009                is_ipv6 ? format_ip6_address : format_ip4_address,
4010                address->ip, address->prefix_length);
4011     }
4012   }
4013
4014   return 0;
4015 }
4016
4017 static int
4018 dump_ipv4_table (vat_main_t * vam)
4019 {
4020   if (vam->json_output)
4021     {
4022       clib_warning
4023         ("JSON output supported only for VPE API calls and dump_stats_table");
4024       return -99;
4025     }
4026
4027   return dump_ip_table (vam, 0);
4028 }
4029
4030 static int
4031 dump_ipv6_table (vat_main_t * vam)
4032 {
4033   if (vam->json_output)
4034     {
4035       clib_warning
4036         ("JSON output supported only for VPE API calls and dump_stats_table");
4037       return -99;
4038     }
4039
4040   return dump_ip_table (vam, 1);
4041 }
4042
4043 static char *
4044 counter_type_to_str (u8 counter_type, u8 is_combined)
4045 {
4046   if (!is_combined)
4047     {
4048       switch (counter_type)
4049         {
4050         case VNET_INTERFACE_COUNTER_DROP:
4051           return "drop";
4052         case VNET_INTERFACE_COUNTER_PUNT:
4053           return "punt";
4054         case VNET_INTERFACE_COUNTER_IP4:
4055           return "ip4";
4056         case VNET_INTERFACE_COUNTER_IP6:
4057           return "ip6";
4058         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4059           return "rx-no-buf";
4060         case VNET_INTERFACE_COUNTER_RX_MISS:
4061           return "rx-miss";
4062         case VNET_INTERFACE_COUNTER_RX_ERROR:
4063           return "rx-error";
4064         case VNET_INTERFACE_COUNTER_TX_ERROR:
4065           return "tx-error";
4066         default:
4067           return "INVALID-COUNTER-TYPE";
4068         }
4069     }
4070   else
4071     {
4072       switch (counter_type)
4073         {
4074         case VNET_INTERFACE_COUNTER_RX:
4075           return "rx";
4076         case VNET_INTERFACE_COUNTER_TX:
4077           return "tx";
4078         default:
4079           return "INVALID-COUNTER-TYPE";
4080         }
4081     }
4082 }
4083
4084 static int
4085 dump_stats_table (vat_main_t * vam)
4086 {
4087   vat_json_node_t node;
4088   vat_json_node_t *msg_array;
4089   vat_json_node_t *msg;
4090   vat_json_node_t *counter_array;
4091   vat_json_node_t *counter;
4092   interface_counter_t c;
4093   u64 packets;
4094   ip4_fib_counter_t *c4;
4095   ip6_fib_counter_t *c6;
4096   int i, j;
4097
4098   if (!vam->json_output)
4099     {
4100       clib_warning ("dump_stats_table supported only in JSON format");
4101       return -99;
4102     }
4103
4104   vat_json_init_object (&node);
4105
4106   /* interface counters */
4107   msg_array = vat_json_object_add (&node, "interface_counters");
4108   vat_json_init_array (msg_array);
4109   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4110     {
4111       msg = vat_json_array_add (msg_array);
4112       vat_json_init_object (msg);
4113       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4114                                        (u8 *) counter_type_to_str (i, 0));
4115       vat_json_object_add_int (msg, "is_combined", 0);
4116       counter_array = vat_json_object_add (msg, "data");
4117       vat_json_init_array (counter_array);
4118       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4119         {
4120           packets = vam->simple_interface_counters[i][j];
4121           vat_json_array_add_uint (counter_array, packets);
4122         }
4123     }
4124   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4125     {
4126       msg = vat_json_array_add (msg_array);
4127       vat_json_init_object (msg);
4128       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4129                                        (u8 *) counter_type_to_str (i, 1));
4130       vat_json_object_add_int (msg, "is_combined", 1);
4131       counter_array = vat_json_object_add (msg, "data");
4132       vat_json_init_array (counter_array);
4133       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4134         {
4135           c = vam->combined_interface_counters[i][j];
4136           counter = vat_json_array_add (counter_array);
4137           vat_json_init_object (counter);
4138           vat_json_object_add_uint (counter, "packets", c.packets);
4139           vat_json_object_add_uint (counter, "bytes", c.bytes);
4140         }
4141     }
4142
4143   /* ip4 fib counters */
4144   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4145   vat_json_init_array (msg_array);
4146   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4147     {
4148       msg = vat_json_array_add (msg_array);
4149       vat_json_init_object (msg);
4150       vat_json_object_add_uint (msg, "vrf_id",
4151                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4152       counter_array = vat_json_object_add (msg, "c");
4153       vat_json_init_array (counter_array);
4154       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4155         {
4156           counter = vat_json_array_add (counter_array);
4157           vat_json_init_object (counter);
4158           c4 = &vam->ip4_fib_counters[i][j];
4159           vat_json_object_add_ip4 (counter, "address", c4->address);
4160           vat_json_object_add_uint (counter, "address_length",
4161                                     c4->address_length);
4162           vat_json_object_add_uint (counter, "packets", c4->packets);
4163           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4164         }
4165     }
4166
4167   /* ip6 fib counters */
4168   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4169   vat_json_init_array (msg_array);
4170   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4171     {
4172       msg = vat_json_array_add (msg_array);
4173       vat_json_init_object (msg);
4174       vat_json_object_add_uint (msg, "vrf_id",
4175                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4176       counter_array = vat_json_object_add (msg, "c");
4177       vat_json_init_array (counter_array);
4178       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4179         {
4180           counter = vat_json_array_add (counter_array);
4181           vat_json_init_object (counter);
4182           c6 = &vam->ip6_fib_counters[i][j];
4183           vat_json_object_add_ip6 (counter, "address", c6->address);
4184           vat_json_object_add_uint (counter, "address_length",
4185                                     c6->address_length);
4186           vat_json_object_add_uint (counter, "packets", c6->packets);
4187           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4188         }
4189     }
4190
4191   vat_json_print (vam->ofp, &node);
4192   vat_json_free (&node);
4193
4194   return 0;
4195 }
4196
4197 int
4198 exec (vat_main_t * vam)
4199 {
4200   api_main_t *am = &api_main;
4201   vl_api_cli_request_t *mp;
4202   f64 timeout;
4203   void *oldheap;
4204   u8 *cmd = 0;
4205   unformat_input_t *i = vam->input;
4206
4207   if (vec_len (i->buffer) == 0)
4208     return -1;
4209
4210   if (vam->exec_mode == 0 && unformat (i, "mode"))
4211     {
4212       vam->exec_mode = 1;
4213       return 0;
4214     }
4215   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4216     {
4217       vam->exec_mode = 0;
4218       return 0;
4219     }
4220
4221
4222   M (CLI_REQUEST, cli_request);
4223
4224   /*
4225    * Copy cmd into shared memory.
4226    * In order for the CLI command to work, it
4227    * must be a vector ending in \n, not a C-string ending
4228    * in \n\0.
4229    */
4230   pthread_mutex_lock (&am->vlib_rp->mutex);
4231   oldheap = svm_push_data_heap (am->vlib_rp);
4232
4233   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4234   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4235
4236   svm_pop_heap (oldheap);
4237   pthread_mutex_unlock (&am->vlib_rp->mutex);
4238
4239   mp->cmd_in_shmem = (u64) cmd;
4240   S;
4241   timeout = vat_time_now (vam) + 10.0;
4242
4243   while (vat_time_now (vam) < timeout)
4244     {
4245       if (vam->result_ready == 1)
4246         {
4247           u8 *free_me;
4248           if (vam->shmem_result != NULL)
4249             fformat (vam->ofp, "%s", vam->shmem_result);
4250           pthread_mutex_lock (&am->vlib_rp->mutex);
4251           oldheap = svm_push_data_heap (am->vlib_rp);
4252
4253           free_me = (u8 *) vam->shmem_result;
4254           vec_free (free_me);
4255
4256           svm_pop_heap (oldheap);
4257           pthread_mutex_unlock (&am->vlib_rp->mutex);
4258           return 0;
4259         }
4260     }
4261   return -99;
4262 }
4263
4264 /*
4265  * Future replacement of exec() that passes CLI buffers directly in
4266  * the API messages instead of an additional shared memory area.
4267  */
4268 static int
4269 exec_inband (vat_main_t * vam)
4270 {
4271   vl_api_cli_inband_t *mp;
4272   f64 timeout;
4273   unformat_input_t *i = vam->input;
4274
4275   if (vec_len (i->buffer) == 0)
4276     return -1;
4277
4278   if (vam->exec_mode == 0 && unformat (i, "mode"))
4279     {
4280       vam->exec_mode = 1;
4281       return 0;
4282     }
4283   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4284     {
4285       vam->exec_mode = 0;
4286       return 0;
4287     }
4288
4289   /*
4290    * In order for the CLI command to work, it
4291    * must be a vector ending in \n, not a C-string ending
4292    * in \n\0.
4293    */
4294   u32 len = vec_len (vam->input->buffer);
4295   M2 (CLI_INBAND, cli_inband, len);
4296   clib_memcpy (mp->cmd, vam->input->buffer, len);
4297   mp->length = htonl (len);
4298
4299   S;
4300   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4301 }
4302
4303 static int
4304 api_create_loopback (vat_main_t * vam)
4305 {
4306   unformat_input_t *i = vam->input;
4307   vl_api_create_loopback_t *mp;
4308   f64 timeout;
4309   u8 mac_address[6];
4310   u8 mac_set = 0;
4311
4312   memset (mac_address, 0, sizeof (mac_address));
4313
4314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4315     {
4316       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4317         mac_set = 1;
4318       else
4319         break;
4320     }
4321
4322   /* Construct the API message */
4323   M (CREATE_LOOPBACK, create_loopback);
4324   if (mac_set)
4325     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4326
4327   S;
4328   W;
4329 }
4330
4331 static int
4332 api_delete_loopback (vat_main_t * vam)
4333 {
4334   unformat_input_t *i = vam->input;
4335   vl_api_delete_loopback_t *mp;
4336   f64 timeout;
4337   u32 sw_if_index = ~0;
4338
4339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4340     {
4341       if (unformat (i, "sw_if_index %d", &sw_if_index))
4342         ;
4343       else
4344         break;
4345     }
4346
4347   if (sw_if_index == ~0)
4348     {
4349       errmsg ("missing sw_if_index\n");
4350       return -99;
4351     }
4352
4353   /* Construct the API message */
4354   M (DELETE_LOOPBACK, delete_loopback);
4355   mp->sw_if_index = ntohl (sw_if_index);
4356
4357   S;
4358   W;
4359 }
4360
4361 static int
4362 api_want_stats (vat_main_t * vam)
4363 {
4364   unformat_input_t *i = vam->input;
4365   vl_api_want_stats_t *mp;
4366   f64 timeout;
4367   int enable = -1;
4368
4369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4370     {
4371       if (unformat (i, "enable"))
4372         enable = 1;
4373       else if (unformat (i, "disable"))
4374         enable = 0;
4375       else
4376         break;
4377     }
4378
4379   if (enable == -1)
4380     {
4381       errmsg ("missing enable|disable\n");
4382       return -99;
4383     }
4384
4385   M (WANT_STATS, want_stats);
4386   mp->enable_disable = enable;
4387
4388   S;
4389   W;
4390 }
4391
4392 static int
4393 api_want_interface_events (vat_main_t * vam)
4394 {
4395   unformat_input_t *i = vam->input;
4396   vl_api_want_interface_events_t *mp;
4397   f64 timeout;
4398   int enable = -1;
4399
4400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4401     {
4402       if (unformat (i, "enable"))
4403         enable = 1;
4404       else if (unformat (i, "disable"))
4405         enable = 0;
4406       else
4407         break;
4408     }
4409
4410   if (enable == -1)
4411     {
4412       errmsg ("missing enable|disable\n");
4413       return -99;
4414     }
4415
4416   M (WANT_INTERFACE_EVENTS, want_interface_events);
4417   mp->enable_disable = enable;
4418
4419   vam->interface_event_display = enable;
4420
4421   S;
4422   W;
4423 }
4424
4425
4426 /* Note: non-static, called once to set up the initial intfc table */
4427 int
4428 api_sw_interface_dump (vat_main_t * vam)
4429 {
4430   vl_api_sw_interface_dump_t *mp;
4431   f64 timeout;
4432   hash_pair_t *p;
4433   name_sort_t *nses = 0, *ns;
4434   sw_interface_subif_t *sub = NULL;
4435
4436   /* Toss the old name table */
4437   /* *INDENT-OFF* */
4438   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4439   ({
4440     vec_add2 (nses, ns, 1);
4441     ns->name = (u8 *)(p->key);
4442     ns->value = (u32) p->value[0];
4443   }));
4444   /* *INDENT-ON* */
4445
4446   hash_free (vam->sw_if_index_by_interface_name);
4447
4448   vec_foreach (ns, nses) vec_free (ns->name);
4449
4450   vec_free (nses);
4451
4452   vec_foreach (sub, vam->sw_if_subif_table)
4453   {
4454     vec_free (sub->interface_name);
4455   }
4456   vec_free (vam->sw_if_subif_table);
4457
4458   /* recreate the interface name hash table */
4459   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4460
4461   /* Get list of ethernets */
4462   M (SW_INTERFACE_DUMP, sw_interface_dump);
4463   mp->name_filter_valid = 1;
4464   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4465   S;
4466
4467   /* and local / loopback interfaces */
4468   M (SW_INTERFACE_DUMP, sw_interface_dump);
4469   mp->name_filter_valid = 1;
4470   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4471   S;
4472
4473   /* and packet-generator interfaces */
4474   M (SW_INTERFACE_DUMP, sw_interface_dump);
4475   mp->name_filter_valid = 1;
4476   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4477   S;
4478
4479   /* and vxlan-gpe tunnel interfaces */
4480   M (SW_INTERFACE_DUMP, sw_interface_dump);
4481   mp->name_filter_valid = 1;
4482   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4483            sizeof (mp->name_filter) - 1);
4484   S;
4485
4486   /* and vxlan tunnel interfaces */
4487   M (SW_INTERFACE_DUMP, sw_interface_dump);
4488   mp->name_filter_valid = 1;
4489   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4490   S;
4491
4492   /* and host (af_packet) interfaces */
4493   M (SW_INTERFACE_DUMP, sw_interface_dump);
4494   mp->name_filter_valid = 1;
4495   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4496   S;
4497
4498   /* and l2tpv3 tunnel interfaces */
4499   M (SW_INTERFACE_DUMP, sw_interface_dump);
4500   mp->name_filter_valid = 1;
4501   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4502            sizeof (mp->name_filter) - 1);
4503   S;
4504
4505   /* and GRE tunnel interfaces */
4506   M (SW_INTERFACE_DUMP, sw_interface_dump);
4507   mp->name_filter_valid = 1;
4508   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4509   S;
4510
4511   /* and LISP-GPE interfaces */
4512   M (SW_INTERFACE_DUMP, sw_interface_dump);
4513   mp->name_filter_valid = 1;
4514   strncpy ((char *) mp->name_filter, "lisp_gpe",
4515            sizeof (mp->name_filter) - 1);
4516   S;
4517
4518   /* and IPSEC tunnel interfaces */
4519   M (SW_INTERFACE_DUMP, sw_interface_dump);
4520   mp->name_filter_valid = 1;
4521   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4522   S;
4523
4524   /* Use a control ping for synchronization */
4525   {
4526     vl_api_control_ping_t *mp;
4527     M (CONTROL_PING, control_ping);
4528     S;
4529   }
4530   W;
4531 }
4532
4533 static int
4534 api_sw_interface_set_flags (vat_main_t * vam)
4535 {
4536   unformat_input_t *i = vam->input;
4537   vl_api_sw_interface_set_flags_t *mp;
4538   f64 timeout;
4539   u32 sw_if_index;
4540   u8 sw_if_index_set = 0;
4541   u8 admin_up = 0, link_up = 0;
4542
4543   /* Parse args required to build the message */
4544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4545     {
4546       if (unformat (i, "admin-up"))
4547         admin_up = 1;
4548       else if (unformat (i, "admin-down"))
4549         admin_up = 0;
4550       else if (unformat (i, "link-up"))
4551         link_up = 1;
4552       else if (unformat (i, "link-down"))
4553         link_up = 0;
4554       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4555         sw_if_index_set = 1;
4556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4557         sw_if_index_set = 1;
4558       else
4559         break;
4560     }
4561
4562   if (sw_if_index_set == 0)
4563     {
4564       errmsg ("missing interface name or sw_if_index\n");
4565       return -99;
4566     }
4567
4568   /* Construct the API message */
4569   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4570   mp->sw_if_index = ntohl (sw_if_index);
4571   mp->admin_up_down = admin_up;
4572   mp->link_up_down = link_up;
4573
4574   /* send it... */
4575   S;
4576
4577   /* Wait for a reply, return the good/bad news... */
4578   W;
4579 }
4580
4581 static int
4582 api_sw_interface_clear_stats (vat_main_t * vam)
4583 {
4584   unformat_input_t *i = vam->input;
4585   vl_api_sw_interface_clear_stats_t *mp;
4586   f64 timeout;
4587   u32 sw_if_index;
4588   u8 sw_if_index_set = 0;
4589
4590   /* Parse args required to build the message */
4591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4592     {
4593       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4594         sw_if_index_set = 1;
4595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4596         sw_if_index_set = 1;
4597       else
4598         break;
4599     }
4600
4601   /* Construct the API message */
4602   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4603
4604   if (sw_if_index_set == 1)
4605     mp->sw_if_index = ntohl (sw_if_index);
4606   else
4607     mp->sw_if_index = ~0;
4608
4609   /* send it... */
4610   S;
4611
4612   /* Wait for a reply, return the good/bad news... */
4613   W;
4614 }
4615
4616 static int
4617 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4618 {
4619   unformat_input_t *i = vam->input;
4620   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4621   f64 timeout;
4622   u32 sw_if_index;
4623   u8 sw_if_index_set = 0;
4624   u32 subport;
4625   u8 subport_set = 0;
4626   u32 pipe;
4627   u8 pipe_set = 0;
4628   u32 profile;
4629   u8 profile_set = 0;
4630
4631   /* Parse args required to build the message */
4632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4633     {
4634       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4635         sw_if_index_set = 1;
4636       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4637         sw_if_index_set = 1;
4638       else if (unformat (i, "subport %u", &subport))
4639         subport_set = 1;
4640       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4641         sw_if_index_set = 1;
4642       else if (unformat (i, "pipe %u", &pipe))
4643         pipe_set = 1;
4644       else if (unformat (i, "profile %u", &profile))
4645         profile_set = 1;
4646       else
4647         break;
4648     }
4649
4650   if (sw_if_index_set == 0)
4651     {
4652       errmsg ("missing interface name or sw_if_index\n");
4653       return -99;
4654     }
4655
4656   if (subport_set == 0)
4657     {
4658       errmsg ("missing subport \n");
4659       return -99;
4660     }
4661
4662   if (pipe_set == 0)
4663     {
4664       errmsg ("missing pipe\n");
4665       return -99;
4666     }
4667
4668   if (profile_set == 0)
4669     {
4670       errmsg ("missing profile\n");
4671       return -99;
4672     }
4673
4674   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4675
4676   mp->sw_if_index = ntohl (sw_if_index);
4677   mp->subport = ntohl (subport);
4678   mp->pipe = ntohl (pipe);
4679   mp->profile = ntohl (profile);
4680
4681
4682   S;
4683   W;
4684   /* NOTREACHED */
4685   return 0;
4686 }
4687
4688 static int
4689 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4690 {
4691   unformat_input_t *i = vam->input;
4692   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4693   f64 timeout;
4694   u32 sw_if_index;
4695   u8 sw_if_index_set = 0;
4696   u32 subport;
4697   u8 subport_set = 0;
4698   u32 tb_rate = 1250000000;     /* 10GbE */
4699   u32 tb_size = 1000000;
4700   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4701   u32 tc_period = 10;
4702
4703   /* Parse args required to build the message */
4704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4705     {
4706       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4707         sw_if_index_set = 1;
4708       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4709         sw_if_index_set = 1;
4710       else if (unformat (i, "subport %u", &subport))
4711         subport_set = 1;
4712       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4713         sw_if_index_set = 1;
4714       else if (unformat (i, "rate %u", &tb_rate))
4715         {
4716           u32 tc_id;
4717
4718           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4719                tc_id++)
4720             tc_rate[tc_id] = tb_rate;
4721         }
4722       else if (unformat (i, "bktsize %u", &tb_size))
4723         ;
4724       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4725         ;
4726       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4727         ;
4728       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4729         ;
4730       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4731         ;
4732       else if (unformat (i, "period %u", &tc_period))
4733         ;
4734       else
4735         break;
4736     }
4737
4738   if (sw_if_index_set == 0)
4739     {
4740       errmsg ("missing interface name or sw_if_index\n");
4741       return -99;
4742     }
4743
4744   if (subport_set == 0)
4745     {
4746       errmsg ("missing subport \n");
4747       return -99;
4748     }
4749
4750   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4751
4752   mp->sw_if_index = ntohl (sw_if_index);
4753   mp->subport = ntohl (subport);
4754   mp->tb_rate = ntohl (tb_rate);
4755   mp->tb_size = ntohl (tb_size);
4756   mp->tc_rate[0] = ntohl (tc_rate[0]);
4757   mp->tc_rate[1] = ntohl (tc_rate[1]);
4758   mp->tc_rate[2] = ntohl (tc_rate[2]);
4759   mp->tc_rate[3] = ntohl (tc_rate[3]);
4760   mp->tc_period = ntohl (tc_period);
4761
4762   S;
4763   W;
4764   /* NOTREACHED */
4765   return 0;
4766 }
4767
4768 static int
4769 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4770 {
4771   unformat_input_t *i = vam->input;
4772   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4773   f64 timeout;
4774   u32 sw_if_index;
4775   u8 sw_if_index_set = 0;
4776   u8 entry_set = 0;
4777   u8 tc_set = 0;
4778   u8 queue_set = 0;
4779   u32 entry, tc, queue;
4780
4781   /* Parse args required to build the message */
4782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4783     {
4784       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4785         sw_if_index_set = 1;
4786       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4787         sw_if_index_set = 1;
4788       else if (unformat (i, "entry %d", &entry))
4789         entry_set = 1;
4790       else if (unformat (i, "tc %d", &tc))
4791         tc_set = 1;
4792       else if (unformat (i, "queue %d", &queue))
4793         queue_set = 1;
4794       else
4795         break;
4796     }
4797
4798   if (sw_if_index_set == 0)
4799     {
4800       errmsg ("missing interface name or sw_if_index\n");
4801       return -99;
4802     }
4803
4804   if (entry_set == 0)
4805     {
4806       errmsg ("missing entry \n");
4807       return -99;
4808     }
4809
4810   if (tc_set == 0)
4811     {
4812       errmsg ("missing traffic class \n");
4813       return -99;
4814     }
4815
4816   if (queue_set == 0)
4817     {
4818       errmsg ("missing queue \n");
4819       return -99;
4820     }
4821
4822   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4823
4824   mp->sw_if_index = ntohl (sw_if_index);
4825   mp->entry = ntohl (entry);
4826   mp->tc = ntohl (tc);
4827   mp->queue = ntohl (queue);
4828
4829   S;
4830   W;
4831   /* NOTREACHED */
4832   return 0;
4833 }
4834
4835 static int
4836 api_sw_interface_add_del_address (vat_main_t * vam)
4837 {
4838   unformat_input_t *i = vam->input;
4839   vl_api_sw_interface_add_del_address_t *mp;
4840   f64 timeout;
4841   u32 sw_if_index;
4842   u8 sw_if_index_set = 0;
4843   u8 is_add = 1, del_all = 0;
4844   u32 address_length = 0;
4845   u8 v4_address_set = 0;
4846   u8 v6_address_set = 0;
4847   ip4_address_t v4address;
4848   ip6_address_t v6address;
4849
4850   /* Parse args required to build the message */
4851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4852     {
4853       if (unformat (i, "del-all"))
4854         del_all = 1;
4855       else if (unformat (i, "del"))
4856         is_add = 0;
4857       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4858         sw_if_index_set = 1;
4859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4860         sw_if_index_set = 1;
4861       else if (unformat (i, "%U/%d",
4862                          unformat_ip4_address, &v4address, &address_length))
4863         v4_address_set = 1;
4864       else if (unformat (i, "%U/%d",
4865                          unformat_ip6_address, &v6address, &address_length))
4866         v6_address_set = 1;
4867       else
4868         break;
4869     }
4870
4871   if (sw_if_index_set == 0)
4872     {
4873       errmsg ("missing interface name or sw_if_index\n");
4874       return -99;
4875     }
4876   if (v4_address_set && v6_address_set)
4877     {
4878       errmsg ("both v4 and v6 addresses set\n");
4879       return -99;
4880     }
4881   if (!v4_address_set && !v6_address_set && !del_all)
4882     {
4883       errmsg ("no addresses set\n");
4884       return -99;
4885     }
4886
4887   /* Construct the API message */
4888   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4889
4890   mp->sw_if_index = ntohl (sw_if_index);
4891   mp->is_add = is_add;
4892   mp->del_all = del_all;
4893   if (v6_address_set)
4894     {
4895       mp->is_ipv6 = 1;
4896       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4897     }
4898   else
4899     {
4900       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4901     }
4902   mp->address_length = address_length;
4903
4904   /* send it... */
4905   S;
4906
4907   /* Wait for a reply, return good/bad news  */
4908   W;
4909 }
4910
4911 static int
4912 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4913 {
4914   unformat_input_t *i = vam->input;
4915   vl_api_sw_interface_set_mpls_enable_t *mp;
4916   f64 timeout;
4917   u32 sw_if_index;
4918   u8 sw_if_index_set = 0;
4919   u8 enable = 1;
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, "disable"))
4929         enable = 0;
4930       else if (unformat (i, "dis"))
4931         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_MPLS_ENABLE, sw_interface_set_mpls_enable);
4944
4945   mp->sw_if_index = ntohl (sw_if_index);
4946   mp->enable = 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_table (vat_main_t * vam)
4957 {
4958   unformat_input_t *i = vam->input;
4959   vl_api_sw_interface_set_table_t *mp;
4960   f64 timeout;
4961   u32 sw_if_index, vrf_id = 0;
4962   u8 sw_if_index_set = 0;
4963   u8 is_ipv6 = 0;
4964
4965   /* Parse args required to build the message */
4966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4967     {
4968       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4969         sw_if_index_set = 1;
4970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4971         sw_if_index_set = 1;
4972       else if (unformat (i, "vrf %d", &vrf_id))
4973         ;
4974       else if (unformat (i, "ipv6"))
4975         is_ipv6 = 1;
4976       else
4977         break;
4978     }
4979
4980   if (sw_if_index_set == 0)
4981     {
4982       errmsg ("missing interface name or sw_if_index\n");
4983       return -99;
4984     }
4985
4986   /* Construct the API message */
4987   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4988
4989   mp->sw_if_index = ntohl (sw_if_index);
4990   mp->is_ipv6 = is_ipv6;
4991   mp->vrf_id = ntohl (vrf_id);
4992
4993   /* send it... */
4994   S;
4995
4996   /* Wait for a reply... */
4997   W;
4998 }
4999
5000 static int
5001 api_sw_interface_set_vpath (vat_main_t * vam)
5002 {
5003   unformat_input_t *i = vam->input;
5004   vl_api_sw_interface_set_vpath_t *mp;
5005   f64 timeout;
5006   u32 sw_if_index = 0;
5007   u8 sw_if_index_set = 0;
5008   u8 is_enable = 0;
5009
5010   /* Parse args required to build the message */
5011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5012     {
5013       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5014         sw_if_index_set = 1;
5015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5016         sw_if_index_set = 1;
5017       else if (unformat (i, "enable"))
5018         is_enable = 1;
5019       else if (unformat (i, "disable"))
5020         is_enable = 0;
5021       else
5022         break;
5023     }
5024
5025   if (sw_if_index_set == 0)
5026     {
5027       errmsg ("missing interface name or sw_if_index\n");
5028       return -99;
5029     }
5030
5031   /* Construct the API message */
5032   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5033
5034   mp->sw_if_index = ntohl (sw_if_index);
5035   mp->enable = is_enable;
5036
5037   /* send it... */
5038   S;
5039
5040   /* Wait for a reply... */
5041   W;
5042 }
5043
5044 static int
5045 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5046 {
5047   unformat_input_t *i = vam->input;
5048   vl_api_sw_interface_set_l2_xconnect_t *mp;
5049   f64 timeout;
5050   u32 rx_sw_if_index;
5051   u8 rx_sw_if_index_set = 0;
5052   u32 tx_sw_if_index;
5053   u8 tx_sw_if_index_set = 0;
5054   u8 enable = 1;
5055
5056   /* Parse args required to build the message */
5057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5058     {
5059       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5060         rx_sw_if_index_set = 1;
5061       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5062         tx_sw_if_index_set = 1;
5063       else if (unformat (i, "rx"))
5064         {
5065           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5066             {
5067               if (unformat (i, "%U", unformat_sw_if_index, vam,
5068                             &rx_sw_if_index))
5069                 rx_sw_if_index_set = 1;
5070             }
5071           else
5072             break;
5073         }
5074       else if (unformat (i, "tx"))
5075         {
5076           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5077             {
5078               if (unformat (i, "%U", unformat_sw_if_index, vam,
5079                             &tx_sw_if_index))
5080                 tx_sw_if_index_set = 1;
5081             }
5082           else
5083             break;
5084         }
5085       else if (unformat (i, "enable"))
5086         enable = 1;
5087       else if (unformat (i, "disable"))
5088         enable = 0;
5089       else
5090         break;
5091     }
5092
5093   if (rx_sw_if_index_set == 0)
5094     {
5095       errmsg ("missing rx interface name or rx_sw_if_index\n");
5096       return -99;
5097     }
5098
5099   if (enable && (tx_sw_if_index_set == 0))
5100     {
5101       errmsg ("missing tx interface name or tx_sw_if_index\n");
5102       return -99;
5103     }
5104
5105   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5106
5107   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5108   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5109   mp->enable = enable;
5110
5111   S;
5112   W;
5113   /* NOTREACHED */
5114   return 0;
5115 }
5116
5117 static int
5118 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5119 {
5120   unformat_input_t *i = vam->input;
5121   vl_api_sw_interface_set_l2_bridge_t *mp;
5122   f64 timeout;
5123   u32 rx_sw_if_index;
5124   u8 rx_sw_if_index_set = 0;
5125   u32 bd_id;
5126   u8 bd_id_set = 0;
5127   u8 bvi = 0;
5128   u32 shg = 0;
5129   u8 enable = 1;
5130
5131   /* Parse args required to build the message */
5132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5133     {
5134       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5135         rx_sw_if_index_set = 1;
5136       else if (unformat (i, "bd_id %d", &bd_id))
5137         bd_id_set = 1;
5138       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5139         rx_sw_if_index_set = 1;
5140       else if (unformat (i, "shg %d", &shg))
5141         ;
5142       else if (unformat (i, "bvi"))
5143         bvi = 1;
5144       else if (unformat (i, "enable"))
5145         enable = 1;
5146       else if (unformat (i, "disable"))
5147         enable = 0;
5148       else
5149         break;
5150     }
5151
5152   if (rx_sw_if_index_set == 0)
5153     {
5154       errmsg ("missing rx interface name or sw_if_index\n");
5155       return -99;
5156     }
5157
5158   if (enable && (bd_id_set == 0))
5159     {
5160       errmsg ("missing bridge domain\n");
5161       return -99;
5162     }
5163
5164   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5165
5166   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5167   mp->bd_id = ntohl (bd_id);
5168   mp->shg = (u8) shg;
5169   mp->bvi = bvi;
5170   mp->enable = enable;
5171
5172   S;
5173   W;
5174   /* NOTREACHED */
5175   return 0;
5176 }
5177
5178 static int
5179 api_bridge_domain_dump (vat_main_t * vam)
5180 {
5181   unformat_input_t *i = vam->input;
5182   vl_api_bridge_domain_dump_t *mp;
5183   f64 timeout;
5184   u32 bd_id = ~0;
5185
5186   /* Parse args required to build the message */
5187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5188     {
5189       if (unformat (i, "bd_id %d", &bd_id))
5190         ;
5191       else
5192         break;
5193     }
5194
5195   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5196   mp->bd_id = ntohl (bd_id);
5197   S;
5198
5199   /* Use a control ping for synchronization */
5200   {
5201     vl_api_control_ping_t *mp;
5202     M (CONTROL_PING, control_ping);
5203     S;
5204   }
5205
5206   W;
5207   /* NOTREACHED */
5208   return 0;
5209 }
5210
5211 static int
5212 api_bridge_domain_add_del (vat_main_t * vam)
5213 {
5214   unformat_input_t *i = vam->input;
5215   vl_api_bridge_domain_add_del_t *mp;
5216   f64 timeout;
5217   u32 bd_id = ~0;
5218   u8 is_add = 1;
5219   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5220
5221   /* Parse args required to build the message */
5222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5223     {
5224       if (unformat (i, "bd_id %d", &bd_id))
5225         ;
5226       else if (unformat (i, "flood %d", &flood))
5227         ;
5228       else if (unformat (i, "uu-flood %d", &uu_flood))
5229         ;
5230       else if (unformat (i, "forward %d", &forward))
5231         ;
5232       else if (unformat (i, "learn %d", &learn))
5233         ;
5234       else if (unformat (i, "arp-term %d", &arp_term))
5235         ;
5236       else if (unformat (i, "del"))
5237         {
5238           is_add = 0;
5239           flood = uu_flood = forward = learn = 0;
5240         }
5241       else
5242         break;
5243     }
5244
5245   if (bd_id == ~0)
5246     {
5247       errmsg ("missing bridge domain\n");
5248       return -99;
5249     }
5250
5251   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5252
5253   mp->bd_id = ntohl (bd_id);
5254   mp->flood = flood;
5255   mp->uu_flood = uu_flood;
5256   mp->forward = forward;
5257   mp->learn = learn;
5258   mp->arp_term = arp_term;
5259   mp->is_add = is_add;
5260
5261   S;
5262   W;
5263   /* NOTREACHED */
5264   return 0;
5265 }
5266
5267 static int
5268 api_l2fib_add_del (vat_main_t * vam)
5269 {
5270   unformat_input_t *i = vam->input;
5271   vl_api_l2fib_add_del_t *mp;
5272   f64 timeout;
5273   u64 mac = 0;
5274   u8 mac_set = 0;
5275   u32 bd_id;
5276   u8 bd_id_set = 0;
5277   u32 sw_if_index;
5278   u8 sw_if_index_set = 0;
5279   u8 is_add = 1;
5280   u8 static_mac = 0;
5281   u8 filter_mac = 0;
5282   u8 bvi_mac = 0;
5283   int count = 1;
5284   f64 before = 0;
5285   int j;
5286
5287   /* Parse args required to build the message */
5288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5289     {
5290       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5291         mac_set = 1;
5292       else if (unformat (i, "bd_id %d", &bd_id))
5293         bd_id_set = 1;
5294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5295         sw_if_index_set = 1;
5296       else if (unformat (i, "sw_if"))
5297         {
5298           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5299             {
5300               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5301                 sw_if_index_set = 1;
5302             }
5303           else
5304             break;
5305         }
5306       else if (unformat (i, "static"))
5307         static_mac = 1;
5308       else if (unformat (i, "filter"))
5309         {
5310           filter_mac = 1;
5311           static_mac = 1;
5312         }
5313       else if (unformat (i, "bvi"))
5314         {
5315           bvi_mac = 1;
5316           static_mac = 1;
5317         }
5318       else if (unformat (i, "del"))
5319         is_add = 0;
5320       else if (unformat (i, "count %d", &count))
5321         ;
5322       else
5323         break;
5324     }
5325
5326   if (mac_set == 0)
5327     {
5328       errmsg ("missing mac address\n");
5329       return -99;
5330     }
5331
5332   if (bd_id_set == 0)
5333     {
5334       errmsg ("missing bridge domain\n");
5335       return -99;
5336     }
5337
5338   if (is_add && (sw_if_index_set == 0))
5339     {
5340       errmsg ("missing interface name or sw_if_index\n");
5341       return -99;
5342     }
5343
5344   if (count > 1)
5345     {
5346       /* Turn on async mode */
5347       vam->async_mode = 1;
5348       vam->async_errors = 0;
5349       before = vat_time_now (vam);
5350     }
5351
5352   for (j = 0; j < count; j++)
5353     {
5354       M (L2FIB_ADD_DEL, l2fib_add_del);
5355
5356       mp->mac = mac;
5357       mp->bd_id = ntohl (bd_id);
5358       mp->is_add = is_add;
5359
5360       if (is_add)
5361         {
5362           mp->sw_if_index = ntohl (sw_if_index);
5363           mp->static_mac = static_mac;
5364           mp->filter_mac = filter_mac;
5365           mp->bvi_mac = bvi_mac;
5366         }
5367       increment_mac_address (&mac);
5368       /* send it... */
5369       S;
5370     }
5371
5372   if (count > 1)
5373     {
5374       vl_api_control_ping_t *mp;
5375       f64 after;
5376
5377       /* Shut off async mode */
5378       vam->async_mode = 0;
5379
5380       M (CONTROL_PING, control_ping);
5381       S;
5382
5383       timeout = vat_time_now (vam) + 1.0;
5384       while (vat_time_now (vam) < timeout)
5385         if (vam->result_ready == 1)
5386           goto out;
5387       vam->retval = -99;
5388
5389     out:
5390       if (vam->retval == -99)
5391         errmsg ("timeout\n");
5392
5393       if (vam->async_errors > 0)
5394         {
5395           errmsg ("%d asynchronous errors\n", vam->async_errors);
5396           vam->retval = -98;
5397         }
5398       vam->async_errors = 0;
5399       after = vat_time_now (vam);
5400
5401       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5402                count, after - before, count / (after - before));
5403     }
5404   else
5405     {
5406       /* Wait for a reply... */
5407       W;
5408     }
5409   /* Return the good/bad news */
5410   return (vam->retval);
5411 }
5412
5413 static int
5414 api_l2_flags (vat_main_t * vam)
5415 {
5416   unformat_input_t *i = vam->input;
5417   vl_api_l2_flags_t *mp;
5418   f64 timeout;
5419   u32 sw_if_index;
5420   u32 feature_bitmap = 0;
5421   u8 sw_if_index_set = 0;
5422
5423   /* Parse args required to build the message */
5424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5425     {
5426       if (unformat (i, "sw_if_index %d", &sw_if_index))
5427         sw_if_index_set = 1;
5428       else if (unformat (i, "sw_if"))
5429         {
5430           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5431             {
5432               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5433                 sw_if_index_set = 1;
5434             }
5435           else
5436             break;
5437         }
5438       else if (unformat (i, "learn"))
5439         feature_bitmap |= L2INPUT_FEAT_LEARN;
5440       else if (unformat (i, "forward"))
5441         feature_bitmap |= L2INPUT_FEAT_FWD;
5442       else if (unformat (i, "flood"))
5443         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5444       else if (unformat (i, "uu-flood"))
5445         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5446       else
5447         break;
5448     }
5449
5450   if (sw_if_index_set == 0)
5451     {
5452       errmsg ("missing interface name or sw_if_index\n");
5453       return -99;
5454     }
5455
5456   M (L2_FLAGS, l2_flags);
5457
5458   mp->sw_if_index = ntohl (sw_if_index);
5459   mp->feature_bitmap = ntohl (feature_bitmap);
5460
5461   S;
5462   W;
5463   /* NOTREACHED */
5464   return 0;
5465 }
5466
5467 static int
5468 api_bridge_flags (vat_main_t * vam)
5469 {
5470   unformat_input_t *i = vam->input;
5471   vl_api_bridge_flags_t *mp;
5472   f64 timeout;
5473   u32 bd_id;
5474   u8 bd_id_set = 0;
5475   u8 is_set = 1;
5476   u32 flags = 0;
5477
5478   /* Parse args required to build the message */
5479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5480     {
5481       if (unformat (i, "bd_id %d", &bd_id))
5482         bd_id_set = 1;
5483       else if (unformat (i, "learn"))
5484         flags |= L2_LEARN;
5485       else if (unformat (i, "forward"))
5486         flags |= L2_FWD;
5487       else if (unformat (i, "flood"))
5488         flags |= L2_FLOOD;
5489       else if (unformat (i, "uu-flood"))
5490         flags |= L2_UU_FLOOD;
5491       else if (unformat (i, "arp-term"))
5492         flags |= L2_ARP_TERM;
5493       else if (unformat (i, "off"))
5494         is_set = 0;
5495       else if (unformat (i, "disable"))
5496         is_set = 0;
5497       else
5498         break;
5499     }
5500
5501   if (bd_id_set == 0)
5502     {
5503       errmsg ("missing bridge domain\n");
5504       return -99;
5505     }
5506
5507   M (BRIDGE_FLAGS, bridge_flags);
5508
5509   mp->bd_id = ntohl (bd_id);
5510   mp->feature_bitmap = ntohl (flags);
5511   mp->is_set = is_set;
5512
5513   S;
5514   W;
5515   /* NOTREACHED */
5516   return 0;
5517 }
5518
5519 static int
5520 api_bd_ip_mac_add_del (vat_main_t * vam)
5521 {
5522   unformat_input_t *i = vam->input;
5523   vl_api_bd_ip_mac_add_del_t *mp;
5524   f64 timeout;
5525   u32 bd_id;
5526   u8 is_ipv6 = 0;
5527   u8 is_add = 1;
5528   u8 bd_id_set = 0;
5529   u8 ip_set = 0;
5530   u8 mac_set = 0;
5531   ip4_address_t v4addr;
5532   ip6_address_t v6addr;
5533   u8 macaddr[6];
5534
5535
5536   /* Parse args required to build the message */
5537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5538     {
5539       if (unformat (i, "bd_id %d", &bd_id))
5540         {
5541           bd_id_set++;
5542         }
5543       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5544         {
5545           ip_set++;
5546         }
5547       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5548         {
5549           ip_set++;
5550           is_ipv6++;
5551         }
5552       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5553         {
5554           mac_set++;
5555         }
5556       else if (unformat (i, "del"))
5557         is_add = 0;
5558       else
5559         break;
5560     }
5561
5562   if (bd_id_set == 0)
5563     {
5564       errmsg ("missing bridge domain\n");
5565       return -99;
5566     }
5567   else if (ip_set == 0)
5568     {
5569       errmsg ("missing IP address\n");
5570       return -99;
5571     }
5572   else if (mac_set == 0)
5573     {
5574       errmsg ("missing MAC address\n");
5575       return -99;
5576     }
5577
5578   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5579
5580   mp->bd_id = ntohl (bd_id);
5581   mp->is_ipv6 = is_ipv6;
5582   mp->is_add = is_add;
5583   if (is_ipv6)
5584     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5585   else
5586     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5587   clib_memcpy (mp->mac_address, macaddr, 6);
5588   S;
5589   W;
5590   /* NOTREACHED */
5591   return 0;
5592 }
5593
5594 static int
5595 api_tap_connect (vat_main_t * vam)
5596 {
5597   unformat_input_t *i = vam->input;
5598   vl_api_tap_connect_t *mp;
5599   f64 timeout;
5600   u8 mac_address[6];
5601   u8 random_mac = 1;
5602   u8 name_set = 0;
5603   u8 *tap_name;
5604
5605   memset (mac_address, 0, sizeof (mac_address));
5606
5607   /* Parse args required to build the message */
5608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5609     {
5610       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5611         {
5612           random_mac = 0;
5613         }
5614       else if (unformat (i, "random-mac"))
5615         random_mac = 1;
5616       else if (unformat (i, "tapname %s", &tap_name))
5617         name_set = 1;
5618       else
5619         break;
5620     }
5621
5622   if (name_set == 0)
5623     {
5624       errmsg ("missing tap name\n");
5625       return -99;
5626     }
5627   if (vec_len (tap_name) > 63)
5628     {
5629       errmsg ("tap name too long\n");
5630     }
5631   vec_add1 (tap_name, 0);
5632
5633   /* Construct the API message */
5634   M (TAP_CONNECT, tap_connect);
5635
5636   mp->use_random_mac = random_mac;
5637   clib_memcpy (mp->mac_address, mac_address, 6);
5638   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5639   vec_free (tap_name);
5640
5641   /* send it... */
5642   S;
5643
5644   /* Wait for a reply... */
5645   W;
5646 }
5647
5648 static int
5649 api_tap_modify (vat_main_t * vam)
5650 {
5651   unformat_input_t *i = vam->input;
5652   vl_api_tap_modify_t *mp;
5653   f64 timeout;
5654   u8 mac_address[6];
5655   u8 random_mac = 1;
5656   u8 name_set = 0;
5657   u8 *tap_name;
5658   u32 sw_if_index = ~0;
5659   u8 sw_if_index_set = 0;
5660
5661   memset (mac_address, 0, sizeof (mac_address));
5662
5663   /* Parse args required to build the message */
5664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5665     {
5666       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5667         sw_if_index_set = 1;
5668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5669         sw_if_index_set = 1;
5670       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5671         {
5672           random_mac = 0;
5673         }
5674       else if (unformat (i, "random-mac"))
5675         random_mac = 1;
5676       else if (unformat (i, "tapname %s", &tap_name))
5677         name_set = 1;
5678       else
5679         break;
5680     }
5681
5682   if (sw_if_index_set == 0)
5683     {
5684       errmsg ("missing vpp interface name");
5685       return -99;
5686     }
5687   if (name_set == 0)
5688     {
5689       errmsg ("missing tap name\n");
5690       return -99;
5691     }
5692   if (vec_len (tap_name) > 63)
5693     {
5694       errmsg ("tap name too long\n");
5695     }
5696   vec_add1 (tap_name, 0);
5697
5698   /* Construct the API message */
5699   M (TAP_MODIFY, tap_modify);
5700
5701   mp->use_random_mac = random_mac;
5702   mp->sw_if_index = ntohl (sw_if_index);
5703   clib_memcpy (mp->mac_address, mac_address, 6);
5704   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5705   vec_free (tap_name);
5706
5707   /* send it... */
5708   S;
5709
5710   /* Wait for a reply... */
5711   W;
5712 }
5713
5714 static int
5715 api_tap_delete (vat_main_t * vam)
5716 {
5717   unformat_input_t *i = vam->input;
5718   vl_api_tap_delete_t *mp;
5719   f64 timeout;
5720   u32 sw_if_index = ~0;
5721   u8 sw_if_index_set = 0;
5722
5723   /* Parse args required to build the message */
5724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5725     {
5726       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5727         sw_if_index_set = 1;
5728       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5729         sw_if_index_set = 1;
5730       else
5731         break;
5732     }
5733
5734   if (sw_if_index_set == 0)
5735     {
5736       errmsg ("missing vpp interface name");
5737       return -99;
5738     }
5739
5740   /* Construct the API message */
5741   M (TAP_DELETE, tap_delete);
5742
5743   mp->sw_if_index = ntohl (sw_if_index);
5744
5745   /* send it... */
5746   S;
5747
5748   /* Wait for a reply... */
5749   W;
5750 }
5751
5752 static int
5753 api_ip_add_del_route (vat_main_t * vam)
5754 {
5755   unformat_input_t *i = vam->input;
5756   vl_api_ip_add_del_route_t *mp;
5757   f64 timeout;
5758   u32 sw_if_index = ~0, vrf_id = 0;
5759   u8 sw_if_index_set = 0;
5760   u8 is_ipv6 = 0;
5761   u8 is_local = 0, is_drop = 0;
5762   u8 is_unreach = 0, is_prohibit = 0;
5763   u8 create_vrf_if_needed = 0;
5764   u8 is_add = 1;
5765   u8 next_hop_weight = 1;
5766   u8 not_last = 0;
5767   u8 is_multipath = 0;
5768   u8 address_set = 0;
5769   u8 address_length_set = 0;
5770   u32 next_hop_table_id = 0;
5771   u32 resolve_attempts = 0;
5772   u32 dst_address_length = 0;
5773   u8 next_hop_set = 0;
5774   ip4_address_t v4_dst_address, v4_next_hop_address;
5775   ip6_address_t v6_dst_address, v6_next_hop_address;
5776   int count = 1;
5777   int j;
5778   f64 before = 0;
5779   u32 random_add_del = 0;
5780   u32 *random_vector = 0;
5781   uword *random_hash;
5782   u32 random_seed = 0xdeaddabe;
5783   u32 classify_table_index = ~0;
5784   u8 is_classify = 0;
5785   u8 resolve_host = 0, resolve_attached = 0;
5786   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5787
5788   /* Parse args required to build the message */
5789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5790     {
5791       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5792         sw_if_index_set = 1;
5793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5794         sw_if_index_set = 1;
5795       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5796         {
5797           address_set = 1;
5798           is_ipv6 = 0;
5799         }
5800       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5801         {
5802           address_set = 1;
5803           is_ipv6 = 1;
5804         }
5805       else if (unformat (i, "/%d", &dst_address_length))
5806         {
5807           address_length_set = 1;
5808         }
5809
5810       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5811                                          &v4_next_hop_address))
5812         {
5813           next_hop_set = 1;
5814         }
5815       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5816                                          &v6_next_hop_address))
5817         {
5818           next_hop_set = 1;
5819         }
5820       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5821         ;
5822       else if (unformat (i, "weight %d", &next_hop_weight))
5823         ;
5824       else if (unformat (i, "drop"))
5825         {
5826           is_drop = 1;
5827         }
5828       else if (unformat (i, "null-send-unreach"))
5829         {
5830           is_unreach = 1;
5831         }
5832       else if (unformat (i, "null-send-prohibit"))
5833         {
5834           is_prohibit = 1;
5835         }
5836       else if (unformat (i, "local"))
5837         {
5838           is_local = 1;
5839         }
5840       else if (unformat (i, "classify %d", &classify_table_index))
5841         {
5842           is_classify = 1;
5843         }
5844       else if (unformat (i, "del"))
5845         is_add = 0;
5846       else if (unformat (i, "add"))
5847         is_add = 1;
5848       else if (unformat (i, "not-last"))
5849         not_last = 1;
5850       else if (unformat (i, "resolve-via-host"))
5851         resolve_host = 1;
5852       else if (unformat (i, "resolve-via-attached"))
5853         resolve_attached = 1;
5854       else if (unformat (i, "multipath"))
5855         is_multipath = 1;
5856       else if (unformat (i, "vrf %d", &vrf_id))
5857         ;
5858       else if (unformat (i, "create-vrf"))
5859         create_vrf_if_needed = 1;
5860       else if (unformat (i, "count %d", &count))
5861         ;
5862       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5863         ;
5864       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5865         ;
5866       else if (unformat (i, "out-label %d", &next_hop_out_label))
5867         ;
5868       else if (unformat (i, "random"))
5869         random_add_del = 1;
5870       else if (unformat (i, "seed %d", &random_seed))
5871         ;
5872       else
5873         {
5874           clib_warning ("parse error '%U'", format_unformat_error, i);
5875           return -99;
5876         }
5877     }
5878
5879   if (resolve_attempts > 0 && sw_if_index_set == 0)
5880     {
5881       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5882       return -99;
5883     }
5884
5885   if (!next_hop_set && !is_drop && !is_local &&
5886       !is_classify && !is_unreach && !is_prohibit)
5887     {
5888       errmsg
5889         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5890       return -99;
5891     }
5892
5893   if (address_set == 0)
5894     {
5895       errmsg ("missing addresses\n");
5896       return -99;
5897     }
5898
5899   if (address_length_set == 0)
5900     {
5901       errmsg ("missing address length\n");
5902       return -99;
5903     }
5904
5905   /* Generate a pile of unique, random routes */
5906   if (random_add_del)
5907     {
5908       u32 this_random_address;
5909       random_hash = hash_create (count, sizeof (uword));
5910
5911       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5912       for (j = 0; j <= count; j++)
5913         {
5914           do
5915             {
5916               this_random_address = random_u32 (&random_seed);
5917               this_random_address =
5918                 clib_host_to_net_u32 (this_random_address);
5919             }
5920           while (hash_get (random_hash, this_random_address));
5921           vec_add1 (random_vector, this_random_address);
5922           hash_set (random_hash, this_random_address, 1);
5923         }
5924       hash_free (random_hash);
5925       v4_dst_address.as_u32 = random_vector[0];
5926     }
5927
5928   if (count > 1)
5929     {
5930       /* Turn on async mode */
5931       vam->async_mode = 1;
5932       vam->async_errors = 0;
5933       before = vat_time_now (vam);
5934     }
5935
5936   for (j = 0; j < count; j++)
5937     {
5938       /* Construct the API message */
5939       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5940
5941       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5942       mp->table_id = ntohl (vrf_id);
5943       if (resolve_attempts > 0)
5944         {
5945           mp->resolve_attempts = ntohl (resolve_attempts);
5946           mp->resolve_if_needed = 1;
5947         }
5948       mp->create_vrf_if_needed = create_vrf_if_needed;
5949
5950       mp->is_add = is_add;
5951       mp->is_drop = is_drop;
5952       mp->is_unreach = is_unreach;
5953       mp->is_prohibit = is_prohibit;
5954       mp->is_ipv6 = is_ipv6;
5955       mp->is_local = is_local;
5956       mp->is_classify = is_classify;
5957       mp->is_multipath = is_multipath;
5958       mp->is_resolve_host = resolve_host;
5959       mp->is_resolve_attached = resolve_attached;
5960       mp->not_last = not_last;
5961       mp->next_hop_weight = next_hop_weight;
5962       mp->dst_address_length = dst_address_length;
5963       mp->next_hop_table_id = ntohl (next_hop_table_id);
5964       mp->classify_table_index = ntohl (classify_table_index);
5965       mp->next_hop_out_label = ntohl (next_hop_out_label);
5966
5967       if (is_ipv6)
5968         {
5969           clib_memcpy (mp->dst_address, &v6_dst_address,
5970                        sizeof (v6_dst_address));
5971           if (next_hop_set)
5972             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5973                          sizeof (v6_next_hop_address));
5974           increment_v6_address (&v6_dst_address);
5975         }
5976       else
5977         {
5978           clib_memcpy (mp->dst_address, &v4_dst_address,
5979                        sizeof (v4_dst_address));
5980           if (next_hop_set)
5981             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5982                          sizeof (v4_next_hop_address));
5983           if (random_add_del)
5984             v4_dst_address.as_u32 = random_vector[j + 1];
5985           else
5986             increment_v4_address (&v4_dst_address);
5987         }
5988       /* send it... */
5989       S;
5990       /* If we receive SIGTERM, stop now... */
5991       if (vam->do_exit)
5992         break;
5993     }
5994
5995   /* When testing multiple add/del ops, use a control-ping to sync */
5996   if (count > 1)
5997     {
5998       vl_api_control_ping_t *mp;
5999       f64 after;
6000
6001       /* Shut off async mode */
6002       vam->async_mode = 0;
6003
6004       M (CONTROL_PING, control_ping);
6005       S;
6006
6007       timeout = vat_time_now (vam) + 1.0;
6008       while (vat_time_now (vam) < timeout)
6009         if (vam->result_ready == 1)
6010           goto out;
6011       vam->retval = -99;
6012
6013     out:
6014       if (vam->retval == -99)
6015         errmsg ("timeout\n");
6016
6017       if (vam->async_errors > 0)
6018         {
6019           errmsg ("%d asynchronous errors\n", vam->async_errors);
6020           vam->retval = -98;
6021         }
6022       vam->async_errors = 0;
6023       after = vat_time_now (vam);
6024
6025       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6026       if (j > 0)
6027         count = j;
6028
6029       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6030                count, after - before, count / (after - before));
6031     }
6032   else
6033     {
6034       /* Wait for a reply... */
6035       W;
6036     }
6037
6038   /* Return the good/bad news */
6039   return (vam->retval);
6040 }
6041
6042 static int
6043 api_mpls_route_add_del (vat_main_t * vam)
6044 {
6045   unformat_input_t *i = vam->input;
6046   vl_api_mpls_route_add_del_t *mp;
6047   f64 timeout;
6048   u32 sw_if_index = ~0, table_id = 0;
6049   u8 create_table_if_needed = 0;
6050   u8 is_add = 1;
6051   u8 next_hop_weight = 1;
6052   u8 is_multipath = 0;
6053   u32 next_hop_table_id = 0;
6054   u8 next_hop_set = 0;
6055   ip4_address_t v4_next_hop_address = {
6056     .as_u32 = 0,
6057   };
6058   ip6_address_t v6_next_hop_address = { {0} };
6059   int count = 1;
6060   int j;
6061   f64 before = 0;
6062   u32 classify_table_index = ~0;
6063   u8 is_classify = 0;
6064   u8 resolve_host = 0, resolve_attached = 0;
6065   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6066   mpls_label_t local_label = MPLS_LABEL_INVALID;
6067   u8 is_eos = 1;
6068   u8 next_hop_proto_is_ip4 = 1;
6069
6070   /* Parse args required to build the message */
6071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6072     {
6073       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6074         ;
6075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6076         ;
6077       else if (unformat (i, "%d", &local_label))
6078         ;
6079       else if (unformat (i, "eos"))
6080         is_eos = 1;
6081       else if (unformat (i, "non-eos"))
6082         is_eos = 0;
6083       else if (unformat (i, "via %U", unformat_ip4_address,
6084                          &v4_next_hop_address))
6085         {
6086           next_hop_set = 1;
6087           next_hop_proto_is_ip4 = 1;
6088         }
6089       else if (unformat (i, "via %U", unformat_ip6_address,
6090                          &v6_next_hop_address))
6091         {
6092           next_hop_set = 1;
6093           next_hop_proto_is_ip4 = 0;
6094         }
6095       else if (unformat (i, "weight %d", &next_hop_weight))
6096         ;
6097       else if (unformat (i, "create-table"))
6098         create_table_if_needed = 1;
6099       else if (unformat (i, "classify %d", &classify_table_index))
6100         {
6101           is_classify = 1;
6102         }
6103       else if (unformat (i, "del"))
6104         is_add = 0;
6105       else if (unformat (i, "add"))
6106         is_add = 1;
6107       else if (unformat (i, "resolve-via-host"))
6108         resolve_host = 1;
6109       else if (unformat (i, "resolve-via-attached"))
6110         resolve_attached = 1;
6111       else if (unformat (i, "multipath"))
6112         is_multipath = 1;
6113       else if (unformat (i, "count %d", &count))
6114         ;
6115       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6116         {
6117           next_hop_set = 1;
6118           next_hop_proto_is_ip4 = 1;
6119         }
6120       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6121         {
6122           next_hop_set = 1;
6123           next_hop_proto_is_ip4 = 0;
6124         }
6125       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6126         ;
6127       else if (unformat (i, "out-label %d", &next_hop_out_label))
6128         ;
6129       else
6130         {
6131           clib_warning ("parse error '%U'", format_unformat_error, i);
6132           return -99;
6133         }
6134     }
6135
6136   if (!next_hop_set && !is_classify)
6137     {
6138       errmsg ("next hop / classify not set\n");
6139       return -99;
6140     }
6141
6142   if (MPLS_LABEL_INVALID == local_label)
6143     {
6144       errmsg ("missing label\n");
6145       return -99;
6146     }
6147
6148   if (count > 1)
6149     {
6150       /* Turn on async mode */
6151       vam->async_mode = 1;
6152       vam->async_errors = 0;
6153       before = vat_time_now (vam);
6154     }
6155
6156   for (j = 0; j < count; j++)
6157     {
6158       /* Construct the API message */
6159       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6160
6161       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6162       mp->mr_table_id = ntohl (table_id);
6163       mp->mr_create_table_if_needed = create_table_if_needed;
6164
6165       mp->mr_is_add = is_add;
6166       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6167       mp->mr_is_classify = is_classify;
6168       mp->mr_is_multipath = is_multipath;
6169       mp->mr_is_resolve_host = resolve_host;
6170       mp->mr_is_resolve_attached = resolve_attached;
6171       mp->mr_next_hop_weight = next_hop_weight;
6172       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6173       mp->mr_classify_table_index = ntohl (classify_table_index);
6174       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6175       mp->mr_label = ntohl (local_label);
6176       mp->mr_eos = is_eos;
6177
6178       if (next_hop_set)
6179         {
6180           if (next_hop_proto_is_ip4)
6181             {
6182               clib_memcpy (mp->mr_next_hop,
6183                            &v4_next_hop_address,
6184                            sizeof (v4_next_hop_address));
6185             }
6186           else
6187             {
6188               clib_memcpy (mp->mr_next_hop,
6189                            &v6_next_hop_address,
6190                            sizeof (v6_next_hop_address));
6191             }
6192         }
6193       local_label++;
6194
6195       /* send it... */
6196       S;
6197       /* If we receive SIGTERM, stop now... */
6198       if (vam->do_exit)
6199         break;
6200     }
6201
6202   /* When testing multiple add/del ops, use a control-ping to sync */
6203   if (count > 1)
6204     {
6205       vl_api_control_ping_t *mp;
6206       f64 after;
6207
6208       /* Shut off async mode */
6209       vam->async_mode = 0;
6210
6211       M (CONTROL_PING, control_ping);
6212       S;
6213
6214       timeout = vat_time_now (vam) + 1.0;
6215       while (vat_time_now (vam) < timeout)
6216         if (vam->result_ready == 1)
6217           goto out;
6218       vam->retval = -99;
6219
6220     out:
6221       if (vam->retval == -99)
6222         errmsg ("timeout\n");
6223
6224       if (vam->async_errors > 0)
6225         {
6226           errmsg ("%d asynchronous errors\n", vam->async_errors);
6227           vam->retval = -98;
6228         }
6229       vam->async_errors = 0;
6230       after = vat_time_now (vam);
6231
6232       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6233       if (j > 0)
6234         count = j;
6235
6236       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6237                count, after - before, count / (after - before));
6238     }
6239   else
6240     {
6241       /* Wait for a reply... */
6242       W;
6243     }
6244
6245   /* Return the good/bad news */
6246   return (vam->retval);
6247 }
6248
6249 static int
6250 api_mpls_ip_bind_unbind (vat_main_t * vam)
6251 {
6252   unformat_input_t *i = vam->input;
6253   vl_api_mpls_ip_bind_unbind_t *mp;
6254   f64 timeout;
6255   u32 ip_table_id = 0;
6256   u8 create_table_if_needed = 0;
6257   u8 is_bind = 1;
6258   u8 is_ip4 = 1;
6259   ip4_address_t v4_address;
6260   ip6_address_t v6_address;
6261   u32 address_length;
6262   u8 address_set = 0;
6263   mpls_label_t local_label = MPLS_LABEL_INVALID;
6264
6265   /* Parse args required to build the message */
6266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6267     {
6268       if (unformat (i, "%U/%d", unformat_ip4_address,
6269                     &v4_address, &address_length))
6270         {
6271           is_ip4 = 1;
6272           address_set = 1;
6273         }
6274       else if (unformat (i, "%U/%d", unformat_ip6_address,
6275                          &v6_address, &address_length))
6276         {
6277           is_ip4 = 0;
6278           address_set = 1;
6279         }
6280       else if (unformat (i, "%d", &local_label))
6281         ;
6282       else if (unformat (i, "create-table"))
6283         create_table_if_needed = 1;
6284       else if (unformat (i, "table-id %d", &ip_table_id))
6285         ;
6286       else if (unformat (i, "unbind"))
6287         is_bind = 0;
6288       else if (unformat (i, "bind"))
6289         is_bind = 1;
6290       else
6291         {
6292           clib_warning ("parse error '%U'", format_unformat_error, i);
6293           return -99;
6294         }
6295     }
6296
6297   if (!address_set)
6298     {
6299       errmsg ("IP addres not set\n");
6300       return -99;
6301     }
6302
6303   if (MPLS_LABEL_INVALID == local_label)
6304     {
6305       errmsg ("missing label\n");
6306       return -99;
6307     }
6308
6309   /* Construct the API message */
6310   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6311
6312   mp->mb_create_table_if_needed = create_table_if_needed;
6313   mp->mb_is_bind = is_bind;
6314   mp->mb_is_ip4 = is_ip4;
6315   mp->mb_ip_table_id = ntohl (ip_table_id);
6316   mp->mb_mpls_table_id = 0;
6317   mp->mb_label = ntohl (local_label);
6318   mp->mb_address_length = address_length;
6319
6320   if (is_ip4)
6321     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6322   else
6323     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6324
6325   /* send it... */
6326   S;
6327
6328   /* Wait for a reply... */
6329   W;
6330 }
6331
6332 static int
6333 api_proxy_arp_add_del (vat_main_t * vam)
6334 {
6335   unformat_input_t *i = vam->input;
6336   vl_api_proxy_arp_add_del_t *mp;
6337   f64 timeout;
6338   u32 vrf_id = 0;
6339   u8 is_add = 1;
6340   ip4_address_t lo, hi;
6341   u8 range_set = 0;
6342
6343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6344     {
6345       if (unformat (i, "vrf %d", &vrf_id))
6346         ;
6347       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6348                          unformat_ip4_address, &hi))
6349         range_set = 1;
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 (range_set == 0)
6360     {
6361       errmsg ("address range not set\n");
6362       return -99;
6363     }
6364
6365   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6366
6367   mp->vrf_id = ntohl (vrf_id);
6368   mp->is_add = is_add;
6369   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6370   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6371
6372   S;
6373   W;
6374   /* NOTREACHED */
6375   return 0;
6376 }
6377
6378 static int
6379 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6380 {
6381   unformat_input_t *i = vam->input;
6382   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6383   f64 timeout;
6384   u32 sw_if_index;
6385   u8 enable = 1;
6386   u8 sw_if_index_set = 0;
6387
6388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6389     {
6390       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6391         sw_if_index_set = 1;
6392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6393         sw_if_index_set = 1;
6394       else if (unformat (i, "enable"))
6395         enable = 1;
6396       else if (unformat (i, "disable"))
6397         enable = 0;
6398       else
6399         {
6400           clib_warning ("parse error '%U'", format_unformat_error, i);
6401           return -99;
6402         }
6403     }
6404
6405   if (sw_if_index_set == 0)
6406     {
6407       errmsg ("missing interface name or sw_if_index\n");
6408       return -99;
6409     }
6410
6411   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6412
6413   mp->sw_if_index = ntohl (sw_if_index);
6414   mp->enable_disable = enable;
6415
6416   S;
6417   W;
6418   /* NOTREACHED */
6419   return 0;
6420 }
6421
6422 static int
6423 api_mpls_add_del_encap (vat_main_t * vam)
6424 {
6425   unformat_input_t *i = vam->input;
6426   vl_api_mpls_add_del_encap_t *mp;
6427   f64 timeout;
6428   u32 vrf_id = 0;
6429   u32 *labels = 0;
6430   u32 label;
6431   ip4_address_t dst_address;
6432   u8 is_add = 1;
6433
6434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6435     {
6436       if (unformat (i, "vrf %d", &vrf_id))
6437         ;
6438       else if (unformat (i, "label %d", &label))
6439         vec_add1 (labels, ntohl (label));
6440       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6441         ;
6442       else if (unformat (i, "del"))
6443         is_add = 0;
6444       else
6445         {
6446           clib_warning ("parse error '%U'", format_unformat_error, i);
6447           return -99;
6448         }
6449     }
6450
6451   if (vec_len (labels) == 0)
6452     {
6453       errmsg ("missing encap label stack\n");
6454       return -99;
6455     }
6456
6457   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6458       sizeof (u32) * vec_len (labels));
6459
6460   mp->vrf_id = ntohl (vrf_id);
6461   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6462   mp->is_add = is_add;
6463   mp->nlabels = vec_len (labels);
6464   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6465
6466   vec_free (labels);
6467
6468   S;
6469   W;
6470   /* NOTREACHED */
6471   return 0;
6472 }
6473
6474 static int
6475 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6476 {
6477   unformat_input_t *i = vam->input;
6478   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6479   f64 timeout;
6480   u32 inner_vrf_id = 0;
6481   ip4_address_t intfc_address;
6482   u8 dst_mac_address[6];
6483   int dst_set = 1;
6484   u32 tmp;
6485   u8 intfc_address_length = 0;
6486   u8 is_add = 1;
6487   u8 l2_only = 0;
6488   u32 tx_sw_if_index;
6489   int tx_sw_if_index_set = 0;
6490
6491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6492     {
6493       if (unformat (i, "vrf %d", &inner_vrf_id))
6494         ;
6495       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6496                          &intfc_address, &tmp))
6497         intfc_address_length = tmp;
6498       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6499         tx_sw_if_index_set = 1;
6500       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6501         tx_sw_if_index_set = 1;
6502       else if (unformat (i, "dst %U", unformat_ethernet_address,
6503                          dst_mac_address))
6504         dst_set = 1;
6505       else if (unformat (i, "l2-only"))
6506         l2_only = 1;
6507       else if (unformat (i, "del"))
6508         is_add = 0;
6509       else
6510         {
6511           clib_warning ("parse error '%U'", format_unformat_error, i);
6512           return -99;
6513         }
6514     }
6515
6516   if (!dst_set)
6517     {
6518       errmsg ("dst (mac address) not set\n");
6519       return -99;
6520     }
6521   if (!tx_sw_if_index_set)
6522     {
6523       errmsg ("tx-intfc not set\n");
6524       return -99;
6525     }
6526
6527   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6528
6529   mp->vrf_id = ntohl (inner_vrf_id);
6530   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6531   mp->adj_address_length = intfc_address_length;
6532   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6533                sizeof (dst_mac_address));
6534   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6535   mp->l2_only = l2_only;
6536   mp->is_add = is_add;
6537
6538   S;
6539   W;
6540   /* NOTREACHED */
6541   return 0;
6542 }
6543
6544 static int
6545 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6546 {
6547   unformat_input_t *i = vam->input;
6548   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6549   f64 timeout;
6550   u32 inner_vrf_id = 0;
6551   u32 outer_vrf_id = 0;
6552   ip4_address_t adj_address;
6553   int adj_address_set = 0;
6554   ip4_address_t next_hop_address;
6555   int next_hop_address_set = 0;
6556   u32 tmp;
6557   u8 adj_address_length = 0;
6558   u8 l2_only = 0;
6559   u8 is_add = 1;
6560   u32 resolve_attempts = 5;
6561   u8 resolve_if_needed = 1;
6562
6563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6564     {
6565       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6566         ;
6567       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6568         ;
6569       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6570                          &adj_address, &tmp))
6571         {
6572           adj_address_length = tmp;
6573           adj_address_set = 1;
6574         }
6575       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6576                          &next_hop_address))
6577         next_hop_address_set = 1;
6578       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6579         ;
6580       else if (unformat (i, "resolve-if-needed %d", &tmp))
6581         resolve_if_needed = tmp;
6582       else if (unformat (i, "l2-only"))
6583         l2_only = 1;
6584       else if (unformat (i, "del"))
6585         is_add = 0;
6586       else
6587         {
6588           clib_warning ("parse error '%U'", format_unformat_error, i);
6589           return -99;
6590         }
6591     }
6592
6593   if (!adj_address_set)
6594     {
6595       errmsg ("adjacency address/mask not set\n");
6596       return -99;
6597     }
6598   if (!next_hop_address_set)
6599     {
6600       errmsg ("ip4 next hop address (in outer fib) not set\n");
6601       return -99;
6602     }
6603
6604   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6605
6606   mp->inner_vrf_id = ntohl (inner_vrf_id);
6607   mp->outer_vrf_id = ntohl (outer_vrf_id);
6608   mp->resolve_attempts = ntohl (resolve_attempts);
6609   mp->resolve_if_needed = resolve_if_needed;
6610   mp->is_add = is_add;
6611   mp->l2_only = l2_only;
6612   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6613   mp->adj_address_length = adj_address_length;
6614   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6615                sizeof (next_hop_address));
6616
6617   S;
6618   W;
6619   /* NOTREACHED */
6620   return 0;
6621 }
6622
6623 static int
6624 api_sw_interface_set_unnumbered (vat_main_t * vam)
6625 {
6626   unformat_input_t *i = vam->input;
6627   vl_api_sw_interface_set_unnumbered_t *mp;
6628   f64 timeout;
6629   u32 sw_if_index;
6630   u32 unnum_sw_index = ~0;
6631   u8 is_add = 1;
6632   u8 sw_if_index_set = 0;
6633
6634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6635     {
6636       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6637         sw_if_index_set = 1;
6638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6639         sw_if_index_set = 1;
6640       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6641         ;
6642       else if (unformat (i, "del"))
6643         is_add = 0;
6644       else
6645         {
6646           clib_warning ("parse error '%U'", format_unformat_error, i);
6647           return -99;
6648         }
6649     }
6650
6651   if (sw_if_index_set == 0)
6652     {
6653       errmsg ("missing interface name or sw_if_index\n");
6654       return -99;
6655     }
6656
6657   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6658
6659   mp->sw_if_index = ntohl (sw_if_index);
6660   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6661   mp->is_add = is_add;
6662
6663   S;
6664   W;
6665   /* NOTREACHED */
6666   return 0;
6667 }
6668
6669 static int
6670 api_ip_neighbor_add_del (vat_main_t * vam)
6671 {
6672   unformat_input_t *i = vam->input;
6673   vl_api_ip_neighbor_add_del_t *mp;
6674   f64 timeout;
6675   u32 sw_if_index;
6676   u8 sw_if_index_set = 0;
6677   u32 vrf_id = 0;
6678   u8 is_add = 1;
6679   u8 is_static = 0;
6680   u8 mac_address[6];
6681   u8 mac_set = 0;
6682   u8 v4_address_set = 0;
6683   u8 v6_address_set = 0;
6684   ip4_address_t v4address;
6685   ip6_address_t v6address;
6686
6687   memset (mac_address, 0, sizeof (mac_address));
6688
6689   /* Parse args required to build the message */
6690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6691     {
6692       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6693         {
6694           mac_set = 1;
6695         }
6696       else if (unformat (i, "del"))
6697         is_add = 0;
6698       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6699         sw_if_index_set = 1;
6700       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6701         sw_if_index_set = 1;
6702       else if (unformat (i, "is_static"))
6703         is_static = 1;
6704       else if (unformat (i, "vrf %d", &vrf_id))
6705         ;
6706       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6707         v4_address_set = 1;
6708       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6709         v6_address_set = 1;
6710       else
6711         {
6712           clib_warning ("parse error '%U'", format_unformat_error, i);
6713           return -99;
6714         }
6715     }
6716
6717   if (sw_if_index_set == 0)
6718     {
6719       errmsg ("missing interface name or sw_if_index\n");
6720       return -99;
6721     }
6722   if (v4_address_set && v6_address_set)
6723     {
6724       errmsg ("both v4 and v6 addresses set\n");
6725       return -99;
6726     }
6727   if (!v4_address_set && !v6_address_set)
6728     {
6729       errmsg ("no address set\n");
6730       return -99;
6731     }
6732
6733   /* Construct the API message */
6734   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6735
6736   mp->sw_if_index = ntohl (sw_if_index);
6737   mp->is_add = is_add;
6738   mp->vrf_id = ntohl (vrf_id);
6739   mp->is_static = is_static;
6740   if (mac_set)
6741     clib_memcpy (mp->mac_address, mac_address, 6);
6742   if (v6_address_set)
6743     {
6744       mp->is_ipv6 = 1;
6745       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6746     }
6747   else
6748     {
6749       /* mp->is_ipv6 = 0; via memset in M macro above */
6750       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6751     }
6752
6753   /* send it... */
6754   S;
6755
6756   /* Wait for a reply, return good/bad news  */
6757   W;
6758
6759   /* NOTREACHED */
6760   return 0;
6761 }
6762
6763 static int
6764 api_reset_vrf (vat_main_t * vam)
6765 {
6766   unformat_input_t *i = vam->input;
6767   vl_api_reset_vrf_t *mp;
6768   f64 timeout;
6769   u32 vrf_id = 0;
6770   u8 is_ipv6 = 0;
6771   u8 vrf_id_set = 0;
6772
6773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6774     {
6775       if (unformat (i, "vrf %d", &vrf_id))
6776         vrf_id_set = 1;
6777       else if (unformat (i, "ipv6"))
6778         is_ipv6 = 1;
6779       else
6780         {
6781           clib_warning ("parse error '%U'", format_unformat_error, i);
6782           return -99;
6783         }
6784     }
6785
6786   if (vrf_id_set == 0)
6787     {
6788       errmsg ("missing vrf id\n");
6789       return -99;
6790     }
6791
6792   M (RESET_VRF, reset_vrf);
6793
6794   mp->vrf_id = ntohl (vrf_id);
6795   mp->is_ipv6 = is_ipv6;
6796
6797   S;
6798   W;
6799   /* NOTREACHED */
6800   return 0;
6801 }
6802
6803 static int
6804 api_create_vlan_subif (vat_main_t * vam)
6805 {
6806   unformat_input_t *i = vam->input;
6807   vl_api_create_vlan_subif_t *mp;
6808   f64 timeout;
6809   u32 sw_if_index;
6810   u8 sw_if_index_set = 0;
6811   u32 vlan_id;
6812   u8 vlan_id_set = 0;
6813
6814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6815     {
6816       if (unformat (i, "sw_if_index %d", &sw_if_index))
6817         sw_if_index_set = 1;
6818       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6819         sw_if_index_set = 1;
6820       else if (unformat (i, "vlan %d", &vlan_id))
6821         vlan_id_set = 1;
6822       else
6823         {
6824           clib_warning ("parse error '%U'", format_unformat_error, i);
6825           return -99;
6826         }
6827     }
6828
6829   if (sw_if_index_set == 0)
6830     {
6831       errmsg ("missing interface name or sw_if_index\n");
6832       return -99;
6833     }
6834
6835   if (vlan_id_set == 0)
6836     {
6837       errmsg ("missing vlan_id\n");
6838       return -99;
6839     }
6840   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6841
6842   mp->sw_if_index = ntohl (sw_if_index);
6843   mp->vlan_id = ntohl (vlan_id);
6844
6845   S;
6846   W;
6847   /* NOTREACHED */
6848   return 0;
6849 }
6850
6851 #define foreach_create_subif_bit                \
6852 _(no_tags)                                      \
6853 _(one_tag)                                      \
6854 _(two_tags)                                     \
6855 _(dot1ad)                                       \
6856 _(exact_match)                                  \
6857 _(default_sub)                                  \
6858 _(outer_vlan_id_any)                            \
6859 _(inner_vlan_id_any)
6860
6861 static int
6862 api_create_subif (vat_main_t * vam)
6863 {
6864   unformat_input_t *i = vam->input;
6865   vl_api_create_subif_t *mp;
6866   f64 timeout;
6867   u32 sw_if_index;
6868   u8 sw_if_index_set = 0;
6869   u32 sub_id;
6870   u8 sub_id_set = 0;
6871   u32 no_tags = 0;
6872   u32 one_tag = 0;
6873   u32 two_tags = 0;
6874   u32 dot1ad = 0;
6875   u32 exact_match = 0;
6876   u32 default_sub = 0;
6877   u32 outer_vlan_id_any = 0;
6878   u32 inner_vlan_id_any = 0;
6879   u32 tmp;
6880   u16 outer_vlan_id = 0;
6881   u16 inner_vlan_id = 0;
6882
6883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6884     {
6885       if (unformat (i, "sw_if_index %d", &sw_if_index))
6886         sw_if_index_set = 1;
6887       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6888         sw_if_index_set = 1;
6889       else if (unformat (i, "sub_id %d", &sub_id))
6890         sub_id_set = 1;
6891       else if (unformat (i, "outer_vlan_id %d", &tmp))
6892         outer_vlan_id = tmp;
6893       else if (unformat (i, "inner_vlan_id %d", &tmp))
6894         inner_vlan_id = tmp;
6895
6896 #define _(a) else if (unformat (i, #a)) a = 1 ;
6897       foreach_create_subif_bit
6898 #undef _
6899         else
6900         {
6901           clib_warning ("parse error '%U'", format_unformat_error, i);
6902           return -99;
6903         }
6904     }
6905
6906   if (sw_if_index_set == 0)
6907     {
6908       errmsg ("missing interface name or sw_if_index\n");
6909       return -99;
6910     }
6911
6912   if (sub_id_set == 0)
6913     {
6914       errmsg ("missing sub_id\n");
6915       return -99;
6916     }
6917   M (CREATE_SUBIF, create_subif);
6918
6919   mp->sw_if_index = ntohl (sw_if_index);
6920   mp->sub_id = ntohl (sub_id);
6921
6922 #define _(a) mp->a = a;
6923   foreach_create_subif_bit;
6924 #undef _
6925
6926   mp->outer_vlan_id = ntohs (outer_vlan_id);
6927   mp->inner_vlan_id = ntohs (inner_vlan_id);
6928
6929   S;
6930   W;
6931   /* NOTREACHED */
6932   return 0;
6933 }
6934
6935 static int
6936 api_oam_add_del (vat_main_t * vam)
6937 {
6938   unformat_input_t *i = vam->input;
6939   vl_api_oam_add_del_t *mp;
6940   f64 timeout;
6941   u32 vrf_id = 0;
6942   u8 is_add = 1;
6943   ip4_address_t src, dst;
6944   u8 src_set = 0;
6945   u8 dst_set = 0;
6946
6947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6948     {
6949       if (unformat (i, "vrf %d", &vrf_id))
6950         ;
6951       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6952         src_set = 1;
6953       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6954         dst_set = 1;
6955       else if (unformat (i, "del"))
6956         is_add = 0;
6957       else
6958         {
6959           clib_warning ("parse error '%U'", format_unformat_error, i);
6960           return -99;
6961         }
6962     }
6963
6964   if (src_set == 0)
6965     {
6966       errmsg ("missing src addr\n");
6967       return -99;
6968     }
6969
6970   if (dst_set == 0)
6971     {
6972       errmsg ("missing dst addr\n");
6973       return -99;
6974     }
6975
6976   M (OAM_ADD_DEL, oam_add_del);
6977
6978   mp->vrf_id = ntohl (vrf_id);
6979   mp->is_add = is_add;
6980   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6981   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6982
6983   S;
6984   W;
6985   /* NOTREACHED */
6986   return 0;
6987 }
6988
6989 static int
6990 api_reset_fib (vat_main_t * vam)
6991 {
6992   unformat_input_t *i = vam->input;
6993   vl_api_reset_fib_t *mp;
6994   f64 timeout;
6995   u32 vrf_id = 0;
6996   u8 is_ipv6 = 0;
6997   u8 vrf_id_set = 0;
6998
6999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7000     {
7001       if (unformat (i, "vrf %d", &vrf_id))
7002         vrf_id_set = 1;
7003       else if (unformat (i, "ipv6"))
7004         is_ipv6 = 1;
7005       else
7006         {
7007           clib_warning ("parse error '%U'", format_unformat_error, i);
7008           return -99;
7009         }
7010     }
7011
7012   if (vrf_id_set == 0)
7013     {
7014       errmsg ("missing vrf id\n");
7015       return -99;
7016     }
7017
7018   M (RESET_FIB, reset_fib);
7019
7020   mp->vrf_id = ntohl (vrf_id);
7021   mp->is_ipv6 = is_ipv6;
7022
7023   S;
7024   W;
7025   /* NOTREACHED */
7026   return 0;
7027 }
7028
7029 static int
7030 api_dhcp_proxy_config (vat_main_t * vam)
7031 {
7032   unformat_input_t *i = vam->input;
7033   vl_api_dhcp_proxy_config_t *mp;
7034   f64 timeout;
7035   u32 vrf_id = 0;
7036   u8 is_add = 1;
7037   u8 insert_cid = 1;
7038   u8 v4_address_set = 0;
7039   u8 v6_address_set = 0;
7040   ip4_address_t v4address;
7041   ip6_address_t v6address;
7042   u8 v4_src_address_set = 0;
7043   u8 v6_src_address_set = 0;
7044   ip4_address_t v4srcaddress;
7045   ip6_address_t v6srcaddress;
7046
7047   /* Parse args required to build the message */
7048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7049     {
7050       if (unformat (i, "del"))
7051         is_add = 0;
7052       else if (unformat (i, "vrf %d", &vrf_id))
7053         ;
7054       else if (unformat (i, "insert-cid %d", &insert_cid))
7055         ;
7056       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7057         v4_address_set = 1;
7058       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7059         v6_address_set = 1;
7060       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7061         v4_src_address_set = 1;
7062       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7063         v6_src_address_set = 1;
7064       else
7065         break;
7066     }
7067
7068   if (v4_address_set && v6_address_set)
7069     {
7070       errmsg ("both v4 and v6 server addresses set\n");
7071       return -99;
7072     }
7073   if (!v4_address_set && !v6_address_set)
7074     {
7075       errmsg ("no server addresses set\n");
7076       return -99;
7077     }
7078
7079   if (v4_src_address_set && v6_src_address_set)
7080     {
7081       errmsg ("both v4 and v6  src addresses set\n");
7082       return -99;
7083     }
7084   if (!v4_src_address_set && !v6_src_address_set)
7085     {
7086       errmsg ("no src addresses set\n");
7087       return -99;
7088     }
7089
7090   if (!(v4_src_address_set && v4_address_set) &&
7091       !(v6_src_address_set && v6_address_set))
7092     {
7093       errmsg ("no matching server and src addresses set\n");
7094       return -99;
7095     }
7096
7097   /* Construct the API message */
7098   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7099
7100   mp->insert_circuit_id = insert_cid;
7101   mp->is_add = is_add;
7102   mp->vrf_id = ntohl (vrf_id);
7103   if (v6_address_set)
7104     {
7105       mp->is_ipv6 = 1;
7106       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7107       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7108     }
7109   else
7110     {
7111       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7112       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7113     }
7114
7115   /* send it... */
7116   S;
7117
7118   /* Wait for a reply, return good/bad news  */
7119   W;
7120   /* NOTREACHED */
7121   return 0;
7122 }
7123
7124 static int
7125 api_dhcp_proxy_config_2 (vat_main_t * vam)
7126 {
7127   unformat_input_t *i = vam->input;
7128   vl_api_dhcp_proxy_config_2_t *mp;
7129   f64 timeout;
7130   u32 rx_vrf_id = 0;
7131   u32 server_vrf_id = 0;
7132   u8 is_add = 1;
7133   u8 insert_cid = 1;
7134   u8 v4_address_set = 0;
7135   u8 v6_address_set = 0;
7136   ip4_address_t v4address;
7137   ip6_address_t v6address;
7138   u8 v4_src_address_set = 0;
7139   u8 v6_src_address_set = 0;
7140   ip4_address_t v4srcaddress;
7141   ip6_address_t v6srcaddress;
7142
7143   /* Parse args required to build the message */
7144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7145     {
7146       if (unformat (i, "del"))
7147         is_add = 0;
7148       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7149         ;
7150       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7151         ;
7152       else if (unformat (i, "insert-cid %d", &insert_cid))
7153         ;
7154       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7155         v4_address_set = 1;
7156       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7157         v6_address_set = 1;
7158       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7159         v4_src_address_set = 1;
7160       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7161         v6_src_address_set = 1;
7162       else
7163         break;
7164     }
7165
7166   if (v4_address_set && v6_address_set)
7167     {
7168       errmsg ("both v4 and v6 server addresses set\n");
7169       return -99;
7170     }
7171   if (!v4_address_set && !v6_address_set)
7172     {
7173       errmsg ("no server addresses set\n");
7174       return -99;
7175     }
7176
7177   if (v4_src_address_set && v6_src_address_set)
7178     {
7179       errmsg ("both v4 and v6  src addresses set\n");
7180       return -99;
7181     }
7182   if (!v4_src_address_set && !v6_src_address_set)
7183     {
7184       errmsg ("no src addresses set\n");
7185       return -99;
7186     }
7187
7188   if (!(v4_src_address_set && v4_address_set) &&
7189       !(v6_src_address_set && v6_address_set))
7190     {
7191       errmsg ("no matching server and src addresses set\n");
7192       return -99;
7193     }
7194
7195   /* Construct the API message */
7196   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7197
7198   mp->insert_circuit_id = insert_cid;
7199   mp->is_add = is_add;
7200   mp->rx_vrf_id = ntohl (rx_vrf_id);
7201   mp->server_vrf_id = ntohl (server_vrf_id);
7202   if (v6_address_set)
7203     {
7204       mp->is_ipv6 = 1;
7205       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7206       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7207     }
7208   else
7209     {
7210       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7211       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7212     }
7213
7214   /* send it... */
7215   S;
7216
7217   /* Wait for a reply, return good/bad news  */
7218   W;
7219   /* NOTREACHED */
7220   return 0;
7221 }
7222
7223 static int
7224 api_dhcp_proxy_set_vss (vat_main_t * vam)
7225 {
7226   unformat_input_t *i = vam->input;
7227   vl_api_dhcp_proxy_set_vss_t *mp;
7228   f64 timeout;
7229   u8 is_ipv6 = 0;
7230   u8 is_add = 1;
7231   u32 tbl_id;
7232   u8 tbl_id_set = 0;
7233   u32 oui;
7234   u8 oui_set = 0;
7235   u32 fib_id;
7236   u8 fib_id_set = 0;
7237
7238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7239     {
7240       if (unformat (i, "tbl_id %d", &tbl_id))
7241         tbl_id_set = 1;
7242       if (unformat (i, "fib_id %d", &fib_id))
7243         fib_id_set = 1;
7244       if (unformat (i, "oui %d", &oui))
7245         oui_set = 1;
7246       else if (unformat (i, "ipv6"))
7247         is_ipv6 = 1;
7248       else if (unformat (i, "del"))
7249         is_add = 0;
7250       else
7251         {
7252           clib_warning ("parse error '%U'", format_unformat_error, i);
7253           return -99;
7254         }
7255     }
7256
7257   if (tbl_id_set == 0)
7258     {
7259       errmsg ("missing tbl id\n");
7260       return -99;
7261     }
7262
7263   if (fib_id_set == 0)
7264     {
7265       errmsg ("missing fib id\n");
7266       return -99;
7267     }
7268   if (oui_set == 0)
7269     {
7270       errmsg ("missing oui\n");
7271       return -99;
7272     }
7273
7274   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7275   mp->tbl_id = ntohl (tbl_id);
7276   mp->fib_id = ntohl (fib_id);
7277   mp->oui = ntohl (oui);
7278   mp->is_ipv6 = is_ipv6;
7279   mp->is_add = is_add;
7280
7281   S;
7282   W;
7283   /* NOTREACHED */
7284   return 0;
7285 }
7286
7287 static int
7288 api_dhcp_client_config (vat_main_t * vam)
7289 {
7290   unformat_input_t *i = vam->input;
7291   vl_api_dhcp_client_config_t *mp;
7292   f64 timeout;
7293   u32 sw_if_index;
7294   u8 sw_if_index_set = 0;
7295   u8 is_add = 1;
7296   u8 *hostname = 0;
7297   u8 disable_event = 0;
7298
7299   /* Parse args required to build the message */
7300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7301     {
7302       if (unformat (i, "del"))
7303         is_add = 0;
7304       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7305         sw_if_index_set = 1;
7306       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7307         sw_if_index_set = 1;
7308       else if (unformat (i, "hostname %s", &hostname))
7309         ;
7310       else if (unformat (i, "disable_event"))
7311         disable_event = 1;
7312       else
7313         break;
7314     }
7315
7316   if (sw_if_index_set == 0)
7317     {
7318       errmsg ("missing interface name or sw_if_index\n");
7319       return -99;
7320     }
7321
7322   if (vec_len (hostname) > 63)
7323     {
7324       errmsg ("hostname too long\n");
7325     }
7326   vec_add1 (hostname, 0);
7327
7328   /* Construct the API message */
7329   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7330
7331   mp->sw_if_index = ntohl (sw_if_index);
7332   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7333   vec_free (hostname);
7334   mp->is_add = is_add;
7335   mp->want_dhcp_event = disable_event ? 0 : 1;
7336   mp->pid = getpid ();
7337
7338   /* send it... */
7339   S;
7340
7341   /* Wait for a reply, return good/bad news  */
7342   W;
7343   /* NOTREACHED */
7344   return 0;
7345 }
7346
7347 static int
7348 api_set_ip_flow_hash (vat_main_t * vam)
7349 {
7350   unformat_input_t *i = vam->input;
7351   vl_api_set_ip_flow_hash_t *mp;
7352   f64 timeout;
7353   u32 vrf_id = 0;
7354   u8 is_ipv6 = 0;
7355   u8 vrf_id_set = 0;
7356   u8 src = 0;
7357   u8 dst = 0;
7358   u8 sport = 0;
7359   u8 dport = 0;
7360   u8 proto = 0;
7361   u8 reverse = 0;
7362
7363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7364     {
7365       if (unformat (i, "vrf %d", &vrf_id))
7366         vrf_id_set = 1;
7367       else if (unformat (i, "ipv6"))
7368         is_ipv6 = 1;
7369       else if (unformat (i, "src"))
7370         src = 1;
7371       else if (unformat (i, "dst"))
7372         dst = 1;
7373       else if (unformat (i, "sport"))
7374         sport = 1;
7375       else if (unformat (i, "dport"))
7376         dport = 1;
7377       else if (unformat (i, "proto"))
7378         proto = 1;
7379       else if (unformat (i, "reverse"))
7380         reverse = 1;
7381
7382       else
7383         {
7384           clib_warning ("parse error '%U'", format_unformat_error, i);
7385           return -99;
7386         }
7387     }
7388
7389   if (vrf_id_set == 0)
7390     {
7391       errmsg ("missing vrf id\n");
7392       return -99;
7393     }
7394
7395   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7396   mp->src = src;
7397   mp->dst = dst;
7398   mp->sport = sport;
7399   mp->dport = dport;
7400   mp->proto = proto;
7401   mp->reverse = reverse;
7402   mp->vrf_id = ntohl (vrf_id);
7403   mp->is_ipv6 = is_ipv6;
7404
7405   S;
7406   W;
7407   /* NOTREACHED */
7408   return 0;
7409 }
7410
7411 static int
7412 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7413 {
7414   unformat_input_t *i = vam->input;
7415   vl_api_sw_interface_ip6_enable_disable_t *mp;
7416   f64 timeout;
7417   u32 sw_if_index;
7418   u8 sw_if_index_set = 0;
7419   u8 enable = 0;
7420
7421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7422     {
7423       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7424         sw_if_index_set = 1;
7425       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7426         sw_if_index_set = 1;
7427       else if (unformat (i, "enable"))
7428         enable = 1;
7429       else if (unformat (i, "disable"))
7430         enable = 0;
7431       else
7432         {
7433           clib_warning ("parse error '%U'", format_unformat_error, i);
7434           return -99;
7435         }
7436     }
7437
7438   if (sw_if_index_set == 0)
7439     {
7440       errmsg ("missing interface name or sw_if_index\n");
7441       return -99;
7442     }
7443
7444   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7445
7446   mp->sw_if_index = ntohl (sw_if_index);
7447   mp->enable = enable;
7448
7449   S;
7450   W;
7451   /* NOTREACHED */
7452   return 0;
7453 }
7454
7455 static int
7456 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7457 {
7458   unformat_input_t *i = vam->input;
7459   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7460   f64 timeout;
7461   u32 sw_if_index;
7462   u8 sw_if_index_set = 0;
7463   u32 address_length = 0;
7464   u8 v6_address_set = 0;
7465   ip6_address_t v6address;
7466
7467   /* Parse args required to build the message */
7468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7469     {
7470       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7471         sw_if_index_set = 1;
7472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7473         sw_if_index_set = 1;
7474       else if (unformat (i, "%U/%d",
7475                          unformat_ip6_address, &v6address, &address_length))
7476         v6_address_set = 1;
7477       else
7478         break;
7479     }
7480
7481   if (sw_if_index_set == 0)
7482     {
7483       errmsg ("missing interface name or sw_if_index\n");
7484       return -99;
7485     }
7486   if (!v6_address_set)
7487     {
7488       errmsg ("no address set\n");
7489       return -99;
7490     }
7491
7492   /* Construct the API message */
7493   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7494      sw_interface_ip6_set_link_local_address);
7495
7496   mp->sw_if_index = ntohl (sw_if_index);
7497   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7498   mp->address_length = address_length;
7499
7500   /* send it... */
7501   S;
7502
7503   /* Wait for a reply, return good/bad news  */
7504   W;
7505
7506   /* NOTREACHED */
7507   return 0;
7508 }
7509
7510
7511 static int
7512 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7513 {
7514   unformat_input_t *i = vam->input;
7515   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7516   f64 timeout;
7517   u32 sw_if_index;
7518   u8 sw_if_index_set = 0;
7519   u32 address_length = 0;
7520   u8 v6_address_set = 0;
7521   ip6_address_t v6address;
7522   u8 use_default = 0;
7523   u8 no_advertise = 0;
7524   u8 off_link = 0;
7525   u8 no_autoconfig = 0;
7526   u8 no_onlink = 0;
7527   u8 is_no = 0;
7528   u32 val_lifetime = 0;
7529   u32 pref_lifetime = 0;
7530
7531   /* Parse args required to build the message */
7532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7533     {
7534       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7535         sw_if_index_set = 1;
7536       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7537         sw_if_index_set = 1;
7538       else if (unformat (i, "%U/%d",
7539                          unformat_ip6_address, &v6address, &address_length))
7540         v6_address_set = 1;
7541       else if (unformat (i, "val_life %d", &val_lifetime))
7542         ;
7543       else if (unformat (i, "pref_life %d", &pref_lifetime))
7544         ;
7545       else if (unformat (i, "def"))
7546         use_default = 1;
7547       else if (unformat (i, "noadv"))
7548         no_advertise = 1;
7549       else if (unformat (i, "offl"))
7550         off_link = 1;
7551       else if (unformat (i, "noauto"))
7552         no_autoconfig = 1;
7553       else if (unformat (i, "nolink"))
7554         no_onlink = 1;
7555       else if (unformat (i, "isno"))
7556         is_no = 1;
7557       else
7558         {
7559           clib_warning ("parse error '%U'", format_unformat_error, i);
7560           return -99;
7561         }
7562     }
7563
7564   if (sw_if_index_set == 0)
7565     {
7566       errmsg ("missing interface name or sw_if_index\n");
7567       return -99;
7568     }
7569   if (!v6_address_set)
7570     {
7571       errmsg ("no address set\n");
7572       return -99;
7573     }
7574
7575   /* Construct the API message */
7576   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7577
7578   mp->sw_if_index = ntohl (sw_if_index);
7579   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7580   mp->address_length = address_length;
7581   mp->use_default = use_default;
7582   mp->no_advertise = no_advertise;
7583   mp->off_link = off_link;
7584   mp->no_autoconfig = no_autoconfig;
7585   mp->no_onlink = no_onlink;
7586   mp->is_no = is_no;
7587   mp->val_lifetime = ntohl (val_lifetime);
7588   mp->pref_lifetime = ntohl (pref_lifetime);
7589
7590   /* send it... */
7591   S;
7592
7593   /* Wait for a reply, return good/bad news  */
7594   W;
7595
7596   /* NOTREACHED */
7597   return 0;
7598 }
7599
7600 static int
7601 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7602 {
7603   unformat_input_t *i = vam->input;
7604   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7605   f64 timeout;
7606   u32 sw_if_index;
7607   u8 sw_if_index_set = 0;
7608   u8 suppress = 0;
7609   u8 managed = 0;
7610   u8 other = 0;
7611   u8 ll_option = 0;
7612   u8 send_unicast = 0;
7613   u8 cease = 0;
7614   u8 is_no = 0;
7615   u8 default_router = 0;
7616   u32 max_interval = 0;
7617   u32 min_interval = 0;
7618   u32 lifetime = 0;
7619   u32 initial_count = 0;
7620   u32 initial_interval = 0;
7621
7622
7623   /* Parse args required to build the message */
7624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7625     {
7626       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7627         sw_if_index_set = 1;
7628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7629         sw_if_index_set = 1;
7630       else if (unformat (i, "maxint %d", &max_interval))
7631         ;
7632       else if (unformat (i, "minint %d", &min_interval))
7633         ;
7634       else if (unformat (i, "life %d", &lifetime))
7635         ;
7636       else if (unformat (i, "count %d", &initial_count))
7637         ;
7638       else if (unformat (i, "interval %d", &initial_interval))
7639         ;
7640       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7641         suppress = 1;
7642       else if (unformat (i, "managed"))
7643         managed = 1;
7644       else if (unformat (i, "other"))
7645         other = 1;
7646       else if (unformat (i, "ll"))
7647         ll_option = 1;
7648       else if (unformat (i, "send"))
7649         send_unicast = 1;
7650       else if (unformat (i, "cease"))
7651         cease = 1;
7652       else if (unformat (i, "isno"))
7653         is_no = 1;
7654       else if (unformat (i, "def"))
7655         default_router = 1;
7656       else
7657         {
7658           clib_warning ("parse error '%U'", format_unformat_error, i);
7659           return -99;
7660         }
7661     }
7662
7663   if (sw_if_index_set == 0)
7664     {
7665       errmsg ("missing interface name or sw_if_index\n");
7666       return -99;
7667     }
7668
7669   /* Construct the API message */
7670   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7671
7672   mp->sw_if_index = ntohl (sw_if_index);
7673   mp->max_interval = ntohl (max_interval);
7674   mp->min_interval = ntohl (min_interval);
7675   mp->lifetime = ntohl (lifetime);
7676   mp->initial_count = ntohl (initial_count);
7677   mp->initial_interval = ntohl (initial_interval);
7678   mp->suppress = suppress;
7679   mp->managed = managed;
7680   mp->other = other;
7681   mp->ll_option = ll_option;
7682   mp->send_unicast = send_unicast;
7683   mp->cease = cease;
7684   mp->is_no = is_no;
7685   mp->default_router = default_router;
7686
7687   /* send it... */
7688   S;
7689
7690   /* Wait for a reply, return good/bad news  */
7691   W;
7692
7693   /* NOTREACHED */
7694   return 0;
7695 }
7696
7697 static int
7698 api_set_arp_neighbor_limit (vat_main_t * vam)
7699 {
7700   unformat_input_t *i = vam->input;
7701   vl_api_set_arp_neighbor_limit_t *mp;
7702   f64 timeout;
7703   u32 arp_nbr_limit;
7704   u8 limit_set = 0;
7705   u8 is_ipv6 = 0;
7706
7707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7708     {
7709       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7710         limit_set = 1;
7711       else if (unformat (i, "ipv6"))
7712         is_ipv6 = 1;
7713       else
7714         {
7715           clib_warning ("parse error '%U'", format_unformat_error, i);
7716           return -99;
7717         }
7718     }
7719
7720   if (limit_set == 0)
7721     {
7722       errmsg ("missing limit value\n");
7723       return -99;
7724     }
7725
7726   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7727
7728   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7729   mp->is_ipv6 = is_ipv6;
7730
7731   S;
7732   W;
7733   /* NOTREACHED */
7734   return 0;
7735 }
7736
7737 static int
7738 api_l2_patch_add_del (vat_main_t * vam)
7739 {
7740   unformat_input_t *i = vam->input;
7741   vl_api_l2_patch_add_del_t *mp;
7742   f64 timeout;
7743   u32 rx_sw_if_index;
7744   u8 rx_sw_if_index_set = 0;
7745   u32 tx_sw_if_index;
7746   u8 tx_sw_if_index_set = 0;
7747   u8 is_add = 1;
7748
7749   /* Parse args required to build the message */
7750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7751     {
7752       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7753         rx_sw_if_index_set = 1;
7754       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7755         tx_sw_if_index_set = 1;
7756       else if (unformat (i, "rx"))
7757         {
7758           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7759             {
7760               if (unformat (i, "%U", unformat_sw_if_index, vam,
7761                             &rx_sw_if_index))
7762                 rx_sw_if_index_set = 1;
7763             }
7764           else
7765             break;
7766         }
7767       else if (unformat (i, "tx"))
7768         {
7769           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7770             {
7771               if (unformat (i, "%U", unformat_sw_if_index, vam,
7772                             &tx_sw_if_index))
7773                 tx_sw_if_index_set = 1;
7774             }
7775           else
7776             break;
7777         }
7778       else if (unformat (i, "del"))
7779         is_add = 0;
7780       else
7781         break;
7782     }
7783
7784   if (rx_sw_if_index_set == 0)
7785     {
7786       errmsg ("missing rx interface name or rx_sw_if_index\n");
7787       return -99;
7788     }
7789
7790   if (tx_sw_if_index_set == 0)
7791     {
7792       errmsg ("missing tx interface name or tx_sw_if_index\n");
7793       return -99;
7794     }
7795
7796   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7797
7798   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7799   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7800   mp->is_add = is_add;
7801
7802   S;
7803   W;
7804   /* NOTREACHED */
7805   return 0;
7806 }
7807
7808 static int
7809 api_ioam_enable (vat_main_t * vam)
7810 {
7811   unformat_input_t *input = vam->input;
7812   vl_api_ioam_enable_t *mp;
7813   f64 timeout;
7814   u32 id = 0;
7815   int has_trace_option = 0;
7816   int has_pot_option = 0;
7817   int has_seqno_option = 0;
7818   int has_analyse_option = 0;
7819
7820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7821     {
7822       if (unformat (input, "trace"))
7823         has_trace_option = 1;
7824       else if (unformat (input, "pot"))
7825         has_pot_option = 1;
7826       else if (unformat (input, "seqno"))
7827         has_seqno_option = 1;
7828       else if (unformat (input, "analyse"))
7829         has_analyse_option = 1;
7830       else
7831         break;
7832     }
7833   M (IOAM_ENABLE, ioam_enable);
7834   mp->id = htons (id);
7835   mp->seqno = has_seqno_option;
7836   mp->analyse = has_analyse_option;
7837   mp->pot_enable = has_pot_option;
7838   mp->trace_enable = has_trace_option;
7839
7840   S;
7841   W;
7842
7843   return (0);
7844
7845 }
7846
7847
7848 static int
7849 api_ioam_disable (vat_main_t * vam)
7850 {
7851   vl_api_ioam_disable_t *mp;
7852   f64 timeout;
7853
7854   M (IOAM_DISABLE, ioam_disable);
7855   S;
7856   W;
7857   return 0;
7858 }
7859
7860 static int
7861 api_sr_tunnel_add_del (vat_main_t * vam)
7862 {
7863   unformat_input_t *i = vam->input;
7864   vl_api_sr_tunnel_add_del_t *mp;
7865   f64 timeout;
7866   int is_del = 0;
7867   int pl_index;
7868   ip6_address_t src_address;
7869   int src_address_set = 0;
7870   ip6_address_t dst_address;
7871   u32 dst_mask_width;
7872   int dst_address_set = 0;
7873   u16 flags = 0;
7874   u32 rx_table_id = 0;
7875   u32 tx_table_id = 0;
7876   ip6_address_t *segments = 0;
7877   ip6_address_t *this_seg;
7878   ip6_address_t *tags = 0;
7879   ip6_address_t *this_tag;
7880   ip6_address_t next_address, tag;
7881   u8 *name = 0;
7882   u8 *policy_name = 0;
7883
7884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7885     {
7886       if (unformat (i, "del"))
7887         is_del = 1;
7888       else if (unformat (i, "name %s", &name))
7889         ;
7890       else if (unformat (i, "policy %s", &policy_name))
7891         ;
7892       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7893         ;
7894       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7895         ;
7896       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7897         src_address_set = 1;
7898       else if (unformat (i, "dst %U/%d",
7899                          unformat_ip6_address, &dst_address, &dst_mask_width))
7900         dst_address_set = 1;
7901       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7902         {
7903           vec_add2 (segments, this_seg, 1);
7904           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7905                        sizeof (*this_seg));
7906         }
7907       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7908         {
7909           vec_add2 (tags, this_tag, 1);
7910           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7911         }
7912       else if (unformat (i, "clean"))
7913         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7914       else if (unformat (i, "protected"))
7915         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7916       else if (unformat (i, "InPE %d", &pl_index))
7917         {
7918           if (pl_index <= 0 || pl_index > 4)
7919             {
7920             pl_index_range_error:
7921               errmsg ("pl index %d out of range\n", pl_index);
7922               return -99;
7923             }
7924           flags |=
7925             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7926         }
7927       else if (unformat (i, "EgPE %d", &pl_index))
7928         {
7929           if (pl_index <= 0 || pl_index > 4)
7930             goto pl_index_range_error;
7931           flags |=
7932             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7933         }
7934       else if (unformat (i, "OrgSrc %d", &pl_index))
7935         {
7936           if (pl_index <= 0 || pl_index > 4)
7937             goto pl_index_range_error;
7938           flags |=
7939             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7940         }
7941       else
7942         break;
7943     }
7944
7945   if (!src_address_set)
7946     {
7947       errmsg ("src address required\n");
7948       return -99;
7949     }
7950
7951   if (!dst_address_set)
7952     {
7953       errmsg ("dst address required\n");
7954       return -99;
7955     }
7956
7957   if (!segments)
7958     {
7959       errmsg ("at least one sr segment required\n");
7960       return -99;
7961     }
7962
7963   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7964       vec_len (segments) * sizeof (ip6_address_t)
7965       + vec_len (tags) * sizeof (ip6_address_t));
7966
7967   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7968   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7969   mp->dst_mask_width = dst_mask_width;
7970   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7971   mp->n_segments = vec_len (segments);
7972   mp->n_tags = vec_len (tags);
7973   mp->is_add = is_del == 0;
7974   clib_memcpy (mp->segs_and_tags, segments,
7975                vec_len (segments) * sizeof (ip6_address_t));
7976   clib_memcpy (mp->segs_and_tags +
7977                vec_len (segments) * sizeof (ip6_address_t), tags,
7978                vec_len (tags) * sizeof (ip6_address_t));
7979
7980   mp->outer_vrf_id = ntohl (rx_table_id);
7981   mp->inner_vrf_id = ntohl (tx_table_id);
7982   memcpy (mp->name, name, vec_len (name));
7983   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7984
7985   vec_free (segments);
7986   vec_free (tags);
7987
7988   S;
7989   W;
7990   /* NOTREACHED */
7991 }
7992
7993 static int
7994 api_sr_policy_add_del (vat_main_t * vam)
7995 {
7996   unformat_input_t *input = vam->input;
7997   vl_api_sr_policy_add_del_t *mp;
7998   f64 timeout;
7999   int is_del = 0;
8000   u8 *name = 0;
8001   u8 *tunnel_name = 0;
8002   u8 **tunnel_names = 0;
8003
8004   int name_set = 0;
8005   int tunnel_set = 0;
8006   int j = 0;
8007   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8008   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8009
8010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8011     {
8012       if (unformat (input, "del"))
8013         is_del = 1;
8014       else if (unformat (input, "name %s", &name))
8015         name_set = 1;
8016       else if (unformat (input, "tunnel %s", &tunnel_name))
8017         {
8018           if (tunnel_name)
8019             {
8020               vec_add1 (tunnel_names, tunnel_name);
8021               /* For serializer:
8022                  - length = #bytes to store in serial vector
8023                  - +1 = byte to store that length
8024                */
8025               tunnel_names_length += (vec_len (tunnel_name) + 1);
8026               tunnel_set = 1;
8027               tunnel_name = 0;
8028             }
8029         }
8030       else
8031         break;
8032     }
8033
8034   if (!name_set)
8035     {
8036       errmsg ("policy name required\n");
8037       return -99;
8038     }
8039
8040   if ((!tunnel_set) && (!is_del))
8041     {
8042       errmsg ("tunnel name required\n");
8043       return -99;
8044     }
8045
8046   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8047
8048
8049
8050   mp->is_add = !is_del;
8051
8052   memcpy (mp->name, name, vec_len (name));
8053   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8054   u8 *serial_orig = 0;
8055   vec_validate (serial_orig, tunnel_names_length);
8056   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8057   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8058
8059   for (j = 0; j < vec_len (tunnel_names); j++)
8060     {
8061       tun_name_len = vec_len (tunnel_names[j]);
8062       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8063       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8064       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8065       serial_orig += tun_name_len;      // Advance past the copy
8066     }
8067   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8068
8069   vec_free (tunnel_names);
8070   vec_free (tunnel_name);
8071
8072   S;
8073   W;
8074   /* NOTREACHED */
8075 }
8076
8077 static int
8078 api_sr_multicast_map_add_del (vat_main_t * vam)
8079 {
8080   unformat_input_t *input = vam->input;
8081   vl_api_sr_multicast_map_add_del_t *mp;
8082   f64 timeout;
8083   int is_del = 0;
8084   ip6_address_t multicast_address;
8085   u8 *policy_name = 0;
8086   int multicast_address_set = 0;
8087
8088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8089     {
8090       if (unformat (input, "del"))
8091         is_del = 1;
8092       else
8093         if (unformat
8094             (input, "address %U", unformat_ip6_address, &multicast_address))
8095         multicast_address_set = 1;
8096       else if (unformat (input, "sr-policy %s", &policy_name))
8097         ;
8098       else
8099         break;
8100     }
8101
8102   if (!is_del && !policy_name)
8103     {
8104       errmsg ("sr-policy name required\n");
8105       return -99;
8106     }
8107
8108
8109   if (!multicast_address_set)
8110     {
8111       errmsg ("address required\n");
8112       return -99;
8113     }
8114
8115   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8116
8117   mp->is_add = !is_del;
8118   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8119   clib_memcpy (mp->multicast_address, &multicast_address,
8120                sizeof (mp->multicast_address));
8121
8122
8123   vec_free (policy_name);
8124
8125   S;
8126   W;
8127   /* NOTREACHED */
8128 }
8129
8130
8131 #define foreach_tcp_proto_field                 \
8132 _(src_port)                                     \
8133 _(dst_port)
8134
8135 #define foreach_udp_proto_field                 \
8136 _(src_port)                                     \
8137 _(dst_port)
8138
8139 #define foreach_ip4_proto_field                 \
8140 _(src_address)                                  \
8141 _(dst_address)                                  \
8142 _(tos)                                          \
8143 _(length)                                       \
8144 _(fragment_id)                                  \
8145 _(ttl)                                          \
8146 _(protocol)                                     \
8147 _(checksum)
8148
8149 uword
8150 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8151 {
8152   u8 **maskp = va_arg (*args, u8 **);
8153   u8 *mask = 0;
8154   u8 found_something = 0;
8155   tcp_header_t *tcp;
8156
8157 #define _(a) u8 a=0;
8158   foreach_tcp_proto_field;
8159 #undef _
8160
8161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8162     {
8163       if (0);
8164 #define _(a) else if (unformat (input, #a)) a=1;
8165       foreach_tcp_proto_field
8166 #undef _
8167         else
8168         break;
8169     }
8170
8171 #define _(a) found_something += a;
8172   foreach_tcp_proto_field;
8173 #undef _
8174
8175   if (found_something == 0)
8176     return 0;
8177
8178   vec_validate (mask, sizeof (*tcp) - 1);
8179
8180   tcp = (tcp_header_t *) mask;
8181
8182 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8183   foreach_tcp_proto_field;
8184 #undef _
8185
8186   *maskp = mask;
8187   return 1;
8188 }
8189
8190 uword
8191 unformat_udp_mask (unformat_input_t * input, va_list * args)
8192 {
8193   u8 **maskp = va_arg (*args, u8 **);
8194   u8 *mask = 0;
8195   u8 found_something = 0;
8196   udp_header_t *udp;
8197
8198 #define _(a) u8 a=0;
8199   foreach_udp_proto_field;
8200 #undef _
8201
8202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8203     {
8204       if (0);
8205 #define _(a) else if (unformat (input, #a)) a=1;
8206       foreach_udp_proto_field
8207 #undef _
8208         else
8209         break;
8210     }
8211
8212 #define _(a) found_something += a;
8213   foreach_udp_proto_field;
8214 #undef _
8215
8216   if (found_something == 0)
8217     return 0;
8218
8219   vec_validate (mask, sizeof (*udp) - 1);
8220
8221   udp = (udp_header_t *) mask;
8222
8223 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8224   foreach_udp_proto_field;
8225 #undef _
8226
8227   *maskp = mask;
8228   return 1;
8229 }
8230
8231 typedef struct
8232 {
8233   u16 src_port, dst_port;
8234 } tcpudp_header_t;
8235
8236 uword
8237 unformat_l4_mask (unformat_input_t * input, va_list * args)
8238 {
8239   u8 **maskp = va_arg (*args, u8 **);
8240   u16 src_port = 0, dst_port = 0;
8241   tcpudp_header_t *tcpudp;
8242
8243   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8244     {
8245       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8246         return 1;
8247       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8248         return 1;
8249       else if (unformat (input, "src_port"))
8250         src_port = 0xFFFF;
8251       else if (unformat (input, "dst_port"))
8252         dst_port = 0xFFFF;
8253       else
8254         return 0;
8255     }
8256
8257   if (!src_port && !dst_port)
8258     return 0;
8259
8260   u8 *mask = 0;
8261   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8262
8263   tcpudp = (tcpudp_header_t *) mask;
8264   tcpudp->src_port = src_port;
8265   tcpudp->dst_port = dst_port;
8266
8267   *maskp = mask;
8268
8269   return 1;
8270 }
8271
8272 uword
8273 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8274 {
8275   u8 **maskp = va_arg (*args, u8 **);
8276   u8 *mask = 0;
8277   u8 found_something = 0;
8278   ip4_header_t *ip;
8279
8280 #define _(a) u8 a=0;
8281   foreach_ip4_proto_field;
8282 #undef _
8283   u8 version = 0;
8284   u8 hdr_length = 0;
8285
8286
8287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8288     {
8289       if (unformat (input, "version"))
8290         version = 1;
8291       else if (unformat (input, "hdr_length"))
8292         hdr_length = 1;
8293       else if (unformat (input, "src"))
8294         src_address = 1;
8295       else if (unformat (input, "dst"))
8296         dst_address = 1;
8297       else if (unformat (input, "proto"))
8298         protocol = 1;
8299
8300 #define _(a) else if (unformat (input, #a)) a=1;
8301       foreach_ip4_proto_field
8302 #undef _
8303         else
8304         break;
8305     }
8306
8307 #define _(a) found_something += a;
8308   foreach_ip4_proto_field;
8309 #undef _
8310
8311   if (found_something == 0)
8312     return 0;
8313
8314   vec_validate (mask, sizeof (*ip) - 1);
8315
8316   ip = (ip4_header_t *) mask;
8317
8318 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8319   foreach_ip4_proto_field;
8320 #undef _
8321
8322   ip->ip_version_and_header_length = 0;
8323
8324   if (version)
8325     ip->ip_version_and_header_length |= 0xF0;
8326
8327   if (hdr_length)
8328     ip->ip_version_and_header_length |= 0x0F;
8329
8330   *maskp = mask;
8331   return 1;
8332 }
8333
8334 #define foreach_ip6_proto_field                 \
8335 _(src_address)                                  \
8336 _(dst_address)                                  \
8337 _(payload_length)                               \
8338 _(hop_limit)                                    \
8339 _(protocol)
8340
8341 uword
8342 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8343 {
8344   u8 **maskp = va_arg (*args, u8 **);
8345   u8 *mask = 0;
8346   u8 found_something = 0;
8347   ip6_header_t *ip;
8348   u32 ip_version_traffic_class_and_flow_label;
8349
8350 #define _(a) u8 a=0;
8351   foreach_ip6_proto_field;
8352 #undef _
8353   u8 version = 0;
8354   u8 traffic_class = 0;
8355   u8 flow_label = 0;
8356
8357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8358     {
8359       if (unformat (input, "version"))
8360         version = 1;
8361       else if (unformat (input, "traffic-class"))
8362         traffic_class = 1;
8363       else if (unformat (input, "flow-label"))
8364         flow_label = 1;
8365       else if (unformat (input, "src"))
8366         src_address = 1;
8367       else if (unformat (input, "dst"))
8368         dst_address = 1;
8369       else if (unformat (input, "proto"))
8370         protocol = 1;
8371
8372 #define _(a) else if (unformat (input, #a)) a=1;
8373       foreach_ip6_proto_field
8374 #undef _
8375         else
8376         break;
8377     }
8378
8379 #define _(a) found_something += a;
8380   foreach_ip6_proto_field;
8381 #undef _
8382
8383   if (found_something == 0)
8384     return 0;
8385
8386   vec_validate (mask, sizeof (*ip) - 1);
8387
8388   ip = (ip6_header_t *) mask;
8389
8390 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8391   foreach_ip6_proto_field;
8392 #undef _
8393
8394   ip_version_traffic_class_and_flow_label = 0;
8395
8396   if (version)
8397     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8398
8399   if (traffic_class)
8400     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8401
8402   if (flow_label)
8403     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8404
8405   ip->ip_version_traffic_class_and_flow_label =
8406     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8407
8408   *maskp = mask;
8409   return 1;
8410 }
8411
8412 uword
8413 unformat_l3_mask (unformat_input_t * input, va_list * args)
8414 {
8415   u8 **maskp = va_arg (*args, u8 **);
8416
8417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8418     {
8419       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8420         return 1;
8421       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8422         return 1;
8423       else
8424         break;
8425     }
8426   return 0;
8427 }
8428
8429 uword
8430 unformat_l2_mask (unformat_input_t * input, va_list * args)
8431 {
8432   u8 **maskp = va_arg (*args, u8 **);
8433   u8 *mask = 0;
8434   u8 src = 0;
8435   u8 dst = 0;
8436   u8 proto = 0;
8437   u8 tag1 = 0;
8438   u8 tag2 = 0;
8439   u8 ignore_tag1 = 0;
8440   u8 ignore_tag2 = 0;
8441   u8 cos1 = 0;
8442   u8 cos2 = 0;
8443   u8 dot1q = 0;
8444   u8 dot1ad = 0;
8445   int len = 14;
8446
8447   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8448     {
8449       if (unformat (input, "src"))
8450         src = 1;
8451       else if (unformat (input, "dst"))
8452         dst = 1;
8453       else if (unformat (input, "proto"))
8454         proto = 1;
8455       else if (unformat (input, "tag1"))
8456         tag1 = 1;
8457       else if (unformat (input, "tag2"))
8458         tag2 = 1;
8459       else if (unformat (input, "ignore-tag1"))
8460         ignore_tag1 = 1;
8461       else if (unformat (input, "ignore-tag2"))
8462         ignore_tag2 = 1;
8463       else if (unformat (input, "cos1"))
8464         cos1 = 1;
8465       else if (unformat (input, "cos2"))
8466         cos2 = 1;
8467       else if (unformat (input, "dot1q"))
8468         dot1q = 1;
8469       else if (unformat (input, "dot1ad"))
8470         dot1ad = 1;
8471       else
8472         break;
8473     }
8474   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8475        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8476     return 0;
8477
8478   if (tag1 || ignore_tag1 || cos1 || dot1q)
8479     len = 18;
8480   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8481     len = 22;
8482
8483   vec_validate (mask, len - 1);
8484
8485   if (dst)
8486     memset (mask, 0xff, 6);
8487
8488   if (src)
8489     memset (mask + 6, 0xff, 6);
8490
8491   if (tag2 || dot1ad)
8492     {
8493       /* inner vlan tag */
8494       if (tag2)
8495         {
8496           mask[19] = 0xff;
8497           mask[18] = 0x0f;
8498         }
8499       if (cos2)
8500         mask[18] |= 0xe0;
8501       if (proto)
8502         mask[21] = mask[20] = 0xff;
8503       if (tag1)
8504         {
8505           mask[15] = 0xff;
8506           mask[14] = 0x0f;
8507         }
8508       if (cos1)
8509         mask[14] |= 0xe0;
8510       *maskp = mask;
8511       return 1;
8512     }
8513   if (tag1 | dot1q)
8514     {
8515       if (tag1)
8516         {
8517           mask[15] = 0xff;
8518           mask[14] = 0x0f;
8519         }
8520       if (cos1)
8521         mask[14] |= 0xe0;
8522       if (proto)
8523         mask[16] = mask[17] = 0xff;
8524
8525       *maskp = mask;
8526       return 1;
8527     }
8528   if (cos2)
8529     mask[18] |= 0xe0;
8530   if (cos1)
8531     mask[14] |= 0xe0;
8532   if (proto)
8533     mask[12] = mask[13] = 0xff;
8534
8535   *maskp = mask;
8536   return 1;
8537 }
8538
8539 uword
8540 unformat_classify_mask (unformat_input_t * input, va_list * args)
8541 {
8542   u8 **maskp = va_arg (*args, u8 **);
8543   u32 *skipp = va_arg (*args, u32 *);
8544   u32 *matchp = va_arg (*args, u32 *);
8545   u32 match;
8546   u8 *mask = 0;
8547   u8 *l2 = 0;
8548   u8 *l3 = 0;
8549   u8 *l4 = 0;
8550   int i;
8551
8552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8553     {
8554       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8555         ;
8556       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8557         ;
8558       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8559         ;
8560       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8561         ;
8562       else
8563         break;
8564     }
8565
8566   if (l4 && !l3)
8567     {
8568       vec_free (mask);
8569       vec_free (l2);
8570       vec_free (l4);
8571       return 0;
8572     }
8573
8574   if (mask || l2 || l3 || l4)
8575     {
8576       if (l2 || l3 || l4)
8577         {
8578           /* "With a free Ethernet header in every package" */
8579           if (l2 == 0)
8580             vec_validate (l2, 13);
8581           mask = l2;
8582           if (vec_len (l3))
8583             {
8584               vec_append (mask, l3);
8585               vec_free (l3);
8586             }
8587           if (vec_len (l4))
8588             {
8589               vec_append (mask, l4);
8590               vec_free (l4);
8591             }
8592         }
8593
8594       /* Scan forward looking for the first significant mask octet */
8595       for (i = 0; i < vec_len (mask); i++)
8596         if (mask[i])
8597           break;
8598
8599       /* compute (skip, match) params */
8600       *skipp = i / sizeof (u32x4);
8601       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8602
8603       /* Pad mask to an even multiple of the vector size */
8604       while (vec_len (mask) % sizeof (u32x4))
8605         vec_add1 (mask, 0);
8606
8607       match = vec_len (mask) / sizeof (u32x4);
8608
8609       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8610         {
8611           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8612           if (*tmp || *(tmp + 1))
8613             break;
8614           match--;
8615         }
8616       if (match == 0)
8617         clib_warning ("BUG: match 0");
8618
8619       _vec_len (mask) = match * sizeof (u32x4);
8620
8621       *matchp = match;
8622       *maskp = mask;
8623
8624       return 1;
8625     }
8626
8627   return 0;
8628 }
8629
8630 #define foreach_l2_next                         \
8631 _(drop, DROP)                                   \
8632 _(ethernet, ETHERNET_INPUT)                     \
8633 _(ip4, IP4_INPUT)                               \
8634 _(ip6, IP6_INPUT)
8635
8636 uword
8637 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8638 {
8639   u32 *miss_next_indexp = va_arg (*args, u32 *);
8640   u32 next_index = 0;
8641   u32 tmp;
8642
8643 #define _(n,N) \
8644   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8645   foreach_l2_next;
8646 #undef _
8647
8648   if (unformat (input, "%d", &tmp))
8649     {
8650       next_index = tmp;
8651       goto out;
8652     }
8653
8654   return 0;
8655
8656 out:
8657   *miss_next_indexp = next_index;
8658   return 1;
8659 }
8660
8661 #define foreach_ip_next                         \
8662 _(drop, DROP)                                   \
8663 _(local, LOCAL)                                 \
8664 _(rewrite, REWRITE)
8665
8666 uword
8667 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8668 {
8669   u32 *miss_next_indexp = va_arg (*args, u32 *);
8670   u32 next_index = 0;
8671   u32 tmp;
8672
8673 #define _(n,N) \
8674   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8675   foreach_ip_next;
8676 #undef _
8677
8678   if (unformat (input, "%d", &tmp))
8679     {
8680       next_index = tmp;
8681       goto out;
8682     }
8683
8684   return 0;
8685
8686 out:
8687   *miss_next_indexp = next_index;
8688   return 1;
8689 }
8690
8691 #define foreach_acl_next                        \
8692 _(deny, DENY)
8693
8694 uword
8695 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8696 {
8697   u32 *miss_next_indexp = va_arg (*args, u32 *);
8698   u32 next_index = 0;
8699   u32 tmp;
8700
8701 #define _(n,N) \
8702   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8703   foreach_acl_next;
8704 #undef _
8705
8706   if (unformat (input, "permit"))
8707     {
8708       next_index = ~0;
8709       goto out;
8710     }
8711   else if (unformat (input, "%d", &tmp))
8712     {
8713       next_index = tmp;
8714       goto out;
8715     }
8716
8717   return 0;
8718
8719 out:
8720   *miss_next_indexp = next_index;
8721   return 1;
8722 }
8723
8724 uword
8725 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8726 {
8727   u32 *r = va_arg (*args, u32 *);
8728
8729   if (unformat (input, "conform-color"))
8730     *r = POLICE_CONFORM;
8731   else if (unformat (input, "exceed-color"))
8732     *r = POLICE_EXCEED;
8733   else
8734     return 0;
8735
8736   return 1;
8737 }
8738
8739 static int
8740 api_classify_add_del_table (vat_main_t * vam)
8741 {
8742   unformat_input_t *i = vam->input;
8743   vl_api_classify_add_del_table_t *mp;
8744
8745   u32 nbuckets = 2;
8746   u32 skip = ~0;
8747   u32 match = ~0;
8748   int is_add = 1;
8749   u32 table_index = ~0;
8750   u32 next_table_index = ~0;
8751   u32 miss_next_index = ~0;
8752   u32 memory_size = 32 << 20;
8753   u8 *mask = 0;
8754   f64 timeout;
8755
8756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8757     {
8758       if (unformat (i, "del"))
8759         is_add = 0;
8760       else if (unformat (i, "buckets %d", &nbuckets))
8761         ;
8762       else if (unformat (i, "memory_size %d", &memory_size))
8763         ;
8764       else if (unformat (i, "skip %d", &skip))
8765         ;
8766       else if (unformat (i, "match %d", &match))
8767         ;
8768       else if (unformat (i, "table %d", &table_index))
8769         ;
8770       else if (unformat (i, "mask %U", unformat_classify_mask,
8771                          &mask, &skip, &match))
8772         ;
8773       else if (unformat (i, "next-table %d", &next_table_index))
8774         ;
8775       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8776                          &miss_next_index))
8777         ;
8778       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8779                          &miss_next_index))
8780         ;
8781       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8782                          &miss_next_index))
8783         ;
8784       else
8785         break;
8786     }
8787
8788   if (is_add && mask == 0)
8789     {
8790       errmsg ("Mask required\n");
8791       return -99;
8792     }
8793
8794   if (is_add && skip == ~0)
8795     {
8796       errmsg ("skip count required\n");
8797       return -99;
8798     }
8799
8800   if (is_add && match == ~0)
8801     {
8802       errmsg ("match count required\n");
8803       return -99;
8804     }
8805
8806   if (!is_add && table_index == ~0)
8807     {
8808       errmsg ("table index required for delete\n");
8809       return -99;
8810     }
8811
8812   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8813
8814   mp->is_add = is_add;
8815   mp->table_index = ntohl (table_index);
8816   mp->nbuckets = ntohl (nbuckets);
8817   mp->memory_size = ntohl (memory_size);
8818   mp->skip_n_vectors = ntohl (skip);
8819   mp->match_n_vectors = ntohl (match);
8820   mp->next_table_index = ntohl (next_table_index);
8821   mp->miss_next_index = ntohl (miss_next_index);
8822   clib_memcpy (mp->mask, mask, vec_len (mask));
8823
8824   vec_free (mask);
8825
8826   S;
8827   W;
8828   /* NOTREACHED */
8829 }
8830
8831 uword
8832 unformat_l4_match (unformat_input_t * input, va_list * args)
8833 {
8834   u8 **matchp = va_arg (*args, u8 **);
8835
8836   u8 *proto_header = 0;
8837   int src_port = 0;
8838   int dst_port = 0;
8839
8840   tcpudp_header_t h;
8841
8842   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8843     {
8844       if (unformat (input, "src_port %d", &src_port))
8845         ;
8846       else if (unformat (input, "dst_port %d", &dst_port))
8847         ;
8848       else
8849         return 0;
8850     }
8851
8852   h.src_port = clib_host_to_net_u16 (src_port);
8853   h.dst_port = clib_host_to_net_u16 (dst_port);
8854   vec_validate (proto_header, sizeof (h) - 1);
8855   memcpy (proto_header, &h, sizeof (h));
8856
8857   *matchp = proto_header;
8858
8859   return 1;
8860 }
8861
8862 uword
8863 unformat_ip4_match (unformat_input_t * input, va_list * args)
8864 {
8865   u8 **matchp = va_arg (*args, u8 **);
8866   u8 *match = 0;
8867   ip4_header_t *ip;
8868   int version = 0;
8869   u32 version_val;
8870   int hdr_length = 0;
8871   u32 hdr_length_val;
8872   int src = 0, dst = 0;
8873   ip4_address_t src_val, dst_val;
8874   int proto = 0;
8875   u32 proto_val;
8876   int tos = 0;
8877   u32 tos_val;
8878   int length = 0;
8879   u32 length_val;
8880   int fragment_id = 0;
8881   u32 fragment_id_val;
8882   int ttl = 0;
8883   int ttl_val;
8884   int checksum = 0;
8885   u32 checksum_val;
8886
8887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8888     {
8889       if (unformat (input, "version %d", &version_val))
8890         version = 1;
8891       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8892         hdr_length = 1;
8893       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8894         src = 1;
8895       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8896         dst = 1;
8897       else if (unformat (input, "proto %d", &proto_val))
8898         proto = 1;
8899       else if (unformat (input, "tos %d", &tos_val))
8900         tos = 1;
8901       else if (unformat (input, "length %d", &length_val))
8902         length = 1;
8903       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8904         fragment_id = 1;
8905       else if (unformat (input, "ttl %d", &ttl_val))
8906         ttl = 1;
8907       else if (unformat (input, "checksum %d", &checksum_val))
8908         checksum = 1;
8909       else
8910         break;
8911     }
8912
8913   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8914       + ttl + checksum == 0)
8915     return 0;
8916
8917   /*
8918    * Aligned because we use the real comparison functions
8919    */
8920   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8921
8922   ip = (ip4_header_t *) match;
8923
8924   /* These are realistically matched in practice */
8925   if (src)
8926     ip->src_address.as_u32 = src_val.as_u32;
8927
8928   if (dst)
8929     ip->dst_address.as_u32 = dst_val.as_u32;
8930
8931   if (proto)
8932     ip->protocol = proto_val;
8933
8934
8935   /* These are not, but they're included for completeness */
8936   if (version)
8937     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8938
8939   if (hdr_length)
8940     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8941
8942   if (tos)
8943     ip->tos = tos_val;
8944
8945   if (length)
8946     ip->length = clib_host_to_net_u16 (length_val);
8947
8948   if (ttl)
8949     ip->ttl = ttl_val;
8950
8951   if (checksum)
8952     ip->checksum = clib_host_to_net_u16 (checksum_val);
8953
8954   *matchp = match;
8955   return 1;
8956 }
8957
8958 uword
8959 unformat_ip6_match (unformat_input_t * input, va_list * args)
8960 {
8961   u8 **matchp = va_arg (*args, u8 **);
8962   u8 *match = 0;
8963   ip6_header_t *ip;
8964   int version = 0;
8965   u32 version_val;
8966   u8 traffic_class = 0;
8967   u32 traffic_class_val = 0;
8968   u8 flow_label = 0;
8969   u8 flow_label_val;
8970   int src = 0, dst = 0;
8971   ip6_address_t src_val, dst_val;
8972   int proto = 0;
8973   u32 proto_val;
8974   int payload_length = 0;
8975   u32 payload_length_val;
8976   int hop_limit = 0;
8977   int hop_limit_val;
8978   u32 ip_version_traffic_class_and_flow_label;
8979
8980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8981     {
8982       if (unformat (input, "version %d", &version_val))
8983         version = 1;
8984       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8985         traffic_class = 1;
8986       else if (unformat (input, "flow_label %d", &flow_label_val))
8987         flow_label = 1;
8988       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8989         src = 1;
8990       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8991         dst = 1;
8992       else if (unformat (input, "proto %d", &proto_val))
8993         proto = 1;
8994       else if (unformat (input, "payload_length %d", &payload_length_val))
8995         payload_length = 1;
8996       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8997         hop_limit = 1;
8998       else
8999         break;
9000     }
9001
9002   if (version + traffic_class + flow_label + src + dst + proto +
9003       payload_length + hop_limit == 0)
9004     return 0;
9005
9006   /*
9007    * Aligned because we use the real comparison functions
9008    */
9009   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9010
9011   ip = (ip6_header_t *) match;
9012
9013   if (src)
9014     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9015
9016   if (dst)
9017     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9018
9019   if (proto)
9020     ip->protocol = proto_val;
9021
9022   ip_version_traffic_class_and_flow_label = 0;
9023
9024   if (version)
9025     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9026
9027   if (traffic_class)
9028     ip_version_traffic_class_and_flow_label |=
9029       (traffic_class_val & 0xFF) << 20;
9030
9031   if (flow_label)
9032     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9033
9034   ip->ip_version_traffic_class_and_flow_label =
9035     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9036
9037   if (payload_length)
9038     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9039
9040   if (hop_limit)
9041     ip->hop_limit = hop_limit_val;
9042
9043   *matchp = match;
9044   return 1;
9045 }
9046
9047 uword
9048 unformat_l3_match (unformat_input_t * input, va_list * args)
9049 {
9050   u8 **matchp = va_arg (*args, u8 **);
9051
9052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9053     {
9054       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9055         return 1;
9056       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9057         return 1;
9058       else
9059         break;
9060     }
9061   return 0;
9062 }
9063
9064 uword
9065 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9066 {
9067   u8 *tagp = va_arg (*args, u8 *);
9068   u32 tag;
9069
9070   if (unformat (input, "%d", &tag))
9071     {
9072       tagp[0] = (tag >> 8) & 0x0F;
9073       tagp[1] = tag & 0xFF;
9074       return 1;
9075     }
9076
9077   return 0;
9078 }
9079
9080 uword
9081 unformat_l2_match (unformat_input_t * input, va_list * args)
9082 {
9083   u8 **matchp = va_arg (*args, u8 **);
9084   u8 *match = 0;
9085   u8 src = 0;
9086   u8 src_val[6];
9087   u8 dst = 0;
9088   u8 dst_val[6];
9089   u8 proto = 0;
9090   u16 proto_val;
9091   u8 tag1 = 0;
9092   u8 tag1_val[2];
9093   u8 tag2 = 0;
9094   u8 tag2_val[2];
9095   int len = 14;
9096   u8 ignore_tag1 = 0;
9097   u8 ignore_tag2 = 0;
9098   u8 cos1 = 0;
9099   u8 cos2 = 0;
9100   u32 cos1_val = 0;
9101   u32 cos2_val = 0;
9102
9103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9104     {
9105       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9106         src = 1;
9107       else
9108         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9109         dst = 1;
9110       else if (unformat (input, "proto %U",
9111                          unformat_ethernet_type_host_byte_order, &proto_val))
9112         proto = 1;
9113       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9114         tag1 = 1;
9115       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9116         tag2 = 1;
9117       else if (unformat (input, "ignore-tag1"))
9118         ignore_tag1 = 1;
9119       else if (unformat (input, "ignore-tag2"))
9120         ignore_tag2 = 1;
9121       else if (unformat (input, "cos1 %d", &cos1_val))
9122         cos1 = 1;
9123       else if (unformat (input, "cos2 %d", &cos2_val))
9124         cos2 = 1;
9125       else
9126         break;
9127     }
9128   if ((src + dst + proto + tag1 + tag2 +
9129        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9130     return 0;
9131
9132   if (tag1 || ignore_tag1 || cos1)
9133     len = 18;
9134   if (tag2 || ignore_tag2 || cos2)
9135     len = 22;
9136
9137   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9138
9139   if (dst)
9140     clib_memcpy (match, dst_val, 6);
9141
9142   if (src)
9143     clib_memcpy (match + 6, src_val, 6);
9144
9145   if (tag2)
9146     {
9147       /* inner vlan tag */
9148       match[19] = tag2_val[1];
9149       match[18] = tag2_val[0];
9150       if (cos2)
9151         match[18] |= (cos2_val & 0x7) << 5;
9152       if (proto)
9153         {
9154           match[21] = proto_val & 0xff;
9155           match[20] = proto_val >> 8;
9156         }
9157       if (tag1)
9158         {
9159           match[15] = tag1_val[1];
9160           match[14] = tag1_val[0];
9161         }
9162       if (cos1)
9163         match[14] |= (cos1_val & 0x7) << 5;
9164       *matchp = match;
9165       return 1;
9166     }
9167   if (tag1)
9168     {
9169       match[15] = tag1_val[1];
9170       match[14] = tag1_val[0];
9171       if (proto)
9172         {
9173           match[17] = proto_val & 0xff;
9174           match[16] = proto_val >> 8;
9175         }
9176       if (cos1)
9177         match[14] |= (cos1_val & 0x7) << 5;
9178
9179       *matchp = match;
9180       return 1;
9181     }
9182   if (cos2)
9183     match[18] |= (cos2_val & 0x7) << 5;
9184   if (cos1)
9185     match[14] |= (cos1_val & 0x7) << 5;
9186   if (proto)
9187     {
9188       match[13] = proto_val & 0xff;
9189       match[12] = proto_val >> 8;
9190     }
9191
9192   *matchp = match;
9193   return 1;
9194 }
9195
9196
9197 uword
9198 unformat_classify_match (unformat_input_t * input, va_list * args)
9199 {
9200   u8 **matchp = va_arg (*args, u8 **);
9201   u32 skip_n_vectors = va_arg (*args, u32);
9202   u32 match_n_vectors = va_arg (*args, u32);
9203
9204   u8 *match = 0;
9205   u8 *l2 = 0;
9206   u8 *l3 = 0;
9207   u8 *l4 = 0;
9208
9209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9210     {
9211       if (unformat (input, "hex %U", unformat_hex_string, &match))
9212         ;
9213       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9214         ;
9215       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9216         ;
9217       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9218         ;
9219       else
9220         break;
9221     }
9222
9223   if (l4 && !l3)
9224     {
9225       vec_free (match);
9226       vec_free (l2);
9227       vec_free (l4);
9228       return 0;
9229     }
9230
9231   if (match || l2 || l3 || l4)
9232     {
9233       if (l2 || l3 || l4)
9234         {
9235           /* "Win a free Ethernet header in every packet" */
9236           if (l2 == 0)
9237             vec_validate_aligned (l2, 13, sizeof (u32x4));
9238           match = l2;
9239           if (vec_len (l3))
9240             {
9241               vec_append_aligned (match, l3, sizeof (u32x4));
9242               vec_free (l3);
9243             }
9244           if (vec_len (l4))
9245             {
9246               vec_append_aligned (match, l4, sizeof (u32x4));
9247               vec_free (l4);
9248             }
9249         }
9250
9251       /* Make sure the vector is big enough even if key is all 0's */
9252       vec_validate_aligned
9253         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9254          sizeof (u32x4));
9255
9256       /* Set size, include skipped vectors */
9257       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9258
9259       *matchp = match;
9260
9261       return 1;
9262     }
9263
9264   return 0;
9265 }
9266
9267 static int
9268 api_classify_add_del_session (vat_main_t * vam)
9269 {
9270   unformat_input_t *i = vam->input;
9271   vl_api_classify_add_del_session_t *mp;
9272   int is_add = 1;
9273   u32 table_index = ~0;
9274   u32 hit_next_index = ~0;
9275   u32 opaque_index = ~0;
9276   u8 *match = 0;
9277   i32 advance = 0;
9278   f64 timeout;
9279   u32 skip_n_vectors = 0;
9280   u32 match_n_vectors = 0;
9281
9282   /*
9283    * Warning: you have to supply skip_n and match_n
9284    * because the API client cant simply look at the classify
9285    * table object.
9286    */
9287
9288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9289     {
9290       if (unformat (i, "del"))
9291         is_add = 0;
9292       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9293                          &hit_next_index))
9294         ;
9295       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9296                          &hit_next_index))
9297         ;
9298       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9299                          &hit_next_index))
9300         ;
9301       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9302         ;
9303       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9304         ;
9305       else if (unformat (i, "opaque-index %d", &opaque_index))
9306         ;
9307       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9308         ;
9309       else if (unformat (i, "match_n %d", &match_n_vectors))
9310         ;
9311       else if (unformat (i, "match %U", unformat_classify_match,
9312                          &match, skip_n_vectors, match_n_vectors))
9313         ;
9314       else if (unformat (i, "advance %d", &advance))
9315         ;
9316       else if (unformat (i, "table-index %d", &table_index))
9317         ;
9318       else
9319         break;
9320     }
9321
9322   if (table_index == ~0)
9323     {
9324       errmsg ("Table index required\n");
9325       return -99;
9326     }
9327
9328   if (is_add && match == 0)
9329     {
9330       errmsg ("Match value required\n");
9331       return -99;
9332     }
9333
9334   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9335
9336   mp->is_add = is_add;
9337   mp->table_index = ntohl (table_index);
9338   mp->hit_next_index = ntohl (hit_next_index);
9339   mp->opaque_index = ntohl (opaque_index);
9340   mp->advance = ntohl (advance);
9341   clib_memcpy (mp->match, match, vec_len (match));
9342   vec_free (match);
9343
9344   S;
9345   W;
9346   /* NOTREACHED */
9347 }
9348
9349 static int
9350 api_classify_set_interface_ip_table (vat_main_t * vam)
9351 {
9352   unformat_input_t *i = vam->input;
9353   vl_api_classify_set_interface_ip_table_t *mp;
9354   f64 timeout;
9355   u32 sw_if_index;
9356   int sw_if_index_set;
9357   u32 table_index = ~0;
9358   u8 is_ipv6 = 0;
9359
9360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9361     {
9362       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9363         sw_if_index_set = 1;
9364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9365         sw_if_index_set = 1;
9366       else if (unformat (i, "table %d", &table_index))
9367         ;
9368       else
9369         {
9370           clib_warning ("parse error '%U'", format_unformat_error, i);
9371           return -99;
9372         }
9373     }
9374
9375   if (sw_if_index_set == 0)
9376     {
9377       errmsg ("missing interface name or sw_if_index\n");
9378       return -99;
9379     }
9380
9381
9382   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9383
9384   mp->sw_if_index = ntohl (sw_if_index);
9385   mp->table_index = ntohl (table_index);
9386   mp->is_ipv6 = is_ipv6;
9387
9388   S;
9389   W;
9390   /* NOTREACHED */
9391   return 0;
9392 }
9393
9394 static int
9395 api_classify_set_interface_l2_tables (vat_main_t * vam)
9396 {
9397   unformat_input_t *i = vam->input;
9398   vl_api_classify_set_interface_l2_tables_t *mp;
9399   f64 timeout;
9400   u32 sw_if_index;
9401   int sw_if_index_set;
9402   u32 ip4_table_index = ~0;
9403   u32 ip6_table_index = ~0;
9404   u32 other_table_index = ~0;
9405   u32 is_input = 1;
9406
9407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9408     {
9409       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9410         sw_if_index_set = 1;
9411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9412         sw_if_index_set = 1;
9413       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9414         ;
9415       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9416         ;
9417       else if (unformat (i, "other-table %d", &other_table_index))
9418         ;
9419       else if (unformat (i, "is-input %d", &is_input))
9420         ;
9421       else
9422         {
9423           clib_warning ("parse error '%U'", format_unformat_error, i);
9424           return -99;
9425         }
9426     }
9427
9428   if (sw_if_index_set == 0)
9429     {
9430       errmsg ("missing interface name or sw_if_index\n");
9431       return -99;
9432     }
9433
9434
9435   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9436
9437   mp->sw_if_index = ntohl (sw_if_index);
9438   mp->ip4_table_index = ntohl (ip4_table_index);
9439   mp->ip6_table_index = ntohl (ip6_table_index);
9440   mp->other_table_index = ntohl (other_table_index);
9441   mp->is_input = (u8) is_input;
9442
9443   S;
9444   W;
9445   /* NOTREACHED */
9446   return 0;
9447 }
9448
9449 static int
9450 api_set_ipfix_exporter (vat_main_t * vam)
9451 {
9452   unformat_input_t *i = vam->input;
9453   vl_api_set_ipfix_exporter_t *mp;
9454   ip4_address_t collector_address;
9455   u8 collector_address_set = 0;
9456   u32 collector_port = ~0;
9457   ip4_address_t src_address;
9458   u8 src_address_set = 0;
9459   u32 vrf_id = ~0;
9460   u32 path_mtu = ~0;
9461   u32 template_interval = ~0;
9462   u8 udp_checksum = 0;
9463   f64 timeout;
9464
9465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9466     {
9467       if (unformat (i, "collector_address %U", unformat_ip4_address,
9468                     &collector_address))
9469         collector_address_set = 1;
9470       else if (unformat (i, "collector_port %d", &collector_port))
9471         ;
9472       else if (unformat (i, "src_address %U", unformat_ip4_address,
9473                          &src_address))
9474         src_address_set = 1;
9475       else if (unformat (i, "vrf_id %d", &vrf_id))
9476         ;
9477       else if (unformat (i, "path_mtu %d", &path_mtu))
9478         ;
9479       else if (unformat (i, "template_interval %d", &template_interval))
9480         ;
9481       else if (unformat (i, "udp_checksum"))
9482         udp_checksum = 1;
9483       else
9484         break;
9485     }
9486
9487   if (collector_address_set == 0)
9488     {
9489       errmsg ("collector_address required\n");
9490       return -99;
9491     }
9492
9493   if (src_address_set == 0)
9494     {
9495       errmsg ("src_address required\n");
9496       return -99;
9497     }
9498
9499   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9500
9501   memcpy (mp->collector_address, collector_address.data,
9502           sizeof (collector_address.data));
9503   mp->collector_port = htons ((u16) collector_port);
9504   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9505   mp->vrf_id = htonl (vrf_id);
9506   mp->path_mtu = htonl (path_mtu);
9507   mp->template_interval = htonl (template_interval);
9508   mp->udp_checksum = udp_checksum;
9509
9510   S;
9511   W;
9512   /* NOTREACHED */
9513 }
9514
9515 static int
9516 api_set_ipfix_classify_stream (vat_main_t * vam)
9517 {
9518   unformat_input_t *i = vam->input;
9519   vl_api_set_ipfix_classify_stream_t *mp;
9520   u32 domain_id = 0;
9521   u32 src_port = UDP_DST_PORT_ipfix;
9522   f64 timeout;
9523
9524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9525     {
9526       if (unformat (i, "domain %d", &domain_id))
9527         ;
9528       else if (unformat (i, "src_port %d", &src_port))
9529         ;
9530       else
9531         {
9532           errmsg ("unknown input `%U'", format_unformat_error, i);
9533           return -99;
9534         }
9535     }
9536
9537   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9538
9539   mp->domain_id = htonl (domain_id);
9540   mp->src_port = htons ((u16) src_port);
9541
9542   S;
9543   W;
9544   /* NOTREACHED */
9545 }
9546
9547 static int
9548 api_ipfix_classify_table_add_del (vat_main_t * vam)
9549 {
9550   unformat_input_t *i = vam->input;
9551   vl_api_ipfix_classify_table_add_del_t *mp;
9552   int is_add = -1;
9553   u32 classify_table_index = ~0;
9554   u8 ip_version = 0;
9555   u8 transport_protocol = 255;
9556   f64 timeout;
9557
9558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9559     {
9560       if (unformat (i, "add"))
9561         is_add = 1;
9562       else if (unformat (i, "del"))
9563         is_add = 0;
9564       else if (unformat (i, "table %d", &classify_table_index))
9565         ;
9566       else if (unformat (i, "ip4"))
9567         ip_version = 4;
9568       else if (unformat (i, "ip6"))
9569         ip_version = 6;
9570       else if (unformat (i, "tcp"))
9571         transport_protocol = 6;
9572       else if (unformat (i, "udp"))
9573         transport_protocol = 17;
9574       else
9575         {
9576           errmsg ("unknown input `%U'", format_unformat_error, i);
9577           return -99;
9578         }
9579     }
9580
9581   if (is_add == -1)
9582     {
9583       errmsg ("expecting: add|del");
9584       return -99;
9585     }
9586   if (classify_table_index == ~0)
9587     {
9588       errmsg ("classifier table not specified");
9589       return -99;
9590     }
9591   if (ip_version == 0)
9592     {
9593       errmsg ("IP version not specified");
9594       return -99;
9595     }
9596
9597   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9598
9599   mp->is_add = is_add;
9600   mp->table_id = htonl (classify_table_index);
9601   mp->ip_version = ip_version;
9602   mp->transport_protocol = transport_protocol;
9603
9604   S;
9605   W;
9606   /* NOTREACHED */
9607 }
9608
9609 static int
9610 api_get_node_index (vat_main_t * vam)
9611 {
9612   unformat_input_t *i = vam->input;
9613   vl_api_get_node_index_t *mp;
9614   f64 timeout;
9615   u8 *name = 0;
9616
9617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9618     {
9619       if (unformat (i, "node %s", &name))
9620         ;
9621       else
9622         break;
9623     }
9624   if (name == 0)
9625     {
9626       errmsg ("node name required\n");
9627       return -99;
9628     }
9629   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9630     {
9631       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9632       return -99;
9633     }
9634
9635   M (GET_NODE_INDEX, get_node_index);
9636   clib_memcpy (mp->node_name, name, vec_len (name));
9637   vec_free (name);
9638
9639   S;
9640   W;
9641   /* NOTREACHED */
9642   return 0;
9643 }
9644
9645 static int
9646 api_get_next_index (vat_main_t * vam)
9647 {
9648   unformat_input_t *i = vam->input;
9649   vl_api_get_next_index_t *mp;
9650   f64 timeout;
9651   u8 *node_name = 0, *next_node_name = 0;
9652
9653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9654     {
9655       if (unformat (i, "node-name %s", &node_name))
9656         ;
9657       else if (unformat (i, "next-node-name %s", &next_node_name))
9658         break;
9659     }
9660
9661   if (node_name == 0)
9662     {
9663       errmsg ("node name required\n");
9664       return -99;
9665     }
9666   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9667     {
9668       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9669       return -99;
9670     }
9671
9672   if (next_node_name == 0)
9673     {
9674       errmsg ("next node name required\n");
9675       return -99;
9676     }
9677   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9678     {
9679       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9680       return -99;
9681     }
9682
9683   M (GET_NEXT_INDEX, get_next_index);
9684   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9685   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9686   vec_free (node_name);
9687   vec_free (next_node_name);
9688
9689   S;
9690   W;
9691   /* NOTREACHED */
9692   return 0;
9693 }
9694
9695 static int
9696 api_add_node_next (vat_main_t * vam)
9697 {
9698   unformat_input_t *i = vam->input;
9699   vl_api_add_node_next_t *mp;
9700   f64 timeout;
9701   u8 *name = 0;
9702   u8 *next = 0;
9703
9704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9705     {
9706       if (unformat (i, "node %s", &name))
9707         ;
9708       else if (unformat (i, "next %s", &next))
9709         ;
9710       else
9711         break;
9712     }
9713   if (name == 0)
9714     {
9715       errmsg ("node name required\n");
9716       return -99;
9717     }
9718   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9719     {
9720       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9721       return -99;
9722     }
9723   if (next == 0)
9724     {
9725       errmsg ("next node required\n");
9726       return -99;
9727     }
9728   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9729     {
9730       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9731       return -99;
9732     }
9733
9734   M (ADD_NODE_NEXT, add_node_next);
9735   clib_memcpy (mp->node_name, name, vec_len (name));
9736   clib_memcpy (mp->next_name, next, vec_len (next));
9737   vec_free (name);
9738   vec_free (next);
9739
9740   S;
9741   W;
9742   /* NOTREACHED */
9743   return 0;
9744 }
9745
9746 static int
9747 api_l2tpv3_create_tunnel (vat_main_t * vam)
9748 {
9749   unformat_input_t *i = vam->input;
9750   ip6_address_t client_address, our_address;
9751   int client_address_set = 0;
9752   int our_address_set = 0;
9753   u32 local_session_id = 0;
9754   u32 remote_session_id = 0;
9755   u64 local_cookie = 0;
9756   u64 remote_cookie = 0;
9757   u8 l2_sublayer_present = 0;
9758   vl_api_l2tpv3_create_tunnel_t *mp;
9759   f64 timeout;
9760
9761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9762     {
9763       if (unformat (i, "client_address %U", unformat_ip6_address,
9764                     &client_address))
9765         client_address_set = 1;
9766       else if (unformat (i, "our_address %U", unformat_ip6_address,
9767                          &our_address))
9768         our_address_set = 1;
9769       else if (unformat (i, "local_session_id %d", &local_session_id))
9770         ;
9771       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9772         ;
9773       else if (unformat (i, "local_cookie %lld", &local_cookie))
9774         ;
9775       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9776         ;
9777       else if (unformat (i, "l2-sublayer-present"))
9778         l2_sublayer_present = 1;
9779       else
9780         break;
9781     }
9782
9783   if (client_address_set == 0)
9784     {
9785       errmsg ("client_address required\n");
9786       return -99;
9787     }
9788
9789   if (our_address_set == 0)
9790     {
9791       errmsg ("our_address required\n");
9792       return -99;
9793     }
9794
9795   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9796
9797   clib_memcpy (mp->client_address, client_address.as_u8,
9798                sizeof (mp->client_address));
9799
9800   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9801
9802   mp->local_session_id = ntohl (local_session_id);
9803   mp->remote_session_id = ntohl (remote_session_id);
9804   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9805   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9806   mp->l2_sublayer_present = l2_sublayer_present;
9807   mp->is_ipv6 = 1;
9808
9809   S;
9810   W;
9811   /* NOTREACHED */
9812   return 0;
9813 }
9814
9815 static int
9816 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9817 {
9818   unformat_input_t *i = vam->input;
9819   u32 sw_if_index;
9820   u8 sw_if_index_set = 0;
9821   u64 new_local_cookie = 0;
9822   u64 new_remote_cookie = 0;
9823   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9824   f64 timeout;
9825
9826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9827     {
9828       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9829         sw_if_index_set = 1;
9830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9831         sw_if_index_set = 1;
9832       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9833         ;
9834       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9835         ;
9836       else
9837         break;
9838     }
9839
9840   if (sw_if_index_set == 0)
9841     {
9842       errmsg ("missing interface name or sw_if_index\n");
9843       return -99;
9844     }
9845
9846   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9847
9848   mp->sw_if_index = ntohl (sw_if_index);
9849   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9850   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9851
9852   S;
9853   W;
9854   /* NOTREACHED */
9855   return 0;
9856 }
9857
9858 static int
9859 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9860 {
9861   unformat_input_t *i = vam->input;
9862   vl_api_l2tpv3_interface_enable_disable_t *mp;
9863   f64 timeout;
9864   u32 sw_if_index;
9865   u8 sw_if_index_set = 0;
9866   u8 enable_disable = 1;
9867
9868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9869     {
9870       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9871         sw_if_index_set = 1;
9872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9873         sw_if_index_set = 1;
9874       else if (unformat (i, "enable"))
9875         enable_disable = 1;
9876       else if (unformat (i, "disable"))
9877         enable_disable = 0;
9878       else
9879         break;
9880     }
9881
9882   if (sw_if_index_set == 0)
9883     {
9884       errmsg ("missing interface name or sw_if_index\n");
9885       return -99;
9886     }
9887
9888   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9889
9890   mp->sw_if_index = ntohl (sw_if_index);
9891   mp->enable_disable = enable_disable;
9892
9893   S;
9894   W;
9895   /* NOTREACHED */
9896   return 0;
9897 }
9898
9899 static int
9900 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9901 {
9902   unformat_input_t *i = vam->input;
9903   vl_api_l2tpv3_set_lookup_key_t *mp;
9904   f64 timeout;
9905   u8 key = ~0;
9906
9907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9908     {
9909       if (unformat (i, "lookup_v6_src"))
9910         key = L2T_LOOKUP_SRC_ADDRESS;
9911       else if (unformat (i, "lookup_v6_dst"))
9912         key = L2T_LOOKUP_DST_ADDRESS;
9913       else if (unformat (i, "lookup_session_id"))
9914         key = L2T_LOOKUP_SESSION_ID;
9915       else
9916         break;
9917     }
9918
9919   if (key == (u8) ~ 0)
9920     {
9921       errmsg ("l2tp session lookup key unset\n");
9922       return -99;
9923     }
9924
9925   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9926
9927   mp->key = key;
9928
9929   S;
9930   W;
9931   /* NOTREACHED */
9932   return 0;
9933 }
9934
9935 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9936   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9937 {
9938   vat_main_t *vam = &vat_main;
9939
9940   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9941            format_ip6_address, mp->our_address,
9942            format_ip6_address, mp->client_address,
9943            clib_net_to_host_u32 (mp->sw_if_index));
9944
9945   fformat (vam->ofp,
9946            "   local cookies %016llx %016llx remote cookie %016llx\n",
9947            clib_net_to_host_u64 (mp->local_cookie[0]),
9948            clib_net_to_host_u64 (mp->local_cookie[1]),
9949            clib_net_to_host_u64 (mp->remote_cookie));
9950
9951   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9952            clib_net_to_host_u32 (mp->local_session_id),
9953            clib_net_to_host_u32 (mp->remote_session_id));
9954
9955   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9956            mp->l2_sublayer_present ? "preset" : "absent");
9957
9958 }
9959
9960 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9961   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9962 {
9963   vat_main_t *vam = &vat_main;
9964   vat_json_node_t *node = NULL;
9965   struct in6_addr addr;
9966
9967   if (VAT_JSON_ARRAY != vam->json_tree.type)
9968     {
9969       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9970       vat_json_init_array (&vam->json_tree);
9971     }
9972   node = vat_json_array_add (&vam->json_tree);
9973
9974   vat_json_init_object (node);
9975
9976   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9977   vat_json_object_add_ip6 (node, "our_address", addr);
9978   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9979   vat_json_object_add_ip6 (node, "client_address", addr);
9980
9981   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9982   vat_json_init_array (lc);
9983   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9984   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9985   vat_json_object_add_uint (node, "remote_cookie",
9986                             clib_net_to_host_u64 (mp->remote_cookie));
9987
9988   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9989   vat_json_object_add_uint (node, "local_session_id",
9990                             clib_net_to_host_u32 (mp->local_session_id));
9991   vat_json_object_add_uint (node, "remote_session_id",
9992                             clib_net_to_host_u32 (mp->remote_session_id));
9993   vat_json_object_add_string_copy (node, "l2_sublayer",
9994                                    mp->l2_sublayer_present ? (u8 *) "present"
9995                                    : (u8 *) "absent");
9996 }
9997
9998 static int
9999 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10000 {
10001   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10002   f64 timeout;
10003
10004   /* Get list of l2tpv3-tunnel interfaces */
10005   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10006   S;
10007
10008   /* Use a control ping for synchronization */
10009   {
10010     vl_api_control_ping_t *mp;
10011     M (CONTROL_PING, control_ping);
10012     S;
10013   }
10014   W;
10015 }
10016
10017
10018 static void vl_api_sw_interface_tap_details_t_handler
10019   (vl_api_sw_interface_tap_details_t * mp)
10020 {
10021   vat_main_t *vam = &vat_main;
10022
10023   fformat (vam->ofp, "%-16s %d\n",
10024            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10025 }
10026
10027 static void vl_api_sw_interface_tap_details_t_handler_json
10028   (vl_api_sw_interface_tap_details_t * mp)
10029 {
10030   vat_main_t *vam = &vat_main;
10031   vat_json_node_t *node = NULL;
10032
10033   if (VAT_JSON_ARRAY != vam->json_tree.type)
10034     {
10035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10036       vat_json_init_array (&vam->json_tree);
10037     }
10038   node = vat_json_array_add (&vam->json_tree);
10039
10040   vat_json_init_object (node);
10041   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10042   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10043 }
10044
10045 static int
10046 api_sw_interface_tap_dump (vat_main_t * vam)
10047 {
10048   vl_api_sw_interface_tap_dump_t *mp;
10049   f64 timeout;
10050
10051   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10052   /* Get list of tap interfaces */
10053   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10054   S;
10055
10056   /* Use a control ping for synchronization */
10057   {
10058     vl_api_control_ping_t *mp;
10059     M (CONTROL_PING, control_ping);
10060     S;
10061   }
10062   W;
10063 }
10064
10065 static uword unformat_vxlan_decap_next
10066   (unformat_input_t * input, va_list * args)
10067 {
10068   u32 *result = va_arg (*args, u32 *);
10069   u32 tmp;
10070
10071   if (unformat (input, "l2"))
10072     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10073   else if (unformat (input, "%d", &tmp))
10074     *result = tmp;
10075   else
10076     return 0;
10077   return 1;
10078 }
10079
10080 static int
10081 api_vxlan_add_del_tunnel (vat_main_t * vam)
10082 {
10083   unformat_input_t *line_input = vam->input;
10084   vl_api_vxlan_add_del_tunnel_t *mp;
10085   f64 timeout;
10086   ip4_address_t src4, dst4;
10087   ip6_address_t src6, dst6;
10088   u8 is_add = 1;
10089   u8 ipv4_set = 0, ipv6_set = 0;
10090   u8 src_set = 0;
10091   u8 dst_set = 0;
10092   u32 encap_vrf_id = 0;
10093   u32 decap_next_index = ~0;
10094   u32 vni = 0;
10095
10096   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10097     {
10098       if (unformat (line_input, "del"))
10099         is_add = 0;
10100       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10101         {
10102           ipv4_set = 1;
10103           src_set = 1;
10104         }
10105       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10106         {
10107           ipv4_set = 1;
10108           dst_set = 1;
10109         }
10110       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10111         {
10112           ipv6_set = 1;
10113           src_set = 1;
10114         }
10115       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10116         {
10117           ipv6_set = 1;
10118           dst_set = 1;
10119         }
10120       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10121         ;
10122       else if (unformat (line_input, "decap-next %U",
10123                          unformat_vxlan_decap_next, &decap_next_index))
10124         ;
10125       else if (unformat (line_input, "vni %d", &vni))
10126         ;
10127       else
10128         {
10129           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10130           return -99;
10131         }
10132     }
10133
10134   if (src_set == 0)
10135     {
10136       errmsg ("tunnel src address not specified\n");
10137       return -99;
10138     }
10139   if (dst_set == 0)
10140     {
10141       errmsg ("tunnel dst address not specified\n");
10142       return -99;
10143     }
10144
10145   if (ipv4_set && ipv6_set)
10146     {
10147       errmsg ("both IPv4 and IPv6 addresses specified");
10148       return -99;
10149     }
10150
10151   if ((vni == 0) || (vni >> 24))
10152     {
10153       errmsg ("vni not specified or out of range\n");
10154       return -99;
10155     }
10156
10157   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10158
10159   if (ipv6_set)
10160     {
10161       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10162       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10163     }
10164   else
10165     {
10166       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10167       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10168     }
10169   mp->encap_vrf_id = ntohl (encap_vrf_id);
10170   mp->decap_next_index = ntohl (decap_next_index);
10171   mp->vni = ntohl (vni);
10172   mp->is_add = is_add;
10173   mp->is_ipv6 = ipv6_set;
10174
10175   S;
10176   W;
10177   /* NOTREACHED */
10178   return 0;
10179 }
10180
10181 static void vl_api_vxlan_tunnel_details_t_handler
10182   (vl_api_vxlan_tunnel_details_t * mp)
10183 {
10184   vat_main_t *vam = &vat_main;
10185
10186   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10187            ntohl (mp->sw_if_index),
10188            format_ip46_address, &(mp->src_address[0]),
10189            IP46_TYPE_ANY,
10190            format_ip46_address, &(mp->dst_address[0]),
10191            IP46_TYPE_ANY,
10192            ntohl (mp->encap_vrf_id),
10193            ntohl (mp->decap_next_index), ntohl (mp->vni));
10194 }
10195
10196 static void vl_api_vxlan_tunnel_details_t_handler_json
10197   (vl_api_vxlan_tunnel_details_t * mp)
10198 {
10199   vat_main_t *vam = &vat_main;
10200   vat_json_node_t *node = NULL;
10201   struct in_addr ip4;
10202   struct in6_addr ip6;
10203
10204   if (VAT_JSON_ARRAY != vam->json_tree.type)
10205     {
10206       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10207       vat_json_init_array (&vam->json_tree);
10208     }
10209   node = vat_json_array_add (&vam->json_tree);
10210
10211   vat_json_init_object (node);
10212   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10213   if (mp->is_ipv6)
10214     {
10215       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10216       vat_json_object_add_ip6 (node, "src_address", ip6);
10217       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10218       vat_json_object_add_ip6 (node, "dst_address", ip6);
10219     }
10220   else
10221     {
10222       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10223       vat_json_object_add_ip4 (node, "src_address", ip4);
10224       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10225       vat_json_object_add_ip4 (node, "dst_address", ip4);
10226     }
10227   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10228   vat_json_object_add_uint (node, "decap_next_index",
10229                             ntohl (mp->decap_next_index));
10230   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10231   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10232 }
10233
10234 static int
10235 api_vxlan_tunnel_dump (vat_main_t * vam)
10236 {
10237   unformat_input_t *i = vam->input;
10238   vl_api_vxlan_tunnel_dump_t *mp;
10239   f64 timeout;
10240   u32 sw_if_index;
10241   u8 sw_if_index_set = 0;
10242
10243   /* Parse args required to build the message */
10244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10245     {
10246       if (unformat (i, "sw_if_index %d", &sw_if_index))
10247         sw_if_index_set = 1;
10248       else
10249         break;
10250     }
10251
10252   if (sw_if_index_set == 0)
10253     {
10254       sw_if_index = ~0;
10255     }
10256
10257   if (!vam->json_output)
10258     {
10259       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10260                "sw_if_index", "src_address", "dst_address",
10261                "encap_vrf_id", "decap_next_index", "vni");
10262     }
10263
10264   /* Get list of vxlan-tunnel interfaces */
10265   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10266
10267   mp->sw_if_index = htonl (sw_if_index);
10268
10269   S;
10270
10271   /* Use a control ping for synchronization */
10272   {
10273     vl_api_control_ping_t *mp;
10274     M (CONTROL_PING, control_ping);
10275     S;
10276   }
10277   W;
10278 }
10279
10280 static int
10281 api_gre_add_del_tunnel (vat_main_t * vam)
10282 {
10283   unformat_input_t *line_input = vam->input;
10284   vl_api_gre_add_del_tunnel_t *mp;
10285   f64 timeout;
10286   ip4_address_t src4, dst4;
10287   u8 is_add = 1;
10288   u8 teb = 0;
10289   u8 src_set = 0;
10290   u8 dst_set = 0;
10291   u32 outer_fib_id = 0;
10292
10293   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10294     {
10295       if (unformat (line_input, "del"))
10296         is_add = 0;
10297       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10298         src_set = 1;
10299       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10300         dst_set = 1;
10301       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10302         ;
10303       else if (unformat (line_input, "teb"))
10304         teb = 1;
10305       else
10306         {
10307           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10308           return -99;
10309         }
10310     }
10311
10312   if (src_set == 0)
10313     {
10314       errmsg ("tunnel src address not specified\n");
10315       return -99;
10316     }
10317   if (dst_set == 0)
10318     {
10319       errmsg ("tunnel dst address not specified\n");
10320       return -99;
10321     }
10322
10323
10324   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10325
10326   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10327   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10328   mp->outer_fib_id = ntohl (outer_fib_id);
10329   mp->is_add = is_add;
10330   mp->teb = teb;
10331
10332   S;
10333   W;
10334   /* NOTREACHED */
10335   return 0;
10336 }
10337
10338 static void vl_api_gre_tunnel_details_t_handler
10339   (vl_api_gre_tunnel_details_t * mp)
10340 {
10341   vat_main_t *vam = &vat_main;
10342
10343   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10344            ntohl (mp->sw_if_index),
10345            format_ip4_address, &mp->src_address,
10346            format_ip4_address, &mp->dst_address,
10347            mp->teb, ntohl (mp->outer_fib_id));
10348 }
10349
10350 static void vl_api_gre_tunnel_details_t_handler_json
10351   (vl_api_gre_tunnel_details_t * mp)
10352 {
10353   vat_main_t *vam = &vat_main;
10354   vat_json_node_t *node = NULL;
10355   struct in_addr ip4;
10356
10357   if (VAT_JSON_ARRAY != vam->json_tree.type)
10358     {
10359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10360       vat_json_init_array (&vam->json_tree);
10361     }
10362   node = vat_json_array_add (&vam->json_tree);
10363
10364   vat_json_init_object (node);
10365   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10366   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10367   vat_json_object_add_ip4 (node, "src_address", ip4);
10368   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10369   vat_json_object_add_ip4 (node, "dst_address", ip4);
10370   vat_json_object_add_uint (node, "teb", mp->teb);
10371   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10372 }
10373
10374 static int
10375 api_gre_tunnel_dump (vat_main_t * vam)
10376 {
10377   unformat_input_t *i = vam->input;
10378   vl_api_gre_tunnel_dump_t *mp;
10379   f64 timeout;
10380   u32 sw_if_index;
10381   u8 sw_if_index_set = 0;
10382
10383   /* Parse args required to build the message */
10384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10385     {
10386       if (unformat (i, "sw_if_index %d", &sw_if_index))
10387         sw_if_index_set = 1;
10388       else
10389         break;
10390     }
10391
10392   if (sw_if_index_set == 0)
10393     {
10394       sw_if_index = ~0;
10395     }
10396
10397   if (!vam->json_output)
10398     {
10399       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10400                "sw_if_index", "src_address", "dst_address", "teb",
10401                "outer_fib_id");
10402     }
10403
10404   /* Get list of gre-tunnel interfaces */
10405   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10406
10407   mp->sw_if_index = htonl (sw_if_index);
10408
10409   S;
10410
10411   /* Use a control ping for synchronization */
10412   {
10413     vl_api_control_ping_t *mp;
10414     M (CONTROL_PING, control_ping);
10415     S;
10416   }
10417   W;
10418 }
10419
10420 static int
10421 api_l2_fib_clear_table (vat_main_t * vam)
10422 {
10423 //  unformat_input_t * i = vam->input;
10424   vl_api_l2_fib_clear_table_t *mp;
10425   f64 timeout;
10426
10427   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10428
10429   S;
10430   W;
10431   /* NOTREACHED */
10432   return 0;
10433 }
10434
10435 static int
10436 api_l2_interface_efp_filter (vat_main_t * vam)
10437 {
10438   unformat_input_t *i = vam->input;
10439   vl_api_l2_interface_efp_filter_t *mp;
10440   f64 timeout;
10441   u32 sw_if_index;
10442   u8 enable = 1;
10443   u8 sw_if_index_set = 0;
10444
10445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10446     {
10447       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10448         sw_if_index_set = 1;
10449       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10450         sw_if_index_set = 1;
10451       else if (unformat (i, "enable"))
10452         enable = 1;
10453       else if (unformat (i, "disable"))
10454         enable = 0;
10455       else
10456         {
10457           clib_warning ("parse error '%U'", format_unformat_error, i);
10458           return -99;
10459         }
10460     }
10461
10462   if (sw_if_index_set == 0)
10463     {
10464       errmsg ("missing sw_if_index\n");
10465       return -99;
10466     }
10467
10468   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10469
10470   mp->sw_if_index = ntohl (sw_if_index);
10471   mp->enable_disable = enable;
10472
10473   S;
10474   W;
10475   /* NOTREACHED */
10476   return 0;
10477 }
10478
10479 #define foreach_vtr_op                          \
10480 _("disable",  L2_VTR_DISABLED)                  \
10481 _("push-1",  L2_VTR_PUSH_1)                     \
10482 _("push-2",  L2_VTR_PUSH_2)                     \
10483 _("pop-1",  L2_VTR_POP_1)                       \
10484 _("pop-2",  L2_VTR_POP_2)                       \
10485 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10486 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10487 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10488 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10489
10490 static int
10491 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10492 {
10493   unformat_input_t *i = vam->input;
10494   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10495   f64 timeout;
10496   u32 sw_if_index;
10497   u8 sw_if_index_set = 0;
10498   u8 vtr_op_set = 0;
10499   u32 vtr_op = 0;
10500   u32 push_dot1q = 1;
10501   u32 tag1 = ~0;
10502   u32 tag2 = ~0;
10503
10504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10505     {
10506       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10507         sw_if_index_set = 1;
10508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10509         sw_if_index_set = 1;
10510       else if (unformat (i, "vtr_op %d", &vtr_op))
10511         vtr_op_set = 1;
10512 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10513       foreach_vtr_op
10514 #undef _
10515         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10516         ;
10517       else if (unformat (i, "tag1 %d", &tag1))
10518         ;
10519       else if (unformat (i, "tag2 %d", &tag2))
10520         ;
10521       else
10522         {
10523           clib_warning ("parse error '%U'", format_unformat_error, i);
10524           return -99;
10525         }
10526     }
10527
10528   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10529     {
10530       errmsg ("missing vtr operation or sw_if_index\n");
10531       return -99;
10532     }
10533
10534   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10535     mp->sw_if_index = ntohl (sw_if_index);
10536   mp->vtr_op = ntohl (vtr_op);
10537   mp->push_dot1q = ntohl (push_dot1q);
10538   mp->tag1 = ntohl (tag1);
10539   mp->tag2 = ntohl (tag2);
10540
10541   S;
10542   W;
10543   /* NOTREACHED */
10544   return 0;
10545 }
10546
10547 static int
10548 api_create_vhost_user_if (vat_main_t * vam)
10549 {
10550   unformat_input_t *i = vam->input;
10551   vl_api_create_vhost_user_if_t *mp;
10552   f64 timeout;
10553   u8 *file_name;
10554   u8 is_server = 0;
10555   u8 file_name_set = 0;
10556   u32 custom_dev_instance = ~0;
10557   u8 hwaddr[6];
10558   u8 use_custom_mac = 0;
10559
10560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10561     {
10562       if (unformat (i, "socket %s", &file_name))
10563         {
10564           file_name_set = 1;
10565         }
10566       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10567         ;
10568       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10569         use_custom_mac = 1;
10570       else if (unformat (i, "server"))
10571         is_server = 1;
10572       else
10573         break;
10574     }
10575
10576   if (file_name_set == 0)
10577     {
10578       errmsg ("missing socket file name\n");
10579       return -99;
10580     }
10581
10582   if (vec_len (file_name) > 255)
10583     {
10584       errmsg ("socket file name too long\n");
10585       return -99;
10586     }
10587   vec_add1 (file_name, 0);
10588
10589   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10590
10591   mp->is_server = is_server;
10592   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10593   vec_free (file_name);
10594   if (custom_dev_instance != ~0)
10595     {
10596       mp->renumber = 1;
10597       mp->custom_dev_instance = ntohl (custom_dev_instance);
10598     }
10599   mp->use_custom_mac = use_custom_mac;
10600   clib_memcpy (mp->mac_address, hwaddr, 6);
10601
10602   S;
10603   W;
10604   /* NOTREACHED */
10605   return 0;
10606 }
10607
10608 static int
10609 api_modify_vhost_user_if (vat_main_t * vam)
10610 {
10611   unformat_input_t *i = vam->input;
10612   vl_api_modify_vhost_user_if_t *mp;
10613   f64 timeout;
10614   u8 *file_name;
10615   u8 is_server = 0;
10616   u8 file_name_set = 0;
10617   u32 custom_dev_instance = ~0;
10618   u8 sw_if_index_set = 0;
10619   u32 sw_if_index = (u32) ~ 0;
10620
10621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10622     {
10623       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10624         sw_if_index_set = 1;
10625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10626         sw_if_index_set = 1;
10627       else if (unformat (i, "socket %s", &file_name))
10628         {
10629           file_name_set = 1;
10630         }
10631       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10632         ;
10633       else if (unformat (i, "server"))
10634         is_server = 1;
10635       else
10636         break;
10637     }
10638
10639   if (sw_if_index_set == 0)
10640     {
10641       errmsg ("missing sw_if_index or interface name\n");
10642       return -99;
10643     }
10644
10645   if (file_name_set == 0)
10646     {
10647       errmsg ("missing socket file name\n");
10648       return -99;
10649     }
10650
10651   if (vec_len (file_name) > 255)
10652     {
10653       errmsg ("socket file name too long\n");
10654       return -99;
10655     }
10656   vec_add1 (file_name, 0);
10657
10658   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10659
10660   mp->sw_if_index = ntohl (sw_if_index);
10661   mp->is_server = is_server;
10662   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10663   vec_free (file_name);
10664   if (custom_dev_instance != ~0)
10665     {
10666       mp->renumber = 1;
10667       mp->custom_dev_instance = ntohl (custom_dev_instance);
10668     }
10669
10670   S;
10671   W;
10672   /* NOTREACHED */
10673   return 0;
10674 }
10675
10676 static int
10677 api_delete_vhost_user_if (vat_main_t * vam)
10678 {
10679   unformat_input_t *i = vam->input;
10680   vl_api_delete_vhost_user_if_t *mp;
10681   f64 timeout;
10682   u32 sw_if_index = ~0;
10683   u8 sw_if_index_set = 0;
10684
10685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10686     {
10687       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10688         sw_if_index_set = 1;
10689       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10690         sw_if_index_set = 1;
10691       else
10692         break;
10693     }
10694
10695   if (sw_if_index_set == 0)
10696     {
10697       errmsg ("missing sw_if_index or interface name\n");
10698       return -99;
10699     }
10700
10701
10702   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10703
10704   mp->sw_if_index = ntohl (sw_if_index);
10705
10706   S;
10707   W;
10708   /* NOTREACHED */
10709   return 0;
10710 }
10711
10712 static void vl_api_sw_interface_vhost_user_details_t_handler
10713   (vl_api_sw_interface_vhost_user_details_t * mp)
10714 {
10715   vat_main_t *vam = &vat_main;
10716
10717   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10718            (char *) mp->interface_name,
10719            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10720            clib_net_to_host_u64 (mp->features), mp->is_server,
10721            ntohl (mp->num_regions), (char *) mp->sock_filename);
10722   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10723 }
10724
10725 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10726   (vl_api_sw_interface_vhost_user_details_t * mp)
10727 {
10728   vat_main_t *vam = &vat_main;
10729   vat_json_node_t *node = NULL;
10730
10731   if (VAT_JSON_ARRAY != vam->json_tree.type)
10732     {
10733       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10734       vat_json_init_array (&vam->json_tree);
10735     }
10736   node = vat_json_array_add (&vam->json_tree);
10737
10738   vat_json_init_object (node);
10739   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10740   vat_json_object_add_string_copy (node, "interface_name",
10741                                    mp->interface_name);
10742   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10743                             ntohl (mp->virtio_net_hdr_sz));
10744   vat_json_object_add_uint (node, "features",
10745                             clib_net_to_host_u64 (mp->features));
10746   vat_json_object_add_uint (node, "is_server", mp->is_server);
10747   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10748   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10749   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10750 }
10751
10752 static int
10753 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10754 {
10755   vl_api_sw_interface_vhost_user_dump_t *mp;
10756   f64 timeout;
10757   fformat (vam->ofp,
10758            "Interface name           idx hdr_sz features server regions filename\n");
10759
10760   /* Get list of vhost-user interfaces */
10761   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10762   S;
10763
10764   /* Use a control ping for synchronization */
10765   {
10766     vl_api_control_ping_t *mp;
10767     M (CONTROL_PING, control_ping);
10768     S;
10769   }
10770   W;
10771 }
10772
10773 static int
10774 api_show_version (vat_main_t * vam)
10775 {
10776   vl_api_show_version_t *mp;
10777   f64 timeout;
10778
10779   M (SHOW_VERSION, show_version);
10780
10781   S;
10782   W;
10783   /* NOTREACHED */
10784   return 0;
10785 }
10786
10787
10788 static int
10789 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10790 {
10791   unformat_input_t *line_input = vam->input;
10792   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10793   f64 timeout;
10794   ip4_address_t local4, remote4;
10795   ip6_address_t local6, remote6;
10796   u8 is_add = 1;
10797   u8 ipv4_set = 0, ipv6_set = 0;
10798   u8 local_set = 0;
10799   u8 remote_set = 0;
10800   u32 encap_vrf_id = 0;
10801   u32 decap_vrf_id = 0;
10802   u8 protocol = ~0;
10803   u32 vni;
10804   u8 vni_set = 0;
10805
10806   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10807     {
10808       if (unformat (line_input, "del"))
10809         is_add = 0;
10810       else if (unformat (line_input, "local %U",
10811                          unformat_ip4_address, &local4))
10812         {
10813           local_set = 1;
10814           ipv4_set = 1;
10815         }
10816       else if (unformat (line_input, "remote %U",
10817                          unformat_ip4_address, &remote4))
10818         {
10819           remote_set = 1;
10820           ipv4_set = 1;
10821         }
10822       else if (unformat (line_input, "local %U",
10823                          unformat_ip6_address, &local6))
10824         {
10825           local_set = 1;
10826           ipv6_set = 1;
10827         }
10828       else if (unformat (line_input, "remote %U",
10829                          unformat_ip6_address, &remote6))
10830         {
10831           remote_set = 1;
10832           ipv6_set = 1;
10833         }
10834       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10835         ;
10836       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10837         ;
10838       else if (unformat (line_input, "vni %d", &vni))
10839         vni_set = 1;
10840       else if (unformat (line_input, "next-ip4"))
10841         protocol = 1;
10842       else if (unformat (line_input, "next-ip6"))
10843         protocol = 2;
10844       else if (unformat (line_input, "next-ethernet"))
10845         protocol = 3;
10846       else if (unformat (line_input, "next-nsh"))
10847         protocol = 4;
10848       else
10849         {
10850           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10851           return -99;
10852         }
10853     }
10854
10855   if (local_set == 0)
10856     {
10857       errmsg ("tunnel local address not specified\n");
10858       return -99;
10859     }
10860   if (remote_set == 0)
10861     {
10862       errmsg ("tunnel remote address not specified\n");
10863       return -99;
10864     }
10865   if (ipv4_set && ipv6_set)
10866     {
10867       errmsg ("both IPv4 and IPv6 addresses specified");
10868       return -99;
10869     }
10870
10871   if (vni_set == 0)
10872     {
10873       errmsg ("vni not specified\n");
10874       return -99;
10875     }
10876
10877   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10878
10879
10880   if (ipv6_set)
10881     {
10882       clib_memcpy (&mp->local, &local6, sizeof (local6));
10883       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10884     }
10885   else
10886     {
10887       clib_memcpy (&mp->local, &local4, sizeof (local4));
10888       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10889     }
10890
10891   mp->encap_vrf_id = ntohl (encap_vrf_id);
10892   mp->decap_vrf_id = ntohl (decap_vrf_id);
10893   mp->protocol = ntohl (protocol);
10894   mp->vni = ntohl (vni);
10895   mp->is_add = is_add;
10896   mp->is_ipv6 = ipv6_set;
10897
10898   S;
10899   W;
10900   /* NOTREACHED */
10901   return 0;
10902 }
10903
10904 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10905   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10906 {
10907   vat_main_t *vam = &vat_main;
10908
10909   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10910            ntohl (mp->sw_if_index),
10911            format_ip46_address, &(mp->local[0]),
10912            format_ip46_address, &(mp->remote[0]),
10913            ntohl (mp->vni),
10914            ntohl (mp->protocol),
10915            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10916 }
10917
10918 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10919   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10920 {
10921   vat_main_t *vam = &vat_main;
10922   vat_json_node_t *node = NULL;
10923   struct in_addr ip4;
10924   struct in6_addr ip6;
10925
10926   if (VAT_JSON_ARRAY != vam->json_tree.type)
10927     {
10928       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10929       vat_json_init_array (&vam->json_tree);
10930     }
10931   node = vat_json_array_add (&vam->json_tree);
10932
10933   vat_json_init_object (node);
10934   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10935   if (mp->is_ipv6)
10936     {
10937       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10938       vat_json_object_add_ip6 (node, "local", ip6);
10939       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10940       vat_json_object_add_ip6 (node, "remote", ip6);
10941     }
10942   else
10943     {
10944       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10945       vat_json_object_add_ip4 (node, "local", ip4);
10946       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10947       vat_json_object_add_ip4 (node, "remote", ip4);
10948     }
10949   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10950   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10951   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10952   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10953   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10954 }
10955
10956 static int
10957 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10958 {
10959   unformat_input_t *i = vam->input;
10960   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10961   f64 timeout;
10962   u32 sw_if_index;
10963   u8 sw_if_index_set = 0;
10964
10965   /* Parse args required to build the message */
10966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10967     {
10968       if (unformat (i, "sw_if_index %d", &sw_if_index))
10969         sw_if_index_set = 1;
10970       else
10971         break;
10972     }
10973
10974   if (sw_if_index_set == 0)
10975     {
10976       sw_if_index = ~0;
10977     }
10978
10979   if (!vam->json_output)
10980     {
10981       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10982                "sw_if_index", "local", "remote", "vni",
10983                "protocol", "encap_vrf_id", "decap_vrf_id");
10984     }
10985
10986   /* Get list of vxlan-tunnel interfaces */
10987   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10988
10989   mp->sw_if_index = htonl (sw_if_index);
10990
10991   S;
10992
10993   /* Use a control ping for synchronization */
10994   {
10995     vl_api_control_ping_t *mp;
10996     M (CONTROL_PING, control_ping);
10997     S;
10998   }
10999   W;
11000 }
11001
11002 u8 *
11003 format_l2_fib_mac_address (u8 * s, va_list * args)
11004 {
11005   u8 *a = va_arg (*args, u8 *);
11006
11007   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11008                  a[2], a[3], a[4], a[5], a[6], a[7]);
11009 }
11010
11011 static void vl_api_l2_fib_table_entry_t_handler
11012   (vl_api_l2_fib_table_entry_t * mp)
11013 {
11014   vat_main_t *vam = &vat_main;
11015
11016   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11017            "       %d       %d     %d\n",
11018            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11019            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11020            mp->bvi_mac);
11021 }
11022
11023 static void vl_api_l2_fib_table_entry_t_handler_json
11024   (vl_api_l2_fib_table_entry_t * mp)
11025 {
11026   vat_main_t *vam = &vat_main;
11027   vat_json_node_t *node = NULL;
11028
11029   if (VAT_JSON_ARRAY != vam->json_tree.type)
11030     {
11031       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11032       vat_json_init_array (&vam->json_tree);
11033     }
11034   node = vat_json_array_add (&vam->json_tree);
11035
11036   vat_json_init_object (node);
11037   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11038   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11039   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11040   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11041   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11042   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11043 }
11044
11045 static int
11046 api_l2_fib_table_dump (vat_main_t * vam)
11047 {
11048   unformat_input_t *i = vam->input;
11049   vl_api_l2_fib_table_dump_t *mp;
11050   f64 timeout;
11051   u32 bd_id;
11052   u8 bd_id_set = 0;
11053
11054   /* Parse args required to build the message */
11055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11056     {
11057       if (unformat (i, "bd_id %d", &bd_id))
11058         bd_id_set = 1;
11059       else
11060         break;
11061     }
11062
11063   if (bd_id_set == 0)
11064     {
11065       errmsg ("missing bridge domain\n");
11066       return -99;
11067     }
11068
11069   fformat (vam->ofp,
11070            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11071
11072   /* Get list of l2 fib entries */
11073   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11074
11075   mp->bd_id = ntohl (bd_id);
11076   S;
11077
11078   /* Use a control ping for synchronization */
11079   {
11080     vl_api_control_ping_t *mp;
11081     M (CONTROL_PING, control_ping);
11082     S;
11083   }
11084   W;
11085 }
11086
11087
11088 static int
11089 api_interface_name_renumber (vat_main_t * vam)
11090 {
11091   unformat_input_t *line_input = vam->input;
11092   vl_api_interface_name_renumber_t *mp;
11093   u32 sw_if_index = ~0;
11094   f64 timeout;
11095   u32 new_show_dev_instance = ~0;
11096
11097   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11098     {
11099       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11100                     &sw_if_index))
11101         ;
11102       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11103         ;
11104       else if (unformat (line_input, "new_show_dev_instance %d",
11105                          &new_show_dev_instance))
11106         ;
11107       else
11108         break;
11109     }
11110
11111   if (sw_if_index == ~0)
11112     {
11113       errmsg ("missing interface name or sw_if_index\n");
11114       return -99;
11115     }
11116
11117   if (new_show_dev_instance == ~0)
11118     {
11119       errmsg ("missing new_show_dev_instance\n");
11120       return -99;
11121     }
11122
11123   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11124
11125   mp->sw_if_index = ntohl (sw_if_index);
11126   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11127
11128   S;
11129   W;
11130 }
11131
11132 static int
11133 api_want_ip4_arp_events (vat_main_t * vam)
11134 {
11135   unformat_input_t *line_input = vam->input;
11136   vl_api_want_ip4_arp_events_t *mp;
11137   f64 timeout;
11138   ip4_address_t address;
11139   int address_set = 0;
11140   u32 enable_disable = 1;
11141
11142   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11143     {
11144       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11145         address_set = 1;
11146       else if (unformat (line_input, "del"))
11147         enable_disable = 0;
11148       else
11149         break;
11150     }
11151
11152   if (address_set == 0)
11153     {
11154       errmsg ("missing addresses\n");
11155       return -99;
11156     }
11157
11158   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11159   mp->enable_disable = enable_disable;
11160   mp->pid = getpid ();
11161   mp->address = address.as_u32;
11162
11163   S;
11164   W;
11165 }
11166
11167 static int
11168 api_want_ip6_nd_events (vat_main_t * vam)
11169 {
11170   unformat_input_t *line_input = vam->input;
11171   vl_api_want_ip6_nd_events_t *mp;
11172   f64 timeout;
11173   ip6_address_t address;
11174   int address_set = 0;
11175   u32 enable_disable = 1;
11176
11177   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11178     {
11179       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11180         address_set = 1;
11181       else if (unformat (line_input, "del"))
11182         enable_disable = 0;
11183       else
11184         break;
11185     }
11186
11187   if (address_set == 0)
11188     {
11189       errmsg ("missing addresses\n");
11190       return -99;
11191     }
11192
11193   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11194   mp->enable_disable = enable_disable;
11195   mp->pid = getpid ();
11196   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11197
11198   S;
11199   W;
11200 }
11201
11202 static int
11203 api_input_acl_set_interface (vat_main_t * vam)
11204 {
11205   unformat_input_t *i = vam->input;
11206   vl_api_input_acl_set_interface_t *mp;
11207   f64 timeout;
11208   u32 sw_if_index;
11209   int sw_if_index_set;
11210   u32 ip4_table_index = ~0;
11211   u32 ip6_table_index = ~0;
11212   u32 l2_table_index = ~0;
11213   u8 is_add = 1;
11214
11215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11216     {
11217       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11218         sw_if_index_set = 1;
11219       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11220         sw_if_index_set = 1;
11221       else if (unformat (i, "del"))
11222         is_add = 0;
11223       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11224         ;
11225       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11226         ;
11227       else if (unformat (i, "l2-table %d", &l2_table_index))
11228         ;
11229       else
11230         {
11231           clib_warning ("parse error '%U'", format_unformat_error, i);
11232           return -99;
11233         }
11234     }
11235
11236   if (sw_if_index_set == 0)
11237     {
11238       errmsg ("missing interface name or sw_if_index\n");
11239       return -99;
11240     }
11241
11242   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11243
11244   mp->sw_if_index = ntohl (sw_if_index);
11245   mp->ip4_table_index = ntohl (ip4_table_index);
11246   mp->ip6_table_index = ntohl (ip6_table_index);
11247   mp->l2_table_index = ntohl (l2_table_index);
11248   mp->is_add = is_add;
11249
11250   S;
11251   W;
11252   /* NOTREACHED */
11253   return 0;
11254 }
11255
11256 static int
11257 api_ip_address_dump (vat_main_t * vam)
11258 {
11259   unformat_input_t *i = vam->input;
11260   vl_api_ip_address_dump_t *mp;
11261   u32 sw_if_index = ~0;
11262   u8 sw_if_index_set = 0;
11263   u8 ipv4_set = 0;
11264   u8 ipv6_set = 0;
11265   f64 timeout;
11266
11267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11268     {
11269       if (unformat (i, "sw_if_index %d", &sw_if_index))
11270         sw_if_index_set = 1;
11271       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11272         sw_if_index_set = 1;
11273       else if (unformat (i, "ipv4"))
11274         ipv4_set = 1;
11275       else if (unformat (i, "ipv6"))
11276         ipv6_set = 1;
11277       else
11278         break;
11279     }
11280
11281   if (ipv4_set && ipv6_set)
11282     {
11283       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11284       return -99;
11285     }
11286
11287   if ((!ipv4_set) && (!ipv6_set))
11288     {
11289       errmsg ("no ipv4 nor ipv6 flag set\n");
11290       return -99;
11291     }
11292
11293   if (sw_if_index_set == 0)
11294     {
11295       errmsg ("missing interface name or sw_if_index\n");
11296       return -99;
11297     }
11298
11299   vam->current_sw_if_index = sw_if_index;
11300   vam->is_ipv6 = ipv6_set;
11301
11302   M (IP_ADDRESS_DUMP, ip_address_dump);
11303   mp->sw_if_index = ntohl (sw_if_index);
11304   mp->is_ipv6 = ipv6_set;
11305   S;
11306
11307   /* Use a control ping for synchronization */
11308   {
11309     vl_api_control_ping_t *mp;
11310     M (CONTROL_PING, control_ping);
11311     S;
11312   }
11313   W;
11314 }
11315
11316 static int
11317 api_ip_dump (vat_main_t * vam)
11318 {
11319   vl_api_ip_dump_t *mp;
11320   unformat_input_t *in = vam->input;
11321   int ipv4_set = 0;
11322   int ipv6_set = 0;
11323   int is_ipv6;
11324   f64 timeout;
11325   int i;
11326
11327   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11328     {
11329       if (unformat (in, "ipv4"))
11330         ipv4_set = 1;
11331       else if (unformat (in, "ipv6"))
11332         ipv6_set = 1;
11333       else
11334         break;
11335     }
11336
11337   if (ipv4_set && ipv6_set)
11338     {
11339       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11340       return -99;
11341     }
11342
11343   if ((!ipv4_set) && (!ipv6_set))
11344     {
11345       errmsg ("no ipv4 nor ipv6 flag set\n");
11346       return -99;
11347     }
11348
11349   is_ipv6 = ipv6_set;
11350   vam->is_ipv6 = is_ipv6;
11351
11352   /* free old data */
11353   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11354     {
11355       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11356     }
11357   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11358
11359   M (IP_DUMP, ip_dump);
11360   mp->is_ipv6 = ipv6_set;
11361   S;
11362
11363   /* Use a control ping for synchronization */
11364   {
11365     vl_api_control_ping_t *mp;
11366     M (CONTROL_PING, control_ping);
11367     S;
11368   }
11369   W;
11370 }
11371
11372 static int
11373 api_ipsec_spd_add_del (vat_main_t * vam)
11374 {
11375 #if DPDK > 0
11376   unformat_input_t *i = vam->input;
11377   vl_api_ipsec_spd_add_del_t *mp;
11378   f64 timeout;
11379   u32 spd_id = ~0;
11380   u8 is_add = 1;
11381
11382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11383     {
11384       if (unformat (i, "spd_id %d", &spd_id))
11385         ;
11386       else if (unformat (i, "del"))
11387         is_add = 0;
11388       else
11389         {
11390           clib_warning ("parse error '%U'", format_unformat_error, i);
11391           return -99;
11392         }
11393     }
11394   if (spd_id == ~0)
11395     {
11396       errmsg ("spd_id must be set\n");
11397       return -99;
11398     }
11399
11400   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11401
11402   mp->spd_id = ntohl (spd_id);
11403   mp->is_add = is_add;
11404
11405   S;
11406   W;
11407   /* NOTREACHED */
11408   return 0;
11409 #else
11410   clib_warning ("unsupported (no dpdk)");
11411   return -99;
11412 #endif
11413 }
11414
11415 static int
11416 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11417 {
11418 #if DPDK > 0
11419   unformat_input_t *i = vam->input;
11420   vl_api_ipsec_interface_add_del_spd_t *mp;
11421   f64 timeout;
11422   u32 sw_if_index;
11423   u8 sw_if_index_set = 0;
11424   u32 spd_id = (u32) ~ 0;
11425   u8 is_add = 1;
11426
11427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11428     {
11429       if (unformat (i, "del"))
11430         is_add = 0;
11431       else if (unformat (i, "spd_id %d", &spd_id))
11432         ;
11433       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11434         sw_if_index_set = 1;
11435       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11436         sw_if_index_set = 1;
11437       else
11438         {
11439           clib_warning ("parse error '%U'", format_unformat_error, i);
11440           return -99;
11441         }
11442
11443     }
11444
11445   if (spd_id == (u32) ~ 0)
11446     {
11447       errmsg ("spd_id must be set\n");
11448       return -99;
11449     }
11450
11451   if (sw_if_index_set == 0)
11452     {
11453       errmsg ("missing interface name or sw_if_index\n");
11454       return -99;
11455     }
11456
11457   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11458
11459   mp->spd_id = ntohl (spd_id);
11460   mp->sw_if_index = ntohl (sw_if_index);
11461   mp->is_add = is_add;
11462
11463   S;
11464   W;
11465   /* NOTREACHED */
11466   return 0;
11467 #else
11468   clib_warning ("unsupported (no dpdk)");
11469   return -99;
11470 #endif
11471 }
11472
11473 static int
11474 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11475 {
11476 #if DPDK > 0
11477   unformat_input_t *i = vam->input;
11478   vl_api_ipsec_spd_add_del_entry_t *mp;
11479   f64 timeout;
11480   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11481   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11482   i32 priority = 0;
11483   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11484   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11485   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11486   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11487
11488   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11489   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11490   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11491   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11492   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11493   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11494
11495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11496     {
11497       if (unformat (i, "del"))
11498         is_add = 0;
11499       if (unformat (i, "outbound"))
11500         is_outbound = 1;
11501       if (unformat (i, "inbound"))
11502         is_outbound = 0;
11503       else if (unformat (i, "spd_id %d", &spd_id))
11504         ;
11505       else if (unformat (i, "sa_id %d", &sa_id))
11506         ;
11507       else if (unformat (i, "priority %d", &priority))
11508         ;
11509       else if (unformat (i, "protocol %d", &protocol))
11510         ;
11511       else if (unformat (i, "lport_start %d", &lport_start))
11512         ;
11513       else if (unformat (i, "lport_stop %d", &lport_stop))
11514         ;
11515       else if (unformat (i, "rport_start %d", &rport_start))
11516         ;
11517       else if (unformat (i, "rport_stop %d", &rport_stop))
11518         ;
11519       else
11520         if (unformat
11521             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11522         {
11523           is_ipv6 = 0;
11524           is_ip_any = 0;
11525         }
11526       else
11527         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11528         {
11529           is_ipv6 = 0;
11530           is_ip_any = 0;
11531         }
11532       else
11533         if (unformat
11534             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11535         {
11536           is_ipv6 = 0;
11537           is_ip_any = 0;
11538         }
11539       else
11540         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11541         {
11542           is_ipv6 = 0;
11543           is_ip_any = 0;
11544         }
11545       else
11546         if (unformat
11547             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11548         {
11549           is_ipv6 = 1;
11550           is_ip_any = 0;
11551         }
11552       else
11553         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11554         {
11555           is_ipv6 = 1;
11556           is_ip_any = 0;
11557         }
11558       else
11559         if (unformat
11560             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11561         {
11562           is_ipv6 = 1;
11563           is_ip_any = 0;
11564         }
11565       else
11566         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11567         {
11568           is_ipv6 = 1;
11569           is_ip_any = 0;
11570         }
11571       else
11572         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11573         {
11574           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11575             {
11576               clib_warning ("unsupported action: 'resolve'");
11577               return -99;
11578             }
11579         }
11580       else
11581         {
11582           clib_warning ("parse error '%U'", format_unformat_error, i);
11583           return -99;
11584         }
11585
11586     }
11587
11588   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11589
11590   mp->spd_id = ntohl (spd_id);
11591   mp->priority = ntohl (priority);
11592   mp->is_outbound = is_outbound;
11593
11594   mp->is_ipv6 = is_ipv6;
11595   if (is_ipv6 || is_ip_any)
11596     {
11597       clib_memcpy (mp->remote_address_start, &raddr6_start,
11598                    sizeof (ip6_address_t));
11599       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11600                    sizeof (ip6_address_t));
11601       clib_memcpy (mp->local_address_start, &laddr6_start,
11602                    sizeof (ip6_address_t));
11603       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11604                    sizeof (ip6_address_t));
11605     }
11606   else
11607     {
11608       clib_memcpy (mp->remote_address_start, &raddr4_start,
11609                    sizeof (ip4_address_t));
11610       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11611                    sizeof (ip4_address_t));
11612       clib_memcpy (mp->local_address_start, &laddr4_start,
11613                    sizeof (ip4_address_t));
11614       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11615                    sizeof (ip4_address_t));
11616     }
11617   mp->protocol = (u8) protocol;
11618   mp->local_port_start = ntohs ((u16) lport_start);
11619   mp->local_port_stop = ntohs ((u16) lport_stop);
11620   mp->remote_port_start = ntohs ((u16) rport_start);
11621   mp->remote_port_stop = ntohs ((u16) rport_stop);
11622   mp->policy = (u8) policy;
11623   mp->sa_id = ntohl (sa_id);
11624   mp->is_add = is_add;
11625   mp->is_ip_any = is_ip_any;
11626   S;
11627   W;
11628   /* NOTREACHED */
11629   return 0;
11630 #else
11631   clib_warning ("unsupported (no dpdk)");
11632   return -99;
11633 #endif
11634 }
11635
11636 static int
11637 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11638 {
11639 #if DPDK > 0
11640   unformat_input_t *i = vam->input;
11641   vl_api_ipsec_sad_add_del_entry_t *mp;
11642   f64 timeout;
11643   u32 sad_id = 0, spi = 0;
11644   u8 *ck = 0, *ik = 0;
11645   u8 is_add = 1;
11646
11647   u8 protocol = IPSEC_PROTOCOL_AH;
11648   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11649   u32 crypto_alg = 0, integ_alg = 0;
11650   ip4_address_t tun_src4;
11651   ip4_address_t tun_dst4;
11652   ip6_address_t tun_src6;
11653   ip6_address_t tun_dst6;
11654
11655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11656     {
11657       if (unformat (i, "del"))
11658         is_add = 0;
11659       else if (unformat (i, "sad_id %d", &sad_id))
11660         ;
11661       else if (unformat (i, "spi %d", &spi))
11662         ;
11663       else if (unformat (i, "esp"))
11664         protocol = IPSEC_PROTOCOL_ESP;
11665       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11666         {
11667           is_tunnel = 1;
11668           is_tunnel_ipv6 = 0;
11669         }
11670       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11671         {
11672           is_tunnel = 1;
11673           is_tunnel_ipv6 = 0;
11674         }
11675       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11676         {
11677           is_tunnel = 1;
11678           is_tunnel_ipv6 = 1;
11679         }
11680       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11681         {
11682           is_tunnel = 1;
11683           is_tunnel_ipv6 = 1;
11684         }
11685       else
11686         if (unformat
11687             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11688         {
11689           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11690               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11691             {
11692               clib_warning ("unsupported crypto-alg: '%U'",
11693                             format_ipsec_crypto_alg, crypto_alg);
11694               return -99;
11695             }
11696         }
11697       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11698         ;
11699       else
11700         if (unformat
11701             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11702         {
11703           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11704               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11705             {
11706               clib_warning ("unsupported integ-alg: '%U'",
11707                             format_ipsec_integ_alg, integ_alg);
11708               return -99;
11709             }
11710         }
11711       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11712         ;
11713       else
11714         {
11715           clib_warning ("parse error '%U'", format_unformat_error, i);
11716           return -99;
11717         }
11718
11719     }
11720
11721   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11722
11723   mp->sad_id = ntohl (sad_id);
11724   mp->is_add = is_add;
11725   mp->protocol = protocol;
11726   mp->spi = ntohl (spi);
11727   mp->is_tunnel = is_tunnel;
11728   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11729   mp->crypto_algorithm = crypto_alg;
11730   mp->integrity_algorithm = integ_alg;
11731   mp->crypto_key_length = vec_len (ck);
11732   mp->integrity_key_length = vec_len (ik);
11733
11734   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11735     mp->crypto_key_length = sizeof (mp->crypto_key);
11736
11737   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11738     mp->integrity_key_length = sizeof (mp->integrity_key);
11739
11740   if (ck)
11741     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11742   if (ik)
11743     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11744
11745   if (is_tunnel)
11746     {
11747       if (is_tunnel_ipv6)
11748         {
11749           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11750                        sizeof (ip6_address_t));
11751           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11752                        sizeof (ip6_address_t));
11753         }
11754       else
11755         {
11756           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11757                        sizeof (ip4_address_t));
11758           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11759                        sizeof (ip4_address_t));
11760         }
11761     }
11762
11763   S;
11764   W;
11765   /* NOTREACHED */
11766   return 0;
11767 #else
11768   clib_warning ("unsupported (no dpdk)");
11769   return -99;
11770 #endif
11771 }
11772
11773 static int
11774 api_ipsec_sa_set_key (vat_main_t * vam)
11775 {
11776 #if DPDK > 0
11777   unformat_input_t *i = vam->input;
11778   vl_api_ipsec_sa_set_key_t *mp;
11779   f64 timeout;
11780   u32 sa_id;
11781   u8 *ck = 0, *ik = 0;
11782
11783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11784     {
11785       if (unformat (i, "sa_id %d", &sa_id))
11786         ;
11787       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11788         ;
11789       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11790         ;
11791       else
11792         {
11793           clib_warning ("parse error '%U'", format_unformat_error, i);
11794           return -99;
11795         }
11796     }
11797
11798   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11799
11800   mp->sa_id = ntohl (sa_id);
11801   mp->crypto_key_length = vec_len (ck);
11802   mp->integrity_key_length = vec_len (ik);
11803
11804   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11805     mp->crypto_key_length = sizeof (mp->crypto_key);
11806
11807   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11808     mp->integrity_key_length = sizeof (mp->integrity_key);
11809
11810   if (ck)
11811     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11812   if (ik)
11813     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11814
11815   S;
11816   W;
11817   /* NOTREACHED */
11818   return 0;
11819 #else
11820   clib_warning ("unsupported (no dpdk)");
11821   return -99;
11822 #endif
11823 }
11824
11825 static int
11826 api_ikev2_profile_add_del (vat_main_t * vam)
11827 {
11828 #if DPDK > 0
11829   unformat_input_t *i = vam->input;
11830   vl_api_ikev2_profile_add_del_t *mp;
11831   f64 timeout;
11832   u8 is_add = 1;
11833   u8 *name = 0;
11834
11835   const char *valid_chars = "a-zA-Z0-9_";
11836
11837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11838     {
11839       if (unformat (i, "del"))
11840         is_add = 0;
11841       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11842         vec_add1 (name, 0);
11843       else
11844         {
11845           errmsg ("parse error '%U'", format_unformat_error, i);
11846           return -99;
11847         }
11848     }
11849
11850   if (!vec_len (name))
11851     {
11852       errmsg ("profile name must be specified");
11853       return -99;
11854     }
11855
11856   if (vec_len (name) > 64)
11857     {
11858       errmsg ("profile name too long");
11859       return -99;
11860     }
11861
11862   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11863
11864   clib_memcpy (mp->name, name, vec_len (name));
11865   mp->is_add = is_add;
11866   vec_free (name);
11867
11868   S;
11869   W;
11870   /* NOTREACHED */
11871   return 0;
11872 #else
11873   clib_warning ("unsupported (no dpdk)");
11874   return -99;
11875 #endif
11876 }
11877
11878 static int
11879 api_ikev2_profile_set_auth (vat_main_t * vam)
11880 {
11881 #if DPDK > 0
11882   unformat_input_t *i = vam->input;
11883   vl_api_ikev2_profile_set_auth_t *mp;
11884   f64 timeout;
11885   u8 *name = 0;
11886   u8 *data = 0;
11887   u32 auth_method = 0;
11888   u8 is_hex = 0;
11889
11890   const char *valid_chars = "a-zA-Z0-9_";
11891
11892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11893     {
11894       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11895         vec_add1 (name, 0);
11896       else if (unformat (i, "auth_method %U",
11897                          unformat_ikev2_auth_method, &auth_method))
11898         ;
11899       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11900         is_hex = 1;
11901       else if (unformat (i, "auth_data %v", &data))
11902         ;
11903       else
11904         {
11905           errmsg ("parse error '%U'", format_unformat_error, i);
11906           return -99;
11907         }
11908     }
11909
11910   if (!vec_len (name))
11911     {
11912       errmsg ("profile name must be specified");
11913       return -99;
11914     }
11915
11916   if (vec_len (name) > 64)
11917     {
11918       errmsg ("profile name too long");
11919       return -99;
11920     }
11921
11922   if (!vec_len (data))
11923     {
11924       errmsg ("auth_data must be specified");
11925       return -99;
11926     }
11927
11928   if (!auth_method)
11929     {
11930       errmsg ("auth_method must be specified");
11931       return -99;
11932     }
11933
11934   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11935
11936   mp->is_hex = is_hex;
11937   mp->auth_method = (u8) auth_method;
11938   mp->data_len = vec_len (data);
11939   clib_memcpy (mp->name, name, vec_len (name));
11940   clib_memcpy (mp->data, data, vec_len (data));
11941   vec_free (name);
11942   vec_free (data);
11943
11944   S;
11945   W;
11946   /* NOTREACHED */
11947   return 0;
11948 #else
11949   clib_warning ("unsupported (no dpdk)");
11950   return -99;
11951 #endif
11952 }
11953
11954 static int
11955 api_ikev2_profile_set_id (vat_main_t * vam)
11956 {
11957 #if DPDK > 0
11958   unformat_input_t *i = vam->input;
11959   vl_api_ikev2_profile_set_id_t *mp;
11960   f64 timeout;
11961   u8 *name = 0;
11962   u8 *data = 0;
11963   u8 is_local = 0;
11964   u32 id_type = 0;
11965   ip4_address_t ip4;
11966
11967   const char *valid_chars = "a-zA-Z0-9_";
11968
11969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11970     {
11971       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11972         vec_add1 (name, 0);
11973       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11974         ;
11975       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11976         {
11977           data = vec_new (u8, 4);
11978           clib_memcpy (data, ip4.as_u8, 4);
11979         }
11980       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11981         ;
11982       else if (unformat (i, "id_data %v", &data))
11983         ;
11984       else if (unformat (i, "local"))
11985         is_local = 1;
11986       else if (unformat (i, "remote"))
11987         is_local = 0;
11988       else
11989         {
11990           errmsg ("parse error '%U'", format_unformat_error, i);
11991           return -99;
11992         }
11993     }
11994
11995   if (!vec_len (name))
11996     {
11997       errmsg ("profile name must be specified");
11998       return -99;
11999     }
12000
12001   if (vec_len (name) > 64)
12002     {
12003       errmsg ("profile name too long");
12004       return -99;
12005     }
12006
12007   if (!vec_len (data))
12008     {
12009       errmsg ("id_data must be specified");
12010       return -99;
12011     }
12012
12013   if (!id_type)
12014     {
12015       errmsg ("id_type must be specified");
12016       return -99;
12017     }
12018
12019   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12020
12021   mp->is_local = is_local;
12022   mp->id_type = (u8) id_type;
12023   mp->data_len = vec_len (data);
12024   clib_memcpy (mp->name, name, vec_len (name));
12025   clib_memcpy (mp->data, data, vec_len (data));
12026   vec_free (name);
12027   vec_free (data);
12028
12029   S;
12030   W;
12031   /* NOTREACHED */
12032   return 0;
12033 #else
12034   clib_warning ("unsupported (no dpdk)");
12035   return -99;
12036 #endif
12037 }
12038
12039 static int
12040 api_ikev2_profile_set_ts (vat_main_t * vam)
12041 {
12042 #if DPDK > 0
12043   unformat_input_t *i = vam->input;
12044   vl_api_ikev2_profile_set_ts_t *mp;
12045   f64 timeout;
12046   u8 *name = 0;
12047   u8 is_local = 0;
12048   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12049   ip4_address_t start_addr, end_addr;
12050
12051   const char *valid_chars = "a-zA-Z0-9_";
12052
12053   start_addr.as_u32 = 0;
12054   end_addr.as_u32 = (u32) ~ 0;
12055
12056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12057     {
12058       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12059         vec_add1 (name, 0);
12060       else if (unformat (i, "protocol %d", &proto))
12061         ;
12062       else if (unformat (i, "start_port %d", &start_port))
12063         ;
12064       else if (unformat (i, "end_port %d", &end_port))
12065         ;
12066       else
12067         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12068         ;
12069       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12070         ;
12071       else if (unformat (i, "local"))
12072         is_local = 1;
12073       else if (unformat (i, "remote"))
12074         is_local = 0;
12075       else
12076         {
12077           errmsg ("parse error '%U'", format_unformat_error, i);
12078           return -99;
12079         }
12080     }
12081
12082   if (!vec_len (name))
12083     {
12084       errmsg ("profile name must be specified");
12085       return -99;
12086     }
12087
12088   if (vec_len (name) > 64)
12089     {
12090       errmsg ("profile name too long");
12091       return -99;
12092     }
12093
12094   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12095
12096   mp->is_local = is_local;
12097   mp->proto = (u8) proto;
12098   mp->start_port = (u16) start_port;
12099   mp->end_port = (u16) end_port;
12100   mp->start_addr = start_addr.as_u32;
12101   mp->end_addr = end_addr.as_u32;
12102   clib_memcpy (mp->name, name, vec_len (name));
12103   vec_free (name);
12104
12105   S;
12106   W;
12107   /* NOTREACHED */
12108   return 0;
12109 #else
12110   clib_warning ("unsupported (no dpdk)");
12111   return -99;
12112 #endif
12113 }
12114
12115 static int
12116 api_ikev2_set_local_key (vat_main_t * vam)
12117 {
12118 #if DPDK > 0
12119   unformat_input_t *i = vam->input;
12120   vl_api_ikev2_set_local_key_t *mp;
12121   f64 timeout;
12122   u8 *file = 0;
12123
12124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12125     {
12126       if (unformat (i, "file %v", &file))
12127         vec_add1 (file, 0);
12128       else
12129         {
12130           errmsg ("parse error '%U'", format_unformat_error, i);
12131           return -99;
12132         }
12133     }
12134
12135   if (!vec_len (file))
12136     {
12137       errmsg ("RSA key file must be specified");
12138       return -99;
12139     }
12140
12141   if (vec_len (file) > 256)
12142     {
12143       errmsg ("file name too long");
12144       return -99;
12145     }
12146
12147   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12148
12149   clib_memcpy (mp->key_file, file, vec_len (file));
12150   vec_free (file);
12151
12152   S;
12153   W;
12154   /* NOTREACHED */
12155   return 0;
12156 #else
12157   clib_warning ("unsupported (no dpdk)");
12158   return -99;
12159 #endif
12160 }
12161
12162 /*
12163  * MAP
12164  */
12165 static int
12166 api_map_add_domain (vat_main_t * vam)
12167 {
12168   unformat_input_t *i = vam->input;
12169   vl_api_map_add_domain_t *mp;
12170   f64 timeout;
12171
12172   ip4_address_t ip4_prefix;
12173   ip6_address_t ip6_prefix;
12174   ip6_address_t ip6_src;
12175   u32 num_m_args = 0;
12176   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12177     0, psid_length = 0;
12178   u8 is_translation = 0;
12179   u32 mtu = 0;
12180   u32 ip6_src_len = 128;
12181
12182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12183     {
12184       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12185                     &ip4_prefix, &ip4_prefix_len))
12186         num_m_args++;
12187       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12188                          &ip6_prefix, &ip6_prefix_len))
12189         num_m_args++;
12190       else
12191         if (unformat
12192             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12193              &ip6_src_len))
12194         num_m_args++;
12195       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12196         num_m_args++;
12197       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12198         num_m_args++;
12199       else if (unformat (i, "psid-offset %d", &psid_offset))
12200         num_m_args++;
12201       else if (unformat (i, "psid-len %d", &psid_length))
12202         num_m_args++;
12203       else if (unformat (i, "mtu %d", &mtu))
12204         num_m_args++;
12205       else if (unformat (i, "map-t"))
12206         is_translation = 1;
12207       else
12208         {
12209           clib_warning ("parse error '%U'", format_unformat_error, i);
12210           return -99;
12211         }
12212     }
12213
12214   if (num_m_args < 3)
12215     {
12216       errmsg ("mandatory argument(s) missing\n");
12217       return -99;
12218     }
12219
12220   /* Construct the API message */
12221   M (MAP_ADD_DOMAIN, map_add_domain);
12222
12223   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12224   mp->ip4_prefix_len = ip4_prefix_len;
12225
12226   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12227   mp->ip6_prefix_len = ip6_prefix_len;
12228
12229   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12230   mp->ip6_src_prefix_len = ip6_src_len;
12231
12232   mp->ea_bits_len = ea_bits_len;
12233   mp->psid_offset = psid_offset;
12234   mp->psid_length = psid_length;
12235   mp->is_translation = is_translation;
12236   mp->mtu = htons (mtu);
12237
12238   /* send it... */
12239   S;
12240
12241   /* Wait for a reply, return good/bad news  */
12242   W;
12243 }
12244
12245 static int
12246 api_map_del_domain (vat_main_t * vam)
12247 {
12248   unformat_input_t *i = vam->input;
12249   vl_api_map_del_domain_t *mp;
12250   f64 timeout;
12251
12252   u32 num_m_args = 0;
12253   u32 index;
12254
12255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12256     {
12257       if (unformat (i, "index %d", &index))
12258         num_m_args++;
12259       else
12260         {
12261           clib_warning ("parse error '%U'", format_unformat_error, i);
12262           return -99;
12263         }
12264     }
12265
12266   if (num_m_args != 1)
12267     {
12268       errmsg ("mandatory argument(s) missing\n");
12269       return -99;
12270     }
12271
12272   /* Construct the API message */
12273   M (MAP_DEL_DOMAIN, map_del_domain);
12274
12275   mp->index = ntohl (index);
12276
12277   /* send it... */
12278   S;
12279
12280   /* Wait for a reply, return good/bad news  */
12281   W;
12282 }
12283
12284 static int
12285 api_map_add_del_rule (vat_main_t * vam)
12286 {
12287   unformat_input_t *i = vam->input;
12288   vl_api_map_add_del_rule_t *mp;
12289   f64 timeout;
12290   u8 is_add = 1;
12291   ip6_address_t ip6_dst;
12292   u32 num_m_args = 0, index, psid = 0;
12293
12294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12295     {
12296       if (unformat (i, "index %d", &index))
12297         num_m_args++;
12298       else if (unformat (i, "psid %d", &psid))
12299         num_m_args++;
12300       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12301         num_m_args++;
12302       else if (unformat (i, "del"))
12303         {
12304           is_add = 0;
12305         }
12306       else
12307         {
12308           clib_warning ("parse error '%U'", format_unformat_error, i);
12309           return -99;
12310         }
12311     }
12312
12313   /* Construct the API message */
12314   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12315
12316   mp->index = ntohl (index);
12317   mp->is_add = is_add;
12318   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12319   mp->psid = ntohs (psid);
12320
12321   /* send it... */
12322   S;
12323
12324   /* Wait for a reply, return good/bad news  */
12325   W;
12326 }
12327
12328 static int
12329 api_map_domain_dump (vat_main_t * vam)
12330 {
12331   vl_api_map_domain_dump_t *mp;
12332   f64 timeout;
12333
12334   /* Construct the API message */
12335   M (MAP_DOMAIN_DUMP, map_domain_dump);
12336
12337   /* send it... */
12338   S;
12339
12340   /* Use a control ping for synchronization */
12341   {
12342     vl_api_control_ping_t *mp;
12343     M (CONTROL_PING, control_ping);
12344     S;
12345   }
12346   W;
12347 }
12348
12349 static int
12350 api_map_rule_dump (vat_main_t * vam)
12351 {
12352   unformat_input_t *i = vam->input;
12353   vl_api_map_rule_dump_t *mp;
12354   f64 timeout;
12355   u32 domain_index = ~0;
12356
12357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12358     {
12359       if (unformat (i, "index %u", &domain_index))
12360         ;
12361       else
12362         break;
12363     }
12364
12365   if (domain_index == ~0)
12366     {
12367       clib_warning ("parse error: domain index expected");
12368       return -99;
12369     }
12370
12371   /* Construct the API message */
12372   M (MAP_RULE_DUMP, map_rule_dump);
12373
12374   mp->domain_index = htonl (domain_index);
12375
12376   /* send it... */
12377   S;
12378
12379   /* Use a control ping for synchronization */
12380   {
12381     vl_api_control_ping_t *mp;
12382     M (CONTROL_PING, control_ping);
12383     S;
12384   }
12385   W;
12386 }
12387
12388 static void vl_api_map_add_domain_reply_t_handler
12389   (vl_api_map_add_domain_reply_t * mp)
12390 {
12391   vat_main_t *vam = &vat_main;
12392   i32 retval = ntohl (mp->retval);
12393
12394   if (vam->async_mode)
12395     {
12396       vam->async_errors += (retval < 0);
12397     }
12398   else
12399     {
12400       vam->retval = retval;
12401       vam->result_ready = 1;
12402     }
12403 }
12404
12405 static void vl_api_map_add_domain_reply_t_handler_json
12406   (vl_api_map_add_domain_reply_t * mp)
12407 {
12408   vat_main_t *vam = &vat_main;
12409   vat_json_node_t node;
12410
12411   vat_json_init_object (&node);
12412   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12413   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12414
12415   vat_json_print (vam->ofp, &node);
12416   vat_json_free (&node);
12417
12418   vam->retval = ntohl (mp->retval);
12419   vam->result_ready = 1;
12420 }
12421
12422 static int
12423 api_get_first_msg_id (vat_main_t * vam)
12424 {
12425   vl_api_get_first_msg_id_t *mp;
12426   f64 timeout;
12427   unformat_input_t *i = vam->input;
12428   u8 *name;
12429   u8 name_set = 0;
12430
12431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12432     {
12433       if (unformat (i, "client %s", &name))
12434         name_set = 1;
12435       else
12436         break;
12437     }
12438
12439   if (name_set == 0)
12440     {
12441       errmsg ("missing client name\n");
12442       return -99;
12443     }
12444   vec_add1 (name, 0);
12445
12446   if (vec_len (name) > 63)
12447     {
12448       errmsg ("client name too long\n");
12449       return -99;
12450     }
12451
12452   M (GET_FIRST_MSG_ID, get_first_msg_id);
12453   clib_memcpy (mp->name, name, vec_len (name));
12454   S;
12455   W;
12456   /* NOTREACHED */
12457   return 0;
12458 }
12459
12460 static int
12461 api_cop_interface_enable_disable (vat_main_t * vam)
12462 {
12463   unformat_input_t *line_input = vam->input;
12464   vl_api_cop_interface_enable_disable_t *mp;
12465   f64 timeout;
12466   u32 sw_if_index = ~0;
12467   u8 enable_disable = 1;
12468
12469   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12470     {
12471       if (unformat (line_input, "disable"))
12472         enable_disable = 0;
12473       if (unformat (line_input, "enable"))
12474         enable_disable = 1;
12475       else if (unformat (line_input, "%U", unformat_sw_if_index,
12476                          vam, &sw_if_index))
12477         ;
12478       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12479         ;
12480       else
12481         break;
12482     }
12483
12484   if (sw_if_index == ~0)
12485     {
12486       errmsg ("missing interface name or sw_if_index\n");
12487       return -99;
12488     }
12489
12490   /* Construct the API message */
12491   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12492   mp->sw_if_index = ntohl (sw_if_index);
12493   mp->enable_disable = enable_disable;
12494
12495   /* send it... */
12496   S;
12497   /* Wait for the reply */
12498   W;
12499 }
12500
12501 static int
12502 api_cop_whitelist_enable_disable (vat_main_t * vam)
12503 {
12504   unformat_input_t *line_input = vam->input;
12505   vl_api_cop_whitelist_enable_disable_t *mp;
12506   f64 timeout;
12507   u32 sw_if_index = ~0;
12508   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12509   u32 fib_id = 0;
12510
12511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12512     {
12513       if (unformat (line_input, "ip4"))
12514         ip4 = 1;
12515       else if (unformat (line_input, "ip6"))
12516         ip6 = 1;
12517       else if (unformat (line_input, "default"))
12518         default_cop = 1;
12519       else if (unformat (line_input, "%U", unformat_sw_if_index,
12520                          vam, &sw_if_index))
12521         ;
12522       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12523         ;
12524       else if (unformat (line_input, "fib-id %d", &fib_id))
12525         ;
12526       else
12527         break;
12528     }
12529
12530   if (sw_if_index == ~0)
12531     {
12532       errmsg ("missing interface name or sw_if_index\n");
12533       return -99;
12534     }
12535
12536   /* Construct the API message */
12537   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12538   mp->sw_if_index = ntohl (sw_if_index);
12539   mp->fib_id = ntohl (fib_id);
12540   mp->ip4 = ip4;
12541   mp->ip6 = ip6;
12542   mp->default_cop = default_cop;
12543
12544   /* send it... */
12545   S;
12546   /* Wait for the reply */
12547   W;
12548 }
12549
12550 static int
12551 api_get_node_graph (vat_main_t * vam)
12552 {
12553   vl_api_get_node_graph_t *mp;
12554   f64 timeout;
12555
12556   M (GET_NODE_GRAPH, get_node_graph);
12557
12558   /* send it... */
12559   S;
12560   /* Wait for the reply */
12561   W;
12562 }
12563
12564 /* *INDENT-OFF* */
12565 /** Used for parsing LISP eids */
12566 typedef CLIB_PACKED(struct{
12567   u8 addr[16];   /**< eid address */
12568   u32 len;       /**< prefix length if IP */
12569   u8 type;      /**< type of eid */
12570 }) lisp_eid_vat_t;
12571 /* *INDENT-ON* */
12572
12573 static uword
12574 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12575 {
12576   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12577
12578   memset (a, 0, sizeof (a[0]));
12579
12580   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12581     {
12582       a->type = 0;              /* ipv4 type */
12583     }
12584   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12585     {
12586       a->type = 1;              /* ipv6 type */
12587     }
12588   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12589     {
12590       a->type = 2;              /* mac type */
12591     }
12592   else
12593     {
12594       return 0;
12595     }
12596
12597   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12598     {
12599       return 0;
12600     }
12601
12602   return 1;
12603 }
12604
12605 static int
12606 lisp_eid_size_vat (u8 type)
12607 {
12608   switch (type)
12609     {
12610     case 0:
12611       return 4;
12612     case 1:
12613       return 16;
12614     case 2:
12615       return 6;
12616     }
12617   return 0;
12618 }
12619
12620 static void
12621 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12622 {
12623   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12624 }
12625
12626 /* *INDENT-OFF* */
12627 /** Used for transferring locators via VPP API */
12628 typedef CLIB_PACKED(struct
12629 {
12630   u32 sw_if_index; /**< locator sw_if_index */
12631   u8 priority; /**< locator priority */
12632   u8 weight;   /**< locator weight */
12633 }) ls_locator_t;
12634 /* *INDENT-ON* */
12635
12636 static int
12637 api_lisp_add_del_locator_set (vat_main_t * vam)
12638 {
12639   unformat_input_t *input = vam->input;
12640   vl_api_lisp_add_del_locator_set_t *mp;
12641   f64 timeout = ~0;
12642   u8 is_add = 1;
12643   u8 *locator_set_name = NULL;
12644   u8 locator_set_name_set = 0;
12645   ls_locator_t locator, *locators = 0;
12646   u32 sw_if_index, priority, weight;
12647   u32 data_len = 0;
12648
12649   /* Parse args required to build the message */
12650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12651     {
12652       if (unformat (input, "del"))
12653         {
12654           is_add = 0;
12655         }
12656       else if (unformat (input, "locator-set %s", &locator_set_name))
12657         {
12658           locator_set_name_set = 1;
12659         }
12660       else if (unformat (input, "sw_if_index %u p %u w %u",
12661                          &sw_if_index, &priority, &weight))
12662         {
12663           locator.sw_if_index = htonl (sw_if_index);
12664           locator.priority = priority;
12665           locator.weight = weight;
12666           vec_add1 (locators, locator);
12667         }
12668       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12669                          vam, &sw_if_index, &priority, &weight))
12670         {
12671           locator.sw_if_index = htonl (sw_if_index);
12672           locator.priority = priority;
12673           locator.weight = weight;
12674           vec_add1 (locators, locator);
12675         }
12676       else
12677         break;
12678     }
12679
12680   if (locator_set_name_set == 0)
12681     {
12682       errmsg ("missing locator-set name");
12683       vec_free (locators);
12684       return -99;
12685     }
12686
12687   if (vec_len (locator_set_name) > 64)
12688     {
12689       errmsg ("locator-set name too long\n");
12690       vec_free (locator_set_name);
12691       vec_free (locators);
12692       return -99;
12693     }
12694   vec_add1 (locator_set_name, 0);
12695
12696   data_len = sizeof (ls_locator_t) * vec_len (locators);
12697
12698   /* Construct the API message */
12699   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12700
12701   mp->is_add = is_add;
12702   clib_memcpy (mp->locator_set_name, locator_set_name,
12703                vec_len (locator_set_name));
12704   vec_free (locator_set_name);
12705
12706   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12707   if (locators)
12708     clib_memcpy (mp->locators, locators, data_len);
12709   vec_free (locators);
12710
12711   /* send it... */
12712   S;
12713
12714   /* Wait for a reply... */
12715   W;
12716
12717   /* NOTREACHED */
12718   return 0;
12719 }
12720
12721 static int
12722 api_lisp_add_del_locator (vat_main_t * vam)
12723 {
12724   unformat_input_t *input = vam->input;
12725   vl_api_lisp_add_del_locator_t *mp;
12726   f64 timeout = ~0;
12727   u32 tmp_if_index = ~0;
12728   u32 sw_if_index = ~0;
12729   u8 sw_if_index_set = 0;
12730   u8 sw_if_index_if_name_set = 0;
12731   u32 priority = ~0;
12732   u8 priority_set = 0;
12733   u32 weight = ~0;
12734   u8 weight_set = 0;
12735   u8 is_add = 1;
12736   u8 *locator_set_name = NULL;
12737   u8 locator_set_name_set = 0;
12738
12739   /* Parse args required to build the message */
12740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12741     {
12742       if (unformat (input, "del"))
12743         {
12744           is_add = 0;
12745         }
12746       else if (unformat (input, "locator-set %s", &locator_set_name))
12747         {
12748           locator_set_name_set = 1;
12749         }
12750       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12751                          &tmp_if_index))
12752         {
12753           sw_if_index_if_name_set = 1;
12754           sw_if_index = tmp_if_index;
12755         }
12756       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12757         {
12758           sw_if_index_set = 1;
12759           sw_if_index = tmp_if_index;
12760         }
12761       else if (unformat (input, "p %d", &priority))
12762         {
12763           priority_set = 1;
12764         }
12765       else if (unformat (input, "w %d", &weight))
12766         {
12767           weight_set = 1;
12768         }
12769       else
12770         break;
12771     }
12772
12773   if (locator_set_name_set == 0)
12774     {
12775       errmsg ("missing locator-set name");
12776       return -99;
12777     }
12778
12779   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12780     {
12781       errmsg ("missing sw_if_index");
12782       vec_free (locator_set_name);
12783       return -99;
12784     }
12785
12786   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12787     {
12788       errmsg ("cannot use both params interface name and sw_if_index");
12789       vec_free (locator_set_name);
12790       return -99;
12791     }
12792
12793   if (priority_set == 0)
12794     {
12795       errmsg ("missing locator-set priority\n");
12796       vec_free (locator_set_name);
12797       return -99;
12798     }
12799
12800   if (weight_set == 0)
12801     {
12802       errmsg ("missing locator-set weight\n");
12803       vec_free (locator_set_name);
12804       return -99;
12805     }
12806
12807   if (vec_len (locator_set_name) > 64)
12808     {
12809       errmsg ("locator-set name too long\n");
12810       vec_free (locator_set_name);
12811       return -99;
12812     }
12813   vec_add1 (locator_set_name, 0);
12814
12815   /* Construct the API message */
12816   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12817
12818   mp->is_add = is_add;
12819   mp->sw_if_index = ntohl (sw_if_index);
12820   mp->priority = priority;
12821   mp->weight = weight;
12822   clib_memcpy (mp->locator_set_name, locator_set_name,
12823                vec_len (locator_set_name));
12824   vec_free (locator_set_name);
12825
12826   /* send it... */
12827   S;
12828
12829   /* Wait for a reply... */
12830   W;
12831
12832   /* NOTREACHED */
12833   return 0;
12834 }
12835
12836 static int
12837 api_lisp_add_del_local_eid (vat_main_t * vam)
12838 {
12839   unformat_input_t *input = vam->input;
12840   vl_api_lisp_add_del_local_eid_t *mp;
12841   f64 timeout = ~0;
12842   u8 is_add = 1;
12843   u8 eid_set = 0;
12844   lisp_eid_vat_t _eid, *eid = &_eid;
12845   u8 *locator_set_name = 0;
12846   u8 locator_set_name_set = 0;
12847   u32 vni = 0;
12848
12849   /* Parse args required to build the message */
12850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12851     {
12852       if (unformat (input, "del"))
12853         {
12854           is_add = 0;
12855         }
12856       else if (unformat (input, "vni %d", &vni))
12857         {
12858           ;
12859         }
12860       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12861         {
12862           eid_set = 1;
12863         }
12864       else if (unformat (input, "locator-set %s", &locator_set_name))
12865         {
12866           locator_set_name_set = 1;
12867         }
12868       else
12869         break;
12870     }
12871
12872   if (locator_set_name_set == 0)
12873     {
12874       errmsg ("missing locator-set name\n");
12875       return -99;
12876     }
12877
12878   if (0 == eid_set)
12879     {
12880       errmsg ("EID address not set!");
12881       vec_free (locator_set_name);
12882       return -99;
12883     }
12884
12885   if (vec_len (locator_set_name) > 64)
12886     {
12887       errmsg ("locator-set name too long\n");
12888       vec_free (locator_set_name);
12889       return -99;
12890     }
12891   vec_add1 (locator_set_name, 0);
12892
12893   /* Construct the API message */
12894   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12895
12896   mp->is_add = is_add;
12897   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12898   mp->eid_type = eid->type;
12899   mp->prefix_len = eid->len;
12900   mp->vni = clib_host_to_net_u32 (vni);
12901   clib_memcpy (mp->locator_set_name, locator_set_name,
12902                vec_len (locator_set_name));
12903
12904   vec_free (locator_set_name);
12905
12906   /* send it... */
12907   S;
12908
12909   /* Wait for a reply... */
12910   W;
12911
12912   /* NOTREACHED */
12913   return 0;
12914 }
12915
12916 /* *INDENT-OFF* */
12917 /** Used for transferring locators via VPP API */
12918 typedef CLIB_PACKED(struct
12919 {
12920   u8 is_ip4; /**< is locator an IPv4 address? */
12921   u8 priority; /**< locator priority */
12922   u8 weight;   /**< locator weight */
12923   u8 addr[16]; /**< IPv4/IPv6 address */
12924 }) rloc_t;
12925 /* *INDENT-ON* */
12926
12927 static int
12928 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12929 {
12930   unformat_input_t *input = vam->input;
12931   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12932   f64 timeout = ~0;
12933   u8 is_add = 1;
12934   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12935   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12936   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12937   u32 action = ~0, p, w;
12938   ip4_address_t rmt_rloc4, lcl_rloc4;
12939   ip6_address_t rmt_rloc6, lcl_rloc6;
12940   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12941
12942   memset (&rloc, 0, sizeof (rloc));
12943
12944   /* Parse args required to build the message */
12945   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12946     {
12947       if (unformat (input, "del"))
12948         {
12949           is_add = 0;
12950         }
12951       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12952         {
12953           rmt_eid_set = 1;
12954         }
12955       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12956         {
12957           lcl_eid_set = 1;
12958         }
12959       else if (unformat (input, "p %d w %d", &p, &w))
12960         {
12961           if (!curr_rloc)
12962             {
12963               errmsg ("No RLOC configured for setting priority/weight!");
12964               return -99;
12965             }
12966           curr_rloc->priority = p;
12967           curr_rloc->weight = w;
12968         }
12969       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12970                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12971         {
12972           rloc.is_ip4 = 1;
12973
12974           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12975           rloc.priority = rloc.weight = 0;
12976           vec_add1 (lcl_locs, rloc);
12977
12978           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12979           vec_add1 (rmt_locs, rloc);
12980           /* priority and weight saved in rmt loc */
12981           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12982         }
12983       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12984                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12985         {
12986           rloc.is_ip4 = 0;
12987           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12988           rloc.priority = rloc.weight = 0;
12989           vec_add1 (lcl_locs, rloc);
12990
12991           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12992           vec_add1 (rmt_locs, rloc);
12993           /* priority and weight saved in rmt loc */
12994           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12995         }
12996       else if (unformat (input, "action %d", &action))
12997         {
12998           ;
12999         }
13000       else
13001         {
13002           clib_warning ("parse error '%U'", format_unformat_error, input);
13003           return -99;
13004         }
13005     }
13006
13007   if (!rmt_eid_set)
13008     {
13009       errmsg ("remote eid addresses not set\n");
13010       return -99;
13011     }
13012
13013   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13014     {
13015       errmsg ("eid types don't match\n");
13016       return -99;
13017     }
13018
13019   if (0 == rmt_locs && (u32) ~ 0 == action)
13020     {
13021       errmsg ("action not set for negative mapping\n");
13022       return -99;
13023     }
13024
13025   /* Construct the API message */
13026   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13027
13028   mp->is_add = is_add;
13029   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13030   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13031   mp->eid_type = rmt_eid->type;
13032   mp->rmt_len = rmt_eid->len;
13033   mp->lcl_len = lcl_eid->len;
13034   mp->action = action;
13035
13036   if (0 != rmt_locs && 0 != lcl_locs)
13037     {
13038       mp->loc_num = vec_len (rmt_locs);
13039       clib_memcpy (mp->lcl_locs, lcl_locs,
13040                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13041       clib_memcpy (mp->rmt_locs, rmt_locs,
13042                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13043     }
13044   vec_free (lcl_locs);
13045   vec_free (rmt_locs);
13046
13047   /* send it... */
13048   S;
13049
13050   /* Wait for a reply... */
13051   W;
13052
13053   /* NOTREACHED */
13054   return 0;
13055 }
13056
13057 static int
13058 api_lisp_add_del_map_resolver (vat_main_t * vam)
13059 {
13060   unformat_input_t *input = vam->input;
13061   vl_api_lisp_add_del_map_resolver_t *mp;
13062   f64 timeout = ~0;
13063   u8 is_add = 1;
13064   u8 ipv4_set = 0;
13065   u8 ipv6_set = 0;
13066   ip4_address_t ipv4;
13067   ip6_address_t ipv6;
13068
13069   /* Parse args required to build the message */
13070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13071     {
13072       if (unformat (input, "del"))
13073         {
13074           is_add = 0;
13075         }
13076       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13077         {
13078           ipv4_set = 1;
13079         }
13080       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13081         {
13082           ipv6_set = 1;
13083         }
13084       else
13085         break;
13086     }
13087
13088   if (ipv4_set && ipv6_set)
13089     {
13090       errmsg ("both eid v4 and v6 addresses set\n");
13091       return -99;
13092     }
13093
13094   if (!ipv4_set && !ipv6_set)
13095     {
13096       errmsg ("eid addresses not set\n");
13097       return -99;
13098     }
13099
13100   /* Construct the API message */
13101   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13102
13103   mp->is_add = is_add;
13104   if (ipv6_set)
13105     {
13106       mp->is_ipv6 = 1;
13107       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13108     }
13109   else
13110     {
13111       mp->is_ipv6 = 0;
13112       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13113     }
13114
13115   /* send it... */
13116   S;
13117
13118   /* Wait for a reply... */
13119   W;
13120
13121   /* NOTREACHED */
13122   return 0;
13123 }
13124
13125 static int
13126 api_lisp_gpe_enable_disable (vat_main_t * vam)
13127 {
13128   unformat_input_t *input = vam->input;
13129   vl_api_lisp_gpe_enable_disable_t *mp;
13130   f64 timeout = ~0;
13131   u8 is_set = 0;
13132   u8 is_en = 1;
13133
13134   /* Parse args required to build the message */
13135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13136     {
13137       if (unformat (input, "enable"))
13138         {
13139           is_set = 1;
13140           is_en = 1;
13141         }
13142       else if (unformat (input, "disable"))
13143         {
13144           is_set = 1;
13145           is_en = 0;
13146         }
13147       else
13148         break;
13149     }
13150
13151   if (is_set == 0)
13152     {
13153       errmsg ("Value not set\n");
13154       return -99;
13155     }
13156
13157   /* Construct the API message */
13158   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13159
13160   mp->is_en = is_en;
13161
13162   /* send it... */
13163   S;
13164
13165   /* Wait for a reply... */
13166   W;
13167
13168   /* NOTREACHED */
13169   return 0;
13170 }
13171
13172 static int
13173 api_lisp_enable_disable (vat_main_t * vam)
13174 {
13175   unformat_input_t *input = vam->input;
13176   vl_api_lisp_enable_disable_t *mp;
13177   f64 timeout = ~0;
13178   u8 is_set = 0;
13179   u8 is_en = 0;
13180
13181   /* Parse args required to build the message */
13182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13183     {
13184       if (unformat (input, "enable"))
13185         {
13186           is_set = 1;
13187           is_en = 1;
13188         }
13189       else if (unformat (input, "disable"))
13190         {
13191           is_set = 1;
13192         }
13193       else
13194         break;
13195     }
13196
13197   if (!is_set)
13198     {
13199       errmsg ("Value not set\n");
13200       return -99;
13201     }
13202
13203   /* Construct the API message */
13204   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13205
13206   mp->is_en = is_en;
13207
13208   /* send it... */
13209   S;
13210
13211   /* Wait for a reply... */
13212   W;
13213
13214   /* NOTREACHED */
13215   return 0;
13216 }
13217
13218 static int
13219 api_show_lisp_map_request_mode (vat_main_t * vam)
13220 {
13221   f64 timeout = ~0;
13222   vl_api_show_lisp_map_request_mode_t *mp;
13223
13224   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13225
13226   /* send */
13227   S;
13228
13229   /* wait for reply */
13230   W;
13231
13232   return 0;
13233 }
13234
13235 static int
13236 api_lisp_map_request_mode (vat_main_t * vam)
13237 {
13238   f64 timeout = ~0;
13239   unformat_input_t *input = vam->input;
13240   vl_api_lisp_map_request_mode_t *mp;
13241   u8 mode = 0;
13242
13243   /* Parse args required to build the message */
13244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13245     {
13246       if (unformat (input, "dst-only"))
13247         mode = 0;
13248       else if (unformat (input, "src-dst"))
13249         mode = 1;
13250       else
13251         {
13252           errmsg ("parse error '%U'", format_unformat_error, input);
13253           return -99;
13254         }
13255     }
13256
13257   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13258
13259   mp->mode = mode;
13260
13261   /* send */
13262   S;
13263
13264   /* wait for reply */
13265   W;
13266
13267   /* notreached */
13268   return 0;
13269 }
13270
13271 /**
13272  * Enable/disable LISP proxy ITR.
13273  *
13274  * @param vam vpp API test context
13275  * @return return code
13276  */
13277 static int
13278 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13279 {
13280   f64 timeout = ~0;
13281   u8 ls_name_set = 0;
13282   unformat_input_t *input = vam->input;
13283   vl_api_lisp_pitr_set_locator_set_t *mp;
13284   u8 is_add = 1;
13285   u8 *ls_name = 0;
13286
13287   /* Parse args required to build the message */
13288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13289     {
13290       if (unformat (input, "del"))
13291         is_add = 0;
13292       else if (unformat (input, "locator-set %s", &ls_name))
13293         ls_name_set = 1;
13294       else
13295         {
13296           errmsg ("parse error '%U'", format_unformat_error, input);
13297           return -99;
13298         }
13299     }
13300
13301   if (!ls_name_set)
13302     {
13303       errmsg ("locator-set name not set!");
13304       return -99;
13305     }
13306
13307   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13308
13309   mp->is_add = is_add;
13310   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13311   vec_free (ls_name);
13312
13313   /* send */
13314   S;
13315
13316   /* wait for reply */
13317   W;
13318
13319   /* notreached */
13320   return 0;
13321 }
13322
13323 static int
13324 api_show_lisp_pitr (vat_main_t * vam)
13325 {
13326   vl_api_show_lisp_pitr_t *mp;
13327   f64 timeout = ~0;
13328
13329   if (!vam->json_output)
13330     {
13331       fformat (vam->ofp, "%=20s\n", "lisp status:");
13332     }
13333
13334   M (SHOW_LISP_PITR, show_lisp_pitr);
13335   /* send it... */
13336   S;
13337
13338   /* Wait for a reply... */
13339   W;
13340
13341   /* NOTREACHED */
13342   return 0;
13343 }
13344
13345 /**
13346  * Add/delete mapping between vni and vrf
13347  */
13348 static int
13349 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13350 {
13351   f64 timeout = ~0;
13352   unformat_input_t *input = vam->input;
13353   vl_api_lisp_eid_table_add_del_map_t *mp;
13354   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13355   u32 vni, vrf, bd_index;
13356
13357   /* Parse args required to build the message */
13358   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13359     {
13360       if (unformat (input, "del"))
13361         is_add = 0;
13362       else if (unformat (input, "vrf %d", &vrf))
13363         vrf_set = 1;
13364       else if (unformat (input, "bd_index %d", &bd_index))
13365         bd_index_set = 1;
13366       else if (unformat (input, "vni %d", &vni))
13367         vni_set = 1;
13368       else
13369         break;
13370     }
13371
13372   if (!vni_set || (!vrf_set && !bd_index_set))
13373     {
13374       errmsg ("missing arguments!");
13375       return -99;
13376     }
13377
13378   if (vrf_set && bd_index_set)
13379     {
13380       errmsg ("error: both vrf and bd entered!");
13381       return -99;
13382     }
13383
13384   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13385
13386   mp->is_add = is_add;
13387   mp->vni = htonl (vni);
13388   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13389   mp->is_l2 = bd_index_set;
13390
13391   /* send */
13392   S;
13393
13394   /* wait for reply */
13395   W;
13396
13397   /* notreached */
13398   return 0;
13399 }
13400
13401 uword
13402 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13403 {
13404   u32 *action = va_arg (*args, u32 *);
13405   u8 *s = 0;
13406
13407   if (unformat (input, "%s", &s))
13408     {
13409       if (!strcmp ((char *) s, "no-action"))
13410         action[0] = 0;
13411       else if (!strcmp ((char *) s, "natively-forward"))
13412         action[0] = 1;
13413       else if (!strcmp ((char *) s, "send-map-request"))
13414         action[0] = 2;
13415       else if (!strcmp ((char *) s, "drop"))
13416         action[0] = 3;
13417       else
13418         {
13419           clib_warning ("invalid action: '%s'", s);
13420           action[0] = 3;
13421         }
13422     }
13423   else
13424     return 0;
13425
13426   vec_free (s);
13427   return 1;
13428 }
13429
13430 /**
13431  * Add/del remote mapping to/from LISP control plane
13432  *
13433  * @param vam vpp API test context
13434  * @return return code
13435  */
13436 static int
13437 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13438 {
13439   unformat_input_t *input = vam->input;
13440   vl_api_lisp_add_del_remote_mapping_t *mp;
13441   f64 timeout = ~0;
13442   u32 vni = 0;
13443   lisp_eid_vat_t _eid, *eid = &_eid;
13444   lisp_eid_vat_t _seid, *seid = &_seid;
13445   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13446   u32 action = ~0, p, w, data_len;
13447   ip4_address_t rloc4;
13448   ip6_address_t rloc6;
13449   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13450
13451   memset (&rloc, 0, sizeof (rloc));
13452
13453   /* Parse args required to build the message */
13454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13455     {
13456       if (unformat (input, "del-all"))
13457         {
13458           del_all = 1;
13459         }
13460       else if (unformat (input, "del"))
13461         {
13462           is_add = 0;
13463         }
13464       else if (unformat (input, "add"))
13465         {
13466           is_add = 1;
13467         }
13468       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13469         {
13470           eid_set = 1;
13471         }
13472       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13473         {
13474           seid_set = 1;
13475         }
13476       else if (unformat (input, "vni %d", &vni))
13477         {
13478           ;
13479         }
13480       else if (unformat (input, "p %d w %d", &p, &w))
13481         {
13482           if (!curr_rloc)
13483             {
13484               errmsg ("No RLOC configured for setting priority/weight!");
13485               return -99;
13486             }
13487           curr_rloc->priority = p;
13488           curr_rloc->weight = w;
13489         }
13490       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13491         {
13492           rloc.is_ip4 = 1;
13493           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13494           vec_add1 (rlocs, rloc);
13495           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13496         }
13497       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13498         {
13499           rloc.is_ip4 = 0;
13500           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13501           vec_add1 (rlocs, rloc);
13502           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13503         }
13504       else if (unformat (input, "action %U",
13505                          unformat_negative_mapping_action, &action))
13506         {
13507           ;
13508         }
13509       else
13510         {
13511           clib_warning ("parse error '%U'", format_unformat_error, input);
13512           return -99;
13513         }
13514     }
13515
13516   if (0 == eid_set)
13517     {
13518       errmsg ("missing params!");
13519       return -99;
13520     }
13521
13522   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13523     {
13524       errmsg ("no action set for negative map-reply!");
13525       return -99;
13526     }
13527
13528   data_len = vec_len (rlocs) * sizeof (rloc_t);
13529
13530   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13531   mp->is_add = is_add;
13532   mp->vni = htonl (vni);
13533   mp->action = (u8) action;
13534   mp->is_src_dst = seid_set;
13535   mp->eid_len = eid->len;
13536   mp->seid_len = seid->len;
13537   mp->del_all = del_all;
13538   mp->eid_type = eid->type;
13539   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13540   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13541
13542   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13543   clib_memcpy (mp->rlocs, rlocs, data_len);
13544   vec_free (rlocs);
13545
13546   /* send it... */
13547   S;
13548
13549   /* Wait for a reply... */
13550   W;
13551
13552   /* NOTREACHED */
13553   return 0;
13554 }
13555
13556 /**
13557  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13558  * forwarding entries in data-plane accordingly.
13559  *
13560  * @param vam vpp API test context
13561  * @return return code
13562  */
13563 static int
13564 api_lisp_add_del_adjacency (vat_main_t * vam)
13565 {
13566   unformat_input_t *input = vam->input;
13567   vl_api_lisp_add_del_adjacency_t *mp;
13568   f64 timeout = ~0;
13569   u32 vni = 0;
13570   ip4_address_t leid4, reid4;
13571   ip6_address_t leid6, reid6;
13572   u8 reid_mac[6] = { 0 };
13573   u8 leid_mac[6] = { 0 };
13574   u8 reid_type, leid_type;
13575   u32 leid_len = 0, reid_len = 0, len;
13576   u8 is_add = 1;
13577
13578   leid_type = reid_type = (u8) ~ 0;
13579
13580   /* Parse args required to build the message */
13581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13582     {
13583       if (unformat (input, "del"))
13584         {
13585           is_add = 0;
13586         }
13587       else if (unformat (input, "add"))
13588         {
13589           is_add = 1;
13590         }
13591       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13592                          &reid4, &len))
13593         {
13594           reid_type = 0;        /* ipv4 */
13595           reid_len = len;
13596         }
13597       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13598                          &reid6, &len))
13599         {
13600           reid_type = 1;        /* ipv6 */
13601           reid_len = len;
13602         }
13603       else if (unformat (input, "reid %U", unformat_ethernet_address,
13604                          reid_mac))
13605         {
13606           reid_type = 2;        /* mac */
13607         }
13608       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13609                          &leid4, &len))
13610         {
13611           leid_type = 0;        /* ipv4 */
13612           leid_len = len;
13613         }
13614       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13615                          &leid6, &len))
13616         {
13617           leid_type = 1;        /* ipv6 */
13618           leid_len = len;
13619         }
13620       else if (unformat (input, "leid %U", unformat_ethernet_address,
13621                          leid_mac))
13622         {
13623           leid_type = 2;        /* mac */
13624         }
13625       else if (unformat (input, "vni %d", &vni))
13626         {
13627           ;
13628         }
13629       else
13630         {
13631           errmsg ("parse error '%U'", format_unformat_error, input);
13632           return -99;
13633         }
13634     }
13635
13636   if ((u8) ~ 0 == reid_type)
13637     {
13638       errmsg ("missing params!");
13639       return -99;
13640     }
13641
13642   if (leid_type != reid_type)
13643     {
13644       errmsg ("remote and local EIDs are of different types!");
13645       return -99;
13646     }
13647
13648   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13649   mp->is_add = is_add;
13650   mp->vni = htonl (vni);
13651   mp->leid_len = leid_len;
13652   mp->reid_len = reid_len;
13653   mp->eid_type = reid_type;
13654
13655   switch (mp->eid_type)
13656     {
13657     case 0:
13658       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13659       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13660       break;
13661     case 1:
13662       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13663       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13664       break;
13665     case 2:
13666       clib_memcpy (mp->leid, leid_mac, 6);
13667       clib_memcpy (mp->reid, reid_mac, 6);
13668       break;
13669     default:
13670       errmsg ("unknown EID type %d!", mp->eid_type);
13671       return 0;
13672     }
13673
13674   /* send it... */
13675   S;
13676
13677   /* Wait for a reply... */
13678   W;
13679
13680   /* NOTREACHED */
13681   return 0;
13682 }
13683
13684 static int
13685 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13686 {
13687   unformat_input_t *input = vam->input;
13688   vl_api_lisp_gpe_add_del_iface_t *mp;
13689   f64 timeout = ~0;
13690   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13691   u32 dp_table = 0, vni = 0;
13692
13693   /* Parse args required to build the message */
13694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13695     {
13696       if (unformat (input, "up"))
13697         {
13698           action_set = 1;
13699           is_add = 1;
13700         }
13701       else if (unformat (input, "down"))
13702         {
13703           action_set = 1;
13704           is_add = 0;
13705         }
13706       else if (unformat (input, "table_id %d", &dp_table))
13707         {
13708           dp_table_set = 1;
13709         }
13710       else if (unformat (input, "bd_id %d", &dp_table))
13711         {
13712           dp_table_set = 1;
13713           is_l2 = 1;
13714         }
13715       else if (unformat (input, "vni %d", &vni))
13716         {
13717           vni_set = 1;
13718         }
13719       else
13720         break;
13721     }
13722
13723   if (action_set == 0)
13724     {
13725       errmsg ("Action not set\n");
13726       return -99;
13727     }
13728   if (dp_table_set == 0 || vni_set == 0)
13729     {
13730       errmsg ("vni and dp_table must be set\n");
13731       return -99;
13732     }
13733
13734   /* Construct the API message */
13735   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13736
13737   mp->is_add = is_add;
13738   mp->dp_table = dp_table;
13739   mp->is_l2 = is_l2;
13740   mp->vni = vni;
13741
13742   /* send it... */
13743   S;
13744
13745   /* Wait for a reply... */
13746   W;
13747
13748   /* NOTREACHED */
13749   return 0;
13750 }
13751
13752 /**
13753  * Add/del map request itr rlocs from LISP control plane and updates
13754  *
13755  * @param vam vpp API test context
13756  * @return return code
13757  */
13758 static int
13759 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13760 {
13761   unformat_input_t *input = vam->input;
13762   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13763   f64 timeout = ~0;
13764   u8 *locator_set_name = 0;
13765   u8 locator_set_name_set = 0;
13766   u8 is_add = 1;
13767
13768   /* Parse args required to build the message */
13769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13770     {
13771       if (unformat (input, "del"))
13772         {
13773           is_add = 0;
13774         }
13775       else if (unformat (input, "%_%v%_", &locator_set_name))
13776         {
13777           locator_set_name_set = 1;
13778         }
13779       else
13780         {
13781           clib_warning ("parse error '%U'", format_unformat_error, input);
13782           return -99;
13783         }
13784     }
13785
13786   if (is_add && !locator_set_name_set)
13787     {
13788       errmsg ("itr-rloc is not set!");
13789       return -99;
13790     }
13791
13792   if (is_add && vec_len (locator_set_name) > 64)
13793     {
13794       errmsg ("itr-rloc locator-set name too long\n");
13795       vec_free (locator_set_name);
13796       return -99;
13797     }
13798
13799   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13800   mp->is_add = is_add;
13801   if (is_add)
13802     {
13803       clib_memcpy (mp->locator_set_name, locator_set_name,
13804                    vec_len (locator_set_name));
13805     }
13806   else
13807     {
13808       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13809     }
13810   vec_free (locator_set_name);
13811
13812   /* send it... */
13813   S;
13814
13815   /* Wait for a reply... */
13816   W;
13817
13818   /* NOTREACHED */
13819   return 0;
13820 }
13821
13822 static int
13823 api_lisp_locator_dump (vat_main_t * vam)
13824 {
13825   unformat_input_t *input = vam->input;
13826   vl_api_lisp_locator_dump_t *mp;
13827   f64 timeout = ~0;
13828   u8 is_index_set = 0, is_name_set = 0;
13829   u8 *ls_name = 0;
13830   u32 ls_index = ~0;
13831
13832   /* Parse args required to build the message */
13833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13834     {
13835       if (unformat (input, "ls_name %_%v%_", &ls_name))
13836         {
13837           is_name_set = 1;
13838         }
13839       else if (unformat (input, "ls_index %d", &ls_index))
13840         {
13841           is_index_set = 1;
13842         }
13843       else
13844         {
13845           errmsg ("parse error '%U'", format_unformat_error, input);
13846           return -99;
13847         }
13848     }
13849
13850   if (!is_index_set && !is_name_set)
13851     {
13852       errmsg ("error: expected one of index or name!\n");
13853       return -99;
13854     }
13855
13856   if (is_index_set && is_name_set)
13857     {
13858       errmsg ("error: only one param expected!\n");
13859       return -99;
13860     }
13861
13862   if (vec_len (ls_name) > 62)
13863     {
13864       errmsg ("error: locator set name too long!");
13865       return -99;
13866     }
13867
13868   if (!vam->json_output)
13869     {
13870       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13871                "weight");
13872     }
13873
13874   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13875   mp->is_index_set = is_index_set;
13876
13877   if (is_index_set)
13878     mp->ls_index = clib_host_to_net_u32 (ls_index);
13879   else
13880     {
13881       vec_add1 (ls_name, 0);
13882       strncpy ((char *) mp->ls_name, (char *) ls_name,
13883                sizeof (mp->ls_name) - 1);
13884     }
13885
13886   /* send it... */
13887   S;
13888
13889   /* Use a control ping for synchronization */
13890   {
13891     vl_api_control_ping_t *mp;
13892     M (CONTROL_PING, control_ping);
13893     S;
13894   }
13895   /* Wait for a reply... */
13896   W;
13897
13898   /* NOTREACHED */
13899   return 0;
13900 }
13901
13902 static int
13903 api_lisp_locator_set_dump (vat_main_t * vam)
13904 {
13905   vl_api_lisp_locator_set_dump_t *mp;
13906   unformat_input_t *input = vam->input;
13907   f64 timeout = ~0;
13908   u8 filter = 0;
13909
13910   /* Parse args required to build the message */
13911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13912     {
13913       if (unformat (input, "local"))
13914         {
13915           filter = 1;
13916         }
13917       else if (unformat (input, "remote"))
13918         {
13919           filter = 2;
13920         }
13921       else
13922         {
13923           errmsg ("parse error '%U'", format_unformat_error, input);
13924           return -99;
13925         }
13926     }
13927
13928   if (!vam->json_output)
13929     {
13930       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13931     }
13932
13933   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13934
13935   mp->filter = filter;
13936
13937   /* send it... */
13938   S;
13939
13940   /* Use a control ping for synchronization */
13941   {
13942     vl_api_control_ping_t *mp;
13943     M (CONTROL_PING, control_ping);
13944     S;
13945   }
13946   /* Wait for a reply... */
13947   W;
13948
13949   /* NOTREACHED */
13950   return 0;
13951 }
13952
13953 static int
13954 api_lisp_eid_table_map_dump (vat_main_t * vam)
13955 {
13956   u8 is_l2 = 0;
13957   u8 mode_set = 0;
13958   unformat_input_t *input = vam->input;
13959   vl_api_lisp_eid_table_map_dump_t *mp;
13960   f64 timeout = ~0;
13961
13962   /* Parse args required to build the message */
13963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13964     {
13965       if (unformat (input, "l2"))
13966         {
13967           is_l2 = 1;
13968           mode_set = 1;
13969         }
13970       else if (unformat (input, "l3"))
13971         {
13972           is_l2 = 0;
13973           mode_set = 1;
13974         }
13975       else
13976         {
13977           errmsg ("parse error '%U'", format_unformat_error, input);
13978           return -99;
13979         }
13980     }
13981
13982   if (!mode_set)
13983     {
13984       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13985       return -99;
13986     }
13987
13988   if (!vam->json_output)
13989     {
13990       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13991     }
13992
13993   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13994   mp->is_l2 = is_l2;
13995
13996   /* send it... */
13997   S;
13998
13999   /* Use a control ping for synchronization */
14000   {
14001     vl_api_control_ping_t *mp;
14002     M (CONTROL_PING, control_ping);
14003     S;
14004   }
14005   /* Wait for a reply... */
14006   W;
14007
14008   /* NOTREACHED */
14009   return 0;
14010 }
14011
14012 static int
14013 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14014 {
14015   vl_api_lisp_eid_table_vni_dump_t *mp;
14016   f64 timeout = ~0;
14017
14018   if (!vam->json_output)
14019     {
14020       fformat (vam->ofp, "VNI\n");
14021     }
14022
14023   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14024
14025   /* send it... */
14026   S;
14027
14028   /* Use a control ping for synchronization */
14029   {
14030     vl_api_control_ping_t *mp;
14031     M (CONTROL_PING, control_ping);
14032     S;
14033   }
14034   /* Wait for a reply... */
14035   W;
14036
14037   /* NOTREACHED */
14038   return 0;
14039 }
14040
14041 static int
14042 api_lisp_eid_table_dump (vat_main_t * vam)
14043 {
14044   unformat_input_t *i = vam->input;
14045   vl_api_lisp_eid_table_dump_t *mp;
14046   f64 timeout = ~0;
14047   struct in_addr ip4;
14048   struct in6_addr ip6;
14049   u8 mac[6];
14050   u8 eid_type = ~0, eid_set = 0;
14051   u32 prefix_length = ~0, t, vni = 0;
14052   u8 filter = 0;
14053
14054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14055     {
14056       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14057         {
14058           eid_set = 1;
14059           eid_type = 0;
14060           prefix_length = t;
14061         }
14062       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14063         {
14064           eid_set = 1;
14065           eid_type = 1;
14066           prefix_length = t;
14067         }
14068       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14069         {
14070           eid_set = 1;
14071           eid_type = 2;
14072         }
14073       else if (unformat (i, "vni %d", &t))
14074         {
14075           vni = t;
14076         }
14077       else if (unformat (i, "local"))
14078         {
14079           filter = 1;
14080         }
14081       else if (unformat (i, "remote"))
14082         {
14083           filter = 2;
14084         }
14085       else
14086         {
14087           errmsg ("parse error '%U'", format_unformat_error, i);
14088           return -99;
14089         }
14090     }
14091
14092   if (!vam->json_output)
14093     {
14094       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14095                "ls_index", "ttl", "authoritative");
14096     }
14097
14098   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14099
14100   mp->filter = filter;
14101   if (eid_set)
14102     {
14103       mp->eid_set = 1;
14104       mp->vni = htonl (vni);
14105       mp->eid_type = eid_type;
14106       switch (eid_type)
14107         {
14108         case 0:
14109           mp->prefix_length = prefix_length;
14110           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14111           break;
14112         case 1:
14113           mp->prefix_length = prefix_length;
14114           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14115           break;
14116         case 2:
14117           clib_memcpy (mp->eid, mac, sizeof (mac));
14118           break;
14119         default:
14120           errmsg ("unknown EID type %d!", eid_type);
14121           return -99;
14122         }
14123     }
14124
14125   /* send it... */
14126   S;
14127
14128   /* Use a control ping for synchronization */
14129   {
14130     vl_api_control_ping_t *mp;
14131     M (CONTROL_PING, control_ping);
14132     S;
14133   }
14134
14135   /* Wait for a reply... */
14136   W;
14137
14138   /* NOTREACHED */
14139   return 0;
14140 }
14141
14142 static int
14143 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14144 {
14145   vl_api_lisp_gpe_tunnel_dump_t *mp;
14146   f64 timeout = ~0;
14147
14148   if (!vam->json_output)
14149     {
14150       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14151                "%=16s%=16s%=16s%=16s%=16s\n",
14152                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14153                "Decap next", "Lisp version", "Flags", "Next protocol",
14154                "ver_res", "res", "iid");
14155     }
14156
14157   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14158   /* send it... */
14159   S;
14160
14161   /* Use a control ping for synchronization */
14162   {
14163     vl_api_control_ping_t *mp;
14164     M (CONTROL_PING, control_ping);
14165     S;
14166   }
14167   /* Wait for a reply... */
14168   W;
14169
14170   /* NOTREACHED */
14171   return 0;
14172 }
14173
14174 static int
14175 api_lisp_adjacencies_get (vat_main_t * vam)
14176 {
14177   unformat_input_t *i = vam->input;
14178   vl_api_lisp_adjacencies_get_t *mp;
14179   f64 timeout = ~0;
14180   u8 vni_set = 0;
14181   u32 vni = ~0;
14182
14183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14184     {
14185       if (unformat (i, "vni %d", &vni))
14186         {
14187           vni_set = 1;
14188         }
14189       else
14190         {
14191           errmsg ("parse error '%U'\n", format_unformat_error, i);
14192           return -99;
14193         }
14194     }
14195
14196   if (!vni_set)
14197     {
14198       errmsg ("vni not set!\n");
14199       return -99;
14200     }
14201
14202   if (!vam->json_output)
14203     {
14204       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14205     }
14206
14207   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14208   mp->vni = clib_host_to_net_u32 (vni);
14209
14210   /* send it... */
14211   S;
14212
14213   /* Wait for a reply... */
14214   W;
14215
14216   /* NOTREACHED */
14217   return 0;
14218 }
14219
14220 static int
14221 api_lisp_map_resolver_dump (vat_main_t * vam)
14222 {
14223   vl_api_lisp_map_resolver_dump_t *mp;
14224   f64 timeout = ~0;
14225
14226   if (!vam->json_output)
14227     {
14228       fformat (vam->ofp, "%=20s\n", "Map resolver");
14229     }
14230
14231   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14232   /* send it... */
14233   S;
14234
14235   /* Use a control ping for synchronization */
14236   {
14237     vl_api_control_ping_t *mp;
14238     M (CONTROL_PING, control_ping);
14239     S;
14240   }
14241   /* Wait for a reply... */
14242   W;
14243
14244   /* NOTREACHED */
14245   return 0;
14246 }
14247
14248 static int
14249 api_show_lisp_status (vat_main_t * vam)
14250 {
14251   vl_api_show_lisp_status_t *mp;
14252   f64 timeout = ~0;
14253
14254   if (!vam->json_output)
14255     {
14256       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14257     }
14258
14259   M (SHOW_LISP_STATUS, show_lisp_status);
14260   /* send it... */
14261   S;
14262   /* Wait for a reply... */
14263   W;
14264
14265   /* NOTREACHED */
14266   return 0;
14267 }
14268
14269 static int
14270 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14271 {
14272   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14273   f64 timeout = ~0;
14274
14275   if (!vam->json_output)
14276     {
14277       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14278     }
14279
14280   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14281   /* send it... */
14282   S;
14283   /* Wait for a reply... */
14284   W;
14285
14286   /* NOTREACHED */
14287   return 0;
14288 }
14289
14290 static int
14291 api_af_packet_create (vat_main_t * vam)
14292 {
14293   unformat_input_t *i = vam->input;
14294   vl_api_af_packet_create_t *mp;
14295   f64 timeout;
14296   u8 *host_if_name = 0;
14297   u8 hw_addr[6];
14298   u8 random_hw_addr = 1;
14299
14300   memset (hw_addr, 0, sizeof (hw_addr));
14301
14302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14303     {
14304       if (unformat (i, "name %s", &host_if_name))
14305         vec_add1 (host_if_name, 0);
14306       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14307         random_hw_addr = 0;
14308       else
14309         break;
14310     }
14311
14312   if (!vec_len (host_if_name))
14313     {
14314       errmsg ("host-interface name must be specified");
14315       return -99;
14316     }
14317
14318   if (vec_len (host_if_name) > 64)
14319     {
14320       errmsg ("host-interface name too long");
14321       return -99;
14322     }
14323
14324   M (AF_PACKET_CREATE, af_packet_create);
14325
14326   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14327   clib_memcpy (mp->hw_addr, hw_addr, 6);
14328   mp->use_random_hw_addr = random_hw_addr;
14329   vec_free (host_if_name);
14330
14331   S;
14332   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14333   /* NOTREACHED */
14334   return 0;
14335 }
14336
14337 static int
14338 api_af_packet_delete (vat_main_t * vam)
14339 {
14340   unformat_input_t *i = vam->input;
14341   vl_api_af_packet_delete_t *mp;
14342   f64 timeout;
14343   u8 *host_if_name = 0;
14344
14345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14346     {
14347       if (unformat (i, "name %s", &host_if_name))
14348         vec_add1 (host_if_name, 0);
14349       else
14350         break;
14351     }
14352
14353   if (!vec_len (host_if_name))
14354     {
14355       errmsg ("host-interface name must be specified");
14356       return -99;
14357     }
14358
14359   if (vec_len (host_if_name) > 64)
14360     {
14361       errmsg ("host-interface name too long");
14362       return -99;
14363     }
14364
14365   M (AF_PACKET_DELETE, af_packet_delete);
14366
14367   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14368   vec_free (host_if_name);
14369
14370   S;
14371   W;
14372   /* NOTREACHED */
14373   return 0;
14374 }
14375
14376 static int
14377 api_policer_add_del (vat_main_t * vam)
14378 {
14379   unformat_input_t *i = vam->input;
14380   vl_api_policer_add_del_t *mp;
14381   f64 timeout;
14382   u8 is_add = 1;
14383   u8 *name = 0;
14384   u32 cir = 0;
14385   u32 eir = 0;
14386   u64 cb = 0;
14387   u64 eb = 0;
14388   u8 rate_type = 0;
14389   u8 round_type = 0;
14390   u8 type = 0;
14391   u8 color_aware = 0;
14392   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14393
14394   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14395   conform_action.dscp = 0;
14396   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14397   exceed_action.dscp = 0;
14398   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14399   violate_action.dscp = 0;
14400
14401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14402     {
14403       if (unformat (i, "del"))
14404         is_add = 0;
14405       else if (unformat (i, "name %s", &name))
14406         vec_add1 (name, 0);
14407       else if (unformat (i, "cir %u", &cir))
14408         ;
14409       else if (unformat (i, "eir %u", &eir))
14410         ;
14411       else if (unformat (i, "cb %u", &cb))
14412         ;
14413       else if (unformat (i, "eb %u", &eb))
14414         ;
14415       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14416                          &rate_type))
14417         ;
14418       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14419                          &round_type))
14420         ;
14421       else if (unformat (i, "type %U", unformat_policer_type, &type))
14422         ;
14423       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14424                          &conform_action))
14425         ;
14426       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14427                          &exceed_action))
14428         ;
14429       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14430                          &violate_action))
14431         ;
14432       else if (unformat (i, "color-aware"))
14433         color_aware = 1;
14434       else
14435         break;
14436     }
14437
14438   if (!vec_len (name))
14439     {
14440       errmsg ("policer name must be specified");
14441       return -99;
14442     }
14443
14444   if (vec_len (name) > 64)
14445     {
14446       errmsg ("policer name too long");
14447       return -99;
14448     }
14449
14450   M (POLICER_ADD_DEL, policer_add_del);
14451
14452   clib_memcpy (mp->name, name, vec_len (name));
14453   vec_free (name);
14454   mp->is_add = is_add;
14455   mp->cir = cir;
14456   mp->eir = eir;
14457   mp->cb = cb;
14458   mp->eb = eb;
14459   mp->rate_type = rate_type;
14460   mp->round_type = round_type;
14461   mp->type = type;
14462   mp->conform_action_type = conform_action.action_type;
14463   mp->conform_dscp = conform_action.dscp;
14464   mp->exceed_action_type = exceed_action.action_type;
14465   mp->exceed_dscp = exceed_action.dscp;
14466   mp->violate_action_type = violate_action.action_type;
14467   mp->violate_dscp = violate_action.dscp;
14468   mp->color_aware = color_aware;
14469
14470   S;
14471   W;
14472   /* NOTREACHED */
14473   return 0;
14474 }
14475
14476 static int
14477 api_policer_dump (vat_main_t * vam)
14478 {
14479   unformat_input_t *i = vam->input;
14480   vl_api_policer_dump_t *mp;
14481   f64 timeout = ~0;
14482   u8 *match_name = 0;
14483   u8 match_name_valid = 0;
14484
14485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14486     {
14487       if (unformat (i, "name %s", &match_name))
14488         {
14489           vec_add1 (match_name, 0);
14490           match_name_valid = 1;
14491         }
14492       else
14493         break;
14494     }
14495
14496   M (POLICER_DUMP, policer_dump);
14497   mp->match_name_valid = match_name_valid;
14498   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14499   vec_free (match_name);
14500   /* send it... */
14501   S;
14502
14503   /* Use a control ping for synchronization */
14504   {
14505     vl_api_control_ping_t *mp;
14506     M (CONTROL_PING, control_ping);
14507     S;
14508   }
14509   /* Wait for a reply... */
14510   W;
14511
14512   /* NOTREACHED */
14513   return 0;
14514 }
14515
14516 static int
14517 api_policer_classify_set_interface (vat_main_t * vam)
14518 {
14519   unformat_input_t *i = vam->input;
14520   vl_api_policer_classify_set_interface_t *mp;
14521   f64 timeout;
14522   u32 sw_if_index;
14523   int sw_if_index_set;
14524   u32 ip4_table_index = ~0;
14525   u32 ip6_table_index = ~0;
14526   u32 l2_table_index = ~0;
14527   u8 is_add = 1;
14528
14529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14530     {
14531       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14532         sw_if_index_set = 1;
14533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14534         sw_if_index_set = 1;
14535       else if (unformat (i, "del"))
14536         is_add = 0;
14537       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14538         ;
14539       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14540         ;
14541       else if (unformat (i, "l2-table %d", &l2_table_index))
14542         ;
14543       else
14544         {
14545           clib_warning ("parse error '%U'", format_unformat_error, i);
14546           return -99;
14547         }
14548     }
14549
14550   if (sw_if_index_set == 0)
14551     {
14552       errmsg ("missing interface name or sw_if_index\n");
14553       return -99;
14554     }
14555
14556   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14557
14558   mp->sw_if_index = ntohl (sw_if_index);
14559   mp->ip4_table_index = ntohl (ip4_table_index);
14560   mp->ip6_table_index = ntohl (ip6_table_index);
14561   mp->l2_table_index = ntohl (l2_table_index);
14562   mp->is_add = is_add;
14563
14564   S;
14565   W;
14566   /* NOTREACHED */
14567   return 0;
14568 }
14569
14570 static int
14571 api_policer_classify_dump (vat_main_t * vam)
14572 {
14573   unformat_input_t *i = vam->input;
14574   vl_api_policer_classify_dump_t *mp;
14575   f64 timeout = ~0;
14576   u8 type = POLICER_CLASSIFY_N_TABLES;
14577
14578   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14579     ;
14580   else
14581     {
14582       errmsg ("classify table type must be specified\n");
14583       return -99;
14584     }
14585
14586   if (!vam->json_output)
14587     {
14588       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14589     }
14590
14591   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14592   mp->type = type;
14593   /* send it... */
14594   S;
14595
14596   /* Use a control ping for synchronization */
14597   {
14598     vl_api_control_ping_t *mp;
14599     M (CONTROL_PING, control_ping);
14600     S;
14601   }
14602   /* Wait for a reply... */
14603   W;
14604
14605   /* NOTREACHED */
14606   return 0;
14607 }
14608
14609 static int
14610 api_netmap_create (vat_main_t * vam)
14611 {
14612   unformat_input_t *i = vam->input;
14613   vl_api_netmap_create_t *mp;
14614   f64 timeout;
14615   u8 *if_name = 0;
14616   u8 hw_addr[6];
14617   u8 random_hw_addr = 1;
14618   u8 is_pipe = 0;
14619   u8 is_master = 0;
14620
14621   memset (hw_addr, 0, sizeof (hw_addr));
14622
14623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14624     {
14625       if (unformat (i, "name %s", &if_name))
14626         vec_add1 (if_name, 0);
14627       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14628         random_hw_addr = 0;
14629       else if (unformat (i, "pipe"))
14630         is_pipe = 1;
14631       else if (unformat (i, "master"))
14632         is_master = 1;
14633       else if (unformat (i, "slave"))
14634         is_master = 0;
14635       else
14636         break;
14637     }
14638
14639   if (!vec_len (if_name))
14640     {
14641       errmsg ("interface name must be specified");
14642       return -99;
14643     }
14644
14645   if (vec_len (if_name) > 64)
14646     {
14647       errmsg ("interface name too long");
14648       return -99;
14649     }
14650
14651   M (NETMAP_CREATE, netmap_create);
14652
14653   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14654   clib_memcpy (mp->hw_addr, hw_addr, 6);
14655   mp->use_random_hw_addr = random_hw_addr;
14656   mp->is_pipe = is_pipe;
14657   mp->is_master = is_master;
14658   vec_free (if_name);
14659
14660   S;
14661   W;
14662   /* NOTREACHED */
14663   return 0;
14664 }
14665
14666 static int
14667 api_netmap_delete (vat_main_t * vam)
14668 {
14669   unformat_input_t *i = vam->input;
14670   vl_api_netmap_delete_t *mp;
14671   f64 timeout;
14672   u8 *if_name = 0;
14673
14674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14675     {
14676       if (unformat (i, "name %s", &if_name))
14677         vec_add1 (if_name, 0);
14678       else
14679         break;
14680     }
14681
14682   if (!vec_len (if_name))
14683     {
14684       errmsg ("interface name must be specified");
14685       return -99;
14686     }
14687
14688   if (vec_len (if_name) > 64)
14689     {
14690       errmsg ("interface name too long");
14691       return -99;
14692     }
14693
14694   M (NETMAP_DELETE, netmap_delete);
14695
14696   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14697   vec_free (if_name);
14698
14699   S;
14700   W;
14701   /* NOTREACHED */
14702   return 0;
14703 }
14704
14705 static void vl_api_mpls_eth_tunnel_details_t_handler
14706   (vl_api_mpls_eth_tunnel_details_t * mp)
14707 {
14708   vat_main_t *vam = &vat_main;
14709   i32 i;
14710   i32 len = ntohl (mp->nlabels);
14711
14712   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14713            ntohl (mp->tunnel_index),
14714            format_ethernet_address, &mp->tunnel_dst_mac,
14715            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14716   for (i = 0; i < len; i++)
14717     {
14718       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14719     }
14720   fformat (vam->ofp, "\n");
14721   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14722            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14723 }
14724
14725 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14726   (vl_api_mpls_eth_tunnel_details_t * mp)
14727 {
14728   vat_main_t *vam = &vat_main;
14729   vat_json_node_t *node = NULL;
14730   struct in_addr ip4;
14731   i32 i;
14732   i32 len = ntohl (mp->nlabels);
14733
14734   if (VAT_JSON_ARRAY != vam->json_tree.type)
14735     {
14736       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14737       vat_json_init_array (&vam->json_tree);
14738     }
14739   node = vat_json_array_add (&vam->json_tree);
14740
14741   vat_json_init_object (node);
14742   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14743   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14744   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14745   vat_json_object_add_uint (node, "inner_fib_index",
14746                             ntohl (mp->inner_fib_index));
14747   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14748   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14749   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14750   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14751   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14752                                    format (0, "%U", format_ethernet_address,
14753                                            &mp->tunnel_dst_mac));
14754   vat_json_object_add_uint (node, "tx_sw_if_index",
14755                             ntohl (mp->tx_sw_if_index));
14756   vat_json_object_add_uint (node, "label_count", len);
14757   for (i = 0; i < len; i++)
14758     {
14759       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14760     }
14761 }
14762
14763 static int
14764 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14765 {
14766   vl_api_mpls_eth_tunnel_dump_t *mp;
14767   f64 timeout;
14768   i32 index = -1;
14769
14770   /* Parse args required to build the message */
14771   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14772     {
14773       if (!unformat (vam->input, "tunnel_index %d", &index))
14774         {
14775           index = -1;
14776           break;
14777         }
14778     }
14779
14780   fformat (vam->ofp, "  tunnel_index %d\n", index);
14781
14782   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14783   mp->tunnel_index = htonl (index);
14784   S;
14785
14786   /* Use a control ping for synchronization */
14787   {
14788     vl_api_control_ping_t *mp;
14789     M (CONTROL_PING, control_ping);
14790     S;
14791   }
14792   W;
14793 }
14794
14795 static void vl_api_mpls_fib_encap_details_t_handler
14796   (vl_api_mpls_fib_encap_details_t * mp)
14797 {
14798   vat_main_t *vam = &vat_main;
14799   i32 i;
14800   i32 len = ntohl (mp->nlabels);
14801
14802   fformat (vam->ofp, "table %d, dest %U, label ",
14803            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14804   for (i = 0; i < len; i++)
14805     {
14806       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14807     }
14808   fformat (vam->ofp, "\n");
14809 }
14810
14811 static void vl_api_mpls_fib_encap_details_t_handler_json
14812   (vl_api_mpls_fib_encap_details_t * mp)
14813 {
14814   vat_main_t *vam = &vat_main;
14815   vat_json_node_t *node = NULL;
14816   i32 i;
14817   i32 len = ntohl (mp->nlabels);
14818   struct in_addr ip4;
14819
14820   if (VAT_JSON_ARRAY != vam->json_tree.type)
14821     {
14822       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14823       vat_json_init_array (&vam->json_tree);
14824     }
14825   node = vat_json_array_add (&vam->json_tree);
14826
14827   vat_json_init_object (node);
14828   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14829   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14830   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14831   vat_json_object_add_ip4 (node, "dest", ip4);
14832   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14833   vat_json_object_add_uint (node, "label_count", len);
14834   for (i = 0; i < len; i++)
14835     {
14836       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14837     }
14838 }
14839
14840 static int
14841 api_mpls_fib_encap_dump (vat_main_t * vam)
14842 {
14843   vl_api_mpls_fib_encap_dump_t *mp;
14844   f64 timeout;
14845
14846   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14847   S;
14848
14849   /* Use a control ping for synchronization */
14850   {
14851     vl_api_control_ping_t *mp;
14852     M (CONTROL_PING, control_ping);
14853     S;
14854   }
14855   W;
14856 }
14857
14858 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14859 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14860
14861 static void
14862 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14863 {
14864   vat_main_t *vam = &vat_main;
14865   int count = ntohl (mp->count);
14866   vl_api_fib_path_t *fp;
14867   int i;
14868
14869   fformat (vam->ofp,
14870            "table-id %d, label %u, ess_bit %u\n",
14871            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14872   fp = mp->path;
14873   for (i = 0; i < count; i++)
14874     {
14875       fformat (vam->ofp,
14876                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, "
14877                "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight),
14878                ntohl (fp->sw_if_index), fp->is_local, fp->is_drop,
14879                fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address,
14880                fp->next_hop, fp->afi);
14881       fp++;
14882     }
14883 }
14884
14885 static void vl_api_mpls_fib_details_t_handler_json
14886   (vl_api_mpls_fib_details_t * mp)
14887 {
14888   vat_main_t *vam = &vat_main;
14889   int count = ntohl (mp->count);
14890   vat_json_node_t *node = NULL;
14891   struct in_addr ip4;
14892   struct in6_addr ip6;
14893   vl_api_fib_path_t *fp;
14894   int i;
14895
14896   if (VAT_JSON_ARRAY != vam->json_tree.type)
14897     {
14898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14899       vat_json_init_array (&vam->json_tree);
14900     }
14901   node = vat_json_array_add (&vam->json_tree);
14902
14903   vat_json_init_object (node);
14904   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14905   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14906   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14907   vat_json_object_add_uint (node, "path_count", count);
14908   fp = mp->path;
14909   for (i = 0; i < count; i++)
14910     {
14911       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14912       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14913       vat_json_object_add_uint (node, "is_local", fp->is_local);
14914       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14915       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14916       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14917       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14918       if (fp->afi == IP46_TYPE_IP4)
14919         {
14920           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14921           vat_json_object_add_ip4 (node, "next_hop", ip4);
14922         }
14923       else if (fp->afi == IP46_TYPE_IP6)
14924         {
14925           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14926           vat_json_object_add_ip6 (node, "next_hop", ip6);
14927         }
14928     }
14929 }
14930
14931 static int
14932 api_mpls_fib_dump (vat_main_t * vam)
14933 {
14934   vl_api_mpls_fib_dump_t *mp;
14935   f64 timeout;
14936
14937   M (MPLS_FIB_DUMP, mpls_fib_dump);
14938   S;
14939
14940   /* Use a control ping for synchronization */
14941   {
14942     vl_api_control_ping_t *mp;
14943     M (CONTROL_PING, control_ping);
14944     S;
14945   }
14946   W;
14947 }
14948
14949 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14950 #define vl_api_ip_fib_details_t_print vl_noop_handler
14951
14952 static void
14953 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14954 {
14955   vat_main_t *vam = &vat_main;
14956   int count = ntohl (mp->count);
14957   vl_api_fib_path_t *fp;
14958   int i;
14959
14960   fformat (vam->ofp,
14961            "table-id %d, prefix %U/%d\n",
14962            ntohl (mp->table_id), format_ip4_address, mp->address,
14963            mp->address_length);
14964   fp = mp->path;
14965   for (i = 0; i < count; i++)
14966     {
14967       fformat (vam->ofp,
14968                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, "
14969                "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight),
14970                ntohl (fp->sw_if_index), fp->is_local, fp->is_drop,
14971                fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address,
14972                fp->next_hop, fp->afi);
14973       fp++;
14974     }
14975 }
14976
14977 static void vl_api_ip_fib_details_t_handler_json
14978   (vl_api_ip_fib_details_t * mp)
14979 {
14980   vat_main_t *vam = &vat_main;
14981   int count = ntohl (mp->count);
14982   vat_json_node_t *node = NULL;
14983   struct in_addr ip4;
14984   struct in6_addr ip6;
14985   vl_api_fib_path_t *fp;
14986   int i;
14987
14988   if (VAT_JSON_ARRAY != vam->json_tree.type)
14989     {
14990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14991       vat_json_init_array (&vam->json_tree);
14992     }
14993   node = vat_json_array_add (&vam->json_tree);
14994
14995   vat_json_init_object (node);
14996   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14997   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
14998   vat_json_object_add_ip4 (node, "prefix", ip4);
14999   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15000   vat_json_object_add_uint (node, "path_count", count);
15001   fp = mp->path;
15002   for (i = 0; i < count; i++)
15003     {
15004       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15005       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15006       vat_json_object_add_uint (node, "is_local", fp->is_local);
15007       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15008       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15009       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15010       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15011       if (fp->afi == IP46_TYPE_IP4)
15012         {
15013           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15014           vat_json_object_add_ip4 (node, "next_hop", ip4);
15015         }
15016       else if (fp->afi == IP46_TYPE_IP6)
15017         {
15018           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15019           vat_json_object_add_ip6 (node, "next_hop", ip6);
15020         }
15021     }
15022 }
15023
15024 static int
15025 api_ip_fib_dump (vat_main_t * vam)
15026 {
15027   vl_api_ip_fib_dump_t *mp;
15028   f64 timeout;
15029
15030   M (IP_FIB_DUMP, ip_fib_dump);
15031   S;
15032
15033   /* Use a control ping for synchronization */
15034   {
15035     vl_api_control_ping_t *mp;
15036     M (CONTROL_PING, control_ping);
15037     S;
15038   }
15039   W;
15040 }
15041
15042 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15043 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15044
15045 static void
15046 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15047 {
15048   vat_main_t *vam = &vat_main;
15049   int count = ntohl (mp->count);
15050   vl_api_fib_path_t *fp;
15051   int i;
15052
15053   fformat (vam->ofp,
15054            "table-id %d, prefix %U/%d\n",
15055            ntohl (mp->table_id), format_ip6_address, mp->address,
15056            mp->address_length);
15057   fp = mp->path;
15058   for (i = 0; i < count; i++)
15059     {
15060       fformat (vam->ofp,
15061                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, "
15062                "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight),
15063                ntohl (fp->sw_if_index), fp->is_local, fp->is_drop,
15064                fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address,
15065                fp->next_hop, fp->afi);
15066       fp++;
15067     }
15068 }
15069
15070 static void vl_api_ip6_fib_details_t_handler_json
15071   (vl_api_ip6_fib_details_t * mp)
15072 {
15073   vat_main_t *vam = &vat_main;
15074   int count = ntohl (mp->count);
15075   vat_json_node_t *node = NULL;
15076   struct in_addr ip4;
15077   struct in6_addr ip6;
15078   vl_api_fib_path_t *fp;
15079   int i;
15080
15081   if (VAT_JSON_ARRAY != vam->json_tree.type)
15082     {
15083       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15084       vat_json_init_array (&vam->json_tree);
15085     }
15086   node = vat_json_array_add (&vam->json_tree);
15087
15088   vat_json_init_object (node);
15089   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15090   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15091   vat_json_object_add_ip6 (node, "prefix", ip6);
15092   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15093   vat_json_object_add_uint (node, "path_count", count);
15094   fp = mp->path;
15095   for (i = 0; i < count; i++)
15096     {
15097       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15098       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15099       vat_json_object_add_uint (node, "is_local", fp->is_local);
15100       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15101       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15102       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15103       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15104       if (fp->afi == IP46_TYPE_IP4)
15105         {
15106           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15107           vat_json_object_add_ip4 (node, "next_hop", ip4);
15108         }
15109       else if (fp->afi == IP46_TYPE_IP6)
15110         {
15111           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15112           vat_json_object_add_ip6 (node, "next_hop", ip6);
15113         }
15114     }
15115 }
15116
15117 static int
15118 api_ip6_fib_dump (vat_main_t * vam)
15119 {
15120   vl_api_ip6_fib_dump_t *mp;
15121   f64 timeout;
15122
15123   M (IP6_FIB_DUMP, ip6_fib_dump);
15124   S;
15125
15126   /* Use a control ping for synchronization */
15127   {
15128     vl_api_control_ping_t *mp;
15129     M (CONTROL_PING, control_ping);
15130     S;
15131   }
15132   W;
15133 }
15134
15135 int
15136 api_classify_table_ids (vat_main_t * vam)
15137 {
15138   vl_api_classify_table_ids_t *mp;
15139   f64 timeout;
15140
15141   /* Construct the API message */
15142   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15143   mp->context = 0;
15144
15145   S;
15146   W;
15147   /* NOTREACHED */
15148   return 0;
15149 }
15150
15151 int
15152 api_classify_table_by_interface (vat_main_t * vam)
15153 {
15154   unformat_input_t *input = vam->input;
15155   vl_api_classify_table_by_interface_t *mp;
15156   f64 timeout;
15157
15158   u32 sw_if_index = ~0;
15159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15160     {
15161       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15162         ;
15163       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15164         ;
15165       else
15166         break;
15167     }
15168   if (sw_if_index == ~0)
15169     {
15170       errmsg ("missing interface name or sw_if_index\n");
15171       return -99;
15172     }
15173
15174   /* Construct the API message */
15175   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15176   mp->context = 0;
15177   mp->sw_if_index = ntohl (sw_if_index);
15178
15179   S;
15180   W;
15181   /* NOTREACHED */
15182   return 0;
15183 }
15184
15185 int
15186 api_classify_table_info (vat_main_t * vam)
15187 {
15188   unformat_input_t *input = vam->input;
15189   vl_api_classify_table_info_t *mp;
15190   f64 timeout;
15191
15192   u32 table_id = ~0;
15193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15194     {
15195       if (unformat (input, "table_id %d", &table_id))
15196         ;
15197       else
15198         break;
15199     }
15200   if (table_id == ~0)
15201     {
15202       errmsg ("missing table id\n");
15203       return -99;
15204     }
15205
15206   /* Construct the API message */
15207   M (CLASSIFY_TABLE_INFO, classify_table_info);
15208   mp->context = 0;
15209   mp->table_id = ntohl (table_id);
15210
15211   S;
15212   W;
15213   /* NOTREACHED */
15214   return 0;
15215 }
15216
15217 int
15218 api_classify_session_dump (vat_main_t * vam)
15219 {
15220   unformat_input_t *input = vam->input;
15221   vl_api_classify_session_dump_t *mp;
15222   f64 timeout;
15223
15224   u32 table_id = ~0;
15225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15226     {
15227       if (unformat (input, "table_id %d", &table_id))
15228         ;
15229       else
15230         break;
15231     }
15232   if (table_id == ~0)
15233     {
15234       errmsg ("missing table id\n");
15235       return -99;
15236     }
15237
15238   /* Construct the API message */
15239   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15240   mp->context = 0;
15241   mp->table_id = ntohl (table_id);
15242   S;
15243
15244   /* Use a control ping for synchronization */
15245   {
15246     vl_api_control_ping_t *mp;
15247     M (CONTROL_PING, control_ping);
15248     S;
15249   }
15250   W;
15251   /* NOTREACHED */
15252   return 0;
15253 }
15254
15255 static void
15256 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15257 {
15258   vat_main_t *vam = &vat_main;
15259
15260   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15261            "src_address %U, vrf_id %d, path_mtu %u, "
15262            "template_interval %u, udp_checksum %d\n",
15263            format_ip4_address, mp->collector_address,
15264            ntohs (mp->collector_port),
15265            format_ip4_address, mp->src_address,
15266            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15267            ntohl (mp->template_interval), mp->udp_checksum);
15268
15269   vam->retval = 0;
15270   vam->result_ready = 1;
15271 }
15272
15273 static void
15274   vl_api_ipfix_exporter_details_t_handler_json
15275   (vl_api_ipfix_exporter_details_t * mp)
15276 {
15277   vat_main_t *vam = &vat_main;
15278   vat_json_node_t node;
15279   struct in_addr collector_address;
15280   struct in_addr src_address;
15281
15282   vat_json_init_object (&node);
15283   clib_memcpy (&collector_address, &mp->collector_address,
15284                sizeof (collector_address));
15285   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15286   vat_json_object_add_uint (&node, "collector_port",
15287                             ntohs (mp->collector_port));
15288   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15289   vat_json_object_add_ip4 (&node, "src_address", src_address);
15290   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15291   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15292   vat_json_object_add_uint (&node, "template_interval",
15293                             ntohl (mp->template_interval));
15294   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15295
15296   vat_json_print (vam->ofp, &node);
15297   vat_json_free (&node);
15298   vam->retval = 0;
15299   vam->result_ready = 1;
15300 }
15301
15302 int
15303 api_ipfix_exporter_dump (vat_main_t * vam)
15304 {
15305   vl_api_ipfix_exporter_dump_t *mp;
15306   f64 timeout;
15307
15308   /* Construct the API message */
15309   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15310   mp->context = 0;
15311
15312   S;
15313   W;
15314   /* NOTREACHED */
15315   return 0;
15316 }
15317
15318 static int
15319 api_ipfix_classify_stream_dump (vat_main_t * vam)
15320 {
15321   vl_api_ipfix_classify_stream_dump_t *mp;
15322   f64 timeout;
15323
15324   /* Construct the API message */
15325   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15326   mp->context = 0;
15327
15328   S;
15329   W;
15330   /* NOTREACHED */
15331   return 0;
15332 }
15333
15334 static void
15335   vl_api_ipfix_classify_stream_details_t_handler
15336   (vl_api_ipfix_classify_stream_details_t * mp)
15337 {
15338   vat_main_t *vam = &vat_main;
15339   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15340            ntohl (mp->domain_id), ntohs (mp->src_port));
15341   vam->retval = 0;
15342   vam->result_ready = 1;
15343 }
15344
15345 static void
15346   vl_api_ipfix_classify_stream_details_t_handler_json
15347   (vl_api_ipfix_classify_stream_details_t * mp)
15348 {
15349   vat_main_t *vam = &vat_main;
15350   vat_json_node_t node;
15351
15352   vat_json_init_object (&node);
15353   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15354   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15355
15356   vat_json_print (vam->ofp, &node);
15357   vat_json_free (&node);
15358   vam->retval = 0;
15359   vam->result_ready = 1;
15360 }
15361
15362 static int
15363 api_ipfix_classify_table_dump (vat_main_t * vam)
15364 {
15365   vl_api_ipfix_classify_table_dump_t *mp;
15366   f64 timeout;
15367
15368   if (!vam->json_output)
15369     {
15370       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15371                "transport_protocol");
15372     }
15373
15374   /* Construct the API message */
15375   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15376
15377   /* send it... */
15378   S;
15379
15380   /* Use a control ping for synchronization */
15381   {
15382     vl_api_control_ping_t *mp;
15383     M (CONTROL_PING, control_ping);
15384     S;
15385   }
15386   W;
15387 }
15388
15389 static void
15390   vl_api_ipfix_classify_table_details_t_handler
15391   (vl_api_ipfix_classify_table_details_t * mp)
15392 {
15393   vat_main_t *vam = &vat_main;
15394   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15395            mp->transport_protocol);
15396 }
15397
15398 static void
15399   vl_api_ipfix_classify_table_details_t_handler_json
15400   (vl_api_ipfix_classify_table_details_t * mp)
15401 {
15402   vat_json_node_t *node = NULL;
15403   vat_main_t *vam = &vat_main;
15404
15405   if (VAT_JSON_ARRAY != vam->json_tree.type)
15406     {
15407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15408       vat_json_init_array (&vam->json_tree);
15409     }
15410
15411   node = vat_json_array_add (&vam->json_tree);
15412   vat_json_init_object (node);
15413
15414   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15415   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15416   vat_json_object_add_uint (node, "transport_protocol",
15417                             mp->transport_protocol);
15418 }
15419
15420 int
15421 api_pg_create_interface (vat_main_t * vam)
15422 {
15423   unformat_input_t *input = vam->input;
15424   vl_api_pg_create_interface_t *mp;
15425   f64 timeout;
15426
15427   u32 if_id = ~0;
15428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15429     {
15430       if (unformat (input, "if_id %d", &if_id))
15431         ;
15432       else
15433         break;
15434     }
15435   if (if_id == ~0)
15436     {
15437       errmsg ("missing pg interface index\n");
15438       return -99;
15439     }
15440
15441   /* Construct the API message */
15442   M (PG_CREATE_INTERFACE, pg_create_interface);
15443   mp->context = 0;
15444   mp->interface_id = ntohl (if_id);
15445
15446   S;
15447   W;
15448   /* NOTREACHED */
15449   return 0;
15450 }
15451
15452 int
15453 api_pg_capture (vat_main_t * vam)
15454 {
15455   unformat_input_t *input = vam->input;
15456   vl_api_pg_capture_t *mp;
15457   f64 timeout;
15458
15459   u32 if_id = ~0;
15460   u8 enable = 1;
15461   u32 count = 1;
15462   u8 pcap_file_set = 0;
15463   u8 *pcap_file = 0;
15464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15465     {
15466       if (unformat (input, "if_id %d", &if_id))
15467         ;
15468       else if (unformat (input, "pcap %s", &pcap_file))
15469         pcap_file_set = 1;
15470       else if (unformat (input, "count %d", &count))
15471         ;
15472       else if (unformat (input, "disable"))
15473         enable = 0;
15474       else
15475         break;
15476     }
15477   if (if_id == ~0)
15478     {
15479       errmsg ("missing pg interface index\n");
15480       return -99;
15481     }
15482   if (pcap_file_set > 0)
15483     {
15484       if (vec_len (pcap_file) > 255)
15485         {
15486           errmsg ("pcap file name is too long\n");
15487           return -99;
15488         }
15489     }
15490
15491   u32 name_len = vec_len (pcap_file);
15492   /* Construct the API message */
15493   M (PG_CAPTURE, pg_capture);
15494   mp->context = 0;
15495   mp->interface_id = ntohl (if_id);
15496   mp->is_enabled = enable;
15497   mp->count = ntohl (count);
15498   mp->pcap_name_length = ntohl (name_len);
15499   if (pcap_file_set != 0)
15500     {
15501       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15502     }
15503   vec_free (pcap_file);
15504
15505   S;
15506   W;
15507   /* NOTREACHED */
15508   return 0;
15509 }
15510
15511 int
15512 api_pg_enable_disable (vat_main_t * vam)
15513 {
15514   unformat_input_t *input = vam->input;
15515   vl_api_pg_enable_disable_t *mp;
15516   f64 timeout;
15517
15518   u8 enable = 1;
15519   u8 stream_name_set = 0;
15520   u8 *stream_name = 0;
15521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15522     {
15523       if (unformat (input, "stream %s", &stream_name))
15524         stream_name_set = 1;
15525       else if (unformat (input, "disable"))
15526         enable = 0;
15527       else
15528         break;
15529     }
15530
15531   if (stream_name_set > 0)
15532     {
15533       if (vec_len (stream_name) > 255)
15534         {
15535           errmsg ("stream name too long\n");
15536           return -99;
15537         }
15538     }
15539
15540   u32 name_len = vec_len (stream_name);
15541   /* Construct the API message */
15542   M (PG_ENABLE_DISABLE, pg_enable_disable);
15543   mp->context = 0;
15544   mp->is_enabled = enable;
15545   if (stream_name_set != 0)
15546     {
15547       mp->stream_name_length = ntohl (name_len);
15548       clib_memcpy (mp->stream_name, stream_name, name_len);
15549     }
15550   vec_free (stream_name);
15551
15552   S;
15553   W;
15554   /* NOTREACHED */
15555   return 0;
15556 }
15557
15558 int
15559 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15560 {
15561   unformat_input_t *input = vam->input;
15562   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15563   f64 timeout;
15564
15565   u16 *low_ports = 0;
15566   u16 *high_ports = 0;
15567   u16 this_low;
15568   u16 this_hi;
15569   ip4_address_t ip4_addr;
15570   ip6_address_t ip6_addr;
15571   u32 length;
15572   u32 tmp, tmp2;
15573   u8 prefix_set = 0;
15574   u32 vrf_id = ~0;
15575   u8 is_add = 1;
15576   u8 is_ipv6 = 0;
15577
15578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15579     {
15580       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15581         {
15582           prefix_set = 1;
15583         }
15584       else
15585         if (unformat
15586             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15587         {
15588           prefix_set = 1;
15589           is_ipv6 = 1;
15590         }
15591       else if (unformat (input, "vrf %d", &vrf_id))
15592         ;
15593       else if (unformat (input, "del"))
15594         is_add = 0;
15595       else if (unformat (input, "port %d", &tmp))
15596         {
15597           if (tmp == 0 || tmp > 65535)
15598             {
15599               errmsg ("port %d out of range", tmp);
15600               return -99;
15601             }
15602           this_low = tmp;
15603           this_hi = this_low + 1;
15604           vec_add1 (low_ports, this_low);
15605           vec_add1 (high_ports, this_hi);
15606         }
15607       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15608         {
15609           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15610             {
15611               errmsg ("incorrect range parameters\n");
15612               return -99;
15613             }
15614           this_low = tmp;
15615           /* Note: in debug CLI +1 is added to high before
15616              passing to real fn that does "the work"
15617              (ip_source_and_port_range_check_add_del).
15618              This fn is a wrapper around the binary API fn a
15619              control plane will call, which expects this increment
15620              to have occurred. Hence letting the binary API control
15621              plane fn do the increment for consistency between VAT
15622              and other control planes.
15623            */
15624           this_hi = tmp2;
15625           vec_add1 (low_ports, this_low);
15626           vec_add1 (high_ports, this_hi);
15627         }
15628       else
15629         break;
15630     }
15631
15632   if (prefix_set == 0)
15633     {
15634       errmsg ("<address>/<mask> not specified\n");
15635       return -99;
15636     }
15637
15638   if (vrf_id == ~0)
15639     {
15640       errmsg ("VRF ID required, not specified\n");
15641       return -99;
15642     }
15643
15644   if (vrf_id == 0)
15645     {
15646       errmsg
15647         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15648       return -99;
15649     }
15650
15651   if (vec_len (low_ports) == 0)
15652     {
15653       errmsg ("At least one port or port range required\n");
15654       return -99;
15655     }
15656
15657   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15658      ip_source_and_port_range_check_add_del);
15659
15660   mp->is_add = is_add;
15661
15662   if (is_ipv6)
15663     {
15664       mp->is_ipv6 = 1;
15665       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15666     }
15667   else
15668     {
15669       mp->is_ipv6 = 0;
15670       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15671     }
15672
15673   mp->mask_length = length;
15674   mp->number_of_ranges = vec_len (low_ports);
15675
15676   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15677   vec_free (low_ports);
15678
15679   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15680   vec_free (high_ports);
15681
15682   mp->vrf_id = ntohl (vrf_id);
15683
15684   S;
15685   W;
15686   /* NOTREACHED */
15687   return 0;
15688 }
15689
15690 int
15691 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15692 {
15693   unformat_input_t *input = vam->input;
15694   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15695   f64 timeout;
15696   u32 sw_if_index = ~0;
15697   int vrf_set = 0;
15698   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15699   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15700   u8 is_add = 1;
15701
15702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15703     {
15704       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15705         ;
15706       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15707         ;
15708       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15709         vrf_set = 1;
15710       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15711         vrf_set = 1;
15712       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15713         vrf_set = 1;
15714       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15715         vrf_set = 1;
15716       else if (unformat (input, "del"))
15717         is_add = 0;
15718       else
15719         break;
15720     }
15721
15722   if (sw_if_index == ~0)
15723     {
15724       errmsg ("Interface required but not specified\n");
15725       return -99;
15726     }
15727
15728   if (vrf_set == 0)
15729     {
15730       errmsg ("VRF ID required but not specified\n");
15731       return -99;
15732     }
15733
15734   if (tcp_out_vrf_id == 0
15735       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15736     {
15737       errmsg
15738         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15739       return -99;
15740     }
15741
15742   /* Construct the API message */
15743   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15744      ip_source_and_port_range_check_interface_add_del);
15745
15746   mp->sw_if_index = ntohl (sw_if_index);
15747   mp->is_add = is_add;
15748   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15749   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15750   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15751   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15752
15753   /* send it... */
15754   S;
15755
15756   /* Wait for a reply... */
15757   W;
15758 }
15759
15760 static int
15761 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15762 {
15763   unformat_input_t *i = vam->input;
15764   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15765   f64 timeout;
15766   u32 local_sa_id = 0;
15767   u32 remote_sa_id = 0;
15768   ip4_address_t src_address;
15769   ip4_address_t dst_address;
15770   u8 is_add = 1;
15771
15772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15773     {
15774       if (unformat (i, "local_sa %d", &local_sa_id))
15775         ;
15776       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15777         ;
15778       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15779         ;
15780       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15781         ;
15782       else if (unformat (i, "del"))
15783         is_add = 0;
15784       else
15785         {
15786           clib_warning ("parse error '%U'", format_unformat_error, i);
15787           return -99;
15788         }
15789     }
15790
15791   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15792
15793   mp->local_sa_id = ntohl (local_sa_id);
15794   mp->remote_sa_id = ntohl (remote_sa_id);
15795   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15796   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15797   mp->is_add = is_add;
15798
15799   S;
15800   W;
15801   /* NOTREACHED */
15802   return 0;
15803 }
15804
15805 static int
15806 api_punt (vat_main_t * vam)
15807 {
15808   unformat_input_t *i = vam->input;
15809   vl_api_punt_t *mp;
15810   f64 timeout;
15811   u32 ipv = ~0;
15812   u32 protocol = ~0;
15813   u32 port = ~0;
15814   int is_add = 1;
15815
15816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15817     {
15818       if (unformat (i, "ip %d", &ipv))
15819         ;
15820       else if (unformat (i, "protocol %d", &protocol))
15821         ;
15822       else if (unformat (i, "port %d", &port))
15823         ;
15824       else if (unformat (i, "del"))
15825         is_add = 0;
15826       else
15827         {
15828           clib_warning ("parse error '%U'", format_unformat_error, i);
15829           return -99;
15830         }
15831     }
15832
15833   M (PUNT, punt);
15834
15835   mp->is_add = (u8) is_add;
15836   mp->ipv = (u8) ipv;
15837   mp->l4_protocol = (u8) protocol;
15838   mp->l4_port = htons ((u16) port);
15839
15840   S;
15841   W;
15842   /* NOTREACHED */
15843   return 0;
15844 }
15845
15846 static void vl_api_ipsec_gre_tunnel_details_t_handler
15847   (vl_api_ipsec_gre_tunnel_details_t * mp)
15848 {
15849   vat_main_t *vam = &vat_main;
15850
15851   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15852            ntohl (mp->sw_if_index),
15853            format_ip4_address, &mp->src_address,
15854            format_ip4_address, &mp->dst_address,
15855            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15856 }
15857
15858 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15859   (vl_api_ipsec_gre_tunnel_details_t * mp)
15860 {
15861   vat_main_t *vam = &vat_main;
15862   vat_json_node_t *node = NULL;
15863   struct in_addr ip4;
15864
15865   if (VAT_JSON_ARRAY != vam->json_tree.type)
15866     {
15867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15868       vat_json_init_array (&vam->json_tree);
15869     }
15870   node = vat_json_array_add (&vam->json_tree);
15871
15872   vat_json_init_object (node);
15873   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15874   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15875   vat_json_object_add_ip4 (node, "src_address", ip4);
15876   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15877   vat_json_object_add_ip4 (node, "dst_address", ip4);
15878   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15879   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15880 }
15881
15882 static int
15883 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15884 {
15885   unformat_input_t *i = vam->input;
15886   vl_api_ipsec_gre_tunnel_dump_t *mp;
15887   f64 timeout;
15888   u32 sw_if_index;
15889   u8 sw_if_index_set = 0;
15890
15891   /* Parse args required to build the message */
15892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15893     {
15894       if (unformat (i, "sw_if_index %d", &sw_if_index))
15895         sw_if_index_set = 1;
15896       else
15897         break;
15898     }
15899
15900   if (sw_if_index_set == 0)
15901     {
15902       sw_if_index = ~0;
15903     }
15904
15905   if (!vam->json_output)
15906     {
15907       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15908                "sw_if_index", "src_address", "dst_address",
15909                "local_sa_id", "remote_sa_id");
15910     }
15911
15912   /* Get list of gre-tunnel interfaces */
15913   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15914
15915   mp->sw_if_index = htonl (sw_if_index);
15916
15917   S;
15918
15919   /* Use a control ping for synchronization */
15920   {
15921     vl_api_control_ping_t *mp;
15922     M (CONTROL_PING, control_ping);
15923     S;
15924   }
15925   W;
15926 }
15927
15928 static int
15929 api_delete_subif (vat_main_t * vam)
15930 {
15931   unformat_input_t *i = vam->input;
15932   vl_api_delete_subif_t *mp;
15933   f64 timeout;
15934   u32 sw_if_index = ~0;
15935
15936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15937     {
15938       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15939         ;
15940       if (unformat (i, "sw_if_index %d", &sw_if_index))
15941         ;
15942       else
15943         break;
15944     }
15945
15946   if (sw_if_index == ~0)
15947     {
15948       errmsg ("missing sw_if_index\n");
15949       return -99;
15950     }
15951
15952   /* Construct the API message */
15953   M (DELETE_SUBIF, delete_subif);
15954   mp->sw_if_index = ntohl (sw_if_index);
15955
15956   S;
15957   W;
15958 }
15959
15960 #define foreach_pbb_vtr_op      \
15961 _("disable",  L2_VTR_DISABLED)  \
15962 _("pop",  L2_VTR_POP_2)         \
15963 _("push",  L2_VTR_PUSH_2)
15964
15965 static int
15966 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15967 {
15968   unformat_input_t *i = vam->input;
15969   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15970   f64 timeout;
15971   u32 sw_if_index = ~0, vtr_op = ~0;
15972   u16 outer_tag = ~0;
15973   u8 dmac[6], smac[6];
15974   u8 dmac_set = 0, smac_set = 0;
15975   u16 vlanid = 0;
15976   u32 sid = ~0;
15977   u32 tmp;
15978
15979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15980     {
15981       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15982         ;
15983       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15984         ;
15985       else if (unformat (i, "vtr_op %d", &vtr_op))
15986         ;
15987 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15988       foreach_pbb_vtr_op
15989 #undef _
15990         else if (unformat (i, "translate_pbb_stag"))
15991         {
15992           if (unformat (i, "%d", &tmp))
15993             {
15994               vtr_op = L2_VTR_TRANSLATE_2_1;
15995               outer_tag = tmp;
15996             }
15997           else
15998             {
15999               errmsg
16000                 ("translate_pbb_stag operation requires outer tag definition\n");
16001               return -99;
16002             }
16003         }
16004       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16005         dmac_set++;
16006       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16007         smac_set++;
16008       else if (unformat (i, "sid %d", &sid))
16009         ;
16010       else if (unformat (i, "vlanid %d", &tmp))
16011         vlanid = tmp;
16012       else
16013         {
16014           clib_warning ("parse error '%U'", format_unformat_error, i);
16015           return -99;
16016         }
16017     }
16018
16019   if ((sw_if_index == ~0) || (vtr_op == ~0))
16020     {
16021       errmsg ("missing sw_if_index or vtr operation\n");
16022       return -99;
16023     }
16024   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16025       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16026     {
16027       errmsg
16028         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16029       return -99;
16030     }
16031
16032   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16033   mp->sw_if_index = ntohl (sw_if_index);
16034   mp->vtr_op = ntohl (vtr_op);
16035   mp->outer_tag = ntohs (outer_tag);
16036   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16037   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16038   mp->b_vlanid = ntohs (vlanid);
16039   mp->i_sid = ntohl (sid);
16040
16041   S;
16042   W;
16043   /* NOTREACHED */
16044   return 0;
16045 }
16046
16047 static int
16048 api_flow_classify_set_interface (vat_main_t * vam)
16049 {
16050   unformat_input_t *i = vam->input;
16051   vl_api_flow_classify_set_interface_t *mp;
16052   f64 timeout;
16053   u32 sw_if_index;
16054   int sw_if_index_set;
16055   u32 ip4_table_index = ~0;
16056   u32 ip6_table_index = ~0;
16057   u8 is_add = 1;
16058
16059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16060     {
16061       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16062         sw_if_index_set = 1;
16063       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16064         sw_if_index_set = 1;
16065       else if (unformat (i, "del"))
16066         is_add = 0;
16067       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16068         ;
16069       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16070         ;
16071       else
16072         {
16073           clib_warning ("parse error '%U'", format_unformat_error, i);
16074           return -99;
16075         }
16076     }
16077
16078   if (sw_if_index_set == 0)
16079     {
16080       errmsg ("missing interface name or sw_if_index\n");
16081       return -99;
16082     }
16083
16084   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16085
16086   mp->sw_if_index = ntohl (sw_if_index);
16087   mp->ip4_table_index = ntohl (ip4_table_index);
16088   mp->ip6_table_index = ntohl (ip6_table_index);
16089   mp->is_add = is_add;
16090
16091   S;
16092   W;
16093   /* NOTREACHED */
16094   return 0;
16095 }
16096
16097 static int
16098 api_flow_classify_dump (vat_main_t * vam)
16099 {
16100   unformat_input_t *i = vam->input;
16101   vl_api_flow_classify_dump_t *mp;
16102   f64 timeout = ~0;
16103   u8 type = FLOW_CLASSIFY_N_TABLES;
16104
16105   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16106     ;
16107   else
16108     {
16109       errmsg ("classify table type must be specified\n");
16110       return -99;
16111     }
16112
16113   if (!vam->json_output)
16114     {
16115       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16116     }
16117
16118   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16119   mp->type = type;
16120   /* send it... */
16121   S;
16122
16123   /* Use a control ping for synchronization */
16124   {
16125     vl_api_control_ping_t *mp;
16126     M (CONTROL_PING, control_ping);
16127     S;
16128   }
16129   /* Wait for a reply... */
16130   W;
16131
16132   /* NOTREACHED */
16133   return 0;
16134 }
16135
16136 static int
16137 q_or_quit (vat_main_t * vam)
16138 {
16139   longjmp (vam->jump_buf, 1);
16140   return 0;                     /* not so much */
16141 }
16142
16143 static int
16144 q (vat_main_t * vam)
16145 {
16146   return q_or_quit (vam);
16147 }
16148
16149 static int
16150 quit (vat_main_t * vam)
16151 {
16152   return q_or_quit (vam);
16153 }
16154
16155 static int
16156 comment (vat_main_t * vam)
16157 {
16158   return 0;
16159 }
16160
16161 static int
16162 cmd_cmp (void *a1, void *a2)
16163 {
16164   u8 **c1 = a1;
16165   u8 **c2 = a2;
16166
16167   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16168 }
16169
16170 static int
16171 help (vat_main_t * vam)
16172 {
16173   u8 **cmds = 0;
16174   u8 *name = 0;
16175   hash_pair_t *p;
16176   unformat_input_t *i = vam->input;
16177   int j;
16178
16179   if (unformat (i, "%s", &name))
16180     {
16181       uword *hs;
16182
16183       vec_add1 (name, 0);
16184
16185       hs = hash_get_mem (vam->help_by_name, name);
16186       if (hs)
16187         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16188       else
16189         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16190       vec_free (name);
16191       return 0;
16192     }
16193
16194   fformat (vam->ofp, "Help is available for the following:\n");
16195
16196     /* *INDENT-OFF* */
16197     hash_foreach_pair (p, vam->function_by_name,
16198     ({
16199       vec_add1 (cmds, (u8 *)(p->key));
16200     }));
16201     /* *INDENT-ON* */
16202
16203   vec_sort_with_function (cmds, cmd_cmp);
16204
16205   for (j = 0; j < vec_len (cmds); j++)
16206     fformat (vam->ofp, "%s\n", cmds[j]);
16207
16208   vec_free (cmds);
16209   return 0;
16210 }
16211
16212 static int
16213 set (vat_main_t * vam)
16214 {
16215   u8 *name = 0, *value = 0;
16216   unformat_input_t *i = vam->input;
16217
16218   if (unformat (i, "%s", &name))
16219     {
16220       /* The input buffer is a vector, not a string. */
16221       value = vec_dup (i->buffer);
16222       vec_delete (value, i->index, 0);
16223       /* Almost certainly has a trailing newline */
16224       if (value[vec_len (value) - 1] == '\n')
16225         value[vec_len (value) - 1] = 0;
16226       /* Make sure it's a proper string, one way or the other */
16227       vec_add1 (value, 0);
16228       (void) clib_macro_set_value (&vam->macro_main,
16229                                    (char *) name, (char *) value);
16230     }
16231   else
16232     errmsg ("usage: set <name> <value>\n");
16233
16234   vec_free (name);
16235   vec_free (value);
16236   return 0;
16237 }
16238
16239 static int
16240 unset (vat_main_t * vam)
16241 {
16242   u8 *name = 0;
16243
16244   if (unformat (vam->input, "%s", &name))
16245     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16246       errmsg ("unset: %s wasn't set\n", name);
16247   vec_free (name);
16248   return 0;
16249 }
16250
16251 typedef struct
16252 {
16253   u8 *name;
16254   u8 *value;
16255 } macro_sort_t;
16256
16257
16258 static int
16259 macro_sort_cmp (void *a1, void *a2)
16260 {
16261   macro_sort_t *s1 = a1;
16262   macro_sort_t *s2 = a2;
16263
16264   return strcmp ((char *) (s1->name), (char *) (s2->name));
16265 }
16266
16267 static int
16268 dump_macro_table (vat_main_t * vam)
16269 {
16270   macro_sort_t *sort_me = 0, *sm;
16271   int i;
16272   hash_pair_t *p;
16273
16274     /* *INDENT-OFF* */
16275     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16276     ({
16277       vec_add2 (sort_me, sm, 1);
16278       sm->name = (u8 *)(p->key);
16279       sm->value = (u8 *) (p->value[0]);
16280     }));
16281     /* *INDENT-ON* */
16282
16283   vec_sort_with_function (sort_me, macro_sort_cmp);
16284
16285   if (vec_len (sort_me))
16286     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16287   else
16288     fformat (vam->ofp, "The macro table is empty...\n");
16289
16290   for (i = 0; i < vec_len (sort_me); i++)
16291     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16292   return 0;
16293 }
16294
16295 static int
16296 dump_node_table (vat_main_t * vam)
16297 {
16298   int i, j;
16299   vlib_node_t *node, *next_node;
16300
16301   if (vec_len (vam->graph_nodes) == 0)
16302     {
16303       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16304       return 0;
16305     }
16306
16307   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16308     {
16309       node = vam->graph_nodes[i];
16310       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16311       for (j = 0; j < vec_len (node->next_nodes); j++)
16312         {
16313           if (node->next_nodes[j] != ~0)
16314             {
16315               next_node = vam->graph_nodes[node->next_nodes[j]];
16316               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16317             }
16318         }
16319     }
16320   return 0;
16321 }
16322
16323 static int
16324 search_node_table (vat_main_t * vam)
16325 {
16326   unformat_input_t *line_input = vam->input;
16327   u8 *node_to_find;
16328   int j;
16329   vlib_node_t *node, *next_node;
16330   uword *p;
16331
16332   if (vam->graph_node_index_by_name == 0)
16333     {
16334       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16335       return 0;
16336     }
16337
16338   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16339     {
16340       if (unformat (line_input, "%s", &node_to_find))
16341         {
16342           vec_add1 (node_to_find, 0);
16343           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16344           if (p == 0)
16345             {
16346               fformat (vam->ofp, "%s not found...\n", node_to_find);
16347               goto out;
16348             }
16349           node = vam->graph_nodes[p[0]];
16350           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16351           for (j = 0; j < vec_len (node->next_nodes); j++)
16352             {
16353               if (node->next_nodes[j] != ~0)
16354                 {
16355                   next_node = vam->graph_nodes[node->next_nodes[j]];
16356                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16357                 }
16358             }
16359         }
16360
16361       else
16362         {
16363           clib_warning ("parse error '%U'", format_unformat_error,
16364                         line_input);
16365           return -99;
16366         }
16367
16368     out:
16369       vec_free (node_to_find);
16370
16371     }
16372
16373   return 0;
16374 }
16375
16376
16377 static int
16378 script (vat_main_t * vam)
16379 {
16380   u8 *s = 0;
16381   char *save_current_file;
16382   unformat_input_t save_input;
16383   jmp_buf save_jump_buf;
16384   u32 save_line_number;
16385
16386   FILE *new_fp, *save_ifp;
16387
16388   if (unformat (vam->input, "%s", &s))
16389     {
16390       new_fp = fopen ((char *) s, "r");
16391       if (new_fp == 0)
16392         {
16393           errmsg ("Couldn't open script file %s\n", s);
16394           vec_free (s);
16395           return -99;
16396         }
16397     }
16398   else
16399     {
16400       errmsg ("Missing script name\n");
16401       return -99;
16402     }
16403
16404   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16405   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16406   save_ifp = vam->ifp;
16407   save_line_number = vam->input_line_number;
16408   save_current_file = (char *) vam->current_file;
16409
16410   vam->input_line_number = 0;
16411   vam->ifp = new_fp;
16412   vam->current_file = s;
16413   do_one_file (vam);
16414
16415   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16416   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16417   vam->ifp = save_ifp;
16418   vam->input_line_number = save_line_number;
16419   vam->current_file = (u8 *) save_current_file;
16420   vec_free (s);
16421
16422   return 0;
16423 }
16424
16425 static int
16426 echo (vat_main_t * vam)
16427 {
16428   fformat (vam->ofp, "%v", vam->input->buffer);
16429   return 0;
16430 }
16431
16432 /* List of API message constructors, CLI names map to api_xxx */
16433 #define foreach_vpe_api_msg                                             \
16434 _(create_loopback,"[mac <mac-addr>]")                                   \
16435 _(sw_interface_dump,"")                                                 \
16436 _(sw_interface_set_flags,                                               \
16437   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16438 _(sw_interface_add_del_address,                                         \
16439   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16440 _(sw_interface_set_table,                                               \
16441   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16442 _(sw_interface_set_mpls_enable,                                                \
16443   "<intfc> | sw_if_index [disable | dis]")                                \
16444 _(sw_interface_set_vpath,                                               \
16445   "<intfc> | sw_if_index <id> enable | disable")                        \
16446 _(sw_interface_set_l2_xconnect,                                         \
16447   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16448   "enable | disable")                                                   \
16449 _(sw_interface_set_l2_bridge,                                           \
16450   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16451   "[shg <split-horizon-group>] [bvi]\n"                                 \
16452   "enable | disable")                                                   \
16453 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16454   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16455   "profile <profile-id>\n")                                             \
16456 _(sw_interface_set_dpdk_hqos_subport,                                   \
16457   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16458   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16459 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16460   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16461 _(bridge_domain_add_del,                                                \
16462   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16463 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16464 _(l2fib_add_del,                                                        \
16465   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16466 _(l2_flags,                                                             \
16467   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16468 _(bridge_flags,                                                         \
16469   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16470 _(tap_connect,                                                          \
16471   "tapname <name> mac <mac-addr> | random-mac")                         \
16472 _(tap_modify,                                                           \
16473   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16474 _(tap_delete,                                                           \
16475   "<vpp-if-name> | sw_if_index <id>")                                   \
16476 _(sw_interface_tap_dump, "")                                            \
16477 _(ip_add_del_route,                                                     \
16478   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16479   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16480   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16481   "[multipath] [count <n>]")                                            \
16482 _(mpls_route_add_del,                                                   \
16483   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16484   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16485   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16486   "[multipath] [count <n>]")                                            \
16487 _(mpls_ip_bind_unbind,                                                  \
16488   "<label> <addr/len>")                                                 \
16489 _(proxy_arp_add_del,                                                    \
16490   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16491 _(proxy_arp_intfc_enable_disable,                                       \
16492   "<intfc> | sw_if_index <id> enable | disable")                        \
16493 _(mpls_add_del_encap,                                                   \
16494   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16495 _(sw_interface_set_unnumbered,                                          \
16496   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16497 _(ip_neighbor_add_del,                                                  \
16498   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16499   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16500 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16501 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16502 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16503   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16504   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16505   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16506 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16507 _(reset_fib, "vrf <n> [ipv6]")                                          \
16508 _(dhcp_proxy_config,                                                    \
16509   "svr <v46-address> src <v46-address>\n"                               \
16510    "insert-cid <n> [del]")                                              \
16511 _(dhcp_proxy_config_2,                                                  \
16512   "svr <v46-address> src <v46-address>\n"                               \
16513    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16514 _(dhcp_proxy_set_vss,                                                   \
16515   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16516 _(dhcp_client_config,                                                   \
16517   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16518 _(set_ip_flow_hash,                                                     \
16519   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16520 _(sw_interface_ip6_enable_disable,                                      \
16521   "<intfc> | sw_if_index <id> enable | disable")                        \
16522 _(sw_interface_ip6_set_link_local_address,                              \
16523   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16524 _(sw_interface_ip6nd_ra_prefix,                                         \
16525   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16526   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16527   "[nolink] [isno]")                                                    \
16528 _(sw_interface_ip6nd_ra_config,                                         \
16529   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16530   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16531   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16532 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16533 _(l2_patch_add_del,                                                     \
16534   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16535   "enable | disable")                                                   \
16536 _(mpls_ethernet_add_del_tunnel,                                         \
16537   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16538   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16539 _(mpls_ethernet_add_del_tunnel_2,                                       \
16540   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16541   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16542 _(sr_tunnel_add_del,                                                    \
16543   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16544   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16545   "[policy <policy_name>]")                                             \
16546 _(sr_policy_add_del,                                                    \
16547   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16548 _(sr_multicast_map_add_del,                                             \
16549   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16550 _(classify_add_del_table,                                               \
16551   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16552   "[del] mask <mask-value>\n"                                           \
16553   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
16554 _(classify_add_del_session,                                             \
16555   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16556   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16557   "  [l3 [ip4|ip6]]")                                                   \
16558 _(classify_set_interface_ip_table,                                      \
16559   "<intfc> | sw_if_index <nn> table <nn>")                              \
16560 _(classify_set_interface_l2_tables,                                     \
16561   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16562   "  [other-table <nn>]")                                               \
16563 _(get_node_index, "node <node-name")                                    \
16564 _(add_node_next, "node <node-name> next <next-node-name>")              \
16565 _(l2tpv3_create_tunnel,                                                 \
16566   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16567   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16568   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16569 _(l2tpv3_set_tunnel_cookies,                                            \
16570   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16571   "[new_remote_cookie <nn>]\n")                                         \
16572 _(l2tpv3_interface_enable_disable,                                      \
16573   "<intfc> | sw_if_index <nn> enable | disable")                        \
16574 _(l2tpv3_set_lookup_key,                                                \
16575   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16576 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16577 _(vxlan_add_del_tunnel,                                                 \
16578   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16579   " [decap-next l2|ip4|ip6] [del]")                                     \
16580 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16581 _(gre_add_del_tunnel,                                                   \
16582   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16583 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16584 _(l2_fib_clear_table, "")                                               \
16585 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16586 _(l2_interface_vlan_tag_rewrite,                                        \
16587   "<intfc> | sw_if_index <nn> \n"                                       \
16588   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16589   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16590 _(create_vhost_user_if,                                                 \
16591         "socket <filename> [server] [renumber <dev_instance>] "         \
16592         "[mac <mac_address>]")                                          \
16593 _(modify_vhost_user_if,                                                 \
16594         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16595         "[server] [renumber <dev_instance>]")                           \
16596 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16597 _(sw_interface_vhost_user_dump, "")                                     \
16598 _(show_version, "")                                                     \
16599 _(vxlan_gpe_add_del_tunnel,                                             \
16600   "local <addr> remote <addr> vni <nn>\n"                               \
16601     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16602   "[next-ethernet] [next-nsh]\n")                                       \
16603 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16604 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16605 _(interface_name_renumber,                                              \
16606   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16607 _(input_acl_set_interface,                                              \
16608   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16609   "  [l2-table <nn>] [del]")                                            \
16610 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16611 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16612 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16613 _(ip_dump, "ipv4 | ipv6")                                               \
16614 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16615 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16616   "  spid_id <n> ")                                                     \
16617 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16618   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16619   "  integ_alg <alg> integ_key <hex>")                                  \
16620 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16621   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16622   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16623   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16624 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16625 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16626 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16627   "(auth_data 0x<data> | auth_data <data>)")                            \
16628 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16629   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16630 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16631   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16632   "(local|remote)")                                                     \
16633 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16634 _(delete_loopback,"sw_if_index <nn>")                                   \
16635 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16636 _(map_add_domain,                                                       \
16637   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16638   "ip6-src <ip6addr> "                                                  \
16639   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16640 _(map_del_domain, "index <n>")                                          \
16641 _(map_add_del_rule,                                                     \
16642   "index <n> psid <n> dst <ip6addr> [del]")                             \
16643 _(map_domain_dump, "")                                                  \
16644 _(map_rule_dump, "index <map-domain>")                                  \
16645 _(want_interface_events,  "enable|disable")                             \
16646 _(want_stats,"enable|disable")                                          \
16647 _(get_first_msg_id, "client <name>")                                    \
16648 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16649 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16650   "fib-id <nn> [ip4][ip6][default]")                                    \
16651 _(get_node_graph, " ")                                                  \
16652 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16653 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16654 _(ioam_disable, "")                                                \
16655 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16656                             " sw_if_index <sw_if_index> p <priority> "  \
16657                             "w <weight>] [del]")                        \
16658 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16659                         "iface <intf> | sw_if_index <sw_if_index> "     \
16660                         "p <priority> w <weight> [del]")                \
16661 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16662                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16663                           "locator-set <locator_name> [del]")           \
16664 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16665   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16666 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16667 _(lisp_gpe_enable_disable, "enable|disable")                            \
16668 _(lisp_enable_disable, "enable|disable")                                \
16669 _(lisp_gpe_add_del_iface, "up|down")                                    \
16670 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16671                                "[seid <seid>] "                         \
16672                                "rloc <locator> p <prio> "               \
16673                                "w <weight> [rloc <loc> ... ] "          \
16674                                "action <action> [del-all]")             \
16675 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16676                           "<local-eid>")                                \
16677 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16678 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16679 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16680 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16681 _(lisp_locator_set_dump, "[local | remote]")                            \
16682 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16683 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16684                        "[local] | [remote]")                            \
16685 _(lisp_eid_table_vni_dump, "")                                          \
16686 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16687 _(lisp_gpe_tunnel_dump, "")                                             \
16688 _(lisp_map_resolver_dump, "")                                           \
16689 _(lisp_adjacencies_get, "vni <vni>")                                    \
16690 _(show_lisp_status, "")                                                 \
16691 _(lisp_get_map_request_itr_rlocs, "")                                   \
16692 _(show_lisp_pitr, "")                                                   \
16693 _(show_lisp_map_request_mode, "")                                       \
16694 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16695 _(af_packet_delete, "name <host interface name>")                       \
16696 _(policer_add_del, "name <policer name> <params> [del]")                \
16697 _(policer_dump, "[name <policer name>]")                                \
16698 _(policer_classify_set_interface,                                       \
16699   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16700   "  [l2-table <nn>] [del]")                                            \
16701 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16702 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16703     "[master|slave]")                                                   \
16704 _(netmap_delete, "name <interface name>")                               \
16705 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16706 _(mpls_fib_encap_dump, "")                                              \
16707 _(mpls_fib_dump, "")                                                    \
16708 _(classify_table_ids, "")                                               \
16709 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16710 _(classify_table_info, "table_id <nn>")                                 \
16711 _(classify_session_dump, "table_id <nn>")                               \
16712 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16713     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16714     "[template_interval <nn>] [udp_checksum]")                          \
16715 _(ipfix_exporter_dump, "")                                              \
16716 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16717 _(ipfix_classify_stream_dump, "")                                       \
16718 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16719 _(ipfix_classify_table_dump, "")                                        \
16720 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16721 _(pg_create_interface, "if_id <nn>")                                    \
16722 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16723 _(pg_enable_disable, "[stream <id>] disable")                           \
16724 _(ip_source_and_port_range_check_add_del,                               \
16725   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16726 _(ip_source_and_port_range_check_interface_add_del,                     \
16727   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16728   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16729 _(ipsec_gre_add_del_tunnel,                                             \
16730   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16731 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16732 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
16733 _(l2_interface_pbb_tag_rewrite,                                         \
16734   "<intfc> | sw_if_index <nn> \n"                                       \
16735   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16736   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16737 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16738 _(flow_classify_set_interface,                                          \
16739   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16740 _(flow_classify_dump, "type [ip4|ip6]")                                 \
16741 _(ip_fib_dump, "")                                                      \
16742 _(ip6_fib_dump, "")
16743
16744 /* List of command functions, CLI names map directly to functions */
16745 #define foreach_cli_function                                    \
16746 _(comment, "usage: comment <ignore-rest-of-line>")              \
16747 _(dump_interface_table, "usage: dump_interface_table")          \
16748 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16749 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16750 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16751 _(dump_stats_table, "usage: dump_stats_table")                  \
16752 _(dump_macro_table, "usage: dump_macro_table ")                 \
16753 _(dump_node_table, "usage: dump_node_table")                    \
16754 _(echo, "usage: echo <message>")                                \
16755 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16756 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16757 _(help, "usage: help")                                          \
16758 _(q, "usage: quit")                                             \
16759 _(quit, "usage: quit")                                          \
16760 _(search_node_table, "usage: search_node_table <name>...")      \
16761 _(set, "usage: set <variable-name> <value>")                    \
16762 _(script, "usage: script <file-name>")                          \
16763 _(unset, "usage: unset <variable-name>")
16764
16765 #define _(N,n)                                  \
16766     static void vl_api_##n##_t_handler_uni      \
16767     (vl_api_##n##_t * mp)                       \
16768     {                                           \
16769         vat_main_t * vam = &vat_main;           \
16770         if (vam->json_output) {                 \
16771             vl_api_##n##_t_handler_json(mp);    \
16772         } else {                                \
16773             vl_api_##n##_t_handler(mp);         \
16774         }                                       \
16775     }
16776 foreach_vpe_api_reply_msg;
16777 #undef _
16778
16779 void
16780 vat_api_hookup (vat_main_t * vam)
16781 {
16782 #define _(N,n)                                                  \
16783     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16784                            vl_api_##n##_t_handler_uni,          \
16785                            vl_noop_handler,                     \
16786                            vl_api_##n##_t_endian,               \
16787                            vl_api_##n##_t_print,                \
16788                            sizeof(vl_api_##n##_t), 1);
16789   foreach_vpe_api_reply_msg;
16790 #undef _
16791
16792   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16793
16794   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16795
16796   vam->function_by_name = hash_create_string (0, sizeof (uword));
16797
16798   vam->help_by_name = hash_create_string (0, sizeof (uword));
16799
16800   /* API messages we can send */
16801 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16802   foreach_vpe_api_msg;
16803 #undef _
16804
16805   /* Help strings */
16806 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16807   foreach_vpe_api_msg;
16808 #undef _
16809
16810   /* CLI functions */
16811 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16812   foreach_cli_function;
16813 #undef _
16814
16815   /* Help strings */
16816 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16817   foreach_cli_function;
16818 #undef _
16819 }
16820
16821 #undef vl_api_version
16822 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16823 #include <vpp-api/vpe.api.h>
16824 #undef vl_api_version
16825
16826 void
16827 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16828 {
16829   /*
16830    * Send the main API signature in slot 0. This bit of code must
16831    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16832    */
16833   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16834 }
16835
16836 /*
16837  * fd.io coding-style-patch-verification: ON
16838  *
16839  * Local Variables:
16840  * eval: (c-set-style "gnu")
16841  * End:
16842  */