Fix a batch of coverity warnings, VPP-486
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53
54 #include "vat/json_format.h"
55
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp-api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp-api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp-api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 uword
75 unformat_sw_if_index (unformat_input_t * input, va_list * args)
76 {
77   vat_main_t *vam = va_arg (*args, vat_main_t *);
78   u32 *result = va_arg (*args, u32 *);
79   u8 *if_name;
80   uword *p;
81
82   if (!unformat (input, "%s", &if_name))
83     return 0;
84
85   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
86   if (p == 0)
87     return 0;
88   *result = p[0];
89   return 1;
90 }
91
92 /* Parse an IP4 address %d.%d.%d.%d. */
93 uword
94 unformat_ip4_address (unformat_input_t * input, va_list * args)
95 {
96   u8 *result = va_arg (*args, u8 *);
97   unsigned a[4];
98
99   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
100     return 0;
101
102   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
103     return 0;
104
105   result[0] = a[0];
106   result[1] = a[1];
107   result[2] = a[2];
108   result[3] = a[3];
109
110   return 1;
111 }
112
113
114 uword
115 unformat_ethernet_address (unformat_input_t * input, va_list * args)
116 {
117   u8 *result = va_arg (*args, u8 *);
118   u32 i, a[6];
119
120   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
121                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
122     return 0;
123
124   /* Check range. */
125   for (i = 0; i < 6; i++)
126     if (a[i] >= (1 << 8))
127       return 0;
128
129   for (i = 0; i < 6; i++)
130     result[i] = a[i];
131
132   return 1;
133 }
134
135 /* Returns ethernet type as an int in host byte order. */
136 uword
137 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
138                                         va_list * args)
139 {
140   u16 *result = va_arg (*args, u16 *);
141   int type;
142
143   /* Numeric type. */
144   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
145     {
146       if (type >= (1 << 16))
147         return 0;
148       *result = type;
149       return 1;
150     }
151   return 0;
152 }
153
154 /* Parse an IP6 address. */
155 uword
156 unformat_ip6_address (unformat_input_t * input, va_list * args)
157 {
158   ip6_address_t *result = va_arg (*args, ip6_address_t *);
159   u16 hex_quads[8];
160   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
161   uword c, n_colon, double_colon_index;
162
163   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
164   double_colon_index = ARRAY_LEN (hex_quads);
165   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
166     {
167       hex_digit = 16;
168       if (c >= '0' && c <= '9')
169         hex_digit = c - '0';
170       else if (c >= 'a' && c <= 'f')
171         hex_digit = c + 10 - 'a';
172       else if (c >= 'A' && c <= 'F')
173         hex_digit = c + 10 - 'A';
174       else if (c == ':' && n_colon < 2)
175         n_colon++;
176       else
177         {
178           unformat_put_input (input);
179           break;
180         }
181
182       /* Too many hex quads. */
183       if (n_hex_quads >= ARRAY_LEN (hex_quads))
184         return 0;
185
186       if (hex_digit < 16)
187         {
188           hex_quad = (hex_quad << 4) | hex_digit;
189
190           /* Hex quad must fit in 16 bits. */
191           if (n_hex_digits >= 4)
192             return 0;
193
194           n_colon = 0;
195           n_hex_digits++;
196         }
197
198       /* Save position of :: */
199       if (n_colon == 2)
200         {
201           /* More than one :: ? */
202           if (double_colon_index < ARRAY_LEN (hex_quads))
203             return 0;
204           double_colon_index = n_hex_quads;
205         }
206
207       if (n_colon > 0 && n_hex_digits > 0)
208         {
209           hex_quads[n_hex_quads++] = hex_quad;
210           hex_quad = 0;
211           n_hex_digits = 0;
212         }
213     }
214
215   if (n_hex_digits > 0)
216     hex_quads[n_hex_quads++] = hex_quad;
217
218   {
219     word i;
220
221     /* Expand :: to appropriate number of zero hex quads. */
222     if (double_colon_index < ARRAY_LEN (hex_quads))
223       {
224         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
225
226         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
227           hex_quads[n_zero + i] = hex_quads[i];
228
229         for (i = 0; i < n_zero; i++)
230           hex_quads[double_colon_index + i] = 0;
231
232         n_hex_quads = ARRAY_LEN (hex_quads);
233       }
234
235     /* Too few hex quads given. */
236     if (n_hex_quads < ARRAY_LEN (hex_quads))
237       return 0;
238
239     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
240       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
241
242     return 1;
243   }
244 }
245
246 uword
247 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
248 {
249 #if DPDK > 0
250   u32 *r = va_arg (*args, u32 *);
251
252   if (0);
253 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254   foreach_ipsec_policy_action
255 #undef _
256     else
257     return 0;
258   return 1;
259 #else
260   return 0;
261 #endif
262 }
263
264 uword
265 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
266 {
267 #if DPDK > 0
268   u32 *r = va_arg (*args, u32 *);
269
270   if (0);
271 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
272   foreach_ipsec_crypto_alg
273 #undef _
274     else
275     return 0;
276   return 1;
277 #else
278   return 0;
279 #endif
280 }
281
282 u8 *
283 format_ipsec_crypto_alg (u8 * s, va_list * args)
284 {
285 #if DPDK > 0
286   u32 i = va_arg (*args, u32);
287   u8 *t = 0;
288
289   switch (i)
290     {
291 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
292       foreach_ipsec_crypto_alg
293 #undef _
294     default:
295       return format (s, "unknown");
296     }
297   return format (s, "%s", t);
298 #else
299   return format (s, "Unimplemented");
300 #endif
301 }
302
303 uword
304 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
305 {
306 #if DPDK > 0
307   u32 *r = va_arg (*args, u32 *);
308
309   if (0);
310 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
311   foreach_ipsec_integ_alg
312 #undef _
313     else
314     return 0;
315   return 1;
316 #else
317   return 0;
318 #endif
319 }
320
321 u8 *
322 format_ipsec_integ_alg (u8 * s, va_list * args)
323 {
324 #if DPDK > 0
325   u32 i = va_arg (*args, u32);
326   u8 *t = 0;
327
328   switch (i)
329     {
330 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
331       foreach_ipsec_integ_alg
332 #undef _
333     default:
334       return format (s, "unknown");
335     }
336   return format (s, "%s", t);
337 #else
338   return format (s, "Unsupported");
339 #endif
340 }
341
342 uword
343 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
344 {
345 #if DPDK > 0
346   u32 *r = va_arg (*args, u32 *);
347
348   if (0);
349 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
350   foreach_ikev2_auth_method
351 #undef _
352     else
353     return 0;
354   return 1;
355 #else
356   return 0;
357 #endif
358 }
359
360 uword
361 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
362 {
363 #if DPDK > 0
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
368   foreach_ikev2_id_type
369 #undef _
370     else
371     return 0;
372   return 1;
373 #else
374   return 0;
375 #endif
376 }
377
378 uword
379 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
380 {
381   u8 *r = va_arg (*args, u8 *);
382
383   if (unformat (input, "kbps"))
384     *r = SSE2_QOS_RATE_KBPS;
385   else if (unformat (input, "pps"))
386     *r = SSE2_QOS_RATE_PPS;
387   else
388     return 0;
389   return 1;
390 }
391
392 uword
393 unformat_policer_round_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "closest"))
398     *r = SSE2_QOS_ROUND_TO_CLOSEST;
399   else if (unformat (input, "up"))
400     *r = SSE2_QOS_ROUND_TO_UP;
401   else if (unformat (input, "down"))
402     *r = SSE2_QOS_ROUND_TO_DOWN;
403   else
404     return 0;
405   return 1;
406 }
407
408 uword
409 unformat_policer_type (unformat_input_t * input, va_list * args)
410 {
411   u8 *r = va_arg (*args, u8 *);
412
413   if (unformat (input, "1r2c"))
414     *r = SSE2_QOS_POLICER_TYPE_1R2C;
415   else if (unformat (input, "1r3c"))
416     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
417   else if (unformat (input, "2r3c-2698"))
418     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
419   else if (unformat (input, "2r3c-4115"))
420     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
421   else if (unformat (input, "2r3c-mef5cf1"))
422     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
423   else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_dscp (unformat_input_t * input, va_list * va)
430 {
431   u8 *r = va_arg (*va, u8 *);
432
433   if (0);
434 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
435   foreach_vnet_dscp
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_policer_action_type (unformat_input_t * input, va_list * va)
444 {
445   sse2_qos_pol_action_params_st *a
446     = va_arg (*va, sse2_qos_pol_action_params_st *);
447
448   if (unformat (input, "drop"))
449     a->action_type = SSE2_QOS_ACTION_DROP;
450   else if (unformat (input, "transmit"))
451     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
452   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
453     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
454   else
455     return 0;
456   return 1;
457 }
458
459 uword
460 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
461 {
462   u32 *r = va_arg (*va, u32 *);
463   u32 tid;
464
465   if (unformat (input, "ip4"))
466     tid = POLICER_CLASSIFY_TABLE_IP4;
467   else if (unformat (input, "ip6"))
468     tid = POLICER_CLASSIFY_TABLE_IP6;
469   else if (unformat (input, "l2"))
470     tid = POLICER_CLASSIFY_TABLE_L2;
471   else
472     return 0;
473
474   *r = tid;
475   return 1;
476 }
477
478 uword
479 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
480 {
481   u32 *r = va_arg (*va, u32 *);
482   u32 tid;
483
484   if (unformat (input, "ip4"))
485     tid = FLOW_CLASSIFY_TABLE_IP4;
486   else if (unformat (input, "ip6"))
487     tid = FLOW_CLASSIFY_TABLE_IP6;
488   else
489     return 0;
490
491   *r = tid;
492   return 1;
493 }
494
495 u8 *
496 format_ip4_address (u8 * s, va_list * args)
497 {
498   u8 *a = va_arg (*args, u8 *);
499   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
500 }
501
502 u8 *
503 format_ip6_address (u8 * s, va_list * args)
504 {
505   ip6_address_t *a = va_arg (*args, ip6_address_t *);
506   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
507
508   i_max_n_zero = ARRAY_LEN (a->as_u16);
509   max_n_zeros = 0;
510   i_first_zero = i_max_n_zero;
511   n_zeros = 0;
512   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
513     {
514       u32 is_zero = a->as_u16[i] == 0;
515       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
516         {
517           i_first_zero = i;
518           n_zeros = 0;
519         }
520       n_zeros += is_zero;
521       if ((!is_zero && n_zeros > max_n_zeros)
522           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
523         {
524           i_max_n_zero = i_first_zero;
525           max_n_zeros = n_zeros;
526           i_first_zero = ARRAY_LEN (a->as_u16);
527           n_zeros = 0;
528         }
529     }
530
531   last_double_colon = 0;
532   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
533     {
534       if (i == i_max_n_zero && max_n_zeros > 1)
535         {
536           s = format (s, "::");
537           i += max_n_zeros - 1;
538           last_double_colon = 1;
539         }
540       else
541         {
542           s = format (s, "%s%x",
543                       (last_double_colon || i == 0) ? "" : ":",
544                       clib_net_to_host_u16 (a->as_u16[i]));
545           last_double_colon = 0;
546         }
547     }
548
549   return s;
550 }
551
552 /* Format an IP46 address. */
553 u8 *
554 format_ip46_address (u8 * s, va_list * args)
555 {
556   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
557   ip46_type_t type = va_arg (*args, ip46_type_t);
558   int is_ip4 = 1;
559
560   switch (type)
561     {
562     case IP46_TYPE_ANY:
563       is_ip4 = ip46_address_is_ip4 (ip46);
564       break;
565     case IP46_TYPE_IP4:
566       is_ip4 = 1;
567       break;
568     case IP46_TYPE_IP6:
569       is_ip4 = 0;
570       break;
571     }
572
573   return is_ip4 ?
574     format (s, "%U", format_ip4_address, &ip46->ip4) :
575     format (s, "%U", format_ip6_address, &ip46->ip6);
576 }
577
578 u8 *
579 format_ethernet_address (u8 * s, va_list * args)
580 {
581   u8 *a = va_arg (*args, u8 *);
582
583   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
584                  a[0], a[1], a[2], a[3], a[4], a[5]);
585 }
586
587 void
588 increment_v4_address (ip4_address_t * a)
589 {
590   u32 v;
591
592   v = ntohl (a->as_u32) + 1;
593   a->as_u32 = ntohl (v);
594 }
595
596 void
597 increment_v6_address (ip6_address_t * a)
598 {
599   u64 v0, v1;
600
601   v0 = clib_net_to_host_u64 (a->as_u64[0]);
602   v1 = clib_net_to_host_u64 (a->as_u64[1]);
603
604   v1 += 1;
605   if (v1 == 0)
606     v0 += 1;
607   a->as_u64[0] = clib_net_to_host_u64 (v0);
608   a->as_u64[1] = clib_net_to_host_u64 (v1);
609 }
610
611 void
612 increment_mac_address (u64 * mac)
613 {
614   u64 tmp = *mac;
615
616   tmp = clib_net_to_host_u64 (tmp);
617   tmp += 1 << 16;               /* skip unused (least significant) octets */
618   tmp = clib_host_to_net_u64 (tmp);
619   *mac = tmp;
620 }
621
622 static void vl_api_create_loopback_reply_t_handler
623   (vl_api_create_loopback_reply_t * mp)
624 {
625   vat_main_t *vam = &vat_main;
626   i32 retval = ntohl (mp->retval);
627
628   vam->retval = retval;
629   vam->regenerate_interface_table = 1;
630   vam->sw_if_index = ntohl (mp->sw_if_index);
631   vam->result_ready = 1;
632 }
633
634 static void vl_api_create_loopback_reply_t_handler_json
635   (vl_api_create_loopback_reply_t * mp)
636 {
637   vat_main_t *vam = &vat_main;
638   vat_json_node_t node;
639
640   vat_json_init_object (&node);
641   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
642   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
643
644   vat_json_print (vam->ofp, &node);
645   vat_json_free (&node);
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_af_packet_create_reply_t_handler
651   (vl_api_af_packet_create_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_af_packet_create_reply_t_handler_json
663   (vl_api_af_packet_create_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_vlan_subif_reply_t_handler
680   (vl_api_create_vlan_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_vlan_subif_reply_t_handler_json
692   (vl_api_create_vlan_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_create_subif_reply_t_handler
709   (vl_api_create_subif_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->sw_if_index = ntohl (mp->sw_if_index);
717   vam->result_ready = 1;
718 }
719
720 static void vl_api_create_subif_reply_t_handler_json
721   (vl_api_create_subif_reply_t * mp)
722 {
723   vat_main_t *vam = &vat_main;
724   vat_json_node_t node;
725
726   vat_json_init_object (&node);
727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
729
730   vat_json_print (vam->ofp, &node);
731   vat_json_free (&node);
732
733   vam->retval = ntohl (mp->retval);
734   vam->result_ready = 1;
735 }
736
737 static void vl_api_interface_name_renumber_reply_t_handler
738   (vl_api_interface_name_renumber_reply_t * mp)
739 {
740   vat_main_t *vam = &vat_main;
741   i32 retval = ntohl (mp->retval);
742
743   vam->retval = retval;
744   vam->regenerate_interface_table = 1;
745   vam->result_ready = 1;
746 }
747
748 static void vl_api_interface_name_renumber_reply_t_handler_json
749   (vl_api_interface_name_renumber_reply_t * mp)
750 {
751   vat_main_t *vam = &vat_main;
752   vat_json_node_t node;
753
754   vat_json_init_object (&node);
755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
756
757   vat_json_print (vam->ofp, &node);
758   vat_json_free (&node);
759
760   vam->retval = ntohl (mp->retval);
761   vam->result_ready = 1;
762 }
763
764 /*
765  * Special-case: build the interface table, maintain
766  * the next loopback sw_if_index vbl.
767  */
768 static void vl_api_sw_interface_details_t_handler
769   (vl_api_sw_interface_details_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   u8 *s = format (0, "%s%c", mp->interface_name, 0);
773
774   hash_set_mem (vam->sw_if_index_by_interface_name, s,
775                 ntohl (mp->sw_if_index));
776
777   /* In sub interface case, fill the sub interface table entry */
778   if (mp->sw_if_index != mp->sup_sw_if_index)
779     {
780       sw_interface_subif_t *sub = NULL;
781
782       vec_add2 (vam->sw_if_subif_table, sub, 1);
783
784       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
785       strncpy ((char *) sub->interface_name, (char *) s,
786                vec_len (sub->interface_name));
787       sub->sw_if_index = ntohl (mp->sw_if_index);
788       sub->sub_id = ntohl (mp->sub_id);
789
790       sub->sub_dot1ad = mp->sub_dot1ad;
791       sub->sub_number_of_tags = mp->sub_number_of_tags;
792       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
793       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
794       sub->sub_exact_match = mp->sub_exact_match;
795       sub->sub_default = mp->sub_default;
796       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
797       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
798
799       /* vlan tag rewrite */
800       sub->vtr_op = ntohl (mp->vtr_op);
801       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
802       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
803       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
804     }
805 }
806
807 static void vl_api_sw_interface_details_t_handler_json
808   (vl_api_sw_interface_details_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t *node = NULL;
812
813   if (VAT_JSON_ARRAY != vam->json_tree.type)
814     {
815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
816       vat_json_init_array (&vam->json_tree);
817     }
818   node = vat_json_array_add (&vam->json_tree);
819
820   vat_json_init_object (node);
821   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
822   vat_json_object_add_uint (node, "sup_sw_if_index",
823                             ntohl (mp->sup_sw_if_index));
824   vat_json_object_add_uint (node, "l2_address_length",
825                             ntohl (mp->l2_address_length));
826   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
827                              sizeof (mp->l2_address));
828   vat_json_object_add_string_copy (node, "interface_name",
829                                    mp->interface_name);
830   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
831   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
832   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
833   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
834   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
835   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
836   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
837   vat_json_object_add_uint (node, "sub_number_of_tags",
838                             mp->sub_number_of_tags);
839   vat_json_object_add_uint (node, "sub_outer_vlan_id",
840                             ntohs (mp->sub_outer_vlan_id));
841   vat_json_object_add_uint (node, "sub_inner_vlan_id",
842                             ntohs (mp->sub_inner_vlan_id));
843   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
844   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
845   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
846                             mp->sub_outer_vlan_id_any);
847   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
848                             mp->sub_inner_vlan_id_any);
849   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
850   vat_json_object_add_uint (node, "vtr_push_dot1q",
851                             ntohl (mp->vtr_push_dot1q));
852   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
853   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
854 }
855
856 static void vl_api_sw_interface_set_flags_t_handler
857   (vl_api_sw_interface_set_flags_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   if (vam->interface_event_display)
861     errmsg ("interface flags: sw_if_index %d %s %s\n",
862             ntohl (mp->sw_if_index),
863             mp->admin_up_down ? "admin-up" : "admin-down",
864             mp->link_up_down ? "link-up" : "link-down");
865 }
866
867 static void vl_api_sw_interface_set_flags_t_handler_json
868   (vl_api_sw_interface_set_flags_t * mp)
869 {
870   /* JSON output not supported */
871 }
872
873 static void
874 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   i32 retval = ntohl (mp->retval);
878
879   vam->retval = retval;
880   vam->shmem_result = (u8 *) mp->reply_in_shmem;
881   vam->result_ready = 1;
882 }
883
884 static void
885 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   vat_json_node_t node;
889   api_main_t *am = &api_main;
890   void *oldheap;
891   u8 *reply;
892
893   vat_json_init_object (&node);
894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
895   vat_json_object_add_uint (&node, "reply_in_shmem",
896                             ntohl (mp->reply_in_shmem));
897   /* Toss the shared-memory original... */
898   pthread_mutex_lock (&am->vlib_rp->mutex);
899   oldheap = svm_push_data_heap (am->vlib_rp);
900
901   reply = (u8 *) (mp->reply_in_shmem);
902   vec_free (reply);
903
904   svm_pop_heap (oldheap);
905   pthread_mutex_unlock (&am->vlib_rp->mutex);
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 static void
915 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   i32 retval = ntohl (mp->retval);
919
920   vam->retval = retval;
921   vam->cmd_reply = mp->reply;
922   vam->result_ready = 1;
923 }
924
925 static void
926 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_string_copy (&node, "reply", mp->reply);
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_classify_add_del_table_reply_t_handler
943   (vl_api_classify_add_del_table_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947   if (vam->async_mode)
948     {
949       vam->async_errors += (retval < 0);
950     }
951   else
952     {
953       vam->retval = retval;
954       if (retval == 0 &&
955           ((mp->new_table_index != 0xFFFFFFFF) ||
956            (mp->skip_n_vectors != 0xFFFFFFFF) ||
957            (mp->match_n_vectors != 0xFFFFFFFF)))
958         /*
959          * Note: this is just barely thread-safe, depends on
960          * the main thread spinning waiting for an answer...
961          */
962         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
963                 ntohl (mp->new_table_index),
964                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
965       vam->result_ready = 1;
966     }
967 }
968
969 static void vl_api_classify_add_del_table_reply_t_handler_json
970   (vl_api_classify_add_del_table_reply_t * mp)
971 {
972   vat_main_t *vam = &vat_main;
973   vat_json_node_t node;
974
975   vat_json_init_object (&node);
976   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
977   vat_json_object_add_uint (&node, "new_table_index",
978                             ntohl (mp->new_table_index));
979   vat_json_object_add_uint (&node, "skip_n_vectors",
980                             ntohl (mp->skip_n_vectors));
981   vat_json_object_add_uint (&node, "match_n_vectors",
982                             ntohl (mp->match_n_vectors));
983
984   vat_json_print (vam->ofp, &node);
985   vat_json_free (&node);
986
987   vam->retval = ntohl (mp->retval);
988   vam->result_ready = 1;
989 }
990
991 static void vl_api_get_node_index_reply_t_handler
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   i32 retval = ntohl (mp->retval);
996   if (vam->async_mode)
997     {
998       vam->async_errors += (retval < 0);
999     }
1000   else
1001     {
1002       vam->retval = retval;
1003       if (retval == 0)
1004         errmsg ("node index %d\n", ntohl (mp->node_index));
1005       vam->result_ready = 1;
1006     }
1007 }
1008
1009 static void vl_api_get_node_index_reply_t_handler_json
1010   (vl_api_get_node_index_reply_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t node;
1014
1015   vat_json_init_object (&node);
1016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1017   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1018
1019   vat_json_print (vam->ofp, &node);
1020   vat_json_free (&node);
1021
1022   vam->retval = ntohl (mp->retval);
1023   vam->result_ready = 1;
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031   if (vam->async_mode)
1032     {
1033       vam->async_errors += (retval < 0);
1034     }
1035   else
1036     {
1037       vam->retval = retval;
1038       if (retval == 0)
1039         errmsg ("next node index %d\n", ntohl (mp->next_index));
1040       vam->result_ready = 1;
1041     }
1042 }
1043
1044 static void vl_api_get_next_index_reply_t_handler_json
1045   (vl_api_get_next_index_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049
1050   vat_json_init_object (&node);
1051   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1052   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1053
1054   vat_json_print (vam->ofp, &node);
1055   vat_json_free (&node);
1056
1057   vam->retval = ntohl (mp->retval);
1058   vam->result_ready = 1;
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   i32 retval = ntohl (mp->retval);
1066   if (vam->async_mode)
1067     {
1068       vam->async_errors += (retval < 0);
1069     }
1070   else
1071     {
1072       vam->retval = retval;
1073       if (retval == 0)
1074         errmsg ("next index %d\n", ntohl (mp->next_index));
1075       vam->result_ready = 1;
1076     }
1077 }
1078
1079 static void vl_api_add_node_next_reply_t_handler_json
1080   (vl_api_add_node_next_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   vat_json_node_t node;
1084
1085   vat_json_init_object (&node);
1086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1087   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1088
1089   vat_json_print (vam->ofp, &node);
1090   vat_json_free (&node);
1091
1092   vam->retval = ntohl (mp->retval);
1093   vam->result_ready = 1;
1094 }
1095
1096 static void vl_api_show_version_reply_t_handler
1097   (vl_api_show_version_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   i32 retval = ntohl (mp->retval);
1101
1102   if (retval >= 0)
1103     {
1104       errmsg ("        program: %s\n", mp->program);
1105       errmsg ("        version: %s\n", mp->version);
1106       errmsg ("     build date: %s\n", mp->build_date);
1107       errmsg ("build directory: %s\n", mp->build_directory);
1108     }
1109   vam->retval = retval;
1110   vam->result_ready = 1;
1111 }
1112
1113 static void vl_api_show_version_reply_t_handler_json
1114   (vl_api_show_version_reply_t * mp)
1115 {
1116   vat_main_t *vam = &vat_main;
1117   vat_json_node_t node;
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "program", mp->program);
1122   vat_json_object_add_string_copy (&node, "version", mp->version);
1123   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1124   vat_json_object_add_string_copy (&node, "build_directory",
1125                                    mp->build_directory);
1126
1127   vat_json_print (vam->ofp, &node);
1128   vat_json_free (&node);
1129
1130   vam->retval = ntohl (mp->retval);
1131   vam->result_ready = 1;
1132 }
1133
1134 static void
1135 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1136 {
1137   vat_main_t *vam = &vat_main;
1138   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1139           mp->mac_ip ? "mac/ip binding" : "address resolution",
1140           format_ip4_address, &mp->address,
1141           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1142 }
1143
1144 static void
1145 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1146 {
1147   /* JSON output not supported */
1148 }
1149
1150 static void
1151 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip6_address, mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 /*
1167  * Special-case: build the bridge domain table, maintain
1168  * the next bd id vbl.
1169  */
1170 static void vl_api_bridge_domain_details_t_handler
1171   (vl_api_bridge_domain_details_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1175
1176   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1177            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1178
1179   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1180            ntohl (mp->bd_id), mp->learn, mp->forward,
1181            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1182
1183   if (n_sw_ifs)
1184     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1185              "Interface Name");
1186 }
1187
1188 static void vl_api_bridge_domain_details_t_handler_json
1189   (vl_api_bridge_domain_details_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   vat_json_node_t *node, *array = NULL;
1193
1194   if (VAT_JSON_ARRAY != vam->json_tree.type)
1195     {
1196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1197       vat_json_init_array (&vam->json_tree);
1198     }
1199   node = vat_json_array_add (&vam->json_tree);
1200
1201   vat_json_init_object (node);
1202   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1203   vat_json_object_add_uint (node, "flood", mp->flood);
1204   vat_json_object_add_uint (node, "forward", mp->forward);
1205   vat_json_object_add_uint (node, "learn", mp->learn);
1206   vat_json_object_add_uint (node, "bvi_sw_if_index",
1207                             ntohl (mp->bvi_sw_if_index));
1208   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1209   array = vat_json_object_add (node, "sw_if");
1210   vat_json_init_array (array);
1211 }
1212
1213 /*
1214  * Special-case: build the bridge domain sw if table.
1215  */
1216 static void vl_api_bridge_domain_sw_if_details_t_handler
1217   (vl_api_bridge_domain_sw_if_details_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   hash_pair_t *p;
1221   u8 *sw_if_name = 0;
1222   u32 sw_if_index;
1223
1224   sw_if_index = ntohl (mp->sw_if_index);
1225   /* *INDENT-OFF* */
1226   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1227   ({
1228     if ((u32) p->value[0] == sw_if_index)
1229       {
1230         sw_if_name = (u8 *)(p->key);
1231         break;
1232       }
1233   }));
1234   /* *INDENT-ON* */
1235
1236   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1237            mp->shg, sw_if_name ? (char *) sw_if_name :
1238            "sw_if_index not found!");
1239 }
1240
1241 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1242   (vl_api_bridge_domain_sw_if_details_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t *node = NULL;
1246   uword last_index = 0;
1247
1248   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1249   ASSERT (vec_len (vam->json_tree.array) >= 1);
1250   last_index = vec_len (vam->json_tree.array) - 1;
1251   node = &vam->json_tree.array[last_index];
1252   node = vat_json_object_get_element (node, "sw_if");
1253   ASSERT (NULL != node);
1254   node = vat_json_array_add (node);
1255
1256   vat_json_init_object (node);
1257   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1258   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1259   vat_json_object_add_uint (node, "shg", mp->shg);
1260 }
1261
1262 static void vl_api_control_ping_reply_t_handler
1263   (vl_api_control_ping_reply_t * mp)
1264 {
1265   vat_main_t *vam = &vat_main;
1266   i32 retval = ntohl (mp->retval);
1267   if (vam->async_mode)
1268     {
1269       vam->async_errors += (retval < 0);
1270     }
1271   else
1272     {
1273       vam->retval = retval;
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler_json
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283
1284   if (VAT_JSON_NONE != vam->json_tree.type)
1285     {
1286       vat_json_print (vam->ofp, &vam->json_tree);
1287       vat_json_free (&vam->json_tree);
1288       vam->json_tree.type = VAT_JSON_NONE;
1289     }
1290   else
1291     {
1292       /* just print [] */
1293       vat_json_init_array (&vam->json_tree);
1294       vat_json_print (vam->ofp, &vam->json_tree);
1295       vam->json_tree.type = VAT_JSON_NONE;
1296     }
1297
1298   vam->retval = retval;
1299   vam->result_ready = 1;
1300 }
1301
1302 static void
1303 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   i32 retval = ntohl (mp->retval);
1307   if (vam->async_mode)
1308     {
1309       vam->async_errors += (retval < 0);
1310     }
1311   else
1312     {
1313       vam->retval = retval;
1314       vam->result_ready = 1;
1315     }
1316 }
1317
1318 static void vl_api_l2_flags_reply_t_handler_json
1319   (vl_api_l2_flags_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   vat_json_node_t node;
1323
1324   vat_json_init_object (&node);
1325   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1326   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1327                             ntohl (mp->resulting_feature_bitmap));
1328
1329   vat_json_print (vam->ofp, &node);
1330   vat_json_free (&node);
1331
1332   vam->retval = ntohl (mp->retval);
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_bridge_flags_reply_t_handler
1337   (vl_api_bridge_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   i32 retval = ntohl (mp->retval);
1341   if (vam->async_mode)
1342     {
1343       vam->async_errors += (retval < 0);
1344     }
1345   else
1346     {
1347       vam->retval = retval;
1348       vam->result_ready = 1;
1349     }
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler_json
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   vat_json_node_t node;
1357
1358   vat_json_init_object (&node);
1359   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1360   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1361                             ntohl (mp->resulting_feature_bitmap));
1362
1363   vat_json_print (vam->ofp, &node);
1364   vat_json_free (&node);
1365
1366   vam->retval = ntohl (mp->retval);
1367   vam->result_ready = 1;
1368 }
1369
1370 static void vl_api_tap_connect_reply_t_handler
1371   (vl_api_tap_connect_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   i32 retval = ntohl (mp->retval);
1375   if (vam->async_mode)
1376     {
1377       vam->async_errors += (retval < 0);
1378     }
1379   else
1380     {
1381       vam->retval = retval;
1382       vam->sw_if_index = ntohl (mp->sw_if_index);
1383       vam->result_ready = 1;
1384     }
1385
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler_json
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   vat_json_node_t node;
1393
1394   vat_json_init_object (&node);
1395   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1396   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1397
1398   vat_json_print (vam->ofp, &node);
1399   vat_json_free (&node);
1400
1401   vam->retval = ntohl (mp->retval);
1402   vam->result_ready = 1;
1403
1404 }
1405
1406 static void
1407 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   i32 retval = ntohl (mp->retval);
1411   if (vam->async_mode)
1412     {
1413       vam->async_errors += (retval < 0);
1414     }
1415   else
1416     {
1417       vam->retval = retval;
1418       vam->sw_if_index = ntohl (mp->sw_if_index);
1419       vam->result_ready = 1;
1420     }
1421 }
1422
1423 static void vl_api_tap_modify_reply_t_handler_json
1424   (vl_api_tap_modify_reply_t * mp)
1425 {
1426   vat_main_t *vam = &vat_main;
1427   vat_json_node_t node;
1428
1429   vat_json_init_object (&node);
1430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1431   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1432
1433   vat_json_print (vam->ofp, &node);
1434   vat_json_free (&node);
1435
1436   vam->retval = ntohl (mp->retval);
1437   vam->result_ready = 1;
1438 }
1439
1440 static void
1441 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   i32 retval = ntohl (mp->retval);
1445   if (vam->async_mode)
1446     {
1447       vam->async_errors += (retval < 0);
1448     }
1449   else
1450     {
1451       vam->retval = retval;
1452       vam->result_ready = 1;
1453     }
1454 }
1455
1456 static void vl_api_tap_delete_reply_t_handler_json
1457   (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   vat_json_node_t node;
1461
1462   vat_json_init_object (&node);
1463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1464
1465   vat_json_print (vam->ofp, &node);
1466   vat_json_free (&node);
1467
1468   vam->retval = ntohl (mp->retval);
1469   vam->result_ready = 1;
1470 }
1471
1472 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1473   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   i32 retval = ntohl (mp->retval);
1477   if (vam->async_mode)
1478     {
1479       vam->async_errors += (retval < 0);
1480     }
1481   else
1482     {
1483       vam->retval = retval;
1484       vam->result_ready = 1;
1485     }
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   vat_json_node_t node;
1493
1494   vat_json_init_object (&node);
1495   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1496   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1497                             ntohl (mp->tunnel_sw_if_index));
1498
1499   vat_json_print (vam->ofp, &node);
1500   vat_json_free (&node);
1501
1502   vam->retval = ntohl (mp->retval);
1503   vam->result_ready = 1;
1504 }
1505
1506 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1507   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   i32 retval = ntohl (mp->retval);
1511   if (vam->async_mode)
1512     {
1513       vam->async_errors += (retval < 0);
1514     }
1515   else
1516     {
1517       vam->retval = retval;
1518       vam->sw_if_index = ntohl (mp->sw_if_index);
1519       vam->result_ready = 1;
1520     }
1521 }
1522
1523 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1524   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1525 {
1526   vat_main_t *vam = &vat_main;
1527   vat_json_node_t node;
1528
1529   vat_json_init_object (&node);
1530   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1531   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540
1541 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1542   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   i32 retval = ntohl (mp->retval);
1546   if (vam->async_mode)
1547     {
1548       vam->async_errors += (retval < 0);
1549     }
1550   else
1551     {
1552       vam->retval = retval;
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   vat_json_node_t node;
1562
1563   vat_json_init_object (&node);
1564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1565   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1575   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->sw_if_index = ntohl (mp->sw_if_index);
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1592   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   vat_json_node_t node;
1596
1597   vat_json_init_object (&node);
1598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1599   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_gre_add_del_tunnel_reply_t_handler
1609   (vl_api_gre_add_del_tunnel_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623 }
1624
1625 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1626   (vl_api_gre_add_del_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   vat_json_node_t node;
1630
1631   vat_json_init_object (&node);
1632   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1633   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1634
1635   vat_json_print (vam->ofp, &node);
1636   vat_json_free (&node);
1637
1638   vam->retval = ntohl (mp->retval);
1639   vam->result_ready = 1;
1640 }
1641
1642 static void vl_api_create_vhost_user_if_reply_t_handler
1643   (vl_api_create_vhost_user_if_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   i32 retval = ntohl (mp->retval);
1647   if (vam->async_mode)
1648     {
1649       vam->async_errors += (retval < 0);
1650     }
1651   else
1652     {
1653       vam->retval = retval;
1654       vam->sw_if_index = ntohl (mp->sw_if_index);
1655       vam->result_ready = 1;
1656     }
1657 }
1658
1659 static void vl_api_create_vhost_user_if_reply_t_handler_json
1660   (vl_api_create_vhost_user_if_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   vat_json_node_t node;
1664
1665   vat_json_init_object (&node);
1666   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1667   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1668
1669   vat_json_print (vam->ofp, &node);
1670   vat_json_free (&node);
1671
1672   vam->retval = ntohl (mp->retval);
1673   vam->result_ready = 1;
1674 }
1675
1676 static void vl_api_ip_address_details_t_handler
1677   (vl_api_ip_address_details_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   static ip_address_details_t empty_ip_address_details = { {0} };
1681   ip_address_details_t *address = NULL;
1682   ip_details_t *current_ip_details = NULL;
1683   ip_details_t *details = NULL;
1684
1685   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1686
1687   if (!details || vam->current_sw_if_index >= vec_len (details)
1688       || !details[vam->current_sw_if_index].present)
1689     {
1690       errmsg ("ip address details arrived but not stored\n");
1691       errmsg ("ip_dump should be called first\n");
1692       return;
1693     }
1694
1695   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1696
1697 #define addresses (current_ip_details->addr)
1698
1699   vec_validate_init_empty (addresses, vec_len (addresses),
1700                            empty_ip_address_details);
1701
1702   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1703
1704   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1705   address->prefix_length = mp->prefix_length;
1706 #undef addresses
1707 }
1708
1709 static void vl_api_ip_address_details_t_handler_json
1710   (vl_api_ip_address_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   vat_json_node_t *node = NULL;
1714   struct in6_addr ip6;
1715   struct in_addr ip4;
1716
1717   if (VAT_JSON_ARRAY != vam->json_tree.type)
1718     {
1719       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1720       vat_json_init_array (&vam->json_tree);
1721     }
1722   node = vat_json_array_add (&vam->json_tree);
1723
1724   vat_json_init_object (node);
1725   if (vam->is_ipv6)
1726     {
1727       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1728       vat_json_object_add_ip6 (node, "ip", ip6);
1729     }
1730   else
1731     {
1732       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1733       vat_json_object_add_ip4 (node, "ip", ip4);
1734     }
1735   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1736 }
1737
1738 static void
1739 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   static ip_details_t empty_ip_details = { 0 };
1743   ip_details_t *ip = NULL;
1744   u32 sw_if_index = ~0;
1745
1746   sw_if_index = ntohl (mp->sw_if_index);
1747
1748   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1749                            sw_if_index, empty_ip_details);
1750
1751   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1752                          sw_if_index);
1753
1754   ip->present = 1;
1755 }
1756
1757 static void
1758 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1759 {
1760   vat_main_t *vam = &vat_main;
1761
1762   if (VAT_JSON_ARRAY != vam->json_tree.type)
1763     {
1764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1765       vat_json_init_array (&vam->json_tree);
1766     }
1767   vat_json_array_add_uint (&vam->json_tree,
1768                            clib_net_to_host_u32 (mp->sw_if_index));
1769 }
1770
1771 static void vl_api_map_domain_details_t_handler_json
1772   (vl_api_map_domain_details_t * mp)
1773 {
1774   vat_json_node_t *node = NULL;
1775   vat_main_t *vam = &vat_main;
1776   struct in6_addr ip6;
1777   struct in_addr ip4;
1778
1779   if (VAT_JSON_ARRAY != vam->json_tree.type)
1780     {
1781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1782       vat_json_init_array (&vam->json_tree);
1783     }
1784
1785   node = vat_json_array_add (&vam->json_tree);
1786   vat_json_init_object (node);
1787
1788   vat_json_object_add_uint (node, "domain_index",
1789                             clib_net_to_host_u32 (mp->domain_index));
1790   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1791   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1792   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1793   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1794   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1795   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1796   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1797   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1798   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1799   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1800   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1801   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1802   vat_json_object_add_uint (node, "flags", mp->flags);
1803   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1804   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1805 }
1806
1807 static void vl_api_map_domain_details_t_handler
1808   (vl_api_map_domain_details_t * mp)
1809 {
1810   vat_main_t *vam = &vat_main;
1811
1812   if (mp->is_translation)
1813     {
1814       fformat (vam->ofp,
1815                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1816                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1817                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1818                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1819                clib_net_to_host_u32 (mp->domain_index));
1820     }
1821   else
1822     {
1823       fformat (vam->ofp,
1824                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1825                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1826                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1827                format_ip6_address, mp->ip6_src,
1828                clib_net_to_host_u32 (mp->domain_index));
1829     }
1830   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1831            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1832            mp->is_translation ? "map-t" : "");
1833 }
1834
1835 static void vl_api_map_rule_details_t_handler_json
1836   (vl_api_map_rule_details_t * mp)
1837 {
1838   struct in6_addr ip6;
1839   vat_json_node_t *node = NULL;
1840   vat_main_t *vam = &vat_main;
1841
1842   if (VAT_JSON_ARRAY != vam->json_tree.type)
1843     {
1844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1845       vat_json_init_array (&vam->json_tree);
1846     }
1847
1848   node = vat_json_array_add (&vam->json_tree);
1849   vat_json_init_object (node);
1850
1851   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1852   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1853   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1854 }
1855
1856 static void
1857 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1861            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1862 }
1863
1864 static void
1865 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1869           "router_addr %U host_mac %U\n",
1870           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1871           format_ip4_address, &mp->host_address,
1872           format_ip4_address, &mp->router_address,
1873           format_ethernet_address, mp->host_mac);
1874 }
1875
1876 static void vl_api_dhcp_compl_event_t_handler_json
1877   (vl_api_dhcp_compl_event_t * mp)
1878 {
1879   /* JSON output not supported */
1880 }
1881
1882 static void
1883 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1884                               u32 counter)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   static u64 default_counter = 0;
1888
1889   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1890                            NULL);
1891   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1892                            sw_if_index, default_counter);
1893   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1894 }
1895
1896 static void
1897 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1898                                 interface_counter_t counter)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   static interface_counter_t default_counter = { 0, };
1902
1903   vec_validate_init_empty (vam->combined_interface_counters,
1904                            vnet_counter_type, NULL);
1905   vec_validate_init_empty (vam->combined_interface_counters
1906                            [vnet_counter_type], sw_if_index, default_counter);
1907   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1908 }
1909
1910 static void vl_api_vnet_interface_counters_t_handler
1911   (vl_api_vnet_interface_counters_t * mp)
1912 {
1913   /* not supported */
1914 }
1915
1916 static void vl_api_vnet_interface_counters_t_handler_json
1917   (vl_api_vnet_interface_counters_t * mp)
1918 {
1919   interface_counter_t counter;
1920   vlib_counter_t *v;
1921   u64 *v_packets;
1922   u64 packets;
1923   u32 count;
1924   u32 first_sw_if_index;
1925   int i;
1926
1927   count = ntohl (mp->count);
1928   first_sw_if_index = ntohl (mp->first_sw_if_index);
1929
1930   if (!mp->is_combined)
1931     {
1932       v_packets = (u64 *) & mp->data;
1933       for (i = 0; i < count; i++)
1934         {
1935           packets =
1936             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1937           set_simple_interface_counter (mp->vnet_counter_type,
1938                                         first_sw_if_index + i, packets);
1939           v_packets++;
1940         }
1941     }
1942   else
1943     {
1944       v = (vlib_counter_t *) & mp->data;
1945       for (i = 0; i < count; i++)
1946         {
1947           counter.packets =
1948             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1949           counter.bytes =
1950             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1951           set_combined_interface_counter (mp->vnet_counter_type,
1952                                           first_sw_if_index + i, counter);
1953           v++;
1954         }
1955     }
1956 }
1957
1958 static u32
1959 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   u32 i;
1963
1964   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1965     {
1966       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1967         {
1968           return i;
1969         }
1970     }
1971   return ~0;
1972 }
1973
1974 static u32
1975 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static void vl_api_vnet_ip4_fib_counters_t_handler
1991   (vl_api_vnet_ip4_fib_counters_t * mp)
1992 {
1993   /* not supported */
1994 }
1995
1996 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1997   (vl_api_vnet_ip4_fib_counters_t * mp)
1998 {
1999   vat_main_t *vam = &vat_main;
2000   vl_api_ip4_fib_counter_t *v;
2001   ip4_fib_counter_t *counter;
2002   struct in_addr ip4;
2003   u32 vrf_id;
2004   u32 vrf_index;
2005   u32 count;
2006   int i;
2007
2008   vrf_id = ntohl (mp->vrf_id);
2009   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2010   if (~0 == vrf_index)
2011     {
2012       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2013       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2014       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2015       vec_validate (vam->ip4_fib_counters, vrf_index);
2016       vam->ip4_fib_counters[vrf_index] = NULL;
2017     }
2018
2019   vec_free (vam->ip4_fib_counters[vrf_index]);
2020   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2021   count = ntohl (mp->count);
2022   for (i = 0; i < count; i++)
2023     {
2024       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2025       counter = &vam->ip4_fib_counters[vrf_index][i];
2026       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2027       counter->address = ip4;
2028       counter->address_length = v->address_length;
2029       counter->packets = clib_net_to_host_u64 (v->packets);
2030       counter->bytes = clib_net_to_host_u64 (v->bytes);
2031       v++;
2032     }
2033 }
2034
2035 static void vl_api_vnet_ip6_fib_counters_t_handler
2036   (vl_api_vnet_ip6_fib_counters_t * mp)
2037 {
2038   /* not supported */
2039 }
2040
2041 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2042   (vl_api_vnet_ip6_fib_counters_t * mp)
2043 {
2044   vat_main_t *vam = &vat_main;
2045   vl_api_ip6_fib_counter_t *v;
2046   ip6_fib_counter_t *counter;
2047   struct in6_addr ip6;
2048   u32 vrf_id;
2049   u32 vrf_index;
2050   u32 count;
2051   int i;
2052
2053   vrf_id = ntohl (mp->vrf_id);
2054   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2055   if (~0 == vrf_index)
2056     {
2057       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2058       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2059       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2060       vec_validate (vam->ip6_fib_counters, vrf_index);
2061       vam->ip6_fib_counters[vrf_index] = NULL;
2062     }
2063
2064   vec_free (vam->ip6_fib_counters[vrf_index]);
2065   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2066   count = ntohl (mp->count);
2067   for (i = 0; i < count; i++)
2068     {
2069       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2070       counter = &vam->ip6_fib_counters[vrf_index][i];
2071       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2072       counter->address = ip6;
2073       counter->address_length = v->address_length;
2074       counter->packets = clib_net_to_host_u64 (v->packets);
2075       counter->bytes = clib_net_to_host_u64 (v->bytes);
2076       v++;
2077     }
2078 }
2079
2080 static void vl_api_get_first_msg_id_reply_t_handler
2081   (vl_api_get_first_msg_id_reply_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   i32 retval = ntohl (mp->retval);
2085
2086   if (vam->async_mode)
2087     {
2088       vam->async_errors += (retval < 0);
2089     }
2090   else
2091     {
2092       vam->retval = retval;
2093       vam->result_ready = 1;
2094     }
2095   if (retval >= 0)
2096     {
2097       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2098     }
2099 }
2100
2101 static void vl_api_get_first_msg_id_reply_t_handler_json
2102   (vl_api_get_first_msg_id_reply_t * mp)
2103 {
2104   vat_main_t *vam = &vat_main;
2105   vat_json_node_t node;
2106
2107   vat_json_init_object (&node);
2108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2109   vat_json_object_add_uint (&node, "first_msg_id",
2110                             (uint) ntohs (mp->first_msg_id));
2111
2112   vat_json_print (vam->ofp, &node);
2113   vat_json_free (&node);
2114
2115   vam->retval = ntohl (mp->retval);
2116   vam->result_ready = 1;
2117 }
2118
2119 static void vl_api_get_node_graph_reply_t_handler
2120   (vl_api_get_node_graph_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   api_main_t *am = &api_main;
2124   i32 retval = ntohl (mp->retval);
2125   u8 *pvt_copy, *reply;
2126   void *oldheap;
2127   vlib_node_t *node;
2128   int i;
2129
2130   if (vam->async_mode)
2131     {
2132       vam->async_errors += (retval < 0);
2133     }
2134   else
2135     {
2136       vam->retval = retval;
2137       vam->result_ready = 1;
2138     }
2139
2140   /* "Should never happen..." */
2141   if (retval != 0)
2142     return;
2143
2144   reply = (u8 *) (mp->reply_in_shmem);
2145   pvt_copy = vec_dup (reply);
2146
2147   /* Toss the shared-memory original... */
2148   pthread_mutex_lock (&am->vlib_rp->mutex);
2149   oldheap = svm_push_data_heap (am->vlib_rp);
2150
2151   vec_free (reply);
2152
2153   svm_pop_heap (oldheap);
2154   pthread_mutex_unlock (&am->vlib_rp->mutex);
2155
2156   if (vam->graph_nodes)
2157     {
2158       hash_free (vam->graph_node_index_by_name);
2159
2160       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2161         {
2162           node = vam->graph_nodes[i];
2163           vec_free (node->name);
2164           vec_free (node->next_nodes);
2165           vec_free (node);
2166         }
2167       vec_free (vam->graph_nodes);
2168     }
2169
2170   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2171   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2172   vec_free (pvt_copy);
2173
2174   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2175     {
2176       node = vam->graph_nodes[i];
2177       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2178     }
2179 }
2180
2181 static void vl_api_get_node_graph_reply_t_handler_json
2182   (vl_api_get_node_graph_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   api_main_t *am = &api_main;
2186   void *oldheap;
2187   vat_json_node_t node;
2188   u8 *reply;
2189
2190   /* $$$$ make this real? */
2191   vat_json_init_object (&node);
2192   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2193   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2194
2195   reply = (u8 *) (mp->reply_in_shmem);
2196
2197   /* Toss the shared-memory original... */
2198   pthread_mutex_lock (&am->vlib_rp->mutex);
2199   oldheap = svm_push_data_heap (am->vlib_rp);
2200
2201   vec_free (reply);
2202
2203   svm_pop_heap (oldheap);
2204   pthread_mutex_unlock (&am->vlib_rp->mutex);
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void
2214 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   u8 *s = 0;
2218
2219   if (mp->local)
2220     {
2221       s = format (s, "%=16d%=16d%=16d\n",
2222                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2223     }
2224   else
2225     {
2226       s = format (s, "%=16U%=16d%=16d\n",
2227                   mp->is_ipv6 ? format_ip6_address :
2228                   format_ip4_address,
2229                   mp->ip_address, mp->priority, mp->weight);
2230     }
2231
2232   fformat (vam->ofp, "%v", s);
2233   vec_free (s);
2234 }
2235
2236 static void
2237 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2238                                             mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   vat_json_node_t *node = NULL;
2242   struct in6_addr ip6;
2243   struct in_addr ip4;
2244
2245   if (VAT_JSON_ARRAY != vam->json_tree.type)
2246     {
2247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2248       vat_json_init_array (&vam->json_tree);
2249     }
2250   node = vat_json_array_add (&vam->json_tree);
2251   vat_json_init_object (node);
2252
2253   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2254   vat_json_object_add_uint (node, "priority", mp->priority);
2255   vat_json_object_add_uint (node, "weight", mp->weight);
2256
2257   if (mp->local)
2258     vat_json_object_add_uint (node, "sw_if_index",
2259                               clib_net_to_host_u32 (mp->sw_if_index));
2260   else
2261     {
2262       if (mp->is_ipv6)
2263         {
2264           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2265           vat_json_object_add_ip6 (node, "address", ip6);
2266         }
2267       else
2268         {
2269           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2270           vat_json_object_add_ip4 (node, "address", ip4);
2271         }
2272     }
2273 }
2274
2275 static void
2276 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2277                                            mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   u8 *ls_name = 0;
2281
2282   ls_name = format (0, "%s", mp->ls_name);
2283
2284   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2285            ls_name);
2286   vec_free (ls_name);
2287 }
2288
2289 static void
2290   vl_api_lisp_locator_set_details_t_handler_json
2291   (vl_api_lisp_locator_set_details_t * mp)
2292 {
2293   vat_main_t *vam = &vat_main;
2294   vat_json_node_t *node = 0;
2295   u8 *ls_name = 0;
2296
2297   ls_name = format (0, "%s", mp->ls_name);
2298   vec_add1 (ls_name, 0);
2299
2300   if (VAT_JSON_ARRAY != vam->json_tree.type)
2301     {
2302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2303       vat_json_init_array (&vam->json_tree);
2304     }
2305   node = vat_json_array_add (&vam->json_tree);
2306
2307   vat_json_init_object (node);
2308   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2309   vat_json_object_add_uint (node, "ls_index",
2310                             clib_net_to_host_u32 (mp->ls_index));
2311   vec_free (ls_name);
2312 }
2313
2314 static u8 *
2315 format_lisp_flat_eid (u8 * s, va_list * args)
2316 {
2317   u32 type = va_arg (*args, u32);
2318   u8 *eid = va_arg (*args, u8 *);
2319   u32 eid_len = va_arg (*args, u32);
2320
2321   switch (type)
2322     {
2323     case 0:
2324       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2325     case 1:
2326       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2327     case 2:
2328       return format (s, "%U", format_ethernet_address, eid);
2329     }
2330   return 0;
2331 }
2332
2333 static u8 *
2334 format_lisp_eid_vat (u8 * s, va_list * args)
2335 {
2336   u32 type = va_arg (*args, u32);
2337   u8 *eid = va_arg (*args, u8 *);
2338   u32 eid_len = va_arg (*args, u32);
2339   u8 *seid = va_arg (*args, u8 *);
2340   u32 seid_len = va_arg (*args, u32);
2341   u32 is_src_dst = va_arg (*args, u32);
2342
2343   if (is_src_dst)
2344     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2345
2346   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2347
2348   return s;
2349 }
2350
2351 static void
2352 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   u8 *s = 0, *eid = 0;
2356
2357   if (~0 == mp->locator_set_index)
2358     s = format (0, "action: %d", mp->action);
2359   else
2360     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2361
2362   eid = format (0, "%U", format_lisp_eid_vat,
2363                 mp->eid_type,
2364                 mp->eid,
2365                 mp->eid_prefix_len,
2366                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2367   vec_add1 (eid, 0);
2368
2369   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2370            clib_net_to_host_u32 (mp->vni),
2371            eid,
2372            mp->is_local ? "local" : "remote",
2373            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2374   vec_free (s);
2375   vec_free (eid);
2376 }
2377
2378 static void
2379 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2380                                               * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   vat_json_node_t *node = 0;
2384   u8 *eid = 0;
2385
2386   if (VAT_JSON_ARRAY != vam->json_tree.type)
2387     {
2388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2389       vat_json_init_array (&vam->json_tree);
2390     }
2391   node = vat_json_array_add (&vam->json_tree);
2392
2393   vat_json_init_object (node);
2394   if (~0 == mp->locator_set_index)
2395     vat_json_object_add_uint (node, "action", mp->action);
2396   else
2397     vat_json_object_add_uint (node, "locator_set_index",
2398                               clib_net_to_host_u32 (mp->locator_set_index));
2399
2400   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2401   eid = format (0, "%U", format_lisp_eid_vat,
2402                 mp->eid_type,
2403                 mp->eid,
2404                 mp->eid_prefix_len,
2405                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2406   vec_add1 (eid, 0);
2407   vat_json_object_add_string_copy (node, "eid", eid);
2408   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2409   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2410   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2411   vec_free (eid);
2412 }
2413
2414 static void
2415   vl_api_lisp_eid_table_map_details_t_handler
2416   (vl_api_lisp_eid_table_map_details_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419
2420   u8 *line = format (0, "%=10d%=10d",
2421                      clib_net_to_host_u32 (mp->vni),
2422                      clib_net_to_host_u32 (mp->dp_table));
2423   fformat (vam->ofp, "%v\n", line);
2424   vec_free (line);
2425 }
2426
2427 static void
2428   vl_api_lisp_eid_table_map_details_t_handler_json
2429   (vl_api_lisp_eid_table_map_details_t * mp)
2430 {
2431   vat_main_t *vam = &vat_main;
2432   vat_json_node_t *node = NULL;
2433
2434   if (VAT_JSON_ARRAY != vam->json_tree.type)
2435     {
2436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2437       vat_json_init_array (&vam->json_tree);
2438     }
2439   node = vat_json_array_add (&vam->json_tree);
2440   vat_json_init_object (node);
2441   vat_json_object_add_uint (node, "dp_table",
2442                             clib_net_to_host_u32 (mp->dp_table));
2443   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2444 }
2445
2446 static void
2447   vl_api_lisp_eid_table_vni_details_t_handler
2448   (vl_api_lisp_eid_table_vni_details_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451
2452   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2453   fformat (vam->ofp, "%v\n", line);
2454   vec_free (line);
2455 }
2456
2457 static void
2458   vl_api_lisp_eid_table_vni_details_t_handler_json
2459   (vl_api_lisp_eid_table_vni_details_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   vat_json_node_t *node = NULL;
2463
2464   if (VAT_JSON_ARRAY != vam->json_tree.type)
2465     {
2466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2467       vat_json_init_array (&vam->json_tree);
2468     }
2469   node = vat_json_array_add (&vam->json_tree);
2470   vat_json_init_object (node);
2471   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2472 }
2473
2474 static u8 *
2475 format_decap_next (u8 * s, va_list * args)
2476 {
2477   u32 next_index = va_arg (*args, u32);
2478
2479   switch (next_index)
2480     {
2481     case LISP_GPE_INPUT_NEXT_DROP:
2482       return format (s, "drop");
2483     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2484       return format (s, "ip4");
2485     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2486       return format (s, "ip6");
2487     default:
2488       return format (s, "unknown %d", next_index);
2489     }
2490   return s;
2491 }
2492
2493 static void
2494 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2495                                           mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   u8 *iid_str;
2499   u8 *flag_str = NULL;
2500
2501   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2502
2503 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2504   foreach_lisp_gpe_flag_bit;
2505 #undef _
2506
2507   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2508            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2509            mp->tunnels,
2510            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2511            mp->source_ip,
2512            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2513            mp->destination_ip,
2514            ntohl (mp->encap_fib_id),
2515            ntohl (mp->decap_fib_id),
2516            format_decap_next, ntohl (mp->dcap_next),
2517            mp->ver_res >> 6,
2518            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2519
2520   vec_free (iid_str);
2521 }
2522
2523 static void
2524   vl_api_lisp_gpe_tunnel_details_t_handler_json
2525   (vl_api_lisp_gpe_tunnel_details_t * mp)
2526 {
2527   vat_main_t *vam = &vat_main;
2528   vat_json_node_t *node = NULL;
2529   struct in6_addr ip6;
2530   struct in_addr ip4;
2531   u8 *next_decap_str;
2532
2533   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2534
2535   if (VAT_JSON_ARRAY != vam->json_tree.type)
2536     {
2537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2538       vat_json_init_array (&vam->json_tree);
2539     }
2540   node = vat_json_array_add (&vam->json_tree);
2541
2542   vat_json_init_object (node);
2543   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2544   if (mp->is_ipv6)
2545     {
2546       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2547       vat_json_object_add_ip6 (node, "source address", ip6);
2548       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2549       vat_json_object_add_ip6 (node, "destination address", ip6);
2550     }
2551   else
2552     {
2553       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2554       vat_json_object_add_ip4 (node, "source address", ip4);
2555       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2556       vat_json_object_add_ip4 (node, "destination address", ip4);
2557     }
2558   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2559   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2560   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2561   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2562   vat_json_object_add_uint (node, "flags", mp->flags);
2563   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2564   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2565   vat_json_object_add_uint (node, "res", mp->res);
2566   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2567
2568   vec_free (next_decap_str);
2569 }
2570
2571 static void
2572   vl_api_lisp_adjacencies_get_reply_t_handler
2573   (vl_api_lisp_adjacencies_get_reply_t * mp)
2574 {
2575   vat_main_t *vam = &vat_main;
2576   u32 i, n;
2577   int retval = clib_net_to_host_u32 (mp->retval);
2578   vl_api_lisp_adjacency_t *a;
2579
2580   if (retval)
2581     goto end;
2582
2583   n = clib_net_to_host_u32 (mp->count);
2584
2585   for (i = 0; i < n; i++)
2586     {
2587       a = &mp->adjacencies[i];
2588       fformat (vam->ofp, "%U %40U\n",
2589                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2590                format_lisp_flat_eid, a->eid_type, a->reid,
2591                a->reid_prefix_len);
2592     }
2593
2594 end:
2595   vam->retval = retval;
2596   vam->result_ready = 1;
2597 }
2598
2599 static void
2600   vl_api_lisp_adjacencies_get_reply_t_handler_json
2601   (vl_api_lisp_adjacencies_get_reply_t * mp)
2602 {
2603   u8 *s = 0;
2604   vat_main_t *vam = &vat_main;
2605   vat_json_node_t *e = 0, root;
2606   u32 i, n;
2607   int retval = clib_net_to_host_u32 (mp->retval);
2608   vl_api_lisp_adjacency_t *a;
2609
2610   if (retval)
2611     goto end;
2612
2613   n = clib_net_to_host_u32 (mp->count);
2614   vat_json_init_array (&root);
2615
2616   for (i = 0; i < n; i++)
2617     {
2618       e = vat_json_array_add (&root);
2619       a = &mp->adjacencies[i];
2620
2621       vat_json_init_object (e);
2622       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2623                   a->leid_prefix_len);
2624       vec_add1 (s, 0);
2625       vat_json_object_add_string_copy (e, "leid", s);
2626       vec_free (s);
2627
2628       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2629                   a->reid_prefix_len);
2630       vec_add1 (s, 0);
2631       vat_json_object_add_string_copy (e, "reid", s);
2632       vec_free (s);
2633     }
2634
2635   vat_json_print (vam->ofp, &root);
2636   vat_json_free (&root);
2637
2638 end:
2639   vam->retval = retval;
2640   vam->result_ready = 1;
2641 }
2642
2643 static void
2644 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2645                                             * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648
2649   fformat (vam->ofp, "%=20U\n",
2650            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2651            mp->ip_address);
2652 }
2653
2654 static void
2655   vl_api_lisp_map_resolver_details_t_handler_json
2656   (vl_api_lisp_map_resolver_details_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   vat_json_node_t *node = NULL;
2660   struct in6_addr ip6;
2661   struct in_addr ip4;
2662
2663   if (VAT_JSON_ARRAY != vam->json_tree.type)
2664     {
2665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2666       vat_json_init_array (&vam->json_tree);
2667     }
2668   node = vat_json_array_add (&vam->json_tree);
2669
2670   vat_json_init_object (node);
2671   if (mp->is_ipv6)
2672     {
2673       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2674       vat_json_object_add_ip6 (node, "map resolver", ip6);
2675     }
2676   else
2677     {
2678       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2679       vat_json_object_add_ip4 (node, "map resolver", ip4);
2680     }
2681 }
2682
2683 static void
2684   vl_api_show_lisp_status_reply_t_handler
2685   (vl_api_show_lisp_status_reply_t * mp)
2686 {
2687   vat_main_t *vam = &vat_main;
2688   i32 retval = ntohl (mp->retval);
2689
2690   if (0 <= retval)
2691     {
2692       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2693                mp->feature_status ? "enabled" : "disabled",
2694                mp->gpe_status ? "enabled" : "disabled");
2695     }
2696
2697   vam->retval = retval;
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_show_lisp_status_reply_t_handler_json
2703   (vl_api_show_lisp_status_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   vat_json_node_t node;
2707   u8 *gpe_status = NULL;
2708   u8 *feature_status = NULL;
2709
2710   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2711   feature_status = format (0, "%s",
2712                            mp->feature_status ? "enabled" : "disabled");
2713   vec_add1 (gpe_status, 0);
2714   vec_add1 (feature_status, 0);
2715
2716   vat_json_init_object (&node);
2717   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2718   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2719
2720   vec_free (gpe_status);
2721   vec_free (feature_status);
2722
2723   vat_json_print (vam->ofp, &node);
2724   vat_json_free (&node);
2725
2726   vam->retval = ntohl (mp->retval);
2727   vam->result_ready = 1;
2728 }
2729
2730 static void
2731   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2732   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2733 {
2734   vat_main_t *vam = &vat_main;
2735   i32 retval = ntohl (mp->retval);
2736
2737   if (retval >= 0)
2738     {
2739       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2740     }
2741
2742   vam->retval = retval;
2743   vam->result_ready = 1;
2744 }
2745
2746 static void
2747   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2748   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2749 {
2750   vat_main_t *vam = &vat_main;
2751   vat_json_node_t *node = NULL;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2762
2763   vat_json_print (vam->ofp, node);
2764   vat_json_free (node);
2765
2766   vam->retval = ntohl (mp->retval);
2767   vam->result_ready = 1;
2768 }
2769
2770 static u8 *
2771 format_lisp_map_request_mode (u8 * s, va_list * args)
2772 {
2773   u32 mode = va_arg (*args, u32);
2774
2775   switch (mode)
2776     {
2777     case 0:
2778       return format (0, "dst-only");
2779     case 1:
2780       return format (0, "src-dst");
2781     }
2782   return 0;
2783 }
2784
2785 static void
2786   vl_api_show_lisp_map_request_mode_reply_t_handler
2787   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   i32 retval = ntohl (mp->retval);
2791
2792   if (0 <= retval)
2793     {
2794       u32 mode = mp->mode;
2795       fformat (vam->ofp, "map_request_mode: %U\n",
2796                format_lisp_map_request_mode, mode);
2797     }
2798
2799   vam->retval = retval;
2800   vam->result_ready = 1;
2801 }
2802
2803 static void
2804   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2805   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   vat_json_node_t node;
2809   u8 *s = 0;
2810   u32 mode;
2811
2812   mode = mp->mode;
2813   s = format (0, "%U", format_lisp_map_request_mode, mode);
2814   vec_add1 (s, 0);
2815
2816   vat_json_init_object (&node);
2817   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2818   vat_json_print (vam->ofp, &node);
2819   vat_json_free (&node);
2820
2821   vec_free (s);
2822   vam->retval = ntohl (mp->retval);
2823   vam->result_ready = 1;
2824 }
2825
2826 static void
2827 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   i32 retval = ntohl (mp->retval);
2831
2832   if (0 <= retval)
2833     {
2834       fformat (vam->ofp, "%-20s%-16s\n",
2835                mp->status ? "enabled" : "disabled",
2836                mp->status ? (char *) mp->locator_set_name : "");
2837     }
2838
2839   vam->retval = retval;
2840   vam->result_ready = 1;
2841 }
2842
2843 static void
2844 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2845                                             mp)
2846 {
2847   vat_main_t *vam = &vat_main;
2848   vat_json_node_t node;
2849   u8 *status = 0;
2850
2851   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2852   vec_add1 (status, 0);
2853
2854   vat_json_init_object (&node);
2855   vat_json_object_add_string_copy (&node, "status", status);
2856   if (mp->status)
2857     {
2858       vat_json_object_add_string_copy (&node, "locator_set",
2859                                        mp->locator_set_name);
2860     }
2861
2862   vec_free (status);
2863
2864   vat_json_print (vam->ofp, &node);
2865   vat_json_free (&node);
2866
2867   vam->retval = ntohl (mp->retval);
2868   vam->result_ready = 1;
2869 }
2870
2871 static u8 *
2872 format_policer_type (u8 * s, va_list * va)
2873 {
2874   u32 i = va_arg (*va, u32);
2875
2876   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2877     s = format (s, "1r2c");
2878   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2879     s = format (s, "1r3c");
2880   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2881     s = format (s, "2r3c-2698");
2882   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2883     s = format (s, "2r3c-4115");
2884   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2885     s = format (s, "2r3c-mef5cf1");
2886   else
2887     s = format (s, "ILLEGAL");
2888   return s;
2889 }
2890
2891 static u8 *
2892 format_policer_rate_type (u8 * s, va_list * va)
2893 {
2894   u32 i = va_arg (*va, u32);
2895
2896   if (i == SSE2_QOS_RATE_KBPS)
2897     s = format (s, "kbps");
2898   else if (i == SSE2_QOS_RATE_PPS)
2899     s = format (s, "pps");
2900   else
2901     s = format (s, "ILLEGAL");
2902   return s;
2903 }
2904
2905 static u8 *
2906 format_policer_round_type (u8 * s, va_list * va)
2907 {
2908   u32 i = va_arg (*va, u32);
2909
2910   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2911     s = format (s, "closest");
2912   else if (i == SSE2_QOS_ROUND_TO_UP)
2913     s = format (s, "up");
2914   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2915     s = format (s, "down");
2916   else
2917     s = format (s, "ILLEGAL");
2918   return s;
2919 }
2920
2921 static u8 *
2922 format_policer_action_type (u8 * s, va_list * va)
2923 {
2924   u32 i = va_arg (*va, u32);
2925
2926   if (i == SSE2_QOS_ACTION_DROP)
2927     s = format (s, "drop");
2928   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2929     s = format (s, "transmit");
2930   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2931     s = format (s, "mark-and-transmit");
2932   else
2933     s = format (s, "ILLEGAL");
2934   return s;
2935 }
2936
2937 static u8 *
2938 format_dscp (u8 * s, va_list * va)
2939 {
2940   u32 i = va_arg (*va, u32);
2941   char *t = 0;
2942
2943   switch (i)
2944     {
2945 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2946       foreach_vnet_dscp
2947 #undef _
2948     default:
2949       return format (s, "ILLEGAL");
2950     }
2951   s = format (s, "%s", t);
2952   return s;
2953 }
2954
2955 static void
2956 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2957 {
2958   vat_main_t *vam = &vat_main;
2959   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2960
2961   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2962     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2963   else
2964     conform_dscp_str = format (0, "");
2965
2966   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2967     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2968   else
2969     exceed_dscp_str = format (0, "");
2970
2971   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2972     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2973   else
2974     violate_dscp_str = format (0, "");
2975
2976   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2977            "rate type %U, round type %U, %s rate, %s color-aware, "
2978            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2979            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2980            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2981            mp->name,
2982            format_policer_type, mp->type,
2983            ntohl (mp->cir),
2984            ntohl (mp->eir),
2985            clib_net_to_host_u64 (mp->cb),
2986            clib_net_to_host_u64 (mp->eb),
2987            format_policer_rate_type, mp->rate_type,
2988            format_policer_round_type, mp->round_type,
2989            mp->single_rate ? "single" : "dual",
2990            mp->color_aware ? "is" : "not",
2991            ntohl (mp->cir_tokens_per_period),
2992            ntohl (mp->pir_tokens_per_period),
2993            ntohl (mp->scale),
2994            ntohl (mp->current_limit),
2995            ntohl (mp->current_bucket),
2996            ntohl (mp->extended_limit),
2997            ntohl (mp->extended_bucket),
2998            clib_net_to_host_u64 (mp->last_update_time),
2999            format_policer_action_type, mp->conform_action_type,
3000            conform_dscp_str,
3001            format_policer_action_type, mp->exceed_action_type,
3002            exceed_dscp_str,
3003            format_policer_action_type, mp->violate_action_type,
3004            violate_dscp_str);
3005
3006   vec_free (conform_dscp_str);
3007   vec_free (exceed_dscp_str);
3008   vec_free (violate_dscp_str);
3009 }
3010
3011 static void vl_api_policer_details_t_handler_json
3012   (vl_api_policer_details_t * mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   vat_json_node_t *node;
3016   u8 *rate_type_str, *round_type_str, *type_str;
3017   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3018
3019   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3020   round_type_str =
3021     format (0, "%U", format_policer_round_type, mp->round_type);
3022   type_str = format (0, "%U", format_policer_type, mp->type);
3023   conform_action_str = format (0, "%U", format_policer_action_type,
3024                                mp->conform_action_type);
3025   exceed_action_str = format (0, "%U", format_policer_action_type,
3026                               mp->exceed_action_type);
3027   violate_action_str = format (0, "%U", format_policer_action_type,
3028                                mp->violate_action_type);
3029
3030   if (VAT_JSON_ARRAY != vam->json_tree.type)
3031     {
3032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3033       vat_json_init_array (&vam->json_tree);
3034     }
3035   node = vat_json_array_add (&vam->json_tree);
3036
3037   vat_json_init_object (node);
3038   vat_json_object_add_string_copy (node, "name", mp->name);
3039   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3040   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3041   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3042   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3043   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3044   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3045   vat_json_object_add_string_copy (node, "type", type_str);
3046   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3047   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3048   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3049   vat_json_object_add_uint (node, "cir_tokens_per_period",
3050                             ntohl (mp->cir_tokens_per_period));
3051   vat_json_object_add_uint (node, "eir_tokens_per_period",
3052                             ntohl (mp->pir_tokens_per_period));
3053   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3054   vat_json_object_add_uint (node, "current_bucket",
3055                             ntohl (mp->current_bucket));
3056   vat_json_object_add_uint (node, "extended_limit",
3057                             ntohl (mp->extended_limit));
3058   vat_json_object_add_uint (node, "extended_bucket",
3059                             ntohl (mp->extended_bucket));
3060   vat_json_object_add_uint (node, "last_update_time",
3061                             ntohl (mp->last_update_time));
3062   vat_json_object_add_string_copy (node, "conform_action",
3063                                    conform_action_str);
3064   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3065     {
3066       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3067       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3068       vec_free (dscp_str);
3069     }
3070   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3071   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3072     {
3073       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3074       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3075       vec_free (dscp_str);
3076     }
3077   vat_json_object_add_string_copy (node, "violate_action",
3078                                    violate_action_str);
3079   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3080     {
3081       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3082       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3083       vec_free (dscp_str);
3084     }
3085
3086   vec_free (rate_type_str);
3087   vec_free (round_type_str);
3088   vec_free (type_str);
3089   vec_free (conform_action_str);
3090   vec_free (exceed_action_str);
3091   vec_free (violate_action_str);
3092 }
3093
3094 static void
3095 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3096                                            mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   int i, count = ntohl (mp->count);
3100
3101   if (count > 0)
3102     fformat (vam->ofp, "classify table ids (%d) : ", count);
3103   for (i = 0; i < count; i++)
3104     {
3105       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3106       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3107     }
3108   vam->retval = ntohl (mp->retval);
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_classify_table_ids_reply_t_handler_json
3114   (vl_api_classify_table_ids_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   int i, count = ntohl (mp->count);
3118
3119   if (count > 0)
3120     {
3121       vat_json_node_t node;
3122
3123       vat_json_init_object (&node);
3124       for (i = 0; i < count; i++)
3125         {
3126           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3127         }
3128       vat_json_print (vam->ofp, &node);
3129       vat_json_free (&node);
3130     }
3131   vam->retval = ntohl (mp->retval);
3132   vam->result_ready = 1;
3133 }
3134
3135 static void
3136   vl_api_classify_table_by_interface_reply_t_handler
3137   (vl_api_classify_table_by_interface_reply_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   u32 table_id;
3141
3142   table_id = ntohl (mp->l2_table_id);
3143   if (table_id != ~0)
3144     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3145   else
3146     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3147   table_id = ntohl (mp->ip4_table_id);
3148   if (table_id != ~0)
3149     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3150   else
3151     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3152   table_id = ntohl (mp->ip6_table_id);
3153   if (table_id != ~0)
3154     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3155   else
3156     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3157   vam->retval = ntohl (mp->retval);
3158   vam->result_ready = 1;
3159 }
3160
3161 static void
3162   vl_api_classify_table_by_interface_reply_t_handler_json
3163   (vl_api_classify_table_by_interface_reply_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   vat_json_node_t node;
3167
3168   vat_json_init_object (&node);
3169
3170   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3171   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3172   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3173
3174   vat_json_print (vam->ofp, &node);
3175   vat_json_free (&node);
3176
3177   vam->retval = ntohl (mp->retval);
3178   vam->result_ready = 1;
3179 }
3180
3181 static void vl_api_policer_add_del_reply_t_handler
3182   (vl_api_policer_add_del_reply_t * mp)
3183 {
3184   vat_main_t *vam = &vat_main;
3185   i32 retval = ntohl (mp->retval);
3186   if (vam->async_mode)
3187     {
3188       vam->async_errors += (retval < 0);
3189     }
3190   else
3191     {
3192       vam->retval = retval;
3193       vam->result_ready = 1;
3194       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3195         /*
3196          * Note: this is just barely thread-safe, depends on
3197          * the main thread spinning waiting for an answer...
3198          */
3199         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3200     }
3201 }
3202
3203 static void vl_api_policer_add_del_reply_t_handler_json
3204   (vl_api_policer_add_del_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t node;
3208
3209   vat_json_init_object (&node);
3210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3211   vat_json_object_add_uint (&node, "policer_index",
3212                             ntohl (mp->policer_index));
3213
3214   vat_json_print (vam->ofp, &node);
3215   vat_json_free (&node);
3216
3217   vam->retval = ntohl (mp->retval);
3218   vam->result_ready = 1;
3219 }
3220
3221 /* Format hex dump. */
3222 u8 *
3223 format_hex_bytes (u8 * s, va_list * va)
3224 {
3225   u8 *bytes = va_arg (*va, u8 *);
3226   int n_bytes = va_arg (*va, int);
3227   uword i;
3228
3229   /* Print short or long form depending on byte count. */
3230   uword short_form = n_bytes <= 32;
3231   uword indent = format_get_indent (s);
3232
3233   if (n_bytes == 0)
3234     return s;
3235
3236   for (i = 0; i < n_bytes; i++)
3237     {
3238       if (!short_form && (i % 32) == 0)
3239         s = format (s, "%08x: ", i);
3240       s = format (s, "%02x", bytes[i]);
3241       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3242         s = format (s, "\n%U", format_white_space, indent);
3243     }
3244
3245   return s;
3246 }
3247
3248 static void
3249 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3250                                             * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   i32 retval = ntohl (mp->retval);
3254   if (retval == 0)
3255     {
3256       fformat (vam->ofp, "classify table info :\n");
3257       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3258                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3259                ntohl (mp->miss_next_index));
3260       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3261                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3262                ntohl (mp->match_n_vectors));
3263       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3264                ntohl (mp->mask_length));
3265     }
3266   vam->retval = retval;
3267   vam->result_ready = 1;
3268 }
3269
3270 static void
3271   vl_api_classify_table_info_reply_t_handler_json
3272   (vl_api_classify_table_info_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   vat_json_node_t node;
3276
3277   i32 retval = ntohl (mp->retval);
3278   if (retval == 0)
3279     {
3280       vat_json_init_object (&node);
3281
3282       vat_json_object_add_int (&node, "sessions",
3283                                ntohl (mp->active_sessions));
3284       vat_json_object_add_int (&node, "nexttbl",
3285                                ntohl (mp->next_table_index));
3286       vat_json_object_add_int (&node, "nextnode",
3287                                ntohl (mp->miss_next_index));
3288       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3289       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3290       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3291       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3292                       ntohl (mp->mask_length), 0);
3293       vat_json_object_add_string_copy (&node, "mask", s);
3294
3295       vat_json_print (vam->ofp, &node);
3296       vat_json_free (&node);
3297     }
3298   vam->retval = ntohl (mp->retval);
3299   vam->result_ready = 1;
3300 }
3301
3302 static void
3303 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3304                                            mp)
3305 {
3306   vat_main_t *vam = &vat_main;
3307
3308   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3309            ntohl (mp->hit_next_index), ntohl (mp->advance),
3310            ntohl (mp->opaque_index));
3311   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3312            ntohl (mp->match_length));
3313 }
3314
3315 static void
3316   vl_api_classify_session_details_t_handler_json
3317   (vl_api_classify_session_details_t * mp)
3318 {
3319   vat_main_t *vam = &vat_main;
3320   vat_json_node_t *node = NULL;
3321
3322   if (VAT_JSON_ARRAY != vam->json_tree.type)
3323     {
3324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3325       vat_json_init_array (&vam->json_tree);
3326     }
3327   node = vat_json_array_add (&vam->json_tree);
3328
3329   vat_json_init_object (node);
3330   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3331   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3332   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3333   u8 *s =
3334     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3335             0);
3336   vat_json_object_add_string_copy (node, "match", s);
3337 }
3338
3339 static void vl_api_pg_create_interface_reply_t_handler
3340   (vl_api_pg_create_interface_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   vam->retval = ntohl (mp->retval);
3345   vam->result_ready = 1;
3346 }
3347
3348 static void vl_api_pg_create_interface_reply_t_handler_json
3349   (vl_api_pg_create_interface_reply_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t node;
3353
3354   i32 retval = ntohl (mp->retval);
3355   if (retval == 0)
3356     {
3357       vat_json_init_object (&node);
3358
3359       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3360
3361       vat_json_print (vam->ofp, &node);
3362       vat_json_free (&node);
3363     }
3364   vam->retval = ntohl (mp->retval);
3365   vam->result_ready = 1;
3366 }
3367
3368 static void vl_api_policer_classify_details_t_handler
3369   (vl_api_policer_classify_details_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372
3373   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3374            ntohl (mp->table_index));
3375 }
3376
3377 static void vl_api_policer_classify_details_t_handler_json
3378   (vl_api_policer_classify_details_t * mp)
3379 {
3380   vat_main_t *vam = &vat_main;
3381   vat_json_node_t *node;
3382
3383   if (VAT_JSON_ARRAY != vam->json_tree.type)
3384     {
3385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3386       vat_json_init_array (&vam->json_tree);
3387     }
3388   node = vat_json_array_add (&vam->json_tree);
3389
3390   vat_json_init_object (node);
3391   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3392   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3393 }
3394
3395 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3396   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399   i32 retval = ntohl (mp->retval);
3400   if (vam->async_mode)
3401     {
3402       vam->async_errors += (retval < 0);
3403     }
3404   else
3405     {
3406       vam->retval = retval;
3407       vam->sw_if_index = ntohl (mp->sw_if_index);
3408       vam->result_ready = 1;
3409     }
3410 }
3411
3412 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3413   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3414 {
3415   vat_main_t *vam = &vat_main;
3416   vat_json_node_t node;
3417
3418   vat_json_init_object (&node);
3419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3420   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3421
3422   vat_json_print (vam->ofp, &node);
3423   vat_json_free (&node);
3424
3425   vam->retval = ntohl (mp->retval);
3426   vam->result_ready = 1;
3427 }
3428
3429 static void vl_api_flow_classify_details_t_handler
3430   (vl_api_flow_classify_details_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3435            ntohl (mp->table_index));
3436 }
3437
3438 static void vl_api_flow_classify_details_t_handler_json
3439   (vl_api_flow_classify_details_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t *node;
3443
3444   if (VAT_JSON_ARRAY != vam->json_tree.type)
3445     {
3446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3447       vat_json_init_array (&vam->json_tree);
3448     }
3449   node = vat_json_array_add (&vam->json_tree);
3450
3451   vat_json_init_object (node);
3452   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3453   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3454 }
3455
3456
3457
3458 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3459 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3460 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3461 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3462 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3463 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3464
3465 /*
3466  * Generate boilerplate reply handlers, which
3467  * dig the return value out of the xxx_reply_t API message,
3468  * stick it into vam->retval, and set vam->result_ready
3469  *
3470  * Could also do this by pointing N message decode slots at
3471  * a single function, but that could break in subtle ways.
3472  */
3473
3474 #define foreach_standard_reply_retval_handler           \
3475 _(sw_interface_set_flags_reply)                         \
3476 _(sw_interface_add_del_address_reply)                   \
3477 _(sw_interface_set_table_reply)                         \
3478 _(sw_interface_set_mpls_enable_reply)                   \
3479 _(sw_interface_set_vpath_reply)                         \
3480 _(sw_interface_set_l2_bridge_reply)                     \
3481 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3482 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3483 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3484 _(bridge_domain_add_del_reply)                          \
3485 _(sw_interface_set_l2_xconnect_reply)                   \
3486 _(l2fib_add_del_reply)                                  \
3487 _(ip_add_del_route_reply)                               \
3488 _(mpls_route_add_del_reply)                             \
3489 _(mpls_ip_bind_unbind_reply)                            \
3490 _(proxy_arp_add_del_reply)                              \
3491 _(proxy_arp_intfc_enable_disable_reply)                 \
3492 _(mpls_add_del_encap_reply)                             \
3493 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3494 _(sw_interface_set_unnumbered_reply)                    \
3495 _(ip_neighbor_add_del_reply)                            \
3496 _(reset_vrf_reply)                                      \
3497 _(oam_add_del_reply)                                    \
3498 _(reset_fib_reply)                                      \
3499 _(dhcp_proxy_config_reply)                              \
3500 _(dhcp_proxy_config_2_reply)                            \
3501 _(dhcp_proxy_set_vss_reply)                             \
3502 _(dhcp_client_config_reply)                             \
3503 _(set_ip_flow_hash_reply)                               \
3504 _(sw_interface_ip6_enable_disable_reply)                \
3505 _(sw_interface_ip6_set_link_local_address_reply)        \
3506 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3507 _(sw_interface_ip6nd_ra_config_reply)                   \
3508 _(set_arp_neighbor_limit_reply)                         \
3509 _(l2_patch_add_del_reply)                               \
3510 _(sr_tunnel_add_del_reply)                              \
3511 _(sr_policy_add_del_reply)                              \
3512 _(sr_multicast_map_add_del_reply)                       \
3513 _(classify_add_del_session_reply)                       \
3514 _(classify_set_interface_ip_table_reply)                \
3515 _(classify_set_interface_l2_tables_reply)               \
3516 _(l2tpv3_set_tunnel_cookies_reply)                      \
3517 _(l2tpv3_interface_enable_disable_reply)                \
3518 _(l2tpv3_set_lookup_key_reply)                          \
3519 _(l2_fib_clear_table_reply)                             \
3520 _(l2_interface_efp_filter_reply)                        \
3521 _(l2_interface_vlan_tag_rewrite_reply)                  \
3522 _(modify_vhost_user_if_reply)                           \
3523 _(delete_vhost_user_if_reply)                           \
3524 _(want_ip4_arp_events_reply)                            \
3525 _(want_ip6_nd_events_reply)                             \
3526 _(input_acl_set_interface_reply)                        \
3527 _(ipsec_spd_add_del_reply)                              \
3528 _(ipsec_interface_add_del_spd_reply)                    \
3529 _(ipsec_spd_add_del_entry_reply)                        \
3530 _(ipsec_sad_add_del_entry_reply)                        \
3531 _(ipsec_sa_set_key_reply)                               \
3532 _(ikev2_profile_add_del_reply)                          \
3533 _(ikev2_profile_set_auth_reply)                         \
3534 _(ikev2_profile_set_id_reply)                           \
3535 _(ikev2_profile_set_ts_reply)                           \
3536 _(ikev2_set_local_key_reply)                            \
3537 _(delete_loopback_reply)                                \
3538 _(bd_ip_mac_add_del_reply)                              \
3539 _(map_del_domain_reply)                                 \
3540 _(map_add_del_rule_reply)                               \
3541 _(want_interface_events_reply)                          \
3542 _(want_stats_reply)                                     \
3543 _(cop_interface_enable_disable_reply)                   \
3544 _(cop_whitelist_enable_disable_reply)                   \
3545 _(sw_interface_clear_stats_reply)                       \
3546 _(ioam_enable_reply)                              \
3547 _(ioam_disable_reply)                              \
3548 _(lisp_add_del_locator_reply)                           \
3549 _(lisp_add_del_local_eid_reply)                         \
3550 _(lisp_add_del_remote_mapping_reply)                    \
3551 _(lisp_add_del_adjacency_reply)                         \
3552 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3553 _(lisp_add_del_map_resolver_reply)                      \
3554 _(lisp_gpe_enable_disable_reply)                        \
3555 _(lisp_gpe_add_del_iface_reply)                         \
3556 _(lisp_enable_disable_reply)                            \
3557 _(lisp_pitr_set_locator_set_reply)                      \
3558 _(lisp_map_request_mode_reply)                          \
3559 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3560 _(lisp_eid_table_add_del_map_reply)                     \
3561 _(vxlan_gpe_add_del_tunnel_reply)                       \
3562 _(af_packet_delete_reply)                               \
3563 _(policer_classify_set_interface_reply)                 \
3564 _(netmap_create_reply)                                  \
3565 _(netmap_delete_reply)                                  \
3566 _(set_ipfix_exporter_reply)                             \
3567 _(set_ipfix_classify_stream_reply)                      \
3568 _(ipfix_classify_table_add_del_reply)                   \
3569 _(flow_classify_set_interface_reply)                    \
3570 _(pg_capture_reply)                                     \
3571 _(pg_enable_disable_reply)                              \
3572 _(ip_source_and_port_range_check_add_del_reply)         \
3573 _(ip_source_and_port_range_check_interface_add_del_reply)\
3574 _(delete_subif_reply)                                   \
3575 _(l2_interface_pbb_tag_rewrite_reply)                   \
3576 _(punt_reply)
3577
3578 #define _(n)                                    \
3579     static void vl_api_##n##_t_handler          \
3580     (vl_api_##n##_t * mp)                       \
3581     {                                           \
3582         vat_main_t * vam = &vat_main;           \
3583         i32 retval = ntohl(mp->retval);         \
3584         if (vam->async_mode) {                  \
3585             vam->async_errors += (retval < 0);  \
3586         } else {                                \
3587             vam->retval = retval;               \
3588             vam->result_ready = 1;              \
3589         }                                       \
3590     }
3591 foreach_standard_reply_retval_handler;
3592 #undef _
3593
3594 #define _(n)                                    \
3595     static void vl_api_##n##_t_handler_json     \
3596     (vl_api_##n##_t * mp)                       \
3597     {                                           \
3598         vat_main_t * vam = &vat_main;           \
3599         vat_json_node_t node;                   \
3600         vat_json_init_object(&node);            \
3601         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3602         vat_json_print(vam->ofp, &node);        \
3603         vam->retval = ntohl(mp->retval);        \
3604         vam->result_ready = 1;                  \
3605     }
3606 foreach_standard_reply_retval_handler;
3607 #undef _
3608
3609 /*
3610  * Table of message reply handlers, must include boilerplate handlers
3611  * we just generated
3612  */
3613
3614 #define foreach_vpe_api_reply_msg                                       \
3615 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3616 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3617 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3618 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3619 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3620 _(CLI_REPLY, cli_reply)                                                 \
3621 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3622 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3623   sw_interface_add_del_address_reply)                                   \
3624 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3625 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3626 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3627 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3628   sw_interface_set_l2_xconnect_reply)                                   \
3629 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3630   sw_interface_set_l2_bridge_reply)                                     \
3631 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3632   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3633 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3634   sw_interface_set_dpdk_hqos_subport_reply)                             \
3635 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3636   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3637 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3638 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3639 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3640 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3641 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3642 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3643 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3644 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3645 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3646 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3647 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3648 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3649 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3650 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3651 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3652   proxy_arp_intfc_enable_disable_reply)                                 \
3653 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3654 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3655   mpls_ethernet_add_del_tunnel_reply)                                   \
3656 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3657   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3658 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3659   sw_interface_set_unnumbered_reply)                                    \
3660 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3661 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3662 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3663 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3664 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3665 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3666 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3667 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3668 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3669 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3670 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3671 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3672   sw_interface_ip6_enable_disable_reply)                                \
3673 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3674   sw_interface_ip6_set_link_local_address_reply)                        \
3675 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3676   sw_interface_ip6nd_ra_prefix_reply)                                   \
3677 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3678   sw_interface_ip6nd_ra_config_reply)                                   \
3679 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3680 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3681 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3682 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3683 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3684 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3685 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3686 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3687 classify_set_interface_ip_table_reply)                                  \
3688 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3689   classify_set_interface_l2_tables_reply)                               \
3690 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3691 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3692 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3693 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3694 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3695   l2tpv3_interface_enable_disable_reply)                                \
3696 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3697 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3698 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3699 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3700 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3701 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3702 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3703 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3704 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3705 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3706 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3707 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3708 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3709 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3710 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3711 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3712 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3713 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3714 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3715 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3716 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3717 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3718 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3719 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3720 _(IP_DETAILS, ip_details)                                               \
3721 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3722 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3723 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3724 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3725 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3726 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3727 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3728 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3729 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3730 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3731 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3732 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3733 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3734 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3735 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3736 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3737 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3738 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3739 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3740 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3741 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3742 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3743 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3744 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3745 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3746 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3747 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3748 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3749 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3750 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3751 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3752 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3753 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3754 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3755 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3756 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3757 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3758 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3759 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3760 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3761 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3762 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3763 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3764 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3765 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3766 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3767 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3768 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3769 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3770 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3771 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3772 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3773 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3774   lisp_add_del_map_request_itr_rlocs_reply)                             \
3775 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3776   lisp_get_map_request_itr_rlocs_reply)                                 \
3777 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3778 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3779 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3780 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3781 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3782 _(POLICER_DETAILS, policer_details)                                     \
3783 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3784 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3785 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3786 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3787 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3788 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3789 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3790 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3791 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3792 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3793 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3794 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3795 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3796 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3797 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3798 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3799 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3800 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3801 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3802 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3803 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3804 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3805 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3806 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3807  ip_source_and_port_range_check_add_del_reply)                          \
3808 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3809  ip_source_and_port_range_check_interface_add_del_reply)                \
3810 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3811 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3812 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3813 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3814 _(PUNT_REPLY, punt_reply)
3815
3816 /* M: construct, but don't yet send a message */
3817
3818 #define M(T,t)                                  \
3819 do {                                            \
3820     vam->result_ready = 0;                      \
3821     mp = vl_msg_api_alloc(sizeof(*mp));         \
3822     memset (mp, 0, sizeof (*mp));               \
3823     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3824     mp->client_index = vam->my_client_index;    \
3825 } while(0);
3826
3827 #define M2(T,t,n)                               \
3828 do {                                            \
3829     vam->result_ready = 0;                      \
3830     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3831     memset (mp, 0, sizeof (*mp));               \
3832     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3833     mp->client_index = vam->my_client_index;    \
3834 } while(0);
3835
3836
3837 /* S: send a message */
3838 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3839
3840 /* W: wait for results, with timeout */
3841 #define W                                       \
3842 do {                                            \
3843     timeout = vat_time_now (vam) + 1.0;         \
3844                                                 \
3845     while (vat_time_now (vam) < timeout) {      \
3846         if (vam->result_ready == 1) {           \
3847             return (vam->retval);               \
3848         }                                       \
3849     }                                           \
3850     return -99;                                 \
3851 } while(0);
3852
3853 /* W2: wait for results, with timeout */
3854 #define W2(body)                                \
3855 do {                                            \
3856     timeout = vat_time_now (vam) + 1.0;         \
3857                                                 \
3858     while (vat_time_now (vam) < timeout) {      \
3859         if (vam->result_ready == 1) {           \
3860           (body);                               \
3861           return (vam->retval);                 \
3862         }                                       \
3863     }                                           \
3864     return -99;                                 \
3865 } while(0);
3866
3867 typedef struct
3868 {
3869   u8 *name;
3870   u32 value;
3871 } name_sort_t;
3872
3873
3874 #define STR_VTR_OP_CASE(op)     \
3875     case L2_VTR_ ## op:         \
3876         return "" # op;
3877
3878 static const char *
3879 str_vtr_op (u32 vtr_op)
3880 {
3881   switch (vtr_op)
3882     {
3883       STR_VTR_OP_CASE (DISABLED);
3884       STR_VTR_OP_CASE (PUSH_1);
3885       STR_VTR_OP_CASE (PUSH_2);
3886       STR_VTR_OP_CASE (POP_1);
3887       STR_VTR_OP_CASE (POP_2);
3888       STR_VTR_OP_CASE (TRANSLATE_1_1);
3889       STR_VTR_OP_CASE (TRANSLATE_1_2);
3890       STR_VTR_OP_CASE (TRANSLATE_2_1);
3891       STR_VTR_OP_CASE (TRANSLATE_2_2);
3892     }
3893
3894   return "UNKNOWN";
3895 }
3896
3897 static int
3898 dump_sub_interface_table (vat_main_t * vam)
3899 {
3900   const sw_interface_subif_t *sub = NULL;
3901
3902   if (vam->json_output)
3903     {
3904       clib_warning
3905         ("JSON output supported only for VPE API calls and dump_stats_table");
3906       return -99;
3907     }
3908
3909   fformat (vam->ofp,
3910            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3911            "Interface", "sw_if_index",
3912            "sub id", "dot1ad", "tags", "outer id",
3913            "inner id", "exact", "default", "outer any", "inner any");
3914
3915   vec_foreach (sub, vam->sw_if_subif_table)
3916   {
3917     fformat (vam->ofp,
3918              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3919              sub->interface_name,
3920              sub->sw_if_index,
3921              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3922              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3923              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3924              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3925     if (sub->vtr_op != L2_VTR_DISABLED)
3926       {
3927         fformat (vam->ofp,
3928                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3929                  "tag1: %d tag2: %d ]\n",
3930                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3931                  sub->vtr_tag1, sub->vtr_tag2);
3932       }
3933   }
3934
3935   return 0;
3936 }
3937
3938 static int
3939 name_sort_cmp (void *a1, void *a2)
3940 {
3941   name_sort_t *n1 = a1;
3942   name_sort_t *n2 = a2;
3943
3944   return strcmp ((char *) n1->name, (char *) n2->name);
3945 }
3946
3947 static int
3948 dump_interface_table (vat_main_t * vam)
3949 {
3950   hash_pair_t *p;
3951   name_sort_t *nses = 0, *ns;
3952
3953   if (vam->json_output)
3954     {
3955       clib_warning
3956         ("JSON output supported only for VPE API calls and dump_stats_table");
3957       return -99;
3958     }
3959
3960   /* *INDENT-OFF* */
3961   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3962   ({
3963     vec_add2 (nses, ns, 1);
3964     ns->name = (u8 *)(p->key);
3965     ns->value = (u32) p->value[0];
3966   }));
3967   /* *INDENT-ON* */
3968
3969   vec_sort_with_function (nses, name_sort_cmp);
3970
3971   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3972   vec_foreach (ns, nses)
3973   {
3974     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3975   }
3976   vec_free (nses);
3977   return 0;
3978 }
3979
3980 static int
3981 dump_ip_table (vat_main_t * vam, int is_ipv6)
3982 {
3983   const ip_details_t *det = NULL;
3984   const ip_address_details_t *address = NULL;
3985   u32 i = ~0;
3986
3987   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3988
3989   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3990   {
3991     i++;
3992     if (!det->present)
3993       {
3994         continue;
3995       }
3996     fformat (vam->ofp, "%-12d\n", i);
3997     fformat (vam->ofp,
3998              "            %-30s%-13s\n", "Address", "Prefix length");
3999     if (!det->addr)
4000       {
4001         continue;
4002       }
4003     vec_foreach (address, det->addr)
4004     {
4005       fformat (vam->ofp,
4006                "            %-30U%-13d\n",
4007                is_ipv6 ? format_ip6_address : format_ip4_address,
4008                address->ip, address->prefix_length);
4009     }
4010   }
4011
4012   return 0;
4013 }
4014
4015 static int
4016 dump_ipv4_table (vat_main_t * vam)
4017 {
4018   if (vam->json_output)
4019     {
4020       clib_warning
4021         ("JSON output supported only for VPE API calls and dump_stats_table");
4022       return -99;
4023     }
4024
4025   return dump_ip_table (vam, 0);
4026 }
4027
4028 static int
4029 dump_ipv6_table (vat_main_t * vam)
4030 {
4031   if (vam->json_output)
4032     {
4033       clib_warning
4034         ("JSON output supported only for VPE API calls and dump_stats_table");
4035       return -99;
4036     }
4037
4038   return dump_ip_table (vam, 1);
4039 }
4040
4041 static char *
4042 counter_type_to_str (u8 counter_type, u8 is_combined)
4043 {
4044   if (!is_combined)
4045     {
4046       switch (counter_type)
4047         {
4048         case VNET_INTERFACE_COUNTER_DROP:
4049           return "drop";
4050         case VNET_INTERFACE_COUNTER_PUNT:
4051           return "punt";
4052         case VNET_INTERFACE_COUNTER_IP4:
4053           return "ip4";
4054         case VNET_INTERFACE_COUNTER_IP6:
4055           return "ip6";
4056         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4057           return "rx-no-buf";
4058         case VNET_INTERFACE_COUNTER_RX_MISS:
4059           return "rx-miss";
4060         case VNET_INTERFACE_COUNTER_RX_ERROR:
4061           return "rx-error";
4062         case VNET_INTERFACE_COUNTER_TX_ERROR:
4063           return "tx-error";
4064         default:
4065           return "INVALID-COUNTER-TYPE";
4066         }
4067     }
4068   else
4069     {
4070       switch (counter_type)
4071         {
4072         case VNET_INTERFACE_COUNTER_RX:
4073           return "rx";
4074         case VNET_INTERFACE_COUNTER_TX:
4075           return "tx";
4076         default:
4077           return "INVALID-COUNTER-TYPE";
4078         }
4079     }
4080 }
4081
4082 static int
4083 dump_stats_table (vat_main_t * vam)
4084 {
4085   vat_json_node_t node;
4086   vat_json_node_t *msg_array;
4087   vat_json_node_t *msg;
4088   vat_json_node_t *counter_array;
4089   vat_json_node_t *counter;
4090   interface_counter_t c;
4091   u64 packets;
4092   ip4_fib_counter_t *c4;
4093   ip6_fib_counter_t *c6;
4094   int i, j;
4095
4096   if (!vam->json_output)
4097     {
4098       clib_warning ("dump_stats_table supported only in JSON format");
4099       return -99;
4100     }
4101
4102   vat_json_init_object (&node);
4103
4104   /* interface counters */
4105   msg_array = vat_json_object_add (&node, "interface_counters");
4106   vat_json_init_array (msg_array);
4107   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4108     {
4109       msg = vat_json_array_add (msg_array);
4110       vat_json_init_object (msg);
4111       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4112                                        (u8 *) counter_type_to_str (i, 0));
4113       vat_json_object_add_int (msg, "is_combined", 0);
4114       counter_array = vat_json_object_add (msg, "data");
4115       vat_json_init_array (counter_array);
4116       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4117         {
4118           packets = vam->simple_interface_counters[i][j];
4119           vat_json_array_add_uint (counter_array, packets);
4120         }
4121     }
4122   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4123     {
4124       msg = vat_json_array_add (msg_array);
4125       vat_json_init_object (msg);
4126       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4127                                        (u8 *) counter_type_to_str (i, 1));
4128       vat_json_object_add_int (msg, "is_combined", 1);
4129       counter_array = vat_json_object_add (msg, "data");
4130       vat_json_init_array (counter_array);
4131       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4132         {
4133           c = vam->combined_interface_counters[i][j];
4134           counter = vat_json_array_add (counter_array);
4135           vat_json_init_object (counter);
4136           vat_json_object_add_uint (counter, "packets", c.packets);
4137           vat_json_object_add_uint (counter, "bytes", c.bytes);
4138         }
4139     }
4140
4141   /* ip4 fib counters */
4142   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4143   vat_json_init_array (msg_array);
4144   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4145     {
4146       msg = vat_json_array_add (msg_array);
4147       vat_json_init_object (msg);
4148       vat_json_object_add_uint (msg, "vrf_id",
4149                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4150       counter_array = vat_json_object_add (msg, "c");
4151       vat_json_init_array (counter_array);
4152       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4153         {
4154           counter = vat_json_array_add (counter_array);
4155           vat_json_init_object (counter);
4156           c4 = &vam->ip4_fib_counters[i][j];
4157           vat_json_object_add_ip4 (counter, "address", c4->address);
4158           vat_json_object_add_uint (counter, "address_length",
4159                                     c4->address_length);
4160           vat_json_object_add_uint (counter, "packets", c4->packets);
4161           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4162         }
4163     }
4164
4165   /* ip6 fib counters */
4166   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4167   vat_json_init_array (msg_array);
4168   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4169     {
4170       msg = vat_json_array_add (msg_array);
4171       vat_json_init_object (msg);
4172       vat_json_object_add_uint (msg, "vrf_id",
4173                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4174       counter_array = vat_json_object_add (msg, "c");
4175       vat_json_init_array (counter_array);
4176       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4177         {
4178           counter = vat_json_array_add (counter_array);
4179           vat_json_init_object (counter);
4180           c6 = &vam->ip6_fib_counters[i][j];
4181           vat_json_object_add_ip6 (counter, "address", c6->address);
4182           vat_json_object_add_uint (counter, "address_length",
4183                                     c6->address_length);
4184           vat_json_object_add_uint (counter, "packets", c6->packets);
4185           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4186         }
4187     }
4188
4189   vat_json_print (vam->ofp, &node);
4190   vat_json_free (&node);
4191
4192   return 0;
4193 }
4194
4195 int
4196 exec (vat_main_t * vam)
4197 {
4198   api_main_t *am = &api_main;
4199   vl_api_cli_request_t *mp;
4200   f64 timeout;
4201   void *oldheap;
4202   u8 *cmd = 0;
4203   unformat_input_t *i = vam->input;
4204
4205   if (vec_len (i->buffer) == 0)
4206     return -1;
4207
4208   if (vam->exec_mode == 0 && unformat (i, "mode"))
4209     {
4210       vam->exec_mode = 1;
4211       return 0;
4212     }
4213   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4214     {
4215       vam->exec_mode = 0;
4216       return 0;
4217     }
4218
4219
4220   M (CLI_REQUEST, cli_request);
4221
4222   /*
4223    * Copy cmd into shared memory.
4224    * In order for the CLI command to work, it
4225    * must be a vector ending in \n, not a C-string ending
4226    * in \n\0.
4227    */
4228   pthread_mutex_lock (&am->vlib_rp->mutex);
4229   oldheap = svm_push_data_heap (am->vlib_rp);
4230
4231   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4232   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4233
4234   svm_pop_heap (oldheap);
4235   pthread_mutex_unlock (&am->vlib_rp->mutex);
4236
4237   mp->cmd_in_shmem = (u64) cmd;
4238   S;
4239   timeout = vat_time_now (vam) + 10.0;
4240
4241   while (vat_time_now (vam) < timeout)
4242     {
4243       if (vam->result_ready == 1)
4244         {
4245           u8 *free_me;
4246           if (vam->shmem_result != NULL)
4247             fformat (vam->ofp, "%s", vam->shmem_result);
4248           pthread_mutex_lock (&am->vlib_rp->mutex);
4249           oldheap = svm_push_data_heap (am->vlib_rp);
4250
4251           free_me = (u8 *) vam->shmem_result;
4252           vec_free (free_me);
4253
4254           svm_pop_heap (oldheap);
4255           pthread_mutex_unlock (&am->vlib_rp->mutex);
4256           return 0;
4257         }
4258     }
4259   return -99;
4260 }
4261
4262 /*
4263  * Future replacement of exec() that passes CLI buffers directly in
4264  * the API messages instead of an additional shared memory area.
4265  */
4266 static int
4267 exec_inband (vat_main_t * vam)
4268 {
4269   vl_api_cli_inband_t *mp;
4270   f64 timeout;
4271   unformat_input_t *i = vam->input;
4272
4273   if (vec_len (i->buffer) == 0)
4274     return -1;
4275
4276   if (vam->exec_mode == 0 && unformat (i, "mode"))
4277     {
4278       vam->exec_mode = 1;
4279       return 0;
4280     }
4281   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4282     {
4283       vam->exec_mode = 0;
4284       return 0;
4285     }
4286
4287   /*
4288    * In order for the CLI command to work, it
4289    * must be a vector ending in \n, not a C-string ending
4290    * in \n\0.
4291    */
4292   u32 len = vec_len (vam->input->buffer);
4293   M2 (CLI_INBAND, cli_inband, len);
4294   clib_memcpy (mp->cmd, vam->input->buffer, len);
4295   mp->length = htonl (len);
4296
4297   S;
4298   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4299 }
4300
4301 static int
4302 api_create_loopback (vat_main_t * vam)
4303 {
4304   unformat_input_t *i = vam->input;
4305   vl_api_create_loopback_t *mp;
4306   f64 timeout;
4307   u8 mac_address[6];
4308   u8 mac_set = 0;
4309
4310   memset (mac_address, 0, sizeof (mac_address));
4311
4312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4313     {
4314       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4315         mac_set = 1;
4316       else
4317         break;
4318     }
4319
4320   /* Construct the API message */
4321   M (CREATE_LOOPBACK, create_loopback);
4322   if (mac_set)
4323     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4324
4325   S;
4326   W;
4327 }
4328
4329 static int
4330 api_delete_loopback (vat_main_t * vam)
4331 {
4332   unformat_input_t *i = vam->input;
4333   vl_api_delete_loopback_t *mp;
4334   f64 timeout;
4335   u32 sw_if_index = ~0;
4336
4337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4338     {
4339       if (unformat (i, "sw_if_index %d", &sw_if_index))
4340         ;
4341       else
4342         break;
4343     }
4344
4345   if (sw_if_index == ~0)
4346     {
4347       errmsg ("missing sw_if_index\n");
4348       return -99;
4349     }
4350
4351   /* Construct the API message */
4352   M (DELETE_LOOPBACK, delete_loopback);
4353   mp->sw_if_index = ntohl (sw_if_index);
4354
4355   S;
4356   W;
4357 }
4358
4359 static int
4360 api_want_stats (vat_main_t * vam)
4361 {
4362   unformat_input_t *i = vam->input;
4363   vl_api_want_stats_t *mp;
4364   f64 timeout;
4365   int enable = -1;
4366
4367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4368     {
4369       if (unformat (i, "enable"))
4370         enable = 1;
4371       else if (unformat (i, "disable"))
4372         enable = 0;
4373       else
4374         break;
4375     }
4376
4377   if (enable == -1)
4378     {
4379       errmsg ("missing enable|disable\n");
4380       return -99;
4381     }
4382
4383   M (WANT_STATS, want_stats);
4384   mp->enable_disable = enable;
4385
4386   S;
4387   W;
4388 }
4389
4390 static int
4391 api_want_interface_events (vat_main_t * vam)
4392 {
4393   unformat_input_t *i = vam->input;
4394   vl_api_want_interface_events_t *mp;
4395   f64 timeout;
4396   int enable = -1;
4397
4398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4399     {
4400       if (unformat (i, "enable"))
4401         enable = 1;
4402       else if (unformat (i, "disable"))
4403         enable = 0;
4404       else
4405         break;
4406     }
4407
4408   if (enable == -1)
4409     {
4410       errmsg ("missing enable|disable\n");
4411       return -99;
4412     }
4413
4414   M (WANT_INTERFACE_EVENTS, want_interface_events);
4415   mp->enable_disable = enable;
4416
4417   vam->interface_event_display = enable;
4418
4419   S;
4420   W;
4421 }
4422
4423
4424 /* Note: non-static, called once to set up the initial intfc table */
4425 int
4426 api_sw_interface_dump (vat_main_t * vam)
4427 {
4428   vl_api_sw_interface_dump_t *mp;
4429   f64 timeout;
4430   hash_pair_t *p;
4431   name_sort_t *nses = 0, *ns;
4432   sw_interface_subif_t *sub = NULL;
4433
4434   /* Toss the old name table */
4435   /* *INDENT-OFF* */
4436   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4437   ({
4438     vec_add2 (nses, ns, 1);
4439     ns->name = (u8 *)(p->key);
4440     ns->value = (u32) p->value[0];
4441   }));
4442   /* *INDENT-ON* */
4443
4444   hash_free (vam->sw_if_index_by_interface_name);
4445
4446   vec_foreach (ns, nses) vec_free (ns->name);
4447
4448   vec_free (nses);
4449
4450   vec_foreach (sub, vam->sw_if_subif_table)
4451   {
4452     vec_free (sub->interface_name);
4453   }
4454   vec_free (vam->sw_if_subif_table);
4455
4456   /* recreate the interface name hash table */
4457   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4458
4459   /* Get list of ethernets */
4460   M (SW_INTERFACE_DUMP, sw_interface_dump);
4461   mp->name_filter_valid = 1;
4462   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4463   S;
4464
4465   /* and local / loopback interfaces */
4466   M (SW_INTERFACE_DUMP, sw_interface_dump);
4467   mp->name_filter_valid = 1;
4468   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4469   S;
4470
4471   /* and packet-generator interfaces */
4472   M (SW_INTERFACE_DUMP, sw_interface_dump);
4473   mp->name_filter_valid = 1;
4474   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4475   S;
4476
4477   /* and vxlan-gpe tunnel interfaces */
4478   M (SW_INTERFACE_DUMP, sw_interface_dump);
4479   mp->name_filter_valid = 1;
4480   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4481            sizeof (mp->name_filter) - 1);
4482   S;
4483
4484   /* and vxlan tunnel interfaces */
4485   M (SW_INTERFACE_DUMP, sw_interface_dump);
4486   mp->name_filter_valid = 1;
4487   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4488   S;
4489
4490   /* and host (af_packet) interfaces */
4491   M (SW_INTERFACE_DUMP, sw_interface_dump);
4492   mp->name_filter_valid = 1;
4493   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4494   S;
4495
4496   /* and l2tpv3 tunnel interfaces */
4497   M (SW_INTERFACE_DUMP, sw_interface_dump);
4498   mp->name_filter_valid = 1;
4499   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4500            sizeof (mp->name_filter) - 1);
4501   S;
4502
4503   /* and GRE tunnel interfaces */
4504   M (SW_INTERFACE_DUMP, sw_interface_dump);
4505   mp->name_filter_valid = 1;
4506   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4507   S;
4508
4509   /* and LISP-GPE interfaces */
4510   M (SW_INTERFACE_DUMP, sw_interface_dump);
4511   mp->name_filter_valid = 1;
4512   strncpy ((char *) mp->name_filter, "lisp_gpe",
4513            sizeof (mp->name_filter) - 1);
4514   S;
4515
4516   /* and IPSEC tunnel interfaces */
4517   M (SW_INTERFACE_DUMP, sw_interface_dump);
4518   mp->name_filter_valid = 1;
4519   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4520   S;
4521
4522   /* Use a control ping for synchronization */
4523   {
4524     vl_api_control_ping_t *mp;
4525     M (CONTROL_PING, control_ping);
4526     S;
4527   }
4528   W;
4529 }
4530
4531 static int
4532 api_sw_interface_set_flags (vat_main_t * vam)
4533 {
4534   unformat_input_t *i = vam->input;
4535   vl_api_sw_interface_set_flags_t *mp;
4536   f64 timeout;
4537   u32 sw_if_index;
4538   u8 sw_if_index_set = 0;
4539   u8 admin_up = 0, link_up = 0;
4540
4541   /* Parse args required to build the message */
4542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4543     {
4544       if (unformat (i, "admin-up"))
4545         admin_up = 1;
4546       else if (unformat (i, "admin-down"))
4547         admin_up = 0;
4548       else if (unformat (i, "link-up"))
4549         link_up = 1;
4550       else if (unformat (i, "link-down"))
4551         link_up = 0;
4552       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4553         sw_if_index_set = 1;
4554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4555         sw_if_index_set = 1;
4556       else
4557         break;
4558     }
4559
4560   if (sw_if_index_set == 0)
4561     {
4562       errmsg ("missing interface name or sw_if_index\n");
4563       return -99;
4564     }
4565
4566   /* Construct the API message */
4567   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4568   mp->sw_if_index = ntohl (sw_if_index);
4569   mp->admin_up_down = admin_up;
4570   mp->link_up_down = link_up;
4571
4572   /* send it... */
4573   S;
4574
4575   /* Wait for a reply, return the good/bad news... */
4576   W;
4577 }
4578
4579 static int
4580 api_sw_interface_clear_stats (vat_main_t * vam)
4581 {
4582   unformat_input_t *i = vam->input;
4583   vl_api_sw_interface_clear_stats_t *mp;
4584   f64 timeout;
4585   u32 sw_if_index;
4586   u8 sw_if_index_set = 0;
4587
4588   /* Parse args required to build the message */
4589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4590     {
4591       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4592         sw_if_index_set = 1;
4593       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4594         sw_if_index_set = 1;
4595       else
4596         break;
4597     }
4598
4599   /* Construct the API message */
4600   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4601
4602   if (sw_if_index_set == 1)
4603     mp->sw_if_index = ntohl (sw_if_index);
4604   else
4605     mp->sw_if_index = ~0;
4606
4607   /* send it... */
4608   S;
4609
4610   /* Wait for a reply, return the good/bad news... */
4611   W;
4612 }
4613
4614 static int
4615 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4616 {
4617   unformat_input_t *i = vam->input;
4618   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4619   f64 timeout;
4620   u32 sw_if_index;
4621   u8 sw_if_index_set = 0;
4622   u32 subport;
4623   u8 subport_set = 0;
4624   u32 pipe;
4625   u8 pipe_set = 0;
4626   u32 profile;
4627   u8 profile_set = 0;
4628
4629   /* Parse args required to build the message */
4630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4631     {
4632       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4633         sw_if_index_set = 1;
4634       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4635         sw_if_index_set = 1;
4636       else if (unformat (i, "subport %u", &subport))
4637         subport_set = 1;
4638       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4639         sw_if_index_set = 1;
4640       else if (unformat (i, "pipe %u", &pipe))
4641         pipe_set = 1;
4642       else if (unformat (i, "profile %u", &profile))
4643         profile_set = 1;
4644       else
4645         break;
4646     }
4647
4648   if (sw_if_index_set == 0)
4649     {
4650       errmsg ("missing interface name or sw_if_index\n");
4651       return -99;
4652     }
4653
4654   if (subport_set == 0)
4655     {
4656       errmsg ("missing subport \n");
4657       return -99;
4658     }
4659
4660   if (pipe_set == 0)
4661     {
4662       errmsg ("missing pipe\n");
4663       return -99;
4664     }
4665
4666   if (profile_set == 0)
4667     {
4668       errmsg ("missing profile\n");
4669       return -99;
4670     }
4671
4672   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4673
4674   mp->sw_if_index = ntohl (sw_if_index);
4675   mp->subport = ntohl (subport);
4676   mp->pipe = ntohl (pipe);
4677   mp->profile = ntohl (profile);
4678
4679
4680   S;
4681   W;
4682   /* NOTREACHED */
4683   return 0;
4684 }
4685
4686 static int
4687 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4688 {
4689   unformat_input_t *i = vam->input;
4690   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4691   f64 timeout;
4692   u32 sw_if_index;
4693   u8 sw_if_index_set = 0;
4694   u32 subport;
4695   u8 subport_set = 0;
4696   u32 tb_rate = 1250000000;     /* 10GbE */
4697   u32 tb_size = 1000000;
4698   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4699   u32 tc_period = 10;
4700
4701   /* Parse args required to build the message */
4702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4703     {
4704       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4705         sw_if_index_set = 1;
4706       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4707         sw_if_index_set = 1;
4708       else if (unformat (i, "subport %u", &subport))
4709         subport_set = 1;
4710       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4711         sw_if_index_set = 1;
4712       else if (unformat (i, "rate %u", &tb_rate))
4713         {
4714           u32 tc_id;
4715
4716           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4717                tc_id++)
4718             tc_rate[tc_id] = tb_rate;
4719         }
4720       else if (unformat (i, "bktsize %u", &tb_size))
4721         ;
4722       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4723         ;
4724       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4725         ;
4726       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4727         ;
4728       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4729         ;
4730       else if (unformat (i, "period %u", &tc_period))
4731         ;
4732       else
4733         break;
4734     }
4735
4736   if (sw_if_index_set == 0)
4737     {
4738       errmsg ("missing interface name or sw_if_index\n");
4739       return -99;
4740     }
4741
4742   if (subport_set == 0)
4743     {
4744       errmsg ("missing subport \n");
4745       return -99;
4746     }
4747
4748   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4749
4750   mp->sw_if_index = ntohl (sw_if_index);
4751   mp->subport = ntohl (subport);
4752   mp->tb_rate = ntohl (tb_rate);
4753   mp->tb_size = ntohl (tb_size);
4754   mp->tc_rate[0] = ntohl (tc_rate[0]);
4755   mp->tc_rate[1] = ntohl (tc_rate[1]);
4756   mp->tc_rate[2] = ntohl (tc_rate[2]);
4757   mp->tc_rate[3] = ntohl (tc_rate[3]);
4758   mp->tc_period = ntohl (tc_period);
4759
4760   S;
4761   W;
4762   /* NOTREACHED */
4763   return 0;
4764 }
4765
4766 static int
4767 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4768 {
4769   unformat_input_t *i = vam->input;
4770   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4771   f64 timeout;
4772   u32 sw_if_index;
4773   u8 sw_if_index_set = 0;
4774   u8 entry_set = 0;
4775   u8 tc_set = 0;
4776   u8 queue_set = 0;
4777   u32 entry, tc, queue;
4778
4779   /* Parse args required to build the message */
4780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4781     {
4782       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4783         sw_if_index_set = 1;
4784       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4785         sw_if_index_set = 1;
4786       else if (unformat (i, "entry %d", &entry))
4787         entry_set = 1;
4788       else if (unformat (i, "tc %d", &tc))
4789         tc_set = 1;
4790       else if (unformat (i, "queue %d", &queue))
4791         queue_set = 1;
4792       else
4793         break;
4794     }
4795
4796   if (sw_if_index_set == 0)
4797     {
4798       errmsg ("missing interface name or sw_if_index\n");
4799       return -99;
4800     }
4801
4802   if (entry_set == 0)
4803     {
4804       errmsg ("missing entry \n");
4805       return -99;
4806     }
4807
4808   if (tc_set == 0)
4809     {
4810       errmsg ("missing traffic class \n");
4811       return -99;
4812     }
4813
4814   if (queue_set == 0)
4815     {
4816       errmsg ("missing queue \n");
4817       return -99;
4818     }
4819
4820   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4821
4822   mp->sw_if_index = ntohl (sw_if_index);
4823   mp->entry = ntohl (entry);
4824   mp->tc = ntohl (tc);
4825   mp->queue = ntohl (queue);
4826
4827   S;
4828   W;
4829   /* NOTREACHED */
4830   return 0;
4831 }
4832
4833 static int
4834 api_sw_interface_add_del_address (vat_main_t * vam)
4835 {
4836   unformat_input_t *i = vam->input;
4837   vl_api_sw_interface_add_del_address_t *mp;
4838   f64 timeout;
4839   u32 sw_if_index;
4840   u8 sw_if_index_set = 0;
4841   u8 is_add = 1, del_all = 0;
4842   u32 address_length = 0;
4843   u8 v4_address_set = 0;
4844   u8 v6_address_set = 0;
4845   ip4_address_t v4address;
4846   ip6_address_t v6address;
4847
4848   /* Parse args required to build the message */
4849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4850     {
4851       if (unformat (i, "del-all"))
4852         del_all = 1;
4853       else if (unformat (i, "del"))
4854         is_add = 0;
4855       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4856         sw_if_index_set = 1;
4857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4858         sw_if_index_set = 1;
4859       else if (unformat (i, "%U/%d",
4860                          unformat_ip4_address, &v4address, &address_length))
4861         v4_address_set = 1;
4862       else if (unformat (i, "%U/%d",
4863                          unformat_ip6_address, &v6address, &address_length))
4864         v6_address_set = 1;
4865       else
4866         break;
4867     }
4868
4869   if (sw_if_index_set == 0)
4870     {
4871       errmsg ("missing interface name or sw_if_index\n");
4872       return -99;
4873     }
4874   if (v4_address_set && v6_address_set)
4875     {
4876       errmsg ("both v4 and v6 addresses set\n");
4877       return -99;
4878     }
4879   if (!v4_address_set && !v6_address_set && !del_all)
4880     {
4881       errmsg ("no addresses set\n");
4882       return -99;
4883     }
4884
4885   /* Construct the API message */
4886   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4887
4888   mp->sw_if_index = ntohl (sw_if_index);
4889   mp->is_add = is_add;
4890   mp->del_all = del_all;
4891   if (v6_address_set)
4892     {
4893       mp->is_ipv6 = 1;
4894       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4895     }
4896   else
4897     {
4898       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4899     }
4900   mp->address_length = address_length;
4901
4902   /* send it... */
4903   S;
4904
4905   /* Wait for a reply, return good/bad news  */
4906   W;
4907 }
4908
4909 static int
4910 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4911 {
4912   unformat_input_t *i = vam->input;
4913   vl_api_sw_interface_set_mpls_enable_t *mp;
4914   f64 timeout;
4915   u32 sw_if_index;
4916   u8 sw_if_index_set = 0;
4917   u8 enable = 1;
4918
4919   /* Parse args required to build the message */
4920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4921     {
4922       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4923         sw_if_index_set = 1;
4924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4925         sw_if_index_set = 1;
4926       else if (unformat (i, "disable"))
4927         enable = 0;
4928       else if (unformat (i, "dis"))
4929         enable = 0;
4930       else
4931         break;
4932     }
4933
4934   if (sw_if_index_set == 0)
4935     {
4936       errmsg ("missing interface name or sw_if_index\n");
4937       return -99;
4938     }
4939
4940   /* Construct the API message */
4941   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4942
4943   mp->sw_if_index = ntohl (sw_if_index);
4944   mp->enable = enable;
4945
4946   /* send it... */
4947   S;
4948
4949   /* Wait for a reply... */
4950   W;
4951 }
4952
4953 static int
4954 api_sw_interface_set_table (vat_main_t * vam)
4955 {
4956   unformat_input_t *i = vam->input;
4957   vl_api_sw_interface_set_table_t *mp;
4958   f64 timeout;
4959   u32 sw_if_index, vrf_id = 0;
4960   u8 sw_if_index_set = 0;
4961   u8 is_ipv6 = 0;
4962
4963   /* Parse args required to build the message */
4964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4965     {
4966       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4967         sw_if_index_set = 1;
4968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4969         sw_if_index_set = 1;
4970       else if (unformat (i, "vrf %d", &vrf_id))
4971         ;
4972       else if (unformat (i, "ipv6"))
4973         is_ipv6 = 1;
4974       else
4975         break;
4976     }
4977
4978   if (sw_if_index_set == 0)
4979     {
4980       errmsg ("missing interface name or sw_if_index\n");
4981       return -99;
4982     }
4983
4984   /* Construct the API message */
4985   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4986
4987   mp->sw_if_index = ntohl (sw_if_index);
4988   mp->is_ipv6 = is_ipv6;
4989   mp->vrf_id = ntohl (vrf_id);
4990
4991   /* send it... */
4992   S;
4993
4994   /* Wait for a reply... */
4995   W;
4996 }
4997
4998 static int
4999 api_sw_interface_set_vpath (vat_main_t * vam)
5000 {
5001   unformat_input_t *i = vam->input;
5002   vl_api_sw_interface_set_vpath_t *mp;
5003   f64 timeout;
5004   u32 sw_if_index = 0;
5005   u8 sw_if_index_set = 0;
5006   u8 is_enable = 0;
5007
5008   /* Parse args required to build the message */
5009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5010     {
5011       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5012         sw_if_index_set = 1;
5013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5014         sw_if_index_set = 1;
5015       else if (unformat (i, "enable"))
5016         is_enable = 1;
5017       else if (unformat (i, "disable"))
5018         is_enable = 0;
5019       else
5020         break;
5021     }
5022
5023   if (sw_if_index_set == 0)
5024     {
5025       errmsg ("missing interface name or sw_if_index\n");
5026       return -99;
5027     }
5028
5029   /* Construct the API message */
5030   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5031
5032   mp->sw_if_index = ntohl (sw_if_index);
5033   mp->enable = is_enable;
5034
5035   /* send it... */
5036   S;
5037
5038   /* Wait for a reply... */
5039   W;
5040 }
5041
5042 static int
5043 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5044 {
5045   unformat_input_t *i = vam->input;
5046   vl_api_sw_interface_set_l2_xconnect_t *mp;
5047   f64 timeout;
5048   u32 rx_sw_if_index;
5049   u8 rx_sw_if_index_set = 0;
5050   u32 tx_sw_if_index;
5051   u8 tx_sw_if_index_set = 0;
5052   u8 enable = 1;
5053
5054   /* Parse args required to build the message */
5055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5056     {
5057       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5058         rx_sw_if_index_set = 1;
5059       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5060         tx_sw_if_index_set = 1;
5061       else if (unformat (i, "rx"))
5062         {
5063           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5064             {
5065               if (unformat (i, "%U", unformat_sw_if_index, vam,
5066                             &rx_sw_if_index))
5067                 rx_sw_if_index_set = 1;
5068             }
5069           else
5070             break;
5071         }
5072       else if (unformat (i, "tx"))
5073         {
5074           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5075             {
5076               if (unformat (i, "%U", unformat_sw_if_index, vam,
5077                             &tx_sw_if_index))
5078                 tx_sw_if_index_set = 1;
5079             }
5080           else
5081             break;
5082         }
5083       else if (unformat (i, "enable"))
5084         enable = 1;
5085       else if (unformat (i, "disable"))
5086         enable = 0;
5087       else
5088         break;
5089     }
5090
5091   if (rx_sw_if_index_set == 0)
5092     {
5093       errmsg ("missing rx interface name or rx_sw_if_index\n");
5094       return -99;
5095     }
5096
5097   if (enable && (tx_sw_if_index_set == 0))
5098     {
5099       errmsg ("missing tx interface name or tx_sw_if_index\n");
5100       return -99;
5101     }
5102
5103   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5104
5105   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5106   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5107   mp->enable = enable;
5108
5109   S;
5110   W;
5111   /* NOTREACHED */
5112   return 0;
5113 }
5114
5115 static int
5116 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5117 {
5118   unformat_input_t *i = vam->input;
5119   vl_api_sw_interface_set_l2_bridge_t *mp;
5120   f64 timeout;
5121   u32 rx_sw_if_index;
5122   u8 rx_sw_if_index_set = 0;
5123   u32 bd_id;
5124   u8 bd_id_set = 0;
5125   u8 bvi = 0;
5126   u32 shg = 0;
5127   u8 enable = 1;
5128
5129   /* Parse args required to build the message */
5130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5131     {
5132       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5133         rx_sw_if_index_set = 1;
5134       else if (unformat (i, "bd_id %d", &bd_id))
5135         bd_id_set = 1;
5136       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5137         rx_sw_if_index_set = 1;
5138       else if (unformat (i, "shg %d", &shg))
5139         ;
5140       else if (unformat (i, "bvi"))
5141         bvi = 1;
5142       else if (unformat (i, "enable"))
5143         enable = 1;
5144       else if (unformat (i, "disable"))
5145         enable = 0;
5146       else
5147         break;
5148     }
5149
5150   if (rx_sw_if_index_set == 0)
5151     {
5152       errmsg ("missing rx interface name or sw_if_index\n");
5153       return -99;
5154     }
5155
5156   if (enable && (bd_id_set == 0))
5157     {
5158       errmsg ("missing bridge domain\n");
5159       return -99;
5160     }
5161
5162   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5163
5164   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5165   mp->bd_id = ntohl (bd_id);
5166   mp->shg = (u8) shg;
5167   mp->bvi = bvi;
5168   mp->enable = enable;
5169
5170   S;
5171   W;
5172   /* NOTREACHED */
5173   return 0;
5174 }
5175
5176 static int
5177 api_bridge_domain_dump (vat_main_t * vam)
5178 {
5179   unformat_input_t *i = vam->input;
5180   vl_api_bridge_domain_dump_t *mp;
5181   f64 timeout;
5182   u32 bd_id = ~0;
5183
5184   /* Parse args required to build the message */
5185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5186     {
5187       if (unformat (i, "bd_id %d", &bd_id))
5188         ;
5189       else
5190         break;
5191     }
5192
5193   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5194   mp->bd_id = ntohl (bd_id);
5195   S;
5196
5197   /* Use a control ping for synchronization */
5198   {
5199     vl_api_control_ping_t *mp;
5200     M (CONTROL_PING, control_ping);
5201     S;
5202   }
5203
5204   W;
5205   /* NOTREACHED */
5206   return 0;
5207 }
5208
5209 static int
5210 api_bridge_domain_add_del (vat_main_t * vam)
5211 {
5212   unformat_input_t *i = vam->input;
5213   vl_api_bridge_domain_add_del_t *mp;
5214   f64 timeout;
5215   u32 bd_id = ~0;
5216   u8 is_add = 1;
5217   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5218
5219   /* Parse args required to build the message */
5220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5221     {
5222       if (unformat (i, "bd_id %d", &bd_id))
5223         ;
5224       else if (unformat (i, "flood %d", &flood))
5225         ;
5226       else if (unformat (i, "uu-flood %d", &uu_flood))
5227         ;
5228       else if (unformat (i, "forward %d", &forward))
5229         ;
5230       else if (unformat (i, "learn %d", &learn))
5231         ;
5232       else if (unformat (i, "arp-term %d", &arp_term))
5233         ;
5234       else if (unformat (i, "del"))
5235         {
5236           is_add = 0;
5237           flood = uu_flood = forward = learn = 0;
5238         }
5239       else
5240         break;
5241     }
5242
5243   if (bd_id == ~0)
5244     {
5245       errmsg ("missing bridge domain\n");
5246       return -99;
5247     }
5248
5249   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5250
5251   mp->bd_id = ntohl (bd_id);
5252   mp->flood = flood;
5253   mp->uu_flood = uu_flood;
5254   mp->forward = forward;
5255   mp->learn = learn;
5256   mp->arp_term = arp_term;
5257   mp->is_add = is_add;
5258
5259   S;
5260   W;
5261   /* NOTREACHED */
5262   return 0;
5263 }
5264
5265 static int
5266 api_l2fib_add_del (vat_main_t * vam)
5267 {
5268   unformat_input_t *i = vam->input;
5269   vl_api_l2fib_add_del_t *mp;
5270   f64 timeout;
5271   u64 mac = 0;
5272   u8 mac_set = 0;
5273   u32 bd_id;
5274   u8 bd_id_set = 0;
5275   u32 sw_if_index;
5276   u8 sw_if_index_set = 0;
5277   u8 is_add = 1;
5278   u8 static_mac = 0;
5279   u8 filter_mac = 0;
5280   u8 bvi_mac = 0;
5281   int count = 1;
5282   f64 before = 0;
5283   int j;
5284
5285   /* Parse args required to build the message */
5286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5287     {
5288       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5289         mac_set = 1;
5290       else if (unformat (i, "bd_id %d", &bd_id))
5291         bd_id_set = 1;
5292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5293         sw_if_index_set = 1;
5294       else if (unformat (i, "sw_if"))
5295         {
5296           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5297             {
5298               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5299                 sw_if_index_set = 1;
5300             }
5301           else
5302             break;
5303         }
5304       else if (unformat (i, "static"))
5305         static_mac = 1;
5306       else if (unformat (i, "filter"))
5307         {
5308           filter_mac = 1;
5309           static_mac = 1;
5310         }
5311       else if (unformat (i, "bvi"))
5312         {
5313           bvi_mac = 1;
5314           static_mac = 1;
5315         }
5316       else if (unformat (i, "del"))
5317         is_add = 0;
5318       else if (unformat (i, "count %d", &count))
5319         ;
5320       else
5321         break;
5322     }
5323
5324   if (mac_set == 0)
5325     {
5326       errmsg ("missing mac address\n");
5327       return -99;
5328     }
5329
5330   if (bd_id_set == 0)
5331     {
5332       errmsg ("missing bridge domain\n");
5333       return -99;
5334     }
5335
5336   if (is_add && (sw_if_index_set == 0))
5337     {
5338       errmsg ("missing interface name or sw_if_index\n");
5339       return -99;
5340     }
5341
5342   if (count > 1)
5343     {
5344       /* Turn on async mode */
5345       vam->async_mode = 1;
5346       vam->async_errors = 0;
5347       before = vat_time_now (vam);
5348     }
5349
5350   for (j = 0; j < count; j++)
5351     {
5352       M (L2FIB_ADD_DEL, l2fib_add_del);
5353
5354       mp->mac = mac;
5355       mp->bd_id = ntohl (bd_id);
5356       mp->is_add = is_add;
5357
5358       if (is_add)
5359         {
5360           mp->sw_if_index = ntohl (sw_if_index);
5361           mp->static_mac = static_mac;
5362           mp->filter_mac = filter_mac;
5363           mp->bvi_mac = bvi_mac;
5364         }
5365       increment_mac_address (&mac);
5366       /* send it... */
5367       S;
5368     }
5369
5370   if (count > 1)
5371     {
5372       vl_api_control_ping_t *mp;
5373       f64 after;
5374
5375       /* Shut off async mode */
5376       vam->async_mode = 0;
5377
5378       M (CONTROL_PING, control_ping);
5379       S;
5380
5381       timeout = vat_time_now (vam) + 1.0;
5382       while (vat_time_now (vam) < timeout)
5383         if (vam->result_ready == 1)
5384           goto out;
5385       vam->retval = -99;
5386
5387     out:
5388       if (vam->retval == -99)
5389         errmsg ("timeout\n");
5390
5391       if (vam->async_errors > 0)
5392         {
5393           errmsg ("%d asynchronous errors\n", vam->async_errors);
5394           vam->retval = -98;
5395         }
5396       vam->async_errors = 0;
5397       after = vat_time_now (vam);
5398
5399       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5400                count, after - before, count / (after - before));
5401     }
5402   else
5403     {
5404       /* Wait for a reply... */
5405       W;
5406     }
5407   /* Return the good/bad news */
5408   return (vam->retval);
5409 }
5410
5411 static int
5412 api_l2_flags (vat_main_t * vam)
5413 {
5414   unformat_input_t *i = vam->input;
5415   vl_api_l2_flags_t *mp;
5416   f64 timeout;
5417   u32 sw_if_index;
5418   u32 feature_bitmap = 0;
5419   u8 sw_if_index_set = 0;
5420
5421   /* Parse args required to build the message */
5422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5423     {
5424       if (unformat (i, "sw_if_index %d", &sw_if_index))
5425         sw_if_index_set = 1;
5426       else if (unformat (i, "sw_if"))
5427         {
5428           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5429             {
5430               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5431                 sw_if_index_set = 1;
5432             }
5433           else
5434             break;
5435         }
5436       else if (unformat (i, "learn"))
5437         feature_bitmap |= L2INPUT_FEAT_LEARN;
5438       else if (unformat (i, "forward"))
5439         feature_bitmap |= L2INPUT_FEAT_FWD;
5440       else if (unformat (i, "flood"))
5441         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5442       else if (unformat (i, "uu-flood"))
5443         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5444       else
5445         break;
5446     }
5447
5448   if (sw_if_index_set == 0)
5449     {
5450       errmsg ("missing interface name or sw_if_index\n");
5451       return -99;
5452     }
5453
5454   M (L2_FLAGS, l2_flags);
5455
5456   mp->sw_if_index = ntohl (sw_if_index);
5457   mp->feature_bitmap = ntohl (feature_bitmap);
5458
5459   S;
5460   W;
5461   /* NOTREACHED */
5462   return 0;
5463 }
5464
5465 static int
5466 api_bridge_flags (vat_main_t * vam)
5467 {
5468   unformat_input_t *i = vam->input;
5469   vl_api_bridge_flags_t *mp;
5470   f64 timeout;
5471   u32 bd_id;
5472   u8 bd_id_set = 0;
5473   u8 is_set = 1;
5474   u32 flags = 0;
5475
5476   /* Parse args required to build the message */
5477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5478     {
5479       if (unformat (i, "bd_id %d", &bd_id))
5480         bd_id_set = 1;
5481       else if (unformat (i, "learn"))
5482         flags |= L2_LEARN;
5483       else if (unformat (i, "forward"))
5484         flags |= L2_FWD;
5485       else if (unformat (i, "flood"))
5486         flags |= L2_FLOOD;
5487       else if (unformat (i, "uu-flood"))
5488         flags |= L2_UU_FLOOD;
5489       else if (unformat (i, "arp-term"))
5490         flags |= L2_ARP_TERM;
5491       else if (unformat (i, "off"))
5492         is_set = 0;
5493       else if (unformat (i, "disable"))
5494         is_set = 0;
5495       else
5496         break;
5497     }
5498
5499   if (bd_id_set == 0)
5500     {
5501       errmsg ("missing bridge domain\n");
5502       return -99;
5503     }
5504
5505   M (BRIDGE_FLAGS, bridge_flags);
5506
5507   mp->bd_id = ntohl (bd_id);
5508   mp->feature_bitmap = ntohl (flags);
5509   mp->is_set = is_set;
5510
5511   S;
5512   W;
5513   /* NOTREACHED */
5514   return 0;
5515 }
5516
5517 static int
5518 api_bd_ip_mac_add_del (vat_main_t * vam)
5519 {
5520   unformat_input_t *i = vam->input;
5521   vl_api_bd_ip_mac_add_del_t *mp;
5522   f64 timeout;
5523   u32 bd_id;
5524   u8 is_ipv6 = 0;
5525   u8 is_add = 1;
5526   u8 bd_id_set = 0;
5527   u8 ip_set = 0;
5528   u8 mac_set = 0;
5529   ip4_address_t v4addr;
5530   ip6_address_t v6addr;
5531   u8 macaddr[6];
5532
5533
5534   /* Parse args required to build the message */
5535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5536     {
5537       if (unformat (i, "bd_id %d", &bd_id))
5538         {
5539           bd_id_set++;
5540         }
5541       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5542         {
5543           ip_set++;
5544         }
5545       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5546         {
5547           ip_set++;
5548           is_ipv6++;
5549         }
5550       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5551         {
5552           mac_set++;
5553         }
5554       else if (unformat (i, "del"))
5555         is_add = 0;
5556       else
5557         break;
5558     }
5559
5560   if (bd_id_set == 0)
5561     {
5562       errmsg ("missing bridge domain\n");
5563       return -99;
5564     }
5565   else if (ip_set == 0)
5566     {
5567       errmsg ("missing IP address\n");
5568       return -99;
5569     }
5570   else if (mac_set == 0)
5571     {
5572       errmsg ("missing MAC address\n");
5573       return -99;
5574     }
5575
5576   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5577
5578   mp->bd_id = ntohl (bd_id);
5579   mp->is_ipv6 = is_ipv6;
5580   mp->is_add = is_add;
5581   if (is_ipv6)
5582     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5583   else
5584     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5585   clib_memcpy (mp->mac_address, macaddr, 6);
5586   S;
5587   W;
5588   /* NOTREACHED */
5589   return 0;
5590 }
5591
5592 static int
5593 api_tap_connect (vat_main_t * vam)
5594 {
5595   unformat_input_t *i = vam->input;
5596   vl_api_tap_connect_t *mp;
5597   f64 timeout;
5598   u8 mac_address[6];
5599   u8 random_mac = 1;
5600   u8 name_set = 0;
5601   u8 *tap_name;
5602
5603   memset (mac_address, 0, sizeof (mac_address));
5604
5605   /* Parse args required to build the message */
5606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5607     {
5608       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5609         {
5610           random_mac = 0;
5611         }
5612       else if (unformat (i, "random-mac"))
5613         random_mac = 1;
5614       else if (unformat (i, "tapname %s", &tap_name))
5615         name_set = 1;
5616       else
5617         break;
5618     }
5619
5620   if (name_set == 0)
5621     {
5622       errmsg ("missing tap name\n");
5623       return -99;
5624     }
5625   if (vec_len (tap_name) > 63)
5626     {
5627       errmsg ("tap name too long\n");
5628     }
5629   vec_add1 (tap_name, 0);
5630
5631   /* Construct the API message */
5632   M (TAP_CONNECT, tap_connect);
5633
5634   mp->use_random_mac = random_mac;
5635   clib_memcpy (mp->mac_address, mac_address, 6);
5636   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5637   vec_free (tap_name);
5638
5639   /* send it... */
5640   S;
5641
5642   /* Wait for a reply... */
5643   W;
5644 }
5645
5646 static int
5647 api_tap_modify (vat_main_t * vam)
5648 {
5649   unformat_input_t *i = vam->input;
5650   vl_api_tap_modify_t *mp;
5651   f64 timeout;
5652   u8 mac_address[6];
5653   u8 random_mac = 1;
5654   u8 name_set = 0;
5655   u8 *tap_name;
5656   u32 sw_if_index = ~0;
5657   u8 sw_if_index_set = 0;
5658
5659   memset (mac_address, 0, sizeof (mac_address));
5660
5661   /* Parse args required to build the message */
5662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5663     {
5664       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5665         sw_if_index_set = 1;
5666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5667         sw_if_index_set = 1;
5668       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5669         {
5670           random_mac = 0;
5671         }
5672       else if (unformat (i, "random-mac"))
5673         random_mac = 1;
5674       else if (unformat (i, "tapname %s", &tap_name))
5675         name_set = 1;
5676       else
5677         break;
5678     }
5679
5680   if (sw_if_index_set == 0)
5681     {
5682       errmsg ("missing vpp interface name");
5683       return -99;
5684     }
5685   if (name_set == 0)
5686     {
5687       errmsg ("missing tap name\n");
5688       return -99;
5689     }
5690   if (vec_len (tap_name) > 63)
5691     {
5692       errmsg ("tap name too long\n");
5693     }
5694   vec_add1 (tap_name, 0);
5695
5696   /* Construct the API message */
5697   M (TAP_MODIFY, tap_modify);
5698
5699   mp->use_random_mac = random_mac;
5700   mp->sw_if_index = ntohl (sw_if_index);
5701   clib_memcpy (mp->mac_address, mac_address, 6);
5702   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5703   vec_free (tap_name);
5704
5705   /* send it... */
5706   S;
5707
5708   /* Wait for a reply... */
5709   W;
5710 }
5711
5712 static int
5713 api_tap_delete (vat_main_t * vam)
5714 {
5715   unformat_input_t *i = vam->input;
5716   vl_api_tap_delete_t *mp;
5717   f64 timeout;
5718   u32 sw_if_index = ~0;
5719   u8 sw_if_index_set = 0;
5720
5721   /* Parse args required to build the message */
5722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723     {
5724       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5725         sw_if_index_set = 1;
5726       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5727         sw_if_index_set = 1;
5728       else
5729         break;
5730     }
5731
5732   if (sw_if_index_set == 0)
5733     {
5734       errmsg ("missing vpp interface name");
5735       return -99;
5736     }
5737
5738   /* Construct the API message */
5739   M (TAP_DELETE, tap_delete);
5740
5741   mp->sw_if_index = ntohl (sw_if_index);
5742
5743   /* send it... */
5744   S;
5745
5746   /* Wait for a reply... */
5747   W;
5748 }
5749
5750 static int
5751 api_ip_add_del_route (vat_main_t * vam)
5752 {
5753   unformat_input_t *i = vam->input;
5754   vl_api_ip_add_del_route_t *mp;
5755   f64 timeout;
5756   u32 sw_if_index = ~0, vrf_id = 0;
5757   u8 sw_if_index_set = 0;
5758   u8 is_ipv6 = 0;
5759   u8 is_local = 0, is_drop = 0;
5760   u8 is_unreach = 0, is_prohibit = 0;
5761   u8 create_vrf_if_needed = 0;
5762   u8 is_add = 1;
5763   u8 next_hop_weight = 1;
5764   u8 not_last = 0;
5765   u8 is_multipath = 0;
5766   u8 address_set = 0;
5767   u8 address_length_set = 0;
5768   u32 next_hop_table_id = 0;
5769   u32 resolve_attempts = 0;
5770   u32 dst_address_length = 0;
5771   u8 next_hop_set = 0;
5772   ip4_address_t v4_dst_address, v4_next_hop_address;
5773   ip6_address_t v6_dst_address, v6_next_hop_address;
5774   int count = 1;
5775   int j;
5776   f64 before = 0;
5777   u32 random_add_del = 0;
5778   u32 *random_vector = 0;
5779   uword *random_hash;
5780   u32 random_seed = 0xdeaddabe;
5781   u32 classify_table_index = ~0;
5782   u8 is_classify = 0;
5783   u8 resolve_host = 0, resolve_attached = 0;
5784   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5785
5786   /* Parse args required to build the message */
5787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5788     {
5789       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5790         sw_if_index_set = 1;
5791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5792         sw_if_index_set = 1;
5793       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5794         {
5795           address_set = 1;
5796           is_ipv6 = 0;
5797         }
5798       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5799         {
5800           address_set = 1;
5801           is_ipv6 = 1;
5802         }
5803       else if (unformat (i, "/%d", &dst_address_length))
5804         {
5805           address_length_set = 1;
5806         }
5807
5808       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5809                                          &v4_next_hop_address))
5810         {
5811           next_hop_set = 1;
5812         }
5813       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5814                                          &v6_next_hop_address))
5815         {
5816           next_hop_set = 1;
5817         }
5818       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5819         ;
5820       else if (unformat (i, "weight %d", &next_hop_weight))
5821         ;
5822       else if (unformat (i, "drop"))
5823         {
5824           is_drop = 1;
5825         }
5826       else if (unformat (i, "null-send-unreach"))
5827         {
5828           is_unreach = 1;
5829         }
5830       else if (unformat (i, "null-send-prohibit"))
5831         {
5832           is_prohibit = 1;
5833         }
5834       else if (unformat (i, "local"))
5835         {
5836           is_local = 1;
5837         }
5838       else if (unformat (i, "classify %d", &classify_table_index))
5839         {
5840           is_classify = 1;
5841         }
5842       else if (unformat (i, "del"))
5843         is_add = 0;
5844       else if (unformat (i, "add"))
5845         is_add = 1;
5846       else if (unformat (i, "not-last"))
5847         not_last = 1;
5848       else if (unformat (i, "resolve-via-host"))
5849         resolve_host = 1;
5850       else if (unformat (i, "resolve-via-attached"))
5851         resolve_attached = 1;
5852       else if (unformat (i, "multipath"))
5853         is_multipath = 1;
5854       else if (unformat (i, "vrf %d", &vrf_id))
5855         ;
5856       else if (unformat (i, "create-vrf"))
5857         create_vrf_if_needed = 1;
5858       else if (unformat (i, "count %d", &count))
5859         ;
5860       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5861         ;
5862       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5863         ;
5864       else if (unformat (i, "out-label %d", &next_hop_out_label))
5865         ;
5866       else if (unformat (i, "random"))
5867         random_add_del = 1;
5868       else if (unformat (i, "seed %d", &random_seed))
5869         ;
5870       else
5871         {
5872           clib_warning ("parse error '%U'", format_unformat_error, i);
5873           return -99;
5874         }
5875     }
5876
5877   if (resolve_attempts > 0 && sw_if_index_set == 0)
5878     {
5879       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5880       return -99;
5881     }
5882
5883   if (!next_hop_set && !is_drop && !is_local &&
5884       !is_classify && !is_unreach && !is_prohibit)
5885     {
5886       errmsg
5887         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5888       return -99;
5889     }
5890
5891   if (address_set == 0)
5892     {
5893       errmsg ("missing addresses\n");
5894       return -99;
5895     }
5896
5897   if (address_length_set == 0)
5898     {
5899       errmsg ("missing address length\n");
5900       return -99;
5901     }
5902
5903   /* Generate a pile of unique, random routes */
5904   if (random_add_del)
5905     {
5906       u32 this_random_address;
5907       random_hash = hash_create (count, sizeof (uword));
5908
5909       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5910       for (j = 0; j <= count; j++)
5911         {
5912           do
5913             {
5914               this_random_address = random_u32 (&random_seed);
5915               this_random_address =
5916                 clib_host_to_net_u32 (this_random_address);
5917             }
5918           while (hash_get (random_hash, this_random_address));
5919           vec_add1 (random_vector, this_random_address);
5920           hash_set (random_hash, this_random_address, 1);
5921         }
5922       hash_free (random_hash);
5923       v4_dst_address.as_u32 = random_vector[0];
5924     }
5925
5926   if (count > 1)
5927     {
5928       /* Turn on async mode */
5929       vam->async_mode = 1;
5930       vam->async_errors = 0;
5931       before = vat_time_now (vam);
5932     }
5933
5934   for (j = 0; j < count; j++)
5935     {
5936       /* Construct the API message */
5937       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5938
5939       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5940       mp->table_id = ntohl (vrf_id);
5941       if (resolve_attempts > 0)
5942         {
5943           mp->resolve_attempts = ntohl (resolve_attempts);
5944           mp->resolve_if_needed = 1;
5945         }
5946       mp->create_vrf_if_needed = create_vrf_if_needed;
5947
5948       mp->is_add = is_add;
5949       mp->is_drop = is_drop;
5950       mp->is_unreach = is_unreach;
5951       mp->is_prohibit = is_prohibit;
5952       mp->is_ipv6 = is_ipv6;
5953       mp->is_local = is_local;
5954       mp->is_classify = is_classify;
5955       mp->is_multipath = is_multipath;
5956       mp->is_resolve_host = resolve_host;
5957       mp->is_resolve_attached = resolve_attached;
5958       mp->not_last = not_last;
5959       mp->next_hop_weight = next_hop_weight;
5960       mp->dst_address_length = dst_address_length;
5961       mp->next_hop_table_id = ntohl (next_hop_table_id);
5962       mp->classify_table_index = ntohl (classify_table_index);
5963       mp->next_hop_out_label = ntohl (next_hop_out_label);
5964
5965       if (is_ipv6)
5966         {
5967           clib_memcpy (mp->dst_address, &v6_dst_address,
5968                        sizeof (v6_dst_address));
5969           if (next_hop_set)
5970             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5971                          sizeof (v6_next_hop_address));
5972           increment_v6_address (&v6_dst_address);
5973         }
5974       else
5975         {
5976           clib_memcpy (mp->dst_address, &v4_dst_address,
5977                        sizeof (v4_dst_address));
5978           if (next_hop_set)
5979             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5980                          sizeof (v4_next_hop_address));
5981           if (random_add_del)
5982             v4_dst_address.as_u32 = random_vector[j + 1];
5983           else
5984             increment_v4_address (&v4_dst_address);
5985         }
5986       /* send it... */
5987       S;
5988       /* If we receive SIGTERM, stop now... */
5989       if (vam->do_exit)
5990         break;
5991     }
5992
5993   /* When testing multiple add/del ops, use a control-ping to sync */
5994   if (count > 1)
5995     {
5996       vl_api_control_ping_t *mp;
5997       f64 after;
5998
5999       /* Shut off async mode */
6000       vam->async_mode = 0;
6001
6002       M (CONTROL_PING, control_ping);
6003       S;
6004
6005       timeout = vat_time_now (vam) + 1.0;
6006       while (vat_time_now (vam) < timeout)
6007         if (vam->result_ready == 1)
6008           goto out;
6009       vam->retval = -99;
6010
6011     out:
6012       if (vam->retval == -99)
6013         errmsg ("timeout\n");
6014
6015       if (vam->async_errors > 0)
6016         {
6017           errmsg ("%d asynchronous errors\n", vam->async_errors);
6018           vam->retval = -98;
6019         }
6020       vam->async_errors = 0;
6021       after = vat_time_now (vam);
6022
6023       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6024       if (j > 0)
6025         count = j;
6026
6027       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6028                count, after - before, count / (after - before));
6029     }
6030   else
6031     {
6032       /* Wait for a reply... */
6033       W;
6034     }
6035
6036   /* Return the good/bad news */
6037   return (vam->retval);
6038 }
6039
6040 static int
6041 api_mpls_route_add_del (vat_main_t * vam)
6042 {
6043   unformat_input_t *i = vam->input;
6044   vl_api_mpls_route_add_del_t *mp;
6045   f64 timeout;
6046   u32 sw_if_index = ~0, table_id = 0;
6047   u8 create_table_if_needed = 0;
6048   u8 is_add = 1;
6049   u8 next_hop_weight = 1;
6050   u8 is_multipath = 0;
6051   u32 next_hop_table_id = 0;
6052   u8 next_hop_set = 0;
6053   ip4_address_t v4_next_hop_address = {
6054     .as_u32 = 0,
6055   };
6056   ip6_address_t v6_next_hop_address = { {0} };
6057   int count = 1;
6058   int j;
6059   f64 before = 0;
6060   u32 classify_table_index = ~0;
6061   u8 is_classify = 0;
6062   u8 resolve_host = 0, resolve_attached = 0;
6063   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6064   mpls_label_t local_label = MPLS_LABEL_INVALID;
6065   u8 is_eos = 1;
6066   u8 next_hop_proto_is_ip4 = 1;
6067
6068   /* Parse args required to build the message */
6069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6070     {
6071       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6072         ;
6073       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6074         ;
6075       else if (unformat (i, "%d", &local_label))
6076         ;
6077       else if (unformat (i, "eos"))
6078         is_eos = 1;
6079       else if (unformat (i, "non-eos"))
6080         is_eos = 0;
6081       else if (unformat (i, "via %U", unformat_ip4_address,
6082                          &v4_next_hop_address))
6083         {
6084           next_hop_set = 1;
6085           next_hop_proto_is_ip4 = 1;
6086         }
6087       else if (unformat (i, "via %U", unformat_ip6_address,
6088                          &v6_next_hop_address))
6089         {
6090           next_hop_set = 1;
6091           next_hop_proto_is_ip4 = 0;
6092         }
6093       else if (unformat (i, "weight %d", &next_hop_weight))
6094         ;
6095       else if (unformat (i, "create-table"))
6096         create_table_if_needed = 1;
6097       else if (unformat (i, "classify %d", &classify_table_index))
6098         {
6099           is_classify = 1;
6100         }
6101       else if (unformat (i, "del"))
6102         is_add = 0;
6103       else if (unformat (i, "add"))
6104         is_add = 1;
6105       else if (unformat (i, "resolve-via-host"))
6106         resolve_host = 1;
6107       else if (unformat (i, "resolve-via-attached"))
6108         resolve_attached = 1;
6109       else if (unformat (i, "multipath"))
6110         is_multipath = 1;
6111       else if (unformat (i, "count %d", &count))
6112         ;
6113       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6114         {
6115           next_hop_set = 1;
6116           next_hop_proto_is_ip4 = 1;
6117         }
6118       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6119         {
6120           next_hop_set = 1;
6121           next_hop_proto_is_ip4 = 0;
6122         }
6123       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6124         ;
6125       else if (unformat (i, "out-label %d", &next_hop_out_label))
6126         ;
6127       else
6128         {
6129           clib_warning ("parse error '%U'", format_unformat_error, i);
6130           return -99;
6131         }
6132     }
6133
6134   if (!next_hop_set && !is_classify)
6135     {
6136       errmsg ("next hop / classify not set\n");
6137       return -99;
6138     }
6139
6140   if (MPLS_LABEL_INVALID == local_label)
6141     {
6142       errmsg ("missing label\n");
6143       return -99;
6144     }
6145
6146   if (count > 1)
6147     {
6148       /* Turn on async mode */
6149       vam->async_mode = 1;
6150       vam->async_errors = 0;
6151       before = vat_time_now (vam);
6152     }
6153
6154   for (j = 0; j < count; j++)
6155     {
6156       /* Construct the API message */
6157       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6158
6159       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6160       mp->mr_table_id = ntohl (table_id);
6161       mp->mr_create_table_if_needed = create_table_if_needed;
6162
6163       mp->mr_is_add = is_add;
6164       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6165       mp->mr_is_classify = is_classify;
6166       mp->mr_is_multipath = is_multipath;
6167       mp->mr_is_resolve_host = resolve_host;
6168       mp->mr_is_resolve_attached = resolve_attached;
6169       mp->mr_next_hop_weight = next_hop_weight;
6170       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6171       mp->mr_classify_table_index = ntohl (classify_table_index);
6172       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6173       mp->mr_label = ntohl (local_label);
6174       mp->mr_eos = is_eos;
6175
6176       if (next_hop_set)
6177         {
6178           if (next_hop_proto_is_ip4)
6179             {
6180               clib_memcpy (mp->mr_next_hop,
6181                            &v4_next_hop_address,
6182                            sizeof (v4_next_hop_address));
6183             }
6184           else
6185             {
6186               clib_memcpy (mp->mr_next_hop,
6187                            &v6_next_hop_address,
6188                            sizeof (v6_next_hop_address));
6189             }
6190         }
6191       local_label++;
6192
6193       /* send it... */
6194       S;
6195       /* If we receive SIGTERM, stop now... */
6196       if (vam->do_exit)
6197         break;
6198     }
6199
6200   /* When testing multiple add/del ops, use a control-ping to sync */
6201   if (count > 1)
6202     {
6203       vl_api_control_ping_t *mp;
6204       f64 after;
6205
6206       /* Shut off async mode */
6207       vam->async_mode = 0;
6208
6209       M (CONTROL_PING, control_ping);
6210       S;
6211
6212       timeout = vat_time_now (vam) + 1.0;
6213       while (vat_time_now (vam) < timeout)
6214         if (vam->result_ready == 1)
6215           goto out;
6216       vam->retval = -99;
6217
6218     out:
6219       if (vam->retval == -99)
6220         errmsg ("timeout\n");
6221
6222       if (vam->async_errors > 0)
6223         {
6224           errmsg ("%d asynchronous errors\n", vam->async_errors);
6225           vam->retval = -98;
6226         }
6227       vam->async_errors = 0;
6228       after = vat_time_now (vam);
6229
6230       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6231       if (j > 0)
6232         count = j;
6233
6234       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6235                count, after - before, count / (after - before));
6236     }
6237   else
6238     {
6239       /* Wait for a reply... */
6240       W;
6241     }
6242
6243   /* Return the good/bad news */
6244   return (vam->retval);
6245 }
6246
6247 static int
6248 api_mpls_ip_bind_unbind (vat_main_t * vam)
6249 {
6250   unformat_input_t *i = vam->input;
6251   vl_api_mpls_ip_bind_unbind_t *mp;
6252   f64 timeout;
6253   u32 ip_table_id = 0;
6254   u8 create_table_if_needed = 0;
6255   u8 is_bind = 1;
6256   u8 is_ip4 = 1;
6257   ip4_address_t v4_address;
6258   ip6_address_t v6_address;
6259   u32 address_length;
6260   u8 address_set = 0;
6261   mpls_label_t local_label = MPLS_LABEL_INVALID;
6262
6263   /* Parse args required to build the message */
6264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6265     {
6266       if (unformat (i, "%U/%d", unformat_ip4_address,
6267                     &v4_address, &address_length))
6268         {
6269           is_ip4 = 1;
6270           address_set = 1;
6271         }
6272       else if (unformat (i, "%U/%d", unformat_ip6_address,
6273                          &v6_address, &address_length))
6274         {
6275           is_ip4 = 0;
6276           address_set = 1;
6277         }
6278       else if (unformat (i, "%d", &local_label))
6279         ;
6280       else if (unformat (i, "create-table"))
6281         create_table_if_needed = 1;
6282       else if (unformat (i, "table-id %d", &ip_table_id))
6283         ;
6284       else if (unformat (i, "unbind"))
6285         is_bind = 0;
6286       else if (unformat (i, "bind"))
6287         is_bind = 1;
6288       else
6289         {
6290           clib_warning ("parse error '%U'", format_unformat_error, i);
6291           return -99;
6292         }
6293     }
6294
6295   if (!address_set)
6296     {
6297       errmsg ("IP addres not set\n");
6298       return -99;
6299     }
6300
6301   if (MPLS_LABEL_INVALID == local_label)
6302     {
6303       errmsg ("missing label\n");
6304       return -99;
6305     }
6306
6307   /* Construct the API message */
6308   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6309
6310   mp->mb_create_table_if_needed = create_table_if_needed;
6311   mp->mb_is_bind = is_bind;
6312   mp->mb_is_ip4 = is_ip4;
6313   mp->mb_ip_table_id = ntohl (ip_table_id);
6314   mp->mb_mpls_table_id = 0;
6315   mp->mb_label = ntohl (local_label);
6316   mp->mb_address_length = address_length;
6317
6318   if (is_ip4)
6319     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6320   else
6321     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6322
6323   /* send it... */
6324   S;
6325
6326   /* Wait for a reply... */
6327   W;
6328 }
6329
6330 static int
6331 api_proxy_arp_add_del (vat_main_t * vam)
6332 {
6333   unformat_input_t *i = vam->input;
6334   vl_api_proxy_arp_add_del_t *mp;
6335   f64 timeout;
6336   u32 vrf_id = 0;
6337   u8 is_add = 1;
6338   ip4_address_t lo, hi;
6339   u8 range_set = 0;
6340
6341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6342     {
6343       if (unformat (i, "vrf %d", &vrf_id))
6344         ;
6345       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6346                          unformat_ip4_address, &hi))
6347         range_set = 1;
6348       else if (unformat (i, "del"))
6349         is_add = 0;
6350       else
6351         {
6352           clib_warning ("parse error '%U'", format_unformat_error, i);
6353           return -99;
6354         }
6355     }
6356
6357   if (range_set == 0)
6358     {
6359       errmsg ("address range not set\n");
6360       return -99;
6361     }
6362
6363   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6364
6365   mp->vrf_id = ntohl (vrf_id);
6366   mp->is_add = is_add;
6367   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6368   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6369
6370   S;
6371   W;
6372   /* NOTREACHED */
6373   return 0;
6374 }
6375
6376 static int
6377 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6378 {
6379   unformat_input_t *i = vam->input;
6380   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6381   f64 timeout;
6382   u32 sw_if_index;
6383   u8 enable = 1;
6384   u8 sw_if_index_set = 0;
6385
6386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6387     {
6388       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6389         sw_if_index_set = 1;
6390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6391         sw_if_index_set = 1;
6392       else if (unformat (i, "enable"))
6393         enable = 1;
6394       else if (unformat (i, "disable"))
6395         enable = 0;
6396       else
6397         {
6398           clib_warning ("parse error '%U'", format_unformat_error, i);
6399           return -99;
6400         }
6401     }
6402
6403   if (sw_if_index_set == 0)
6404     {
6405       errmsg ("missing interface name or sw_if_index\n");
6406       return -99;
6407     }
6408
6409   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6410
6411   mp->sw_if_index = ntohl (sw_if_index);
6412   mp->enable_disable = enable;
6413
6414   S;
6415   W;
6416   /* NOTREACHED */
6417   return 0;
6418 }
6419
6420 static int
6421 api_mpls_add_del_encap (vat_main_t * vam)
6422 {
6423   unformat_input_t *i = vam->input;
6424   vl_api_mpls_add_del_encap_t *mp;
6425   f64 timeout;
6426   u32 vrf_id = 0;
6427   u32 *labels = 0;
6428   u32 label;
6429   ip4_address_t dst_address;
6430   u8 is_add = 1;
6431
6432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6433     {
6434       if (unformat (i, "vrf %d", &vrf_id))
6435         ;
6436       else if (unformat (i, "label %d", &label))
6437         vec_add1 (labels, ntohl (label));
6438       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6439         ;
6440       else if (unformat (i, "del"))
6441         is_add = 0;
6442       else
6443         {
6444           clib_warning ("parse error '%U'", format_unformat_error, i);
6445           return -99;
6446         }
6447     }
6448
6449   if (vec_len (labels) == 0)
6450     {
6451       errmsg ("missing encap label stack\n");
6452       return -99;
6453     }
6454
6455   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6456       sizeof (u32) * vec_len (labels));
6457
6458   mp->vrf_id = ntohl (vrf_id);
6459   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6460   mp->is_add = is_add;
6461   mp->nlabels = vec_len (labels);
6462   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6463
6464   vec_free (labels);
6465
6466   S;
6467   W;
6468   /* NOTREACHED */
6469   return 0;
6470 }
6471
6472 static int
6473 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6474 {
6475   unformat_input_t *i = vam->input;
6476   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6477   f64 timeout;
6478   u32 inner_vrf_id = 0;
6479   ip4_address_t intfc_address;
6480   u8 dst_mac_address[6];
6481   int dst_set = 1;
6482   u32 tmp;
6483   u8 intfc_address_length = 0;
6484   u8 is_add = 1;
6485   u8 l2_only = 0;
6486   u32 tx_sw_if_index;
6487   int tx_sw_if_index_set = 0;
6488
6489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6490     {
6491       if (unformat (i, "vrf %d", &inner_vrf_id))
6492         ;
6493       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6494                          &intfc_address, &tmp))
6495         intfc_address_length = tmp;
6496       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6497         tx_sw_if_index_set = 1;
6498       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6499         tx_sw_if_index_set = 1;
6500       else if (unformat (i, "dst %U", unformat_ethernet_address,
6501                          dst_mac_address))
6502         dst_set = 1;
6503       else if (unformat (i, "l2-only"))
6504         l2_only = 1;
6505       else if (unformat (i, "del"))
6506         is_add = 0;
6507       else
6508         {
6509           clib_warning ("parse error '%U'", format_unformat_error, i);
6510           return -99;
6511         }
6512     }
6513
6514   if (!dst_set)
6515     {
6516       errmsg ("dst (mac address) not set\n");
6517       return -99;
6518     }
6519   if (!tx_sw_if_index_set)
6520     {
6521       errmsg ("tx-intfc not set\n");
6522       return -99;
6523     }
6524
6525   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6526
6527   mp->vrf_id = ntohl (inner_vrf_id);
6528   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6529   mp->adj_address_length = intfc_address_length;
6530   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6531                sizeof (dst_mac_address));
6532   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6533   mp->l2_only = l2_only;
6534   mp->is_add = is_add;
6535
6536   S;
6537   W;
6538   /* NOTREACHED */
6539   return 0;
6540 }
6541
6542 static int
6543 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6544 {
6545   unformat_input_t *i = vam->input;
6546   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6547   f64 timeout;
6548   u32 inner_vrf_id = 0;
6549   u32 outer_vrf_id = 0;
6550   ip4_address_t adj_address;
6551   int adj_address_set = 0;
6552   ip4_address_t next_hop_address;
6553   int next_hop_address_set = 0;
6554   u32 tmp;
6555   u8 adj_address_length = 0;
6556   u8 l2_only = 0;
6557   u8 is_add = 1;
6558   u32 resolve_attempts = 5;
6559   u8 resolve_if_needed = 1;
6560
6561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6562     {
6563       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6564         ;
6565       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6566         ;
6567       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6568                          &adj_address, &tmp))
6569         {
6570           adj_address_length = tmp;
6571           adj_address_set = 1;
6572         }
6573       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6574                          &next_hop_address))
6575         next_hop_address_set = 1;
6576       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6577         ;
6578       else if (unformat (i, "resolve-if-needed %d", &tmp))
6579         resolve_if_needed = tmp;
6580       else if (unformat (i, "l2-only"))
6581         l2_only = 1;
6582       else if (unformat (i, "del"))
6583         is_add = 0;
6584       else
6585         {
6586           clib_warning ("parse error '%U'", format_unformat_error, i);
6587           return -99;
6588         }
6589     }
6590
6591   if (!adj_address_set)
6592     {
6593       errmsg ("adjacency address/mask not set\n");
6594       return -99;
6595     }
6596   if (!next_hop_address_set)
6597     {
6598       errmsg ("ip4 next hop address (in outer fib) not set\n");
6599       return -99;
6600     }
6601
6602   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6603
6604   mp->inner_vrf_id = ntohl (inner_vrf_id);
6605   mp->outer_vrf_id = ntohl (outer_vrf_id);
6606   mp->resolve_attempts = ntohl (resolve_attempts);
6607   mp->resolve_if_needed = resolve_if_needed;
6608   mp->is_add = is_add;
6609   mp->l2_only = l2_only;
6610   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6611   mp->adj_address_length = adj_address_length;
6612   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6613                sizeof (next_hop_address));
6614
6615   S;
6616   W;
6617   /* NOTREACHED */
6618   return 0;
6619 }
6620
6621 static int
6622 api_sw_interface_set_unnumbered (vat_main_t * vam)
6623 {
6624   unformat_input_t *i = vam->input;
6625   vl_api_sw_interface_set_unnumbered_t *mp;
6626   f64 timeout;
6627   u32 sw_if_index;
6628   u32 unnum_sw_index = ~0;
6629   u8 is_add = 1;
6630   u8 sw_if_index_set = 0;
6631
6632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6633     {
6634       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6635         sw_if_index_set = 1;
6636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6637         sw_if_index_set = 1;
6638       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6639         ;
6640       else if (unformat (i, "del"))
6641         is_add = 0;
6642       else
6643         {
6644           clib_warning ("parse error '%U'", format_unformat_error, i);
6645           return -99;
6646         }
6647     }
6648
6649   if (sw_if_index_set == 0)
6650     {
6651       errmsg ("missing interface name or sw_if_index\n");
6652       return -99;
6653     }
6654
6655   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6656
6657   mp->sw_if_index = ntohl (sw_if_index);
6658   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6659   mp->is_add = is_add;
6660
6661   S;
6662   W;
6663   /* NOTREACHED */
6664   return 0;
6665 }
6666
6667 static int
6668 api_ip_neighbor_add_del (vat_main_t * vam)
6669 {
6670   unformat_input_t *i = vam->input;
6671   vl_api_ip_neighbor_add_del_t *mp;
6672   f64 timeout;
6673   u32 sw_if_index;
6674   u8 sw_if_index_set = 0;
6675   u32 vrf_id = 0;
6676   u8 is_add = 1;
6677   u8 is_static = 0;
6678   u8 mac_address[6];
6679   u8 mac_set = 0;
6680   u8 v4_address_set = 0;
6681   u8 v6_address_set = 0;
6682   ip4_address_t v4address;
6683   ip6_address_t v6address;
6684
6685   memset (mac_address, 0, sizeof (mac_address));
6686
6687   /* Parse args required to build the message */
6688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6689     {
6690       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6691         {
6692           mac_set = 1;
6693         }
6694       else if (unformat (i, "del"))
6695         is_add = 0;
6696       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6697         sw_if_index_set = 1;
6698       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6699         sw_if_index_set = 1;
6700       else if (unformat (i, "is_static"))
6701         is_static = 1;
6702       else if (unformat (i, "vrf %d", &vrf_id))
6703         ;
6704       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6705         v4_address_set = 1;
6706       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6707         v6_address_set = 1;
6708       else
6709         {
6710           clib_warning ("parse error '%U'", format_unformat_error, i);
6711           return -99;
6712         }
6713     }
6714
6715   if (sw_if_index_set == 0)
6716     {
6717       errmsg ("missing interface name or sw_if_index\n");
6718       return -99;
6719     }
6720   if (v4_address_set && v6_address_set)
6721     {
6722       errmsg ("both v4 and v6 addresses set\n");
6723       return -99;
6724     }
6725   if (!v4_address_set && !v6_address_set)
6726     {
6727       errmsg ("no address set\n");
6728       return -99;
6729     }
6730
6731   /* Construct the API message */
6732   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6733
6734   mp->sw_if_index = ntohl (sw_if_index);
6735   mp->is_add = is_add;
6736   mp->vrf_id = ntohl (vrf_id);
6737   mp->is_static = is_static;
6738   if (mac_set)
6739     clib_memcpy (mp->mac_address, mac_address, 6);
6740   if (v6_address_set)
6741     {
6742       mp->is_ipv6 = 1;
6743       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6744     }
6745   else
6746     {
6747       /* mp->is_ipv6 = 0; via memset in M macro above */
6748       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6749     }
6750
6751   /* send it... */
6752   S;
6753
6754   /* Wait for a reply, return good/bad news  */
6755   W;
6756
6757   /* NOTREACHED */
6758   return 0;
6759 }
6760
6761 static int
6762 api_reset_vrf (vat_main_t * vam)
6763 {
6764   unformat_input_t *i = vam->input;
6765   vl_api_reset_vrf_t *mp;
6766   f64 timeout;
6767   u32 vrf_id = 0;
6768   u8 is_ipv6 = 0;
6769   u8 vrf_id_set = 0;
6770
6771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6772     {
6773       if (unformat (i, "vrf %d", &vrf_id))
6774         vrf_id_set = 1;
6775       else if (unformat (i, "ipv6"))
6776         is_ipv6 = 1;
6777       else
6778         {
6779           clib_warning ("parse error '%U'", format_unformat_error, i);
6780           return -99;
6781         }
6782     }
6783
6784   if (vrf_id_set == 0)
6785     {
6786       errmsg ("missing vrf id\n");
6787       return -99;
6788     }
6789
6790   M (RESET_VRF, reset_vrf);
6791
6792   mp->vrf_id = ntohl (vrf_id);
6793   mp->is_ipv6 = is_ipv6;
6794
6795   S;
6796   W;
6797   /* NOTREACHED */
6798   return 0;
6799 }
6800
6801 static int
6802 api_create_vlan_subif (vat_main_t * vam)
6803 {
6804   unformat_input_t *i = vam->input;
6805   vl_api_create_vlan_subif_t *mp;
6806   f64 timeout;
6807   u32 sw_if_index;
6808   u8 sw_if_index_set = 0;
6809   u32 vlan_id;
6810   u8 vlan_id_set = 0;
6811
6812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6813     {
6814       if (unformat (i, "sw_if_index %d", &sw_if_index))
6815         sw_if_index_set = 1;
6816       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6817         sw_if_index_set = 1;
6818       else if (unformat (i, "vlan %d", &vlan_id))
6819         vlan_id_set = 1;
6820       else
6821         {
6822           clib_warning ("parse error '%U'", format_unformat_error, i);
6823           return -99;
6824         }
6825     }
6826
6827   if (sw_if_index_set == 0)
6828     {
6829       errmsg ("missing interface name or sw_if_index\n");
6830       return -99;
6831     }
6832
6833   if (vlan_id_set == 0)
6834     {
6835       errmsg ("missing vlan_id\n");
6836       return -99;
6837     }
6838   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6839
6840   mp->sw_if_index = ntohl (sw_if_index);
6841   mp->vlan_id = ntohl (vlan_id);
6842
6843   S;
6844   W;
6845   /* NOTREACHED */
6846   return 0;
6847 }
6848
6849 #define foreach_create_subif_bit                \
6850 _(no_tags)                                      \
6851 _(one_tag)                                      \
6852 _(two_tags)                                     \
6853 _(dot1ad)                                       \
6854 _(exact_match)                                  \
6855 _(default_sub)                                  \
6856 _(outer_vlan_id_any)                            \
6857 _(inner_vlan_id_any)
6858
6859 static int
6860 api_create_subif (vat_main_t * vam)
6861 {
6862   unformat_input_t *i = vam->input;
6863   vl_api_create_subif_t *mp;
6864   f64 timeout;
6865   u32 sw_if_index;
6866   u8 sw_if_index_set = 0;
6867   u32 sub_id;
6868   u8 sub_id_set = 0;
6869   u32 no_tags = 0;
6870   u32 one_tag = 0;
6871   u32 two_tags = 0;
6872   u32 dot1ad = 0;
6873   u32 exact_match = 0;
6874   u32 default_sub = 0;
6875   u32 outer_vlan_id_any = 0;
6876   u32 inner_vlan_id_any = 0;
6877   u32 tmp;
6878   u16 outer_vlan_id = 0;
6879   u16 inner_vlan_id = 0;
6880
6881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6882     {
6883       if (unformat (i, "sw_if_index %d", &sw_if_index))
6884         sw_if_index_set = 1;
6885       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6886         sw_if_index_set = 1;
6887       else if (unformat (i, "sub_id %d", &sub_id))
6888         sub_id_set = 1;
6889       else if (unformat (i, "outer_vlan_id %d", &tmp))
6890         outer_vlan_id = tmp;
6891       else if (unformat (i, "inner_vlan_id %d", &tmp))
6892         inner_vlan_id = tmp;
6893
6894 #define _(a) else if (unformat (i, #a)) a = 1 ;
6895       foreach_create_subif_bit
6896 #undef _
6897         else
6898         {
6899           clib_warning ("parse error '%U'", format_unformat_error, i);
6900           return -99;
6901         }
6902     }
6903
6904   if (sw_if_index_set == 0)
6905     {
6906       errmsg ("missing interface name or sw_if_index\n");
6907       return -99;
6908     }
6909
6910   if (sub_id_set == 0)
6911     {
6912       errmsg ("missing sub_id\n");
6913       return -99;
6914     }
6915   M (CREATE_SUBIF, create_subif);
6916
6917   mp->sw_if_index = ntohl (sw_if_index);
6918   mp->sub_id = ntohl (sub_id);
6919
6920 #define _(a) mp->a = a;
6921   foreach_create_subif_bit;
6922 #undef _
6923
6924   mp->outer_vlan_id = ntohs (outer_vlan_id);
6925   mp->inner_vlan_id = ntohs (inner_vlan_id);
6926
6927   S;
6928   W;
6929   /* NOTREACHED */
6930   return 0;
6931 }
6932
6933 static int
6934 api_oam_add_del (vat_main_t * vam)
6935 {
6936   unformat_input_t *i = vam->input;
6937   vl_api_oam_add_del_t *mp;
6938   f64 timeout;
6939   u32 vrf_id = 0;
6940   u8 is_add = 1;
6941   ip4_address_t src, dst;
6942   u8 src_set = 0;
6943   u8 dst_set = 0;
6944
6945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6946     {
6947       if (unformat (i, "vrf %d", &vrf_id))
6948         ;
6949       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6950         src_set = 1;
6951       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6952         dst_set = 1;
6953       else if (unformat (i, "del"))
6954         is_add = 0;
6955       else
6956         {
6957           clib_warning ("parse error '%U'", format_unformat_error, i);
6958           return -99;
6959         }
6960     }
6961
6962   if (src_set == 0)
6963     {
6964       errmsg ("missing src addr\n");
6965       return -99;
6966     }
6967
6968   if (dst_set == 0)
6969     {
6970       errmsg ("missing dst addr\n");
6971       return -99;
6972     }
6973
6974   M (OAM_ADD_DEL, oam_add_del);
6975
6976   mp->vrf_id = ntohl (vrf_id);
6977   mp->is_add = is_add;
6978   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6979   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6980
6981   S;
6982   W;
6983   /* NOTREACHED */
6984   return 0;
6985 }
6986
6987 static int
6988 api_reset_fib (vat_main_t * vam)
6989 {
6990   unformat_input_t *i = vam->input;
6991   vl_api_reset_fib_t *mp;
6992   f64 timeout;
6993   u32 vrf_id = 0;
6994   u8 is_ipv6 = 0;
6995   u8 vrf_id_set = 0;
6996
6997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6998     {
6999       if (unformat (i, "vrf %d", &vrf_id))
7000         vrf_id_set = 1;
7001       else if (unformat (i, "ipv6"))
7002         is_ipv6 = 1;
7003       else
7004         {
7005           clib_warning ("parse error '%U'", format_unformat_error, i);
7006           return -99;
7007         }
7008     }
7009
7010   if (vrf_id_set == 0)
7011     {
7012       errmsg ("missing vrf id\n");
7013       return -99;
7014     }
7015
7016   M (RESET_FIB, reset_fib);
7017
7018   mp->vrf_id = ntohl (vrf_id);
7019   mp->is_ipv6 = is_ipv6;
7020
7021   S;
7022   W;
7023   /* NOTREACHED */
7024   return 0;
7025 }
7026
7027 static int
7028 api_dhcp_proxy_config (vat_main_t * vam)
7029 {
7030   unformat_input_t *i = vam->input;
7031   vl_api_dhcp_proxy_config_t *mp;
7032   f64 timeout;
7033   u32 vrf_id = 0;
7034   u8 is_add = 1;
7035   u8 insert_cid = 1;
7036   u8 v4_address_set = 0;
7037   u8 v6_address_set = 0;
7038   ip4_address_t v4address;
7039   ip6_address_t v6address;
7040   u8 v4_src_address_set = 0;
7041   u8 v6_src_address_set = 0;
7042   ip4_address_t v4srcaddress;
7043   ip6_address_t v6srcaddress;
7044
7045   /* Parse args required to build the message */
7046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7047     {
7048       if (unformat (i, "del"))
7049         is_add = 0;
7050       else if (unformat (i, "vrf %d", &vrf_id))
7051         ;
7052       else if (unformat (i, "insert-cid %d", &insert_cid))
7053         ;
7054       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7055         v4_address_set = 1;
7056       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7057         v6_address_set = 1;
7058       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7059         v4_src_address_set = 1;
7060       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7061         v6_src_address_set = 1;
7062       else
7063         break;
7064     }
7065
7066   if (v4_address_set && v6_address_set)
7067     {
7068       errmsg ("both v4 and v6 server addresses set\n");
7069       return -99;
7070     }
7071   if (!v4_address_set && !v6_address_set)
7072     {
7073       errmsg ("no server addresses set\n");
7074       return -99;
7075     }
7076
7077   if (v4_src_address_set && v6_src_address_set)
7078     {
7079       errmsg ("both v4 and v6  src addresses set\n");
7080       return -99;
7081     }
7082   if (!v4_src_address_set && !v6_src_address_set)
7083     {
7084       errmsg ("no src addresses set\n");
7085       return -99;
7086     }
7087
7088   if (!(v4_src_address_set && v4_address_set) &&
7089       !(v6_src_address_set && v6_address_set))
7090     {
7091       errmsg ("no matching server and src addresses set\n");
7092       return -99;
7093     }
7094
7095   /* Construct the API message */
7096   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7097
7098   mp->insert_circuit_id = insert_cid;
7099   mp->is_add = is_add;
7100   mp->vrf_id = ntohl (vrf_id);
7101   if (v6_address_set)
7102     {
7103       mp->is_ipv6 = 1;
7104       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7105       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7106     }
7107   else
7108     {
7109       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7110       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7111     }
7112
7113   /* send it... */
7114   S;
7115
7116   /* Wait for a reply, return good/bad news  */
7117   W;
7118   /* NOTREACHED */
7119   return 0;
7120 }
7121
7122 static int
7123 api_dhcp_proxy_config_2 (vat_main_t * vam)
7124 {
7125   unformat_input_t *i = vam->input;
7126   vl_api_dhcp_proxy_config_2_t *mp;
7127   f64 timeout;
7128   u32 rx_vrf_id = 0;
7129   u32 server_vrf_id = 0;
7130   u8 is_add = 1;
7131   u8 insert_cid = 1;
7132   u8 v4_address_set = 0;
7133   u8 v6_address_set = 0;
7134   ip4_address_t v4address;
7135   ip6_address_t v6address;
7136   u8 v4_src_address_set = 0;
7137   u8 v6_src_address_set = 0;
7138   ip4_address_t v4srcaddress;
7139   ip6_address_t v6srcaddress;
7140
7141   /* Parse args required to build the message */
7142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7143     {
7144       if (unformat (i, "del"))
7145         is_add = 0;
7146       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7147         ;
7148       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7149         ;
7150       else if (unformat (i, "insert-cid %d", &insert_cid))
7151         ;
7152       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7153         v4_address_set = 1;
7154       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7155         v6_address_set = 1;
7156       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7157         v4_src_address_set = 1;
7158       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7159         v6_src_address_set = 1;
7160       else
7161         break;
7162     }
7163
7164   if (v4_address_set && v6_address_set)
7165     {
7166       errmsg ("both v4 and v6 server addresses set\n");
7167       return -99;
7168     }
7169   if (!v4_address_set && !v6_address_set)
7170     {
7171       errmsg ("no server addresses set\n");
7172       return -99;
7173     }
7174
7175   if (v4_src_address_set && v6_src_address_set)
7176     {
7177       errmsg ("both v4 and v6  src addresses set\n");
7178       return -99;
7179     }
7180   if (!v4_src_address_set && !v6_src_address_set)
7181     {
7182       errmsg ("no src addresses set\n");
7183       return -99;
7184     }
7185
7186   if (!(v4_src_address_set && v4_address_set) &&
7187       !(v6_src_address_set && v6_address_set))
7188     {
7189       errmsg ("no matching server and src addresses set\n");
7190       return -99;
7191     }
7192
7193   /* Construct the API message */
7194   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7195
7196   mp->insert_circuit_id = insert_cid;
7197   mp->is_add = is_add;
7198   mp->rx_vrf_id = ntohl (rx_vrf_id);
7199   mp->server_vrf_id = ntohl (server_vrf_id);
7200   if (v6_address_set)
7201     {
7202       mp->is_ipv6 = 1;
7203       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7204       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7205     }
7206   else
7207     {
7208       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7209       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7210     }
7211
7212   /* send it... */
7213   S;
7214
7215   /* Wait for a reply, return good/bad news  */
7216   W;
7217   /* NOTREACHED */
7218   return 0;
7219 }
7220
7221 static int
7222 api_dhcp_proxy_set_vss (vat_main_t * vam)
7223 {
7224   unformat_input_t *i = vam->input;
7225   vl_api_dhcp_proxy_set_vss_t *mp;
7226   f64 timeout;
7227   u8 is_ipv6 = 0;
7228   u8 is_add = 1;
7229   u32 tbl_id;
7230   u8 tbl_id_set = 0;
7231   u32 oui;
7232   u8 oui_set = 0;
7233   u32 fib_id;
7234   u8 fib_id_set = 0;
7235
7236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7237     {
7238       if (unformat (i, "tbl_id %d", &tbl_id))
7239         tbl_id_set = 1;
7240       if (unformat (i, "fib_id %d", &fib_id))
7241         fib_id_set = 1;
7242       if (unformat (i, "oui %d", &oui))
7243         oui_set = 1;
7244       else if (unformat (i, "ipv6"))
7245         is_ipv6 = 1;
7246       else if (unformat (i, "del"))
7247         is_add = 0;
7248       else
7249         {
7250           clib_warning ("parse error '%U'", format_unformat_error, i);
7251           return -99;
7252         }
7253     }
7254
7255   if (tbl_id_set == 0)
7256     {
7257       errmsg ("missing tbl id\n");
7258       return -99;
7259     }
7260
7261   if (fib_id_set == 0)
7262     {
7263       errmsg ("missing fib id\n");
7264       return -99;
7265     }
7266   if (oui_set == 0)
7267     {
7268       errmsg ("missing oui\n");
7269       return -99;
7270     }
7271
7272   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7273   mp->tbl_id = ntohl (tbl_id);
7274   mp->fib_id = ntohl (fib_id);
7275   mp->oui = ntohl (oui);
7276   mp->is_ipv6 = is_ipv6;
7277   mp->is_add = is_add;
7278
7279   S;
7280   W;
7281   /* NOTREACHED */
7282   return 0;
7283 }
7284
7285 static int
7286 api_dhcp_client_config (vat_main_t * vam)
7287 {
7288   unformat_input_t *i = vam->input;
7289   vl_api_dhcp_client_config_t *mp;
7290   f64 timeout;
7291   u32 sw_if_index;
7292   u8 sw_if_index_set = 0;
7293   u8 is_add = 1;
7294   u8 *hostname = 0;
7295   u8 disable_event = 0;
7296
7297   /* Parse args required to build the message */
7298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7299     {
7300       if (unformat (i, "del"))
7301         is_add = 0;
7302       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7303         sw_if_index_set = 1;
7304       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7305         sw_if_index_set = 1;
7306       else if (unformat (i, "hostname %s", &hostname))
7307         ;
7308       else if (unformat (i, "disable_event"))
7309         disable_event = 1;
7310       else
7311         break;
7312     }
7313
7314   if (sw_if_index_set == 0)
7315     {
7316       errmsg ("missing interface name or sw_if_index\n");
7317       return -99;
7318     }
7319
7320   if (vec_len (hostname) > 63)
7321     {
7322       errmsg ("hostname too long\n");
7323     }
7324   vec_add1 (hostname, 0);
7325
7326   /* Construct the API message */
7327   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7328
7329   mp->sw_if_index = ntohl (sw_if_index);
7330   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7331   vec_free (hostname);
7332   mp->is_add = is_add;
7333   mp->want_dhcp_event = disable_event ? 0 : 1;
7334   mp->pid = getpid ();
7335
7336   /* send it... */
7337   S;
7338
7339   /* Wait for a reply, return good/bad news  */
7340   W;
7341   /* NOTREACHED */
7342   return 0;
7343 }
7344
7345 static int
7346 api_set_ip_flow_hash (vat_main_t * vam)
7347 {
7348   unformat_input_t *i = vam->input;
7349   vl_api_set_ip_flow_hash_t *mp;
7350   f64 timeout;
7351   u32 vrf_id = 0;
7352   u8 is_ipv6 = 0;
7353   u8 vrf_id_set = 0;
7354   u8 src = 0;
7355   u8 dst = 0;
7356   u8 sport = 0;
7357   u8 dport = 0;
7358   u8 proto = 0;
7359   u8 reverse = 0;
7360
7361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7362     {
7363       if (unformat (i, "vrf %d", &vrf_id))
7364         vrf_id_set = 1;
7365       else if (unformat (i, "ipv6"))
7366         is_ipv6 = 1;
7367       else if (unformat (i, "src"))
7368         src = 1;
7369       else if (unformat (i, "dst"))
7370         dst = 1;
7371       else if (unformat (i, "sport"))
7372         sport = 1;
7373       else if (unformat (i, "dport"))
7374         dport = 1;
7375       else if (unformat (i, "proto"))
7376         proto = 1;
7377       else if (unformat (i, "reverse"))
7378         reverse = 1;
7379
7380       else
7381         {
7382           clib_warning ("parse error '%U'", format_unformat_error, i);
7383           return -99;
7384         }
7385     }
7386
7387   if (vrf_id_set == 0)
7388     {
7389       errmsg ("missing vrf id\n");
7390       return -99;
7391     }
7392
7393   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7394   mp->src = src;
7395   mp->dst = dst;
7396   mp->sport = sport;
7397   mp->dport = dport;
7398   mp->proto = proto;
7399   mp->reverse = reverse;
7400   mp->vrf_id = ntohl (vrf_id);
7401   mp->is_ipv6 = is_ipv6;
7402
7403   S;
7404   W;
7405   /* NOTREACHED */
7406   return 0;
7407 }
7408
7409 static int
7410 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7411 {
7412   unformat_input_t *i = vam->input;
7413   vl_api_sw_interface_ip6_enable_disable_t *mp;
7414   f64 timeout;
7415   u32 sw_if_index;
7416   u8 sw_if_index_set = 0;
7417   u8 enable = 0;
7418
7419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7420     {
7421       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7422         sw_if_index_set = 1;
7423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7424         sw_if_index_set = 1;
7425       else if (unformat (i, "enable"))
7426         enable = 1;
7427       else if (unformat (i, "disable"))
7428         enable = 0;
7429       else
7430         {
7431           clib_warning ("parse error '%U'", format_unformat_error, i);
7432           return -99;
7433         }
7434     }
7435
7436   if (sw_if_index_set == 0)
7437     {
7438       errmsg ("missing interface name or sw_if_index\n");
7439       return -99;
7440     }
7441
7442   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7443
7444   mp->sw_if_index = ntohl (sw_if_index);
7445   mp->enable = enable;
7446
7447   S;
7448   W;
7449   /* NOTREACHED */
7450   return 0;
7451 }
7452
7453 static int
7454 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7455 {
7456   unformat_input_t *i = vam->input;
7457   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7458   f64 timeout;
7459   u32 sw_if_index;
7460   u8 sw_if_index_set = 0;
7461   u32 address_length = 0;
7462   u8 v6_address_set = 0;
7463   ip6_address_t v6address;
7464
7465   /* Parse args required to build the message */
7466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7467     {
7468       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7469         sw_if_index_set = 1;
7470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7471         sw_if_index_set = 1;
7472       else if (unformat (i, "%U/%d",
7473                          unformat_ip6_address, &v6address, &address_length))
7474         v6_address_set = 1;
7475       else
7476         break;
7477     }
7478
7479   if (sw_if_index_set == 0)
7480     {
7481       errmsg ("missing interface name or sw_if_index\n");
7482       return -99;
7483     }
7484   if (!v6_address_set)
7485     {
7486       errmsg ("no address set\n");
7487       return -99;
7488     }
7489
7490   /* Construct the API message */
7491   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7492      sw_interface_ip6_set_link_local_address);
7493
7494   mp->sw_if_index = ntohl (sw_if_index);
7495   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7496   mp->address_length = address_length;
7497
7498   /* send it... */
7499   S;
7500
7501   /* Wait for a reply, return good/bad news  */
7502   W;
7503
7504   /* NOTREACHED */
7505   return 0;
7506 }
7507
7508
7509 static int
7510 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7511 {
7512   unformat_input_t *i = vam->input;
7513   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7514   f64 timeout;
7515   u32 sw_if_index;
7516   u8 sw_if_index_set = 0;
7517   u32 address_length = 0;
7518   u8 v6_address_set = 0;
7519   ip6_address_t v6address;
7520   u8 use_default = 0;
7521   u8 no_advertise = 0;
7522   u8 off_link = 0;
7523   u8 no_autoconfig = 0;
7524   u8 no_onlink = 0;
7525   u8 is_no = 0;
7526   u32 val_lifetime = 0;
7527   u32 pref_lifetime = 0;
7528
7529   /* Parse args required to build the message */
7530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7531     {
7532       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7533         sw_if_index_set = 1;
7534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7535         sw_if_index_set = 1;
7536       else if (unformat (i, "%U/%d",
7537                          unformat_ip6_address, &v6address, &address_length))
7538         v6_address_set = 1;
7539       else if (unformat (i, "val_life %d", &val_lifetime))
7540         ;
7541       else if (unformat (i, "pref_life %d", &pref_lifetime))
7542         ;
7543       else if (unformat (i, "def"))
7544         use_default = 1;
7545       else if (unformat (i, "noadv"))
7546         no_advertise = 1;
7547       else if (unformat (i, "offl"))
7548         off_link = 1;
7549       else if (unformat (i, "noauto"))
7550         no_autoconfig = 1;
7551       else if (unformat (i, "nolink"))
7552         no_onlink = 1;
7553       else if (unformat (i, "isno"))
7554         is_no = 1;
7555       else
7556         {
7557           clib_warning ("parse error '%U'", format_unformat_error, i);
7558           return -99;
7559         }
7560     }
7561
7562   if (sw_if_index_set == 0)
7563     {
7564       errmsg ("missing interface name or sw_if_index\n");
7565       return -99;
7566     }
7567   if (!v6_address_set)
7568     {
7569       errmsg ("no address set\n");
7570       return -99;
7571     }
7572
7573   /* Construct the API message */
7574   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7575
7576   mp->sw_if_index = ntohl (sw_if_index);
7577   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7578   mp->address_length = address_length;
7579   mp->use_default = use_default;
7580   mp->no_advertise = no_advertise;
7581   mp->off_link = off_link;
7582   mp->no_autoconfig = no_autoconfig;
7583   mp->no_onlink = no_onlink;
7584   mp->is_no = is_no;
7585   mp->val_lifetime = ntohl (val_lifetime);
7586   mp->pref_lifetime = ntohl (pref_lifetime);
7587
7588   /* send it... */
7589   S;
7590
7591   /* Wait for a reply, return good/bad news  */
7592   W;
7593
7594   /* NOTREACHED */
7595   return 0;
7596 }
7597
7598 static int
7599 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7600 {
7601   unformat_input_t *i = vam->input;
7602   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7603   f64 timeout;
7604   u32 sw_if_index;
7605   u8 sw_if_index_set = 0;
7606   u8 suppress = 0;
7607   u8 managed = 0;
7608   u8 other = 0;
7609   u8 ll_option = 0;
7610   u8 send_unicast = 0;
7611   u8 cease = 0;
7612   u8 is_no = 0;
7613   u8 default_router = 0;
7614   u32 max_interval = 0;
7615   u32 min_interval = 0;
7616   u32 lifetime = 0;
7617   u32 initial_count = 0;
7618   u32 initial_interval = 0;
7619
7620
7621   /* Parse args required to build the message */
7622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7623     {
7624       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7625         sw_if_index_set = 1;
7626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7627         sw_if_index_set = 1;
7628       else if (unformat (i, "maxint %d", &max_interval))
7629         ;
7630       else if (unformat (i, "minint %d", &min_interval))
7631         ;
7632       else if (unformat (i, "life %d", &lifetime))
7633         ;
7634       else if (unformat (i, "count %d", &initial_count))
7635         ;
7636       else if (unformat (i, "interval %d", &initial_interval))
7637         ;
7638       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7639         suppress = 1;
7640       else if (unformat (i, "managed"))
7641         managed = 1;
7642       else if (unformat (i, "other"))
7643         other = 1;
7644       else if (unformat (i, "ll"))
7645         ll_option = 1;
7646       else if (unformat (i, "send"))
7647         send_unicast = 1;
7648       else if (unformat (i, "cease"))
7649         cease = 1;
7650       else if (unformat (i, "isno"))
7651         is_no = 1;
7652       else if (unformat (i, "def"))
7653         default_router = 1;
7654       else
7655         {
7656           clib_warning ("parse error '%U'", format_unformat_error, i);
7657           return -99;
7658         }
7659     }
7660
7661   if (sw_if_index_set == 0)
7662     {
7663       errmsg ("missing interface name or sw_if_index\n");
7664       return -99;
7665     }
7666
7667   /* Construct the API message */
7668   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7669
7670   mp->sw_if_index = ntohl (sw_if_index);
7671   mp->max_interval = ntohl (max_interval);
7672   mp->min_interval = ntohl (min_interval);
7673   mp->lifetime = ntohl (lifetime);
7674   mp->initial_count = ntohl (initial_count);
7675   mp->initial_interval = ntohl (initial_interval);
7676   mp->suppress = suppress;
7677   mp->managed = managed;
7678   mp->other = other;
7679   mp->ll_option = ll_option;
7680   mp->send_unicast = send_unicast;
7681   mp->cease = cease;
7682   mp->is_no = is_no;
7683   mp->default_router = default_router;
7684
7685   /* send it... */
7686   S;
7687
7688   /* Wait for a reply, return good/bad news  */
7689   W;
7690
7691   /* NOTREACHED */
7692   return 0;
7693 }
7694
7695 static int
7696 api_set_arp_neighbor_limit (vat_main_t * vam)
7697 {
7698   unformat_input_t *i = vam->input;
7699   vl_api_set_arp_neighbor_limit_t *mp;
7700   f64 timeout;
7701   u32 arp_nbr_limit;
7702   u8 limit_set = 0;
7703   u8 is_ipv6 = 0;
7704
7705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7706     {
7707       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7708         limit_set = 1;
7709       else if (unformat (i, "ipv6"))
7710         is_ipv6 = 1;
7711       else
7712         {
7713           clib_warning ("parse error '%U'", format_unformat_error, i);
7714           return -99;
7715         }
7716     }
7717
7718   if (limit_set == 0)
7719     {
7720       errmsg ("missing limit value\n");
7721       return -99;
7722     }
7723
7724   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7725
7726   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7727   mp->is_ipv6 = is_ipv6;
7728
7729   S;
7730   W;
7731   /* NOTREACHED */
7732   return 0;
7733 }
7734
7735 static int
7736 api_l2_patch_add_del (vat_main_t * vam)
7737 {
7738   unformat_input_t *i = vam->input;
7739   vl_api_l2_patch_add_del_t *mp;
7740   f64 timeout;
7741   u32 rx_sw_if_index;
7742   u8 rx_sw_if_index_set = 0;
7743   u32 tx_sw_if_index;
7744   u8 tx_sw_if_index_set = 0;
7745   u8 is_add = 1;
7746
7747   /* Parse args required to build the message */
7748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7749     {
7750       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7751         rx_sw_if_index_set = 1;
7752       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7753         tx_sw_if_index_set = 1;
7754       else if (unformat (i, "rx"))
7755         {
7756           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7757             {
7758               if (unformat (i, "%U", unformat_sw_if_index, vam,
7759                             &rx_sw_if_index))
7760                 rx_sw_if_index_set = 1;
7761             }
7762           else
7763             break;
7764         }
7765       else if (unformat (i, "tx"))
7766         {
7767           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7768             {
7769               if (unformat (i, "%U", unformat_sw_if_index, vam,
7770                             &tx_sw_if_index))
7771                 tx_sw_if_index_set = 1;
7772             }
7773           else
7774             break;
7775         }
7776       else if (unformat (i, "del"))
7777         is_add = 0;
7778       else
7779         break;
7780     }
7781
7782   if (rx_sw_if_index_set == 0)
7783     {
7784       errmsg ("missing rx interface name or rx_sw_if_index\n");
7785       return -99;
7786     }
7787
7788   if (tx_sw_if_index_set == 0)
7789     {
7790       errmsg ("missing tx interface name or tx_sw_if_index\n");
7791       return -99;
7792     }
7793
7794   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7795
7796   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7797   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7798   mp->is_add = is_add;
7799
7800   S;
7801   W;
7802   /* NOTREACHED */
7803   return 0;
7804 }
7805
7806 static int
7807 api_ioam_enable (vat_main_t * vam)
7808 {
7809   unformat_input_t *input = vam->input;
7810   vl_api_ioam_enable_t *mp;
7811   f64 timeout;
7812   u32 id = 0;
7813   int has_trace_option = 0;
7814   int has_pot_option = 0;
7815   int has_seqno_option = 0;
7816   int has_analyse_option = 0;
7817
7818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7819     {
7820       if (unformat (input, "trace"))
7821         has_trace_option = 1;
7822       else if (unformat (input, "pot"))
7823         has_pot_option = 1;
7824       else if (unformat (input, "seqno"))
7825         has_seqno_option = 1;
7826       else if (unformat (input, "analyse"))
7827         has_analyse_option = 1;
7828       else
7829         break;
7830     }
7831   M (IOAM_ENABLE, ioam_enable);
7832   mp->id = htons (id);
7833   mp->seqno = has_seqno_option;
7834   mp->analyse = has_analyse_option;
7835   mp->pot_enable = has_pot_option;
7836   mp->trace_enable = has_trace_option;
7837
7838   S;
7839   W;
7840
7841   return (0);
7842
7843 }
7844
7845
7846 static int
7847 api_ioam_disable (vat_main_t * vam)
7848 {
7849   vl_api_ioam_disable_t *mp;
7850   f64 timeout;
7851
7852   M (IOAM_DISABLE, ioam_disable);
7853   S;
7854   W;
7855   return 0;
7856 }
7857
7858 static int
7859 api_sr_tunnel_add_del (vat_main_t * vam)
7860 {
7861   unformat_input_t *i = vam->input;
7862   vl_api_sr_tunnel_add_del_t *mp;
7863   f64 timeout;
7864   int is_del = 0;
7865   int pl_index;
7866   ip6_address_t src_address;
7867   int src_address_set = 0;
7868   ip6_address_t dst_address;
7869   u32 dst_mask_width;
7870   int dst_address_set = 0;
7871   u16 flags = 0;
7872   u32 rx_table_id = 0;
7873   u32 tx_table_id = 0;
7874   ip6_address_t *segments = 0;
7875   ip6_address_t *this_seg;
7876   ip6_address_t *tags = 0;
7877   ip6_address_t *this_tag;
7878   ip6_address_t next_address, tag;
7879   u8 *name = 0;
7880   u8 *policy_name = 0;
7881
7882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7883     {
7884       if (unformat (i, "del"))
7885         is_del = 1;
7886       else if (unformat (i, "name %s", &name))
7887         ;
7888       else if (unformat (i, "policy %s", &policy_name))
7889         ;
7890       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7891         ;
7892       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7893         ;
7894       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7895         src_address_set = 1;
7896       else if (unformat (i, "dst %U/%d",
7897                          unformat_ip6_address, &dst_address, &dst_mask_width))
7898         dst_address_set = 1;
7899       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7900         {
7901           vec_add2 (segments, this_seg, 1);
7902           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7903                        sizeof (*this_seg));
7904         }
7905       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7906         {
7907           vec_add2 (tags, this_tag, 1);
7908           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7909         }
7910       else if (unformat (i, "clean"))
7911         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7912       else if (unformat (i, "protected"))
7913         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7914       else if (unformat (i, "InPE %d", &pl_index))
7915         {
7916           if (pl_index <= 0 || pl_index > 4)
7917             {
7918             pl_index_range_error:
7919               errmsg ("pl index %d out of range\n", pl_index);
7920               return -99;
7921             }
7922           flags |=
7923             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7924         }
7925       else if (unformat (i, "EgPE %d", &pl_index))
7926         {
7927           if (pl_index <= 0 || pl_index > 4)
7928             goto pl_index_range_error;
7929           flags |=
7930             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7931         }
7932       else if (unformat (i, "OrgSrc %d", &pl_index))
7933         {
7934           if (pl_index <= 0 || pl_index > 4)
7935             goto pl_index_range_error;
7936           flags |=
7937             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7938         }
7939       else
7940         break;
7941     }
7942
7943   if (!src_address_set)
7944     {
7945       errmsg ("src address required\n");
7946       return -99;
7947     }
7948
7949   if (!dst_address_set)
7950     {
7951       errmsg ("dst address required\n");
7952       return -99;
7953     }
7954
7955   if (!segments)
7956     {
7957       errmsg ("at least one sr segment required\n");
7958       return -99;
7959     }
7960
7961   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7962       vec_len (segments) * sizeof (ip6_address_t)
7963       + vec_len (tags) * sizeof (ip6_address_t));
7964
7965   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7966   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7967   mp->dst_mask_width = dst_mask_width;
7968   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7969   mp->n_segments = vec_len (segments);
7970   mp->n_tags = vec_len (tags);
7971   mp->is_add = is_del == 0;
7972   clib_memcpy (mp->segs_and_tags, segments,
7973                vec_len (segments) * sizeof (ip6_address_t));
7974   clib_memcpy (mp->segs_and_tags +
7975                vec_len (segments) * sizeof (ip6_address_t), tags,
7976                vec_len (tags) * sizeof (ip6_address_t));
7977
7978   mp->outer_vrf_id = ntohl (rx_table_id);
7979   mp->inner_vrf_id = ntohl (tx_table_id);
7980   memcpy (mp->name, name, vec_len (name));
7981   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7982
7983   vec_free (segments);
7984   vec_free (tags);
7985
7986   S;
7987   W;
7988   /* NOTREACHED */
7989 }
7990
7991 static int
7992 api_sr_policy_add_del (vat_main_t * vam)
7993 {
7994   unformat_input_t *input = vam->input;
7995   vl_api_sr_policy_add_del_t *mp;
7996   f64 timeout;
7997   int is_del = 0;
7998   u8 *name = 0;
7999   u8 *tunnel_name = 0;
8000   u8 **tunnel_names = 0;
8001
8002   int name_set = 0;
8003   int tunnel_set = 0;
8004   int j = 0;
8005   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8006   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8007
8008   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8009     {
8010       if (unformat (input, "del"))
8011         is_del = 1;
8012       else if (unformat (input, "name %s", &name))
8013         name_set = 1;
8014       else if (unformat (input, "tunnel %s", &tunnel_name))
8015         {
8016           if (tunnel_name)
8017             {
8018               vec_add1 (tunnel_names, tunnel_name);
8019               /* For serializer:
8020                  - length = #bytes to store in serial vector
8021                  - +1 = byte to store that length
8022                */
8023               tunnel_names_length += (vec_len (tunnel_name) + 1);
8024               tunnel_set = 1;
8025               tunnel_name = 0;
8026             }
8027         }
8028       else
8029         break;
8030     }
8031
8032   if (!name_set)
8033     {
8034       errmsg ("policy name required\n");
8035       return -99;
8036     }
8037
8038   if ((!tunnel_set) && (!is_del))
8039     {
8040       errmsg ("tunnel name required\n");
8041       return -99;
8042     }
8043
8044   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8045
8046
8047
8048   mp->is_add = !is_del;
8049
8050   memcpy (mp->name, name, vec_len (name));
8051   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8052   u8 *serial_orig = 0;
8053   vec_validate (serial_orig, tunnel_names_length);
8054   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8055   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8056
8057   for (j = 0; j < vec_len (tunnel_names); j++)
8058     {
8059       tun_name_len = vec_len (tunnel_names[j]);
8060       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8061       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8062       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8063       serial_orig += tun_name_len;      // Advance past the copy
8064     }
8065   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8066
8067   vec_free (tunnel_names);
8068   vec_free (tunnel_name);
8069
8070   S;
8071   W;
8072   /* NOTREACHED */
8073 }
8074
8075 static int
8076 api_sr_multicast_map_add_del (vat_main_t * vam)
8077 {
8078   unformat_input_t *input = vam->input;
8079   vl_api_sr_multicast_map_add_del_t *mp;
8080   f64 timeout;
8081   int is_del = 0;
8082   ip6_address_t multicast_address;
8083   u8 *policy_name = 0;
8084   int multicast_address_set = 0;
8085
8086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8087     {
8088       if (unformat (input, "del"))
8089         is_del = 1;
8090       else
8091         if (unformat
8092             (input, "address %U", unformat_ip6_address, &multicast_address))
8093         multicast_address_set = 1;
8094       else if (unformat (input, "sr-policy %s", &policy_name))
8095         ;
8096       else
8097         break;
8098     }
8099
8100   if (!is_del && !policy_name)
8101     {
8102       errmsg ("sr-policy name required\n");
8103       return -99;
8104     }
8105
8106
8107   if (!multicast_address_set)
8108     {
8109       errmsg ("address required\n");
8110       return -99;
8111     }
8112
8113   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8114
8115   mp->is_add = !is_del;
8116   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8117   clib_memcpy (mp->multicast_address, &multicast_address,
8118                sizeof (mp->multicast_address));
8119
8120
8121   vec_free (policy_name);
8122
8123   S;
8124   W;
8125   /* NOTREACHED */
8126 }
8127
8128
8129 #define foreach_tcp_proto_field                 \
8130 _(src_port)                                     \
8131 _(dst_port)
8132
8133 #define foreach_udp_proto_field                 \
8134 _(src_port)                                     \
8135 _(dst_port)
8136
8137 #define foreach_ip4_proto_field                 \
8138 _(src_address)                                  \
8139 _(dst_address)                                  \
8140 _(tos)                                          \
8141 _(length)                                       \
8142 _(fragment_id)                                  \
8143 _(ttl)                                          \
8144 _(protocol)                                     \
8145 _(checksum)
8146
8147 uword
8148 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8149 {
8150   u8 **maskp = va_arg (*args, u8 **);
8151   u8 *mask = 0;
8152   u8 found_something = 0;
8153   tcp_header_t *tcp;
8154
8155 #define _(a) u8 a=0;
8156   foreach_tcp_proto_field;
8157 #undef _
8158
8159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8160     {
8161       if (0);
8162 #define _(a) else if (unformat (input, #a)) a=1;
8163       foreach_tcp_proto_field
8164 #undef _
8165         else
8166         break;
8167     }
8168
8169 #define _(a) found_something += a;
8170   foreach_tcp_proto_field;
8171 #undef _
8172
8173   if (found_something == 0)
8174     return 0;
8175
8176   vec_validate (mask, sizeof (*tcp) - 1);
8177
8178   tcp = (tcp_header_t *) mask;
8179
8180 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8181   foreach_tcp_proto_field;
8182 #undef _
8183
8184   *maskp = mask;
8185   return 1;
8186 }
8187
8188 uword
8189 unformat_udp_mask (unformat_input_t * input, va_list * args)
8190 {
8191   u8 **maskp = va_arg (*args, u8 **);
8192   u8 *mask = 0;
8193   u8 found_something = 0;
8194   udp_header_t *udp;
8195
8196 #define _(a) u8 a=0;
8197   foreach_udp_proto_field;
8198 #undef _
8199
8200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8201     {
8202       if (0);
8203 #define _(a) else if (unformat (input, #a)) a=1;
8204       foreach_udp_proto_field
8205 #undef _
8206         else
8207         break;
8208     }
8209
8210 #define _(a) found_something += a;
8211   foreach_udp_proto_field;
8212 #undef _
8213
8214   if (found_something == 0)
8215     return 0;
8216
8217   vec_validate (mask, sizeof (*udp) - 1);
8218
8219   udp = (udp_header_t *) mask;
8220
8221 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8222   foreach_udp_proto_field;
8223 #undef _
8224
8225   *maskp = mask;
8226   return 1;
8227 }
8228
8229 typedef struct
8230 {
8231   u16 src_port, dst_port;
8232 } tcpudp_header_t;
8233
8234 uword
8235 unformat_l4_mask (unformat_input_t * input, va_list * args)
8236 {
8237   u8 **maskp = va_arg (*args, u8 **);
8238   u16 src_port = 0, dst_port = 0;
8239   tcpudp_header_t *tcpudp;
8240
8241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8242     {
8243       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8244         return 1;
8245       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8246         return 1;
8247       else if (unformat (input, "src_port"))
8248         src_port = 0xFFFF;
8249       else if (unformat (input, "dst_port"))
8250         dst_port = 0xFFFF;
8251       else
8252         return 0;
8253     }
8254
8255   if (!src_port && !dst_port)
8256     return 0;
8257
8258   u8 *mask = 0;
8259   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8260
8261   tcpudp = (tcpudp_header_t *) mask;
8262   tcpudp->src_port = src_port;
8263   tcpudp->dst_port = dst_port;
8264
8265   *maskp = mask;
8266
8267   return 1;
8268 }
8269
8270 uword
8271 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8272 {
8273   u8 **maskp = va_arg (*args, u8 **);
8274   u8 *mask = 0;
8275   u8 found_something = 0;
8276   ip4_header_t *ip;
8277
8278 #define _(a) u8 a=0;
8279   foreach_ip4_proto_field;
8280 #undef _
8281   u8 version = 0;
8282   u8 hdr_length = 0;
8283
8284
8285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8286     {
8287       if (unformat (input, "version"))
8288         version = 1;
8289       else if (unformat (input, "hdr_length"))
8290         hdr_length = 1;
8291       else if (unformat (input, "src"))
8292         src_address = 1;
8293       else if (unformat (input, "dst"))
8294         dst_address = 1;
8295       else if (unformat (input, "proto"))
8296         protocol = 1;
8297
8298 #define _(a) else if (unformat (input, #a)) a=1;
8299       foreach_ip4_proto_field
8300 #undef _
8301         else
8302         break;
8303     }
8304
8305 #define _(a) found_something += a;
8306   foreach_ip4_proto_field;
8307 #undef _
8308
8309   if (found_something == 0)
8310     return 0;
8311
8312   vec_validate (mask, sizeof (*ip) - 1);
8313
8314   ip = (ip4_header_t *) mask;
8315
8316 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8317   foreach_ip4_proto_field;
8318 #undef _
8319
8320   ip->ip_version_and_header_length = 0;
8321
8322   if (version)
8323     ip->ip_version_and_header_length |= 0xF0;
8324
8325   if (hdr_length)
8326     ip->ip_version_and_header_length |= 0x0F;
8327
8328   *maskp = mask;
8329   return 1;
8330 }
8331
8332 #define foreach_ip6_proto_field                 \
8333 _(src_address)                                  \
8334 _(dst_address)                                  \
8335 _(payload_length)                               \
8336 _(hop_limit)                                    \
8337 _(protocol)
8338
8339 uword
8340 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8341 {
8342   u8 **maskp = va_arg (*args, u8 **);
8343   u8 *mask = 0;
8344   u8 found_something = 0;
8345   ip6_header_t *ip;
8346   u32 ip_version_traffic_class_and_flow_label;
8347
8348 #define _(a) u8 a=0;
8349   foreach_ip6_proto_field;
8350 #undef _
8351   u8 version = 0;
8352   u8 traffic_class = 0;
8353   u8 flow_label = 0;
8354
8355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8356     {
8357       if (unformat (input, "version"))
8358         version = 1;
8359       else if (unformat (input, "traffic-class"))
8360         traffic_class = 1;
8361       else if (unformat (input, "flow-label"))
8362         flow_label = 1;
8363       else if (unformat (input, "src"))
8364         src_address = 1;
8365       else if (unformat (input, "dst"))
8366         dst_address = 1;
8367       else if (unformat (input, "proto"))
8368         protocol = 1;
8369
8370 #define _(a) else if (unformat (input, #a)) a=1;
8371       foreach_ip6_proto_field
8372 #undef _
8373         else
8374         break;
8375     }
8376
8377 #define _(a) found_something += a;
8378   foreach_ip6_proto_field;
8379 #undef _
8380
8381   if (found_something == 0)
8382     return 0;
8383
8384   vec_validate (mask, sizeof (*ip) - 1);
8385
8386   ip = (ip6_header_t *) mask;
8387
8388 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8389   foreach_ip6_proto_field;
8390 #undef _
8391
8392   ip_version_traffic_class_and_flow_label = 0;
8393
8394   if (version)
8395     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8396
8397   if (traffic_class)
8398     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8399
8400   if (flow_label)
8401     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8402
8403   ip->ip_version_traffic_class_and_flow_label =
8404     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8405
8406   *maskp = mask;
8407   return 1;
8408 }
8409
8410 uword
8411 unformat_l3_mask (unformat_input_t * input, va_list * args)
8412 {
8413   u8 **maskp = va_arg (*args, u8 **);
8414
8415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8416     {
8417       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8418         return 1;
8419       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8420         return 1;
8421       else
8422         break;
8423     }
8424   return 0;
8425 }
8426
8427 uword
8428 unformat_l2_mask (unformat_input_t * input, va_list * args)
8429 {
8430   u8 **maskp = va_arg (*args, u8 **);
8431   u8 *mask = 0;
8432   u8 src = 0;
8433   u8 dst = 0;
8434   u8 proto = 0;
8435   u8 tag1 = 0;
8436   u8 tag2 = 0;
8437   u8 ignore_tag1 = 0;
8438   u8 ignore_tag2 = 0;
8439   u8 cos1 = 0;
8440   u8 cos2 = 0;
8441   u8 dot1q = 0;
8442   u8 dot1ad = 0;
8443   int len = 14;
8444
8445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8446     {
8447       if (unformat (input, "src"))
8448         src = 1;
8449       else if (unformat (input, "dst"))
8450         dst = 1;
8451       else if (unformat (input, "proto"))
8452         proto = 1;
8453       else if (unformat (input, "tag1"))
8454         tag1 = 1;
8455       else if (unformat (input, "tag2"))
8456         tag2 = 1;
8457       else if (unformat (input, "ignore-tag1"))
8458         ignore_tag1 = 1;
8459       else if (unformat (input, "ignore-tag2"))
8460         ignore_tag2 = 1;
8461       else if (unformat (input, "cos1"))
8462         cos1 = 1;
8463       else if (unformat (input, "cos2"))
8464         cos2 = 1;
8465       else if (unformat (input, "dot1q"))
8466         dot1q = 1;
8467       else if (unformat (input, "dot1ad"))
8468         dot1ad = 1;
8469       else
8470         break;
8471     }
8472   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8473        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8474     return 0;
8475
8476   if (tag1 || ignore_tag1 || cos1 || dot1q)
8477     len = 18;
8478   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8479     len = 22;
8480
8481   vec_validate (mask, len - 1);
8482
8483   if (dst)
8484     memset (mask, 0xff, 6);
8485
8486   if (src)
8487     memset (mask + 6, 0xff, 6);
8488
8489   if (tag2 || dot1ad)
8490     {
8491       /* inner vlan tag */
8492       if (tag2)
8493         {
8494           mask[19] = 0xff;
8495           mask[18] = 0x0f;
8496         }
8497       if (cos2)
8498         mask[18] |= 0xe0;
8499       if (proto)
8500         mask[21] = mask[20] = 0xff;
8501       if (tag1)
8502         {
8503           mask[15] = 0xff;
8504           mask[14] = 0x0f;
8505         }
8506       if (cos1)
8507         mask[14] |= 0xe0;
8508       *maskp = mask;
8509       return 1;
8510     }
8511   if (tag1 | dot1q)
8512     {
8513       if (tag1)
8514         {
8515           mask[15] = 0xff;
8516           mask[14] = 0x0f;
8517         }
8518       if (cos1)
8519         mask[14] |= 0xe0;
8520       if (proto)
8521         mask[16] = mask[17] = 0xff;
8522
8523       *maskp = mask;
8524       return 1;
8525     }
8526   if (cos2)
8527     mask[18] |= 0xe0;
8528   if (cos1)
8529     mask[14] |= 0xe0;
8530   if (proto)
8531     mask[12] = mask[13] = 0xff;
8532
8533   *maskp = mask;
8534   return 1;
8535 }
8536
8537 uword
8538 unformat_classify_mask (unformat_input_t * input, va_list * args)
8539 {
8540   u8 **maskp = va_arg (*args, u8 **);
8541   u32 *skipp = va_arg (*args, u32 *);
8542   u32 *matchp = va_arg (*args, u32 *);
8543   u32 match;
8544   u8 *mask = 0;
8545   u8 *l2 = 0;
8546   u8 *l3 = 0;
8547   u8 *l4 = 0;
8548   int i;
8549
8550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8551     {
8552       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8553         ;
8554       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8555         ;
8556       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8557         ;
8558       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8559         ;
8560       else
8561         break;
8562     }
8563
8564   if (l4 && !l3)
8565     {
8566       vec_free (mask);
8567       vec_free (l2);
8568       vec_free (l4);
8569       return 0;
8570     }
8571
8572   if (mask || l2 || l3 || l4)
8573     {
8574       if (l2 || l3 || l4)
8575         {
8576           /* "With a free Ethernet header in every package" */
8577           if (l2 == 0)
8578             vec_validate (l2, 13);
8579           mask = l2;
8580           if (vec_len (l3))
8581             {
8582               vec_append (mask, l3);
8583               vec_free (l3);
8584             }
8585           if (vec_len (l4))
8586             {
8587               vec_append (mask, l4);
8588               vec_free (l4);
8589             }
8590         }
8591
8592       /* Scan forward looking for the first significant mask octet */
8593       for (i = 0; i < vec_len (mask); i++)
8594         if (mask[i])
8595           break;
8596
8597       /* compute (skip, match) params */
8598       *skipp = i / sizeof (u32x4);
8599       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8600
8601       /* Pad mask to an even multiple of the vector size */
8602       while (vec_len (mask) % sizeof (u32x4))
8603         vec_add1 (mask, 0);
8604
8605       match = vec_len (mask) / sizeof (u32x4);
8606
8607       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8608         {
8609           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8610           if (*tmp || *(tmp + 1))
8611             break;
8612           match--;
8613         }
8614       if (match == 0)
8615         clib_warning ("BUG: match 0");
8616
8617       _vec_len (mask) = match * sizeof (u32x4);
8618
8619       *matchp = match;
8620       *maskp = mask;
8621
8622       return 1;
8623     }
8624
8625   return 0;
8626 }
8627
8628 #define foreach_l2_next                         \
8629 _(drop, DROP)                                   \
8630 _(ethernet, ETHERNET_INPUT)                     \
8631 _(ip4, IP4_INPUT)                               \
8632 _(ip6, IP6_INPUT)
8633
8634 uword
8635 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8636 {
8637   u32 *miss_next_indexp = va_arg (*args, u32 *);
8638   u32 next_index = 0;
8639   u32 tmp;
8640
8641 #define _(n,N) \
8642   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8643   foreach_l2_next;
8644 #undef _
8645
8646   if (unformat (input, "%d", &tmp))
8647     {
8648       next_index = tmp;
8649       goto out;
8650     }
8651
8652   return 0;
8653
8654 out:
8655   *miss_next_indexp = next_index;
8656   return 1;
8657 }
8658
8659 #define foreach_ip_next                         \
8660 _(drop, DROP)                                   \
8661 _(local, LOCAL)                                 \
8662 _(rewrite, REWRITE)
8663
8664 uword
8665 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8666 {
8667   u32 *miss_next_indexp = va_arg (*args, u32 *);
8668   u32 next_index = 0;
8669   u32 tmp;
8670
8671 #define _(n,N) \
8672   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8673   foreach_ip_next;
8674 #undef _
8675
8676   if (unformat (input, "%d", &tmp))
8677     {
8678       next_index = tmp;
8679       goto out;
8680     }
8681
8682   return 0;
8683
8684 out:
8685   *miss_next_indexp = next_index;
8686   return 1;
8687 }
8688
8689 #define foreach_acl_next                        \
8690 _(deny, DENY)
8691
8692 uword
8693 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8694 {
8695   u32 *miss_next_indexp = va_arg (*args, u32 *);
8696   u32 next_index = 0;
8697   u32 tmp;
8698
8699 #define _(n,N) \
8700   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8701   foreach_acl_next;
8702 #undef _
8703
8704   if (unformat (input, "permit"))
8705     {
8706       next_index = ~0;
8707       goto out;
8708     }
8709   else if (unformat (input, "%d", &tmp))
8710     {
8711       next_index = tmp;
8712       goto out;
8713     }
8714
8715   return 0;
8716
8717 out:
8718   *miss_next_indexp = next_index;
8719   return 1;
8720 }
8721
8722 uword
8723 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8724 {
8725   u32 *r = va_arg (*args, u32 *);
8726
8727   if (unformat (input, "conform-color"))
8728     *r = POLICE_CONFORM;
8729   else if (unformat (input, "exceed-color"))
8730     *r = POLICE_EXCEED;
8731   else
8732     return 0;
8733
8734   return 1;
8735 }
8736
8737 static int
8738 api_classify_add_del_table (vat_main_t * vam)
8739 {
8740   unformat_input_t *i = vam->input;
8741   vl_api_classify_add_del_table_t *mp;
8742
8743   u32 nbuckets = 2;
8744   u32 skip = ~0;
8745   u32 match = ~0;
8746   int is_add = 1;
8747   u32 table_index = ~0;
8748   u32 next_table_index = ~0;
8749   u32 miss_next_index = ~0;
8750   u32 memory_size = 32 << 20;
8751   u8 *mask = 0;
8752   f64 timeout;
8753
8754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8755     {
8756       if (unformat (i, "del"))
8757         is_add = 0;
8758       else if (unformat (i, "buckets %d", &nbuckets))
8759         ;
8760       else if (unformat (i, "memory_size %d", &memory_size))
8761         ;
8762       else if (unformat (i, "skip %d", &skip))
8763         ;
8764       else if (unformat (i, "match %d", &match))
8765         ;
8766       else if (unformat (i, "table %d", &table_index))
8767         ;
8768       else if (unformat (i, "mask %U", unformat_classify_mask,
8769                          &mask, &skip, &match))
8770         ;
8771       else if (unformat (i, "next-table %d", &next_table_index))
8772         ;
8773       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8774                          &miss_next_index))
8775         ;
8776       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8777                          &miss_next_index))
8778         ;
8779       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8780                          &miss_next_index))
8781         ;
8782       else
8783         break;
8784     }
8785
8786   if (is_add && mask == 0)
8787     {
8788       errmsg ("Mask required\n");
8789       return -99;
8790     }
8791
8792   if (is_add && skip == ~0)
8793     {
8794       errmsg ("skip count required\n");
8795       return -99;
8796     }
8797
8798   if (is_add && match == ~0)
8799     {
8800       errmsg ("match count required\n");
8801       return -99;
8802     }
8803
8804   if (!is_add && table_index == ~0)
8805     {
8806       errmsg ("table index required for delete\n");
8807       return -99;
8808     }
8809
8810   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8811
8812   mp->is_add = is_add;
8813   mp->table_index = ntohl (table_index);
8814   mp->nbuckets = ntohl (nbuckets);
8815   mp->memory_size = ntohl (memory_size);
8816   mp->skip_n_vectors = ntohl (skip);
8817   mp->match_n_vectors = ntohl (match);
8818   mp->next_table_index = ntohl (next_table_index);
8819   mp->miss_next_index = ntohl (miss_next_index);
8820   clib_memcpy (mp->mask, mask, vec_len (mask));
8821
8822   vec_free (mask);
8823
8824   S;
8825   W;
8826   /* NOTREACHED */
8827 }
8828
8829 uword
8830 unformat_l4_match (unformat_input_t * input, va_list * args)
8831 {
8832   u8 **matchp = va_arg (*args, u8 **);
8833
8834   u8 *proto_header = 0;
8835   int src_port = 0;
8836   int dst_port = 0;
8837
8838   tcpudp_header_t h;
8839
8840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8841     {
8842       if (unformat (input, "src_port %d", &src_port))
8843         ;
8844       else if (unformat (input, "dst_port %d", &dst_port))
8845         ;
8846       else
8847         return 0;
8848     }
8849
8850   h.src_port = clib_host_to_net_u16 (src_port);
8851   h.dst_port = clib_host_to_net_u16 (dst_port);
8852   vec_validate (proto_header, sizeof (h) - 1);
8853   memcpy (proto_header, &h, sizeof (h));
8854
8855   *matchp = proto_header;
8856
8857   return 1;
8858 }
8859
8860 uword
8861 unformat_ip4_match (unformat_input_t * input, va_list * args)
8862 {
8863   u8 **matchp = va_arg (*args, u8 **);
8864   u8 *match = 0;
8865   ip4_header_t *ip;
8866   int version = 0;
8867   u32 version_val;
8868   int hdr_length = 0;
8869   u32 hdr_length_val;
8870   int src = 0, dst = 0;
8871   ip4_address_t src_val, dst_val;
8872   int proto = 0;
8873   u32 proto_val;
8874   int tos = 0;
8875   u32 tos_val;
8876   int length = 0;
8877   u32 length_val;
8878   int fragment_id = 0;
8879   u32 fragment_id_val;
8880   int ttl = 0;
8881   int ttl_val;
8882   int checksum = 0;
8883   u32 checksum_val;
8884
8885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8886     {
8887       if (unformat (input, "version %d", &version_val))
8888         version = 1;
8889       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8890         hdr_length = 1;
8891       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8892         src = 1;
8893       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8894         dst = 1;
8895       else if (unformat (input, "proto %d", &proto_val))
8896         proto = 1;
8897       else if (unformat (input, "tos %d", &tos_val))
8898         tos = 1;
8899       else if (unformat (input, "length %d", &length_val))
8900         length = 1;
8901       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8902         fragment_id = 1;
8903       else if (unformat (input, "ttl %d", &ttl_val))
8904         ttl = 1;
8905       else if (unformat (input, "checksum %d", &checksum_val))
8906         checksum = 1;
8907       else
8908         break;
8909     }
8910
8911   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8912       + ttl + checksum == 0)
8913     return 0;
8914
8915   /*
8916    * Aligned because we use the real comparison functions
8917    */
8918   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8919
8920   ip = (ip4_header_t *) match;
8921
8922   /* These are realistically matched in practice */
8923   if (src)
8924     ip->src_address.as_u32 = src_val.as_u32;
8925
8926   if (dst)
8927     ip->dst_address.as_u32 = dst_val.as_u32;
8928
8929   if (proto)
8930     ip->protocol = proto_val;
8931
8932
8933   /* These are not, but they're included for completeness */
8934   if (version)
8935     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8936
8937   if (hdr_length)
8938     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8939
8940   if (tos)
8941     ip->tos = tos_val;
8942
8943   if (length)
8944     ip->length = clib_host_to_net_u16 (length_val);
8945
8946   if (ttl)
8947     ip->ttl = ttl_val;
8948
8949   if (checksum)
8950     ip->checksum = clib_host_to_net_u16 (checksum_val);
8951
8952   *matchp = match;
8953   return 1;
8954 }
8955
8956 uword
8957 unformat_ip6_match (unformat_input_t * input, va_list * args)
8958 {
8959   u8 **matchp = va_arg (*args, u8 **);
8960   u8 *match = 0;
8961   ip6_header_t *ip;
8962   int version = 0;
8963   u32 version_val;
8964   u8 traffic_class = 0;
8965   u32 traffic_class_val = 0;
8966   u8 flow_label = 0;
8967   u8 flow_label_val;
8968   int src = 0, dst = 0;
8969   ip6_address_t src_val, dst_val;
8970   int proto = 0;
8971   u32 proto_val;
8972   int payload_length = 0;
8973   u32 payload_length_val;
8974   int hop_limit = 0;
8975   int hop_limit_val;
8976   u32 ip_version_traffic_class_and_flow_label;
8977
8978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8979     {
8980       if (unformat (input, "version %d", &version_val))
8981         version = 1;
8982       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8983         traffic_class = 1;
8984       else if (unformat (input, "flow_label %d", &flow_label_val))
8985         flow_label = 1;
8986       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8987         src = 1;
8988       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8989         dst = 1;
8990       else if (unformat (input, "proto %d", &proto_val))
8991         proto = 1;
8992       else if (unformat (input, "payload_length %d", &payload_length_val))
8993         payload_length = 1;
8994       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8995         hop_limit = 1;
8996       else
8997         break;
8998     }
8999
9000   if (version + traffic_class + flow_label + src + dst + proto +
9001       payload_length + hop_limit == 0)
9002     return 0;
9003
9004   /*
9005    * Aligned because we use the real comparison functions
9006    */
9007   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9008
9009   ip = (ip6_header_t *) match;
9010
9011   if (src)
9012     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9013
9014   if (dst)
9015     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9016
9017   if (proto)
9018     ip->protocol = proto_val;
9019
9020   ip_version_traffic_class_and_flow_label = 0;
9021
9022   if (version)
9023     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9024
9025   if (traffic_class)
9026     ip_version_traffic_class_and_flow_label |=
9027       (traffic_class_val & 0xFF) << 20;
9028
9029   if (flow_label)
9030     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9031
9032   ip->ip_version_traffic_class_and_flow_label =
9033     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9034
9035   if (payload_length)
9036     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9037
9038   if (hop_limit)
9039     ip->hop_limit = hop_limit_val;
9040
9041   *matchp = match;
9042   return 1;
9043 }
9044
9045 uword
9046 unformat_l3_match (unformat_input_t * input, va_list * args)
9047 {
9048   u8 **matchp = va_arg (*args, u8 **);
9049
9050   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9051     {
9052       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9053         return 1;
9054       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9055         return 1;
9056       else
9057         break;
9058     }
9059   return 0;
9060 }
9061
9062 uword
9063 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9064 {
9065   u8 *tagp = va_arg (*args, u8 *);
9066   u32 tag;
9067
9068   if (unformat (input, "%d", &tag))
9069     {
9070       tagp[0] = (tag >> 8) & 0x0F;
9071       tagp[1] = tag & 0xFF;
9072       return 1;
9073     }
9074
9075   return 0;
9076 }
9077
9078 uword
9079 unformat_l2_match (unformat_input_t * input, va_list * args)
9080 {
9081   u8 **matchp = va_arg (*args, u8 **);
9082   u8 *match = 0;
9083   u8 src = 0;
9084   u8 src_val[6];
9085   u8 dst = 0;
9086   u8 dst_val[6];
9087   u8 proto = 0;
9088   u16 proto_val;
9089   u8 tag1 = 0;
9090   u8 tag1_val[2];
9091   u8 tag2 = 0;
9092   u8 tag2_val[2];
9093   int len = 14;
9094   u8 ignore_tag1 = 0;
9095   u8 ignore_tag2 = 0;
9096   u8 cos1 = 0;
9097   u8 cos2 = 0;
9098   u32 cos1_val = 0;
9099   u32 cos2_val = 0;
9100
9101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9102     {
9103       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9104         src = 1;
9105       else
9106         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9107         dst = 1;
9108       else if (unformat (input, "proto %U",
9109                          unformat_ethernet_type_host_byte_order, &proto_val))
9110         proto = 1;
9111       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9112         tag1 = 1;
9113       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9114         tag2 = 1;
9115       else if (unformat (input, "ignore-tag1"))
9116         ignore_tag1 = 1;
9117       else if (unformat (input, "ignore-tag2"))
9118         ignore_tag2 = 1;
9119       else if (unformat (input, "cos1 %d", &cos1_val))
9120         cos1 = 1;
9121       else if (unformat (input, "cos2 %d", &cos2_val))
9122         cos2 = 1;
9123       else
9124         break;
9125     }
9126   if ((src + dst + proto + tag1 + tag2 +
9127        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9128     return 0;
9129
9130   if (tag1 || ignore_tag1 || cos1)
9131     len = 18;
9132   if (tag2 || ignore_tag2 || cos2)
9133     len = 22;
9134
9135   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9136
9137   if (dst)
9138     clib_memcpy (match, dst_val, 6);
9139
9140   if (src)
9141     clib_memcpy (match + 6, src_val, 6);
9142
9143   if (tag2)
9144     {
9145       /* inner vlan tag */
9146       match[19] = tag2_val[1];
9147       match[18] = tag2_val[0];
9148       if (cos2)
9149         match[18] |= (cos2_val & 0x7) << 5;
9150       if (proto)
9151         {
9152           match[21] = proto_val & 0xff;
9153           match[20] = proto_val >> 8;
9154         }
9155       if (tag1)
9156         {
9157           match[15] = tag1_val[1];
9158           match[14] = tag1_val[0];
9159         }
9160       if (cos1)
9161         match[14] |= (cos1_val & 0x7) << 5;
9162       *matchp = match;
9163       return 1;
9164     }
9165   if (tag1)
9166     {
9167       match[15] = tag1_val[1];
9168       match[14] = tag1_val[0];
9169       if (proto)
9170         {
9171           match[17] = proto_val & 0xff;
9172           match[16] = proto_val >> 8;
9173         }
9174       if (cos1)
9175         match[14] |= (cos1_val & 0x7) << 5;
9176
9177       *matchp = match;
9178       return 1;
9179     }
9180   if (cos2)
9181     match[18] |= (cos2_val & 0x7) << 5;
9182   if (cos1)
9183     match[14] |= (cos1_val & 0x7) << 5;
9184   if (proto)
9185     {
9186       match[13] = proto_val & 0xff;
9187       match[12] = proto_val >> 8;
9188     }
9189
9190   *matchp = match;
9191   return 1;
9192 }
9193
9194
9195 uword
9196 unformat_classify_match (unformat_input_t * input, va_list * args)
9197 {
9198   u8 **matchp = va_arg (*args, u8 **);
9199   u32 skip_n_vectors = va_arg (*args, u32);
9200   u32 match_n_vectors = va_arg (*args, u32);
9201
9202   u8 *match = 0;
9203   u8 *l2 = 0;
9204   u8 *l3 = 0;
9205   u8 *l4 = 0;
9206
9207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9208     {
9209       if (unformat (input, "hex %U", unformat_hex_string, &match))
9210         ;
9211       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9212         ;
9213       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9214         ;
9215       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9216         ;
9217       else
9218         break;
9219     }
9220
9221   if (l4 && !l3)
9222     {
9223       vec_free (match);
9224       vec_free (l2);
9225       vec_free (l4);
9226       return 0;
9227     }
9228
9229   if (match || l2 || l3 || l4)
9230     {
9231       if (l2 || l3 || l4)
9232         {
9233           /* "Win a free Ethernet header in every packet" */
9234           if (l2 == 0)
9235             vec_validate_aligned (l2, 13, sizeof (u32x4));
9236           match = l2;
9237           if (vec_len (l3))
9238             {
9239               vec_append_aligned (match, l3, sizeof (u32x4));
9240               vec_free (l3);
9241             }
9242           if (vec_len (l4))
9243             {
9244               vec_append_aligned (match, l4, sizeof (u32x4));
9245               vec_free (l4);
9246             }
9247         }
9248
9249       /* Make sure the vector is big enough even if key is all 0's */
9250       vec_validate_aligned
9251         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9252          sizeof (u32x4));
9253
9254       /* Set size, include skipped vectors */
9255       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9256
9257       *matchp = match;
9258
9259       return 1;
9260     }
9261
9262   return 0;
9263 }
9264
9265 static int
9266 api_classify_add_del_session (vat_main_t * vam)
9267 {
9268   unformat_input_t *i = vam->input;
9269   vl_api_classify_add_del_session_t *mp;
9270   int is_add = 1;
9271   u32 table_index = ~0;
9272   u32 hit_next_index = ~0;
9273   u32 opaque_index = ~0;
9274   u8 *match = 0;
9275   i32 advance = 0;
9276   f64 timeout;
9277   u32 skip_n_vectors = 0;
9278   u32 match_n_vectors = 0;
9279
9280   /*
9281    * Warning: you have to supply skip_n and match_n
9282    * because the API client cant simply look at the classify
9283    * table object.
9284    */
9285
9286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9287     {
9288       if (unformat (i, "del"))
9289         is_add = 0;
9290       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9291                          &hit_next_index))
9292         ;
9293       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9294                          &hit_next_index))
9295         ;
9296       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9297                          &hit_next_index))
9298         ;
9299       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9300         ;
9301       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9302         ;
9303       else if (unformat (i, "opaque-index %d", &opaque_index))
9304         ;
9305       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9306         ;
9307       else if (unformat (i, "match_n %d", &match_n_vectors))
9308         ;
9309       else if (unformat (i, "match %U", unformat_classify_match,
9310                          &match, skip_n_vectors, match_n_vectors))
9311         ;
9312       else if (unformat (i, "advance %d", &advance))
9313         ;
9314       else if (unformat (i, "table-index %d", &table_index))
9315         ;
9316       else
9317         break;
9318     }
9319
9320   if (table_index == ~0)
9321     {
9322       errmsg ("Table index required\n");
9323       return -99;
9324     }
9325
9326   if (is_add && match == 0)
9327     {
9328       errmsg ("Match value required\n");
9329       return -99;
9330     }
9331
9332   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9333
9334   mp->is_add = is_add;
9335   mp->table_index = ntohl (table_index);
9336   mp->hit_next_index = ntohl (hit_next_index);
9337   mp->opaque_index = ntohl (opaque_index);
9338   mp->advance = ntohl (advance);
9339   clib_memcpy (mp->match, match, vec_len (match));
9340   vec_free (match);
9341
9342   S;
9343   W;
9344   /* NOTREACHED */
9345 }
9346
9347 static int
9348 api_classify_set_interface_ip_table (vat_main_t * vam)
9349 {
9350   unformat_input_t *i = vam->input;
9351   vl_api_classify_set_interface_ip_table_t *mp;
9352   f64 timeout;
9353   u32 sw_if_index;
9354   int sw_if_index_set;
9355   u32 table_index = ~0;
9356   u8 is_ipv6 = 0;
9357
9358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9359     {
9360       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9361         sw_if_index_set = 1;
9362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9363         sw_if_index_set = 1;
9364       else if (unformat (i, "table %d", &table_index))
9365         ;
9366       else
9367         {
9368           clib_warning ("parse error '%U'", format_unformat_error, i);
9369           return -99;
9370         }
9371     }
9372
9373   if (sw_if_index_set == 0)
9374     {
9375       errmsg ("missing interface name or sw_if_index\n");
9376       return -99;
9377     }
9378
9379
9380   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9381
9382   mp->sw_if_index = ntohl (sw_if_index);
9383   mp->table_index = ntohl (table_index);
9384   mp->is_ipv6 = is_ipv6;
9385
9386   S;
9387   W;
9388   /* NOTREACHED */
9389   return 0;
9390 }
9391
9392 static int
9393 api_classify_set_interface_l2_tables (vat_main_t * vam)
9394 {
9395   unformat_input_t *i = vam->input;
9396   vl_api_classify_set_interface_l2_tables_t *mp;
9397   f64 timeout;
9398   u32 sw_if_index;
9399   int sw_if_index_set;
9400   u32 ip4_table_index = ~0;
9401   u32 ip6_table_index = ~0;
9402   u32 other_table_index = ~0;
9403   u32 is_input = 1;
9404
9405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9406     {
9407       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9408         sw_if_index_set = 1;
9409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9410         sw_if_index_set = 1;
9411       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9412         ;
9413       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9414         ;
9415       else if (unformat (i, "other-table %d", &other_table_index))
9416         ;
9417       else if (unformat (i, "is-input %d", &is_input))
9418         ;
9419       else
9420         {
9421           clib_warning ("parse error '%U'", format_unformat_error, i);
9422           return -99;
9423         }
9424     }
9425
9426   if (sw_if_index_set == 0)
9427     {
9428       errmsg ("missing interface name or sw_if_index\n");
9429       return -99;
9430     }
9431
9432
9433   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9434
9435   mp->sw_if_index = ntohl (sw_if_index);
9436   mp->ip4_table_index = ntohl (ip4_table_index);
9437   mp->ip6_table_index = ntohl (ip6_table_index);
9438   mp->other_table_index = ntohl (other_table_index);
9439   mp->is_input = (u8) is_input;
9440
9441   S;
9442   W;
9443   /* NOTREACHED */
9444   return 0;
9445 }
9446
9447 static int
9448 api_set_ipfix_exporter (vat_main_t * vam)
9449 {
9450   unformat_input_t *i = vam->input;
9451   vl_api_set_ipfix_exporter_t *mp;
9452   ip4_address_t collector_address;
9453   u8 collector_address_set = 0;
9454   u32 collector_port = ~0;
9455   ip4_address_t src_address;
9456   u8 src_address_set = 0;
9457   u32 vrf_id = ~0;
9458   u32 path_mtu = ~0;
9459   u32 template_interval = ~0;
9460   u8 udp_checksum = 0;
9461   f64 timeout;
9462
9463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9464     {
9465       if (unformat (i, "collector_address %U", unformat_ip4_address,
9466                     &collector_address))
9467         collector_address_set = 1;
9468       else if (unformat (i, "collector_port %d", &collector_port))
9469         ;
9470       else if (unformat (i, "src_address %U", unformat_ip4_address,
9471                          &src_address))
9472         src_address_set = 1;
9473       else if (unformat (i, "vrf_id %d", &vrf_id))
9474         ;
9475       else if (unformat (i, "path_mtu %d", &path_mtu))
9476         ;
9477       else if (unformat (i, "template_interval %d", &template_interval))
9478         ;
9479       else if (unformat (i, "udp_checksum"))
9480         udp_checksum = 1;
9481       else
9482         break;
9483     }
9484
9485   if (collector_address_set == 0)
9486     {
9487       errmsg ("collector_address required\n");
9488       return -99;
9489     }
9490
9491   if (src_address_set == 0)
9492     {
9493       errmsg ("src_address required\n");
9494       return -99;
9495     }
9496
9497   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9498
9499   memcpy (mp->collector_address, collector_address.data,
9500           sizeof (collector_address.data));
9501   mp->collector_port = htons ((u16) collector_port);
9502   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9503   mp->vrf_id = htonl (vrf_id);
9504   mp->path_mtu = htonl (path_mtu);
9505   mp->template_interval = htonl (template_interval);
9506   mp->udp_checksum = udp_checksum;
9507
9508   S;
9509   W;
9510   /* NOTREACHED */
9511 }
9512
9513 static int
9514 api_set_ipfix_classify_stream (vat_main_t * vam)
9515 {
9516   unformat_input_t *i = vam->input;
9517   vl_api_set_ipfix_classify_stream_t *mp;
9518   u32 domain_id = 0;
9519   u32 src_port = UDP_DST_PORT_ipfix;
9520   f64 timeout;
9521
9522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9523     {
9524       if (unformat (i, "domain %d", &domain_id))
9525         ;
9526       else if (unformat (i, "src_port %d", &src_port))
9527         ;
9528       else
9529         {
9530           errmsg ("unknown input `%U'", format_unformat_error, i);
9531           return -99;
9532         }
9533     }
9534
9535   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9536
9537   mp->domain_id = htonl (domain_id);
9538   mp->src_port = htons ((u16) src_port);
9539
9540   S;
9541   W;
9542   /* NOTREACHED */
9543 }
9544
9545 static int
9546 api_ipfix_classify_table_add_del (vat_main_t * vam)
9547 {
9548   unformat_input_t *i = vam->input;
9549   vl_api_ipfix_classify_table_add_del_t *mp;
9550   int is_add = -1;
9551   u32 classify_table_index = ~0;
9552   u8 ip_version = 0;
9553   u8 transport_protocol = 255;
9554   f64 timeout;
9555
9556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9557     {
9558       if (unformat (i, "add"))
9559         is_add = 1;
9560       else if (unformat (i, "del"))
9561         is_add = 0;
9562       else if (unformat (i, "table %d", &classify_table_index))
9563         ;
9564       else if (unformat (i, "ip4"))
9565         ip_version = 4;
9566       else if (unformat (i, "ip6"))
9567         ip_version = 6;
9568       else if (unformat (i, "tcp"))
9569         transport_protocol = 6;
9570       else if (unformat (i, "udp"))
9571         transport_protocol = 17;
9572       else
9573         {
9574           errmsg ("unknown input `%U'", format_unformat_error, i);
9575           return -99;
9576         }
9577     }
9578
9579   if (is_add == -1)
9580     {
9581       errmsg ("expecting: add|del");
9582       return -99;
9583     }
9584   if (classify_table_index == ~0)
9585     {
9586       errmsg ("classifier table not specified");
9587       return -99;
9588     }
9589   if (ip_version == 0)
9590     {
9591       errmsg ("IP version not specified");
9592       return -99;
9593     }
9594
9595   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9596
9597   mp->is_add = is_add;
9598   mp->table_id = htonl (classify_table_index);
9599   mp->ip_version = ip_version;
9600   mp->transport_protocol = transport_protocol;
9601
9602   S;
9603   W;
9604   /* NOTREACHED */
9605 }
9606
9607 static int
9608 api_get_node_index (vat_main_t * vam)
9609 {
9610   unformat_input_t *i = vam->input;
9611   vl_api_get_node_index_t *mp;
9612   f64 timeout;
9613   u8 *name = 0;
9614
9615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9616     {
9617       if (unformat (i, "node %s", &name))
9618         ;
9619       else
9620         break;
9621     }
9622   if (name == 0)
9623     {
9624       errmsg ("node name required\n");
9625       return -99;
9626     }
9627   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9628     {
9629       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9630       return -99;
9631     }
9632
9633   M (GET_NODE_INDEX, get_node_index);
9634   clib_memcpy (mp->node_name, name, vec_len (name));
9635   vec_free (name);
9636
9637   S;
9638   W;
9639   /* NOTREACHED */
9640   return 0;
9641 }
9642
9643 static int
9644 api_get_next_index (vat_main_t * vam)
9645 {
9646   unformat_input_t *i = vam->input;
9647   vl_api_get_next_index_t *mp;
9648   f64 timeout;
9649   u8 *node_name = 0, *next_node_name = 0;
9650
9651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9652     {
9653       if (unformat (i, "node-name %s", &node_name))
9654         ;
9655       else if (unformat (i, "next-node-name %s", &next_node_name))
9656         break;
9657     }
9658
9659   if (node_name == 0)
9660     {
9661       errmsg ("node name required\n");
9662       return -99;
9663     }
9664   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9665     {
9666       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9667       return -99;
9668     }
9669
9670   if (next_node_name == 0)
9671     {
9672       errmsg ("next node name required\n");
9673       return -99;
9674     }
9675   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9676     {
9677       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9678       return -99;
9679     }
9680
9681   M (GET_NEXT_INDEX, get_next_index);
9682   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9683   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9684   vec_free (node_name);
9685   vec_free (next_node_name);
9686
9687   S;
9688   W;
9689   /* NOTREACHED */
9690   return 0;
9691 }
9692
9693 static int
9694 api_add_node_next (vat_main_t * vam)
9695 {
9696   unformat_input_t *i = vam->input;
9697   vl_api_add_node_next_t *mp;
9698   f64 timeout;
9699   u8 *name = 0;
9700   u8 *next = 0;
9701
9702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9703     {
9704       if (unformat (i, "node %s", &name))
9705         ;
9706       else if (unformat (i, "next %s", &next))
9707         ;
9708       else
9709         break;
9710     }
9711   if (name == 0)
9712     {
9713       errmsg ("node name required\n");
9714       return -99;
9715     }
9716   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9717     {
9718       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9719       return -99;
9720     }
9721   if (next == 0)
9722     {
9723       errmsg ("next node required\n");
9724       return -99;
9725     }
9726   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9727     {
9728       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9729       return -99;
9730     }
9731
9732   M (ADD_NODE_NEXT, add_node_next);
9733   clib_memcpy (mp->node_name, name, vec_len (name));
9734   clib_memcpy (mp->next_name, next, vec_len (next));
9735   vec_free (name);
9736   vec_free (next);
9737
9738   S;
9739   W;
9740   /* NOTREACHED */
9741   return 0;
9742 }
9743
9744 static int
9745 api_l2tpv3_create_tunnel (vat_main_t * vam)
9746 {
9747   unformat_input_t *i = vam->input;
9748   ip6_address_t client_address, our_address;
9749   int client_address_set = 0;
9750   int our_address_set = 0;
9751   u32 local_session_id = 0;
9752   u32 remote_session_id = 0;
9753   u64 local_cookie = 0;
9754   u64 remote_cookie = 0;
9755   u8 l2_sublayer_present = 0;
9756   vl_api_l2tpv3_create_tunnel_t *mp;
9757   f64 timeout;
9758
9759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9760     {
9761       if (unformat (i, "client_address %U", unformat_ip6_address,
9762                     &client_address))
9763         client_address_set = 1;
9764       else if (unformat (i, "our_address %U", unformat_ip6_address,
9765                          &our_address))
9766         our_address_set = 1;
9767       else if (unformat (i, "local_session_id %d", &local_session_id))
9768         ;
9769       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9770         ;
9771       else if (unformat (i, "local_cookie %lld", &local_cookie))
9772         ;
9773       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9774         ;
9775       else if (unformat (i, "l2-sublayer-present"))
9776         l2_sublayer_present = 1;
9777       else
9778         break;
9779     }
9780
9781   if (client_address_set == 0)
9782     {
9783       errmsg ("client_address required\n");
9784       return -99;
9785     }
9786
9787   if (our_address_set == 0)
9788     {
9789       errmsg ("our_address required\n");
9790       return -99;
9791     }
9792
9793   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9794
9795   clib_memcpy (mp->client_address, client_address.as_u8,
9796                sizeof (mp->client_address));
9797
9798   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9799
9800   mp->local_session_id = ntohl (local_session_id);
9801   mp->remote_session_id = ntohl (remote_session_id);
9802   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9803   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9804   mp->l2_sublayer_present = l2_sublayer_present;
9805   mp->is_ipv6 = 1;
9806
9807   S;
9808   W;
9809   /* NOTREACHED */
9810   return 0;
9811 }
9812
9813 static int
9814 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9815 {
9816   unformat_input_t *i = vam->input;
9817   u32 sw_if_index;
9818   u8 sw_if_index_set = 0;
9819   u64 new_local_cookie = 0;
9820   u64 new_remote_cookie = 0;
9821   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9822   f64 timeout;
9823
9824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9825     {
9826       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9827         sw_if_index_set = 1;
9828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9829         sw_if_index_set = 1;
9830       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9831         ;
9832       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9833         ;
9834       else
9835         break;
9836     }
9837
9838   if (sw_if_index_set == 0)
9839     {
9840       errmsg ("missing interface name or sw_if_index\n");
9841       return -99;
9842     }
9843
9844   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9845
9846   mp->sw_if_index = ntohl (sw_if_index);
9847   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9848   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9849
9850   S;
9851   W;
9852   /* NOTREACHED */
9853   return 0;
9854 }
9855
9856 static int
9857 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9858 {
9859   unformat_input_t *i = vam->input;
9860   vl_api_l2tpv3_interface_enable_disable_t *mp;
9861   f64 timeout;
9862   u32 sw_if_index;
9863   u8 sw_if_index_set = 0;
9864   u8 enable_disable = 1;
9865
9866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9867     {
9868       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9869         sw_if_index_set = 1;
9870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9871         sw_if_index_set = 1;
9872       else if (unformat (i, "enable"))
9873         enable_disable = 1;
9874       else if (unformat (i, "disable"))
9875         enable_disable = 0;
9876       else
9877         break;
9878     }
9879
9880   if (sw_if_index_set == 0)
9881     {
9882       errmsg ("missing interface name or sw_if_index\n");
9883       return -99;
9884     }
9885
9886   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9887
9888   mp->sw_if_index = ntohl (sw_if_index);
9889   mp->enable_disable = enable_disable;
9890
9891   S;
9892   W;
9893   /* NOTREACHED */
9894   return 0;
9895 }
9896
9897 static int
9898 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9899 {
9900   unformat_input_t *i = vam->input;
9901   vl_api_l2tpv3_set_lookup_key_t *mp;
9902   f64 timeout;
9903   u8 key = ~0;
9904
9905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9906     {
9907       if (unformat (i, "lookup_v6_src"))
9908         key = L2T_LOOKUP_SRC_ADDRESS;
9909       else if (unformat (i, "lookup_v6_dst"))
9910         key = L2T_LOOKUP_DST_ADDRESS;
9911       else if (unformat (i, "lookup_session_id"))
9912         key = L2T_LOOKUP_SESSION_ID;
9913       else
9914         break;
9915     }
9916
9917   if (key == (u8) ~ 0)
9918     {
9919       errmsg ("l2tp session lookup key unset\n");
9920       return -99;
9921     }
9922
9923   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9924
9925   mp->key = key;
9926
9927   S;
9928   W;
9929   /* NOTREACHED */
9930   return 0;
9931 }
9932
9933 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9934   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9935 {
9936   vat_main_t *vam = &vat_main;
9937
9938   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9939            format_ip6_address, mp->our_address,
9940            format_ip6_address, mp->client_address,
9941            clib_net_to_host_u32 (mp->sw_if_index));
9942
9943   fformat (vam->ofp,
9944            "   local cookies %016llx %016llx remote cookie %016llx\n",
9945            clib_net_to_host_u64 (mp->local_cookie[0]),
9946            clib_net_to_host_u64 (mp->local_cookie[1]),
9947            clib_net_to_host_u64 (mp->remote_cookie));
9948
9949   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9950            clib_net_to_host_u32 (mp->local_session_id),
9951            clib_net_to_host_u32 (mp->remote_session_id));
9952
9953   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9954            mp->l2_sublayer_present ? "preset" : "absent");
9955
9956 }
9957
9958 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9959   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9960 {
9961   vat_main_t *vam = &vat_main;
9962   vat_json_node_t *node = NULL;
9963   struct in6_addr addr;
9964
9965   if (VAT_JSON_ARRAY != vam->json_tree.type)
9966     {
9967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9968       vat_json_init_array (&vam->json_tree);
9969     }
9970   node = vat_json_array_add (&vam->json_tree);
9971
9972   vat_json_init_object (node);
9973
9974   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9975   vat_json_object_add_ip6 (node, "our_address", addr);
9976   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9977   vat_json_object_add_ip6 (node, "client_address", addr);
9978
9979   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9980   vat_json_init_array (lc);
9981   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9982   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9983   vat_json_object_add_uint (node, "remote_cookie",
9984                             clib_net_to_host_u64 (mp->remote_cookie));
9985
9986   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9987   vat_json_object_add_uint (node, "local_session_id",
9988                             clib_net_to_host_u32 (mp->local_session_id));
9989   vat_json_object_add_uint (node, "remote_session_id",
9990                             clib_net_to_host_u32 (mp->remote_session_id));
9991   vat_json_object_add_string_copy (node, "l2_sublayer",
9992                                    mp->l2_sublayer_present ? (u8 *) "present"
9993                                    : (u8 *) "absent");
9994 }
9995
9996 static int
9997 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9998 {
9999   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10000   f64 timeout;
10001
10002   /* Get list of l2tpv3-tunnel interfaces */
10003   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10004   S;
10005
10006   /* Use a control ping for synchronization */
10007   {
10008     vl_api_control_ping_t *mp;
10009     M (CONTROL_PING, control_ping);
10010     S;
10011   }
10012   W;
10013 }
10014
10015
10016 static void vl_api_sw_interface_tap_details_t_handler
10017   (vl_api_sw_interface_tap_details_t * mp)
10018 {
10019   vat_main_t *vam = &vat_main;
10020
10021   fformat (vam->ofp, "%-16s %d\n",
10022            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10023 }
10024
10025 static void vl_api_sw_interface_tap_details_t_handler_json
10026   (vl_api_sw_interface_tap_details_t * mp)
10027 {
10028   vat_main_t *vam = &vat_main;
10029   vat_json_node_t *node = NULL;
10030
10031   if (VAT_JSON_ARRAY != vam->json_tree.type)
10032     {
10033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10034       vat_json_init_array (&vam->json_tree);
10035     }
10036   node = vat_json_array_add (&vam->json_tree);
10037
10038   vat_json_init_object (node);
10039   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10040   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10041 }
10042
10043 static int
10044 api_sw_interface_tap_dump (vat_main_t * vam)
10045 {
10046   vl_api_sw_interface_tap_dump_t *mp;
10047   f64 timeout;
10048
10049   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10050   /* Get list of tap interfaces */
10051   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10052   S;
10053
10054   /* Use a control ping for synchronization */
10055   {
10056     vl_api_control_ping_t *mp;
10057     M (CONTROL_PING, control_ping);
10058     S;
10059   }
10060   W;
10061 }
10062
10063 static uword unformat_vxlan_decap_next
10064   (unformat_input_t * input, va_list * args)
10065 {
10066   u32 *result = va_arg (*args, u32 *);
10067   u32 tmp;
10068
10069   if (unformat (input, "drop"))
10070     *result = VXLAN_INPUT_NEXT_DROP;
10071   else if (unformat (input, "ip4"))
10072     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
10073   else if (unformat (input, "ip6"))
10074     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
10075   else if (unformat (input, "l2"))
10076     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10077   else if (unformat (input, "%d", &tmp))
10078     *result = tmp;
10079   else
10080     return 0;
10081   return 1;
10082 }
10083
10084 static int
10085 api_vxlan_add_del_tunnel (vat_main_t * vam)
10086 {
10087   unformat_input_t *line_input = vam->input;
10088   vl_api_vxlan_add_del_tunnel_t *mp;
10089   f64 timeout;
10090   ip4_address_t src4, dst4;
10091   ip6_address_t src6, dst6;
10092   u8 is_add = 1;
10093   u8 ipv4_set = 0, ipv6_set = 0;
10094   u8 src_set = 0;
10095   u8 dst_set = 0;
10096   u32 encap_vrf_id = 0;
10097   u32 decap_next_index = ~0;
10098   u32 vni = 0;
10099
10100   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10101     {
10102       if (unformat (line_input, "del"))
10103         is_add = 0;
10104       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10105         {
10106           ipv4_set = 1;
10107           src_set = 1;
10108         }
10109       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10110         {
10111           ipv4_set = 1;
10112           dst_set = 1;
10113         }
10114       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10115         {
10116           ipv6_set = 1;
10117           src_set = 1;
10118         }
10119       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10120         {
10121           ipv6_set = 1;
10122           dst_set = 1;
10123         }
10124       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10125         ;
10126       else if (unformat (line_input, "decap-next %U",
10127                          unformat_vxlan_decap_next, &decap_next_index))
10128         ;
10129       else if (unformat (line_input, "vni %d", &vni))
10130         ;
10131       else
10132         {
10133           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10134           return -99;
10135         }
10136     }
10137
10138   if (src_set == 0)
10139     {
10140       errmsg ("tunnel src address not specified\n");
10141       return -99;
10142     }
10143   if (dst_set == 0)
10144     {
10145       errmsg ("tunnel dst address not specified\n");
10146       return -99;
10147     }
10148
10149   if (ipv4_set && ipv6_set)
10150     {
10151       errmsg ("both IPv4 and IPv6 addresses specified");
10152       return -99;
10153     }
10154
10155   if ((vni == 0) || (vni >> 24))
10156     {
10157       errmsg ("vni not specified or out of range\n");
10158       return -99;
10159     }
10160
10161   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10162
10163   if (ipv6_set)
10164     {
10165       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10166       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10167     }
10168   else
10169     {
10170       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10171       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10172     }
10173   mp->encap_vrf_id = ntohl (encap_vrf_id);
10174   mp->decap_next_index = ntohl (decap_next_index);
10175   mp->vni = ntohl (vni);
10176   mp->is_add = is_add;
10177   mp->is_ipv6 = ipv6_set;
10178
10179   S;
10180   W;
10181   /* NOTREACHED */
10182   return 0;
10183 }
10184
10185 static void vl_api_vxlan_tunnel_details_t_handler
10186   (vl_api_vxlan_tunnel_details_t * mp)
10187 {
10188   vat_main_t *vam = &vat_main;
10189
10190   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10191            ntohl (mp->sw_if_index),
10192            format_ip46_address, &(mp->src_address[0]),
10193            IP46_TYPE_ANY,
10194            format_ip46_address, &(mp->dst_address[0]),
10195            IP46_TYPE_ANY,
10196            ntohl (mp->encap_vrf_id),
10197            ntohl (mp->decap_next_index), ntohl (mp->vni));
10198 }
10199
10200 static void vl_api_vxlan_tunnel_details_t_handler_json
10201   (vl_api_vxlan_tunnel_details_t * mp)
10202 {
10203   vat_main_t *vam = &vat_main;
10204   vat_json_node_t *node = NULL;
10205   struct in_addr ip4;
10206   struct in6_addr ip6;
10207
10208   if (VAT_JSON_ARRAY != vam->json_tree.type)
10209     {
10210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10211       vat_json_init_array (&vam->json_tree);
10212     }
10213   node = vat_json_array_add (&vam->json_tree);
10214
10215   vat_json_init_object (node);
10216   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10217   if (mp->is_ipv6)
10218     {
10219       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10220       vat_json_object_add_ip6 (node, "src_address", ip6);
10221       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10222       vat_json_object_add_ip6 (node, "dst_address", ip6);
10223     }
10224   else
10225     {
10226       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10227       vat_json_object_add_ip4 (node, "src_address", ip4);
10228       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10229       vat_json_object_add_ip4 (node, "dst_address", ip4);
10230     }
10231   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10232   vat_json_object_add_uint (node, "decap_next_index",
10233                             ntohl (mp->decap_next_index));
10234   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10235   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10236 }
10237
10238 static int
10239 api_vxlan_tunnel_dump (vat_main_t * vam)
10240 {
10241   unformat_input_t *i = vam->input;
10242   vl_api_vxlan_tunnel_dump_t *mp;
10243   f64 timeout;
10244   u32 sw_if_index;
10245   u8 sw_if_index_set = 0;
10246
10247   /* Parse args required to build the message */
10248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10249     {
10250       if (unformat (i, "sw_if_index %d", &sw_if_index))
10251         sw_if_index_set = 1;
10252       else
10253         break;
10254     }
10255
10256   if (sw_if_index_set == 0)
10257     {
10258       sw_if_index = ~0;
10259     }
10260
10261   if (!vam->json_output)
10262     {
10263       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10264                "sw_if_index", "src_address", "dst_address",
10265                "encap_vrf_id", "decap_next_index", "vni");
10266     }
10267
10268   /* Get list of vxlan-tunnel interfaces */
10269   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10270
10271   mp->sw_if_index = htonl (sw_if_index);
10272
10273   S;
10274
10275   /* Use a control ping for synchronization */
10276   {
10277     vl_api_control_ping_t *mp;
10278     M (CONTROL_PING, control_ping);
10279     S;
10280   }
10281   W;
10282 }
10283
10284 static int
10285 api_gre_add_del_tunnel (vat_main_t * vam)
10286 {
10287   unformat_input_t *line_input = vam->input;
10288   vl_api_gre_add_del_tunnel_t *mp;
10289   f64 timeout;
10290   ip4_address_t src4, dst4;
10291   u8 is_add = 1;
10292   u8 teb = 0;
10293   u8 src_set = 0;
10294   u8 dst_set = 0;
10295   u32 outer_fib_id = 0;
10296
10297   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10298     {
10299       if (unformat (line_input, "del"))
10300         is_add = 0;
10301       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10302         src_set = 1;
10303       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10304         dst_set = 1;
10305       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10306         ;
10307       else if (unformat (line_input, "teb"))
10308         teb = 1;
10309       else
10310         {
10311           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10312           return -99;
10313         }
10314     }
10315
10316   if (src_set == 0)
10317     {
10318       errmsg ("tunnel src address not specified\n");
10319       return -99;
10320     }
10321   if (dst_set == 0)
10322     {
10323       errmsg ("tunnel dst address not specified\n");
10324       return -99;
10325     }
10326
10327
10328   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10329
10330   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10331   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10332   mp->outer_fib_id = ntohl (outer_fib_id);
10333   mp->is_add = is_add;
10334   mp->teb = teb;
10335
10336   S;
10337   W;
10338   /* NOTREACHED */
10339   return 0;
10340 }
10341
10342 static void vl_api_gre_tunnel_details_t_handler
10343   (vl_api_gre_tunnel_details_t * mp)
10344 {
10345   vat_main_t *vam = &vat_main;
10346
10347   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10348            ntohl (mp->sw_if_index),
10349            format_ip4_address, &mp->src_address,
10350            format_ip4_address, &mp->dst_address,
10351            mp->teb, ntohl (mp->outer_fib_id));
10352 }
10353
10354 static void vl_api_gre_tunnel_details_t_handler_json
10355   (vl_api_gre_tunnel_details_t * mp)
10356 {
10357   vat_main_t *vam = &vat_main;
10358   vat_json_node_t *node = NULL;
10359   struct in_addr ip4;
10360
10361   if (VAT_JSON_ARRAY != vam->json_tree.type)
10362     {
10363       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10364       vat_json_init_array (&vam->json_tree);
10365     }
10366   node = vat_json_array_add (&vam->json_tree);
10367
10368   vat_json_init_object (node);
10369   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10370   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10371   vat_json_object_add_ip4 (node, "src_address", ip4);
10372   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10373   vat_json_object_add_ip4 (node, "dst_address", ip4);
10374   vat_json_object_add_uint (node, "teb", mp->teb);
10375   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10376 }
10377
10378 static int
10379 api_gre_tunnel_dump (vat_main_t * vam)
10380 {
10381   unformat_input_t *i = vam->input;
10382   vl_api_gre_tunnel_dump_t *mp;
10383   f64 timeout;
10384   u32 sw_if_index;
10385   u8 sw_if_index_set = 0;
10386
10387   /* Parse args required to build the message */
10388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10389     {
10390       if (unformat (i, "sw_if_index %d", &sw_if_index))
10391         sw_if_index_set = 1;
10392       else
10393         break;
10394     }
10395
10396   if (sw_if_index_set == 0)
10397     {
10398       sw_if_index = ~0;
10399     }
10400
10401   if (!vam->json_output)
10402     {
10403       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10404                "sw_if_index", "src_address", "dst_address", "teb",
10405                "outer_fib_id");
10406     }
10407
10408   /* Get list of gre-tunnel interfaces */
10409   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10410
10411   mp->sw_if_index = htonl (sw_if_index);
10412
10413   S;
10414
10415   /* Use a control ping for synchronization */
10416   {
10417     vl_api_control_ping_t *mp;
10418     M (CONTROL_PING, control_ping);
10419     S;
10420   }
10421   W;
10422 }
10423
10424 static int
10425 api_l2_fib_clear_table (vat_main_t * vam)
10426 {
10427 //  unformat_input_t * i = vam->input;
10428   vl_api_l2_fib_clear_table_t *mp;
10429   f64 timeout;
10430
10431   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10432
10433   S;
10434   W;
10435   /* NOTREACHED */
10436   return 0;
10437 }
10438
10439 static int
10440 api_l2_interface_efp_filter (vat_main_t * vam)
10441 {
10442   unformat_input_t *i = vam->input;
10443   vl_api_l2_interface_efp_filter_t *mp;
10444   f64 timeout;
10445   u32 sw_if_index;
10446   u8 enable = 1;
10447   u8 sw_if_index_set = 0;
10448
10449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10450     {
10451       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10452         sw_if_index_set = 1;
10453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10454         sw_if_index_set = 1;
10455       else if (unformat (i, "enable"))
10456         enable = 1;
10457       else if (unformat (i, "disable"))
10458         enable = 0;
10459       else
10460         {
10461           clib_warning ("parse error '%U'", format_unformat_error, i);
10462           return -99;
10463         }
10464     }
10465
10466   if (sw_if_index_set == 0)
10467     {
10468       errmsg ("missing sw_if_index\n");
10469       return -99;
10470     }
10471
10472   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10473
10474   mp->sw_if_index = ntohl (sw_if_index);
10475   mp->enable_disable = enable;
10476
10477   S;
10478   W;
10479   /* NOTREACHED */
10480   return 0;
10481 }
10482
10483 #define foreach_vtr_op                          \
10484 _("disable",  L2_VTR_DISABLED)                  \
10485 _("push-1",  L2_VTR_PUSH_1)                     \
10486 _("push-2",  L2_VTR_PUSH_2)                     \
10487 _("pop-1",  L2_VTR_POP_1)                       \
10488 _("pop-2",  L2_VTR_POP_2)                       \
10489 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10490 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10491 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10492 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10493
10494 static int
10495 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10496 {
10497   unformat_input_t *i = vam->input;
10498   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10499   f64 timeout;
10500   u32 sw_if_index;
10501   u8 sw_if_index_set = 0;
10502   u8 vtr_op_set = 0;
10503   u32 vtr_op = 0;
10504   u32 push_dot1q = 1;
10505   u32 tag1 = ~0;
10506   u32 tag2 = ~0;
10507
10508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10509     {
10510       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10511         sw_if_index_set = 1;
10512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10513         sw_if_index_set = 1;
10514       else if (unformat (i, "vtr_op %d", &vtr_op))
10515         vtr_op_set = 1;
10516 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10517       foreach_vtr_op
10518 #undef _
10519         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10520         ;
10521       else if (unformat (i, "tag1 %d", &tag1))
10522         ;
10523       else if (unformat (i, "tag2 %d", &tag2))
10524         ;
10525       else
10526         {
10527           clib_warning ("parse error '%U'", format_unformat_error, i);
10528           return -99;
10529         }
10530     }
10531
10532   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10533     {
10534       errmsg ("missing vtr operation or sw_if_index\n");
10535       return -99;
10536     }
10537
10538   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10539     mp->sw_if_index = ntohl (sw_if_index);
10540   mp->vtr_op = ntohl (vtr_op);
10541   mp->push_dot1q = ntohl (push_dot1q);
10542   mp->tag1 = ntohl (tag1);
10543   mp->tag2 = ntohl (tag2);
10544
10545   S;
10546   W;
10547   /* NOTREACHED */
10548   return 0;
10549 }
10550
10551 static int
10552 api_create_vhost_user_if (vat_main_t * vam)
10553 {
10554   unformat_input_t *i = vam->input;
10555   vl_api_create_vhost_user_if_t *mp;
10556   f64 timeout;
10557   u8 *file_name;
10558   u8 is_server = 0;
10559   u8 file_name_set = 0;
10560   u32 custom_dev_instance = ~0;
10561   u8 hwaddr[6];
10562   u8 use_custom_mac = 0;
10563
10564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10565     {
10566       if (unformat (i, "socket %s", &file_name))
10567         {
10568           file_name_set = 1;
10569         }
10570       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10571         ;
10572       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10573         use_custom_mac = 1;
10574       else if (unformat (i, "server"))
10575         is_server = 1;
10576       else
10577         break;
10578     }
10579
10580   if (file_name_set == 0)
10581     {
10582       errmsg ("missing socket file name\n");
10583       return -99;
10584     }
10585
10586   if (vec_len (file_name) > 255)
10587     {
10588       errmsg ("socket file name too long\n");
10589       return -99;
10590     }
10591   vec_add1 (file_name, 0);
10592
10593   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10594
10595   mp->is_server = is_server;
10596   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10597   vec_free (file_name);
10598   if (custom_dev_instance != ~0)
10599     {
10600       mp->renumber = 1;
10601       mp->custom_dev_instance = ntohl (custom_dev_instance);
10602     }
10603   mp->use_custom_mac = use_custom_mac;
10604   clib_memcpy (mp->mac_address, hwaddr, 6);
10605
10606   S;
10607   W;
10608   /* NOTREACHED */
10609   return 0;
10610 }
10611
10612 static int
10613 api_modify_vhost_user_if (vat_main_t * vam)
10614 {
10615   unformat_input_t *i = vam->input;
10616   vl_api_modify_vhost_user_if_t *mp;
10617   f64 timeout;
10618   u8 *file_name;
10619   u8 is_server = 0;
10620   u8 file_name_set = 0;
10621   u32 custom_dev_instance = ~0;
10622   u8 sw_if_index_set = 0;
10623   u32 sw_if_index = (u32) ~ 0;
10624
10625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10626     {
10627       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10628         sw_if_index_set = 1;
10629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10630         sw_if_index_set = 1;
10631       else if (unformat (i, "socket %s", &file_name))
10632         {
10633           file_name_set = 1;
10634         }
10635       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10636         ;
10637       else if (unformat (i, "server"))
10638         is_server = 1;
10639       else
10640         break;
10641     }
10642
10643   if (sw_if_index_set == 0)
10644     {
10645       errmsg ("missing sw_if_index or interface name\n");
10646       return -99;
10647     }
10648
10649   if (file_name_set == 0)
10650     {
10651       errmsg ("missing socket file name\n");
10652       return -99;
10653     }
10654
10655   if (vec_len (file_name) > 255)
10656     {
10657       errmsg ("socket file name too long\n");
10658       return -99;
10659     }
10660   vec_add1 (file_name, 0);
10661
10662   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10663
10664   mp->sw_if_index = ntohl (sw_if_index);
10665   mp->is_server = is_server;
10666   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10667   vec_free (file_name);
10668   if (custom_dev_instance != ~0)
10669     {
10670       mp->renumber = 1;
10671       mp->custom_dev_instance = ntohl (custom_dev_instance);
10672     }
10673
10674   S;
10675   W;
10676   /* NOTREACHED */
10677   return 0;
10678 }
10679
10680 static int
10681 api_delete_vhost_user_if (vat_main_t * vam)
10682 {
10683   unformat_input_t *i = vam->input;
10684   vl_api_delete_vhost_user_if_t *mp;
10685   f64 timeout;
10686   u32 sw_if_index = ~0;
10687   u8 sw_if_index_set = 0;
10688
10689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10690     {
10691       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10692         sw_if_index_set = 1;
10693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10694         sw_if_index_set = 1;
10695       else
10696         break;
10697     }
10698
10699   if (sw_if_index_set == 0)
10700     {
10701       errmsg ("missing sw_if_index or interface name\n");
10702       return -99;
10703     }
10704
10705
10706   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10707
10708   mp->sw_if_index = ntohl (sw_if_index);
10709
10710   S;
10711   W;
10712   /* NOTREACHED */
10713   return 0;
10714 }
10715
10716 static void vl_api_sw_interface_vhost_user_details_t_handler
10717   (vl_api_sw_interface_vhost_user_details_t * mp)
10718 {
10719   vat_main_t *vam = &vat_main;
10720
10721   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10722            (char *) mp->interface_name,
10723            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10724            clib_net_to_host_u64 (mp->features), mp->is_server,
10725            ntohl (mp->num_regions), (char *) mp->sock_filename);
10726   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10727 }
10728
10729 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10730   (vl_api_sw_interface_vhost_user_details_t * mp)
10731 {
10732   vat_main_t *vam = &vat_main;
10733   vat_json_node_t *node = NULL;
10734
10735   if (VAT_JSON_ARRAY != vam->json_tree.type)
10736     {
10737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10738       vat_json_init_array (&vam->json_tree);
10739     }
10740   node = vat_json_array_add (&vam->json_tree);
10741
10742   vat_json_init_object (node);
10743   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10744   vat_json_object_add_string_copy (node, "interface_name",
10745                                    mp->interface_name);
10746   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10747                             ntohl (mp->virtio_net_hdr_sz));
10748   vat_json_object_add_uint (node, "features",
10749                             clib_net_to_host_u64 (mp->features));
10750   vat_json_object_add_uint (node, "is_server", mp->is_server);
10751   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10752   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10753   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10754 }
10755
10756 static int
10757 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10758 {
10759   vl_api_sw_interface_vhost_user_dump_t *mp;
10760   f64 timeout;
10761   fformat (vam->ofp,
10762            "Interface name           idx hdr_sz features server regions filename\n");
10763
10764   /* Get list of vhost-user interfaces */
10765   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10766   S;
10767
10768   /* Use a control ping for synchronization */
10769   {
10770     vl_api_control_ping_t *mp;
10771     M (CONTROL_PING, control_ping);
10772     S;
10773   }
10774   W;
10775 }
10776
10777 static int
10778 api_show_version (vat_main_t * vam)
10779 {
10780   vl_api_show_version_t *mp;
10781   f64 timeout;
10782
10783   M (SHOW_VERSION, show_version);
10784
10785   S;
10786   W;
10787   /* NOTREACHED */
10788   return 0;
10789 }
10790
10791
10792 static int
10793 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10794 {
10795   unformat_input_t *line_input = vam->input;
10796   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10797   f64 timeout;
10798   ip4_address_t local4, remote4;
10799   ip6_address_t local6, remote6;
10800   u8 is_add = 1;
10801   u8 ipv4_set = 0, ipv6_set = 0;
10802   u8 local_set = 0;
10803   u8 remote_set = 0;
10804   u32 encap_vrf_id = 0;
10805   u32 decap_vrf_id = 0;
10806   u8 protocol = ~0;
10807   u32 vni;
10808   u8 vni_set = 0;
10809
10810   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10811     {
10812       if (unformat (line_input, "del"))
10813         is_add = 0;
10814       else if (unformat (line_input, "local %U",
10815                          unformat_ip4_address, &local4))
10816         {
10817           local_set = 1;
10818           ipv4_set = 1;
10819         }
10820       else if (unformat (line_input, "remote %U",
10821                          unformat_ip4_address, &remote4))
10822         {
10823           remote_set = 1;
10824           ipv4_set = 1;
10825         }
10826       else if (unformat (line_input, "local %U",
10827                          unformat_ip6_address, &local6))
10828         {
10829           local_set = 1;
10830           ipv6_set = 1;
10831         }
10832       else if (unformat (line_input, "remote %U",
10833                          unformat_ip6_address, &remote6))
10834         {
10835           remote_set = 1;
10836           ipv6_set = 1;
10837         }
10838       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10839         ;
10840       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10841         ;
10842       else if (unformat (line_input, "vni %d", &vni))
10843         vni_set = 1;
10844       else if (unformat (line_input, "next-ip4"))
10845         protocol = 1;
10846       else if (unformat (line_input, "next-ip6"))
10847         protocol = 2;
10848       else if (unformat (line_input, "next-ethernet"))
10849         protocol = 3;
10850       else if (unformat (line_input, "next-nsh"))
10851         protocol = 4;
10852       else
10853         {
10854           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10855           return -99;
10856         }
10857     }
10858
10859   if (local_set == 0)
10860     {
10861       errmsg ("tunnel local address not specified\n");
10862       return -99;
10863     }
10864   if (remote_set == 0)
10865     {
10866       errmsg ("tunnel remote address not specified\n");
10867       return -99;
10868     }
10869   if (ipv4_set && ipv6_set)
10870     {
10871       errmsg ("both IPv4 and IPv6 addresses specified");
10872       return -99;
10873     }
10874
10875   if (vni_set == 0)
10876     {
10877       errmsg ("vni not specified\n");
10878       return -99;
10879     }
10880
10881   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10882
10883
10884   if (ipv6_set)
10885     {
10886       clib_memcpy (&mp->local, &local6, sizeof (local6));
10887       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10888     }
10889   else
10890     {
10891       clib_memcpy (&mp->local, &local4, sizeof (local4));
10892       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10893     }
10894
10895   mp->encap_vrf_id = ntohl (encap_vrf_id);
10896   mp->decap_vrf_id = ntohl (decap_vrf_id);
10897   mp->protocol = ntohl (protocol);
10898   mp->vni = ntohl (vni);
10899   mp->is_add = is_add;
10900   mp->is_ipv6 = ipv6_set;
10901
10902   S;
10903   W;
10904   /* NOTREACHED */
10905   return 0;
10906 }
10907
10908 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10909   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10910 {
10911   vat_main_t *vam = &vat_main;
10912
10913   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10914            ntohl (mp->sw_if_index),
10915            format_ip46_address, &(mp->local[0]),
10916            format_ip46_address, &(mp->remote[0]),
10917            ntohl (mp->vni),
10918            ntohl (mp->protocol),
10919            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10920 }
10921
10922 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10923   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10924 {
10925   vat_main_t *vam = &vat_main;
10926   vat_json_node_t *node = NULL;
10927   struct in_addr ip4;
10928   struct in6_addr ip6;
10929
10930   if (VAT_JSON_ARRAY != vam->json_tree.type)
10931     {
10932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10933       vat_json_init_array (&vam->json_tree);
10934     }
10935   node = vat_json_array_add (&vam->json_tree);
10936
10937   vat_json_init_object (node);
10938   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10939   if (mp->is_ipv6)
10940     {
10941       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10942       vat_json_object_add_ip6 (node, "local", ip6);
10943       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10944       vat_json_object_add_ip6 (node, "remote", ip6);
10945     }
10946   else
10947     {
10948       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10949       vat_json_object_add_ip4 (node, "local", ip4);
10950       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10951       vat_json_object_add_ip4 (node, "remote", ip4);
10952     }
10953   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10954   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10955   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10956   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10957   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10958 }
10959
10960 static int
10961 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10962 {
10963   unformat_input_t *i = vam->input;
10964   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10965   f64 timeout;
10966   u32 sw_if_index;
10967   u8 sw_if_index_set = 0;
10968
10969   /* Parse args required to build the message */
10970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10971     {
10972       if (unformat (i, "sw_if_index %d", &sw_if_index))
10973         sw_if_index_set = 1;
10974       else
10975         break;
10976     }
10977
10978   if (sw_if_index_set == 0)
10979     {
10980       sw_if_index = ~0;
10981     }
10982
10983   if (!vam->json_output)
10984     {
10985       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10986                "sw_if_index", "local", "remote", "vni",
10987                "protocol", "encap_vrf_id", "decap_vrf_id");
10988     }
10989
10990   /* Get list of vxlan-tunnel interfaces */
10991   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10992
10993   mp->sw_if_index = htonl (sw_if_index);
10994
10995   S;
10996
10997   /* Use a control ping for synchronization */
10998   {
10999     vl_api_control_ping_t *mp;
11000     M (CONTROL_PING, control_ping);
11001     S;
11002   }
11003   W;
11004 }
11005
11006 u8 *
11007 format_l2_fib_mac_address (u8 * s, va_list * args)
11008 {
11009   u8 *a = va_arg (*args, u8 *);
11010
11011   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11012                  a[2], a[3], a[4], a[5], a[6], a[7]);
11013 }
11014
11015 static void vl_api_l2_fib_table_entry_t_handler
11016   (vl_api_l2_fib_table_entry_t * mp)
11017 {
11018   vat_main_t *vam = &vat_main;
11019
11020   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11021            "       %d       %d     %d\n",
11022            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11023            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11024            mp->bvi_mac);
11025 }
11026
11027 static void vl_api_l2_fib_table_entry_t_handler_json
11028   (vl_api_l2_fib_table_entry_t * mp)
11029 {
11030   vat_main_t *vam = &vat_main;
11031   vat_json_node_t *node = NULL;
11032
11033   if (VAT_JSON_ARRAY != vam->json_tree.type)
11034     {
11035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11036       vat_json_init_array (&vam->json_tree);
11037     }
11038   node = vat_json_array_add (&vam->json_tree);
11039
11040   vat_json_init_object (node);
11041   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11042   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11043   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11044   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11045   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11046   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11047 }
11048
11049 static int
11050 api_l2_fib_table_dump (vat_main_t * vam)
11051 {
11052   unformat_input_t *i = vam->input;
11053   vl_api_l2_fib_table_dump_t *mp;
11054   f64 timeout;
11055   u32 bd_id;
11056   u8 bd_id_set = 0;
11057
11058   /* Parse args required to build the message */
11059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11060     {
11061       if (unformat (i, "bd_id %d", &bd_id))
11062         bd_id_set = 1;
11063       else
11064         break;
11065     }
11066
11067   if (bd_id_set == 0)
11068     {
11069       errmsg ("missing bridge domain\n");
11070       return -99;
11071     }
11072
11073   fformat (vam->ofp,
11074            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11075
11076   /* Get list of l2 fib entries */
11077   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11078
11079   mp->bd_id = ntohl (bd_id);
11080   S;
11081
11082   /* Use a control ping for synchronization */
11083   {
11084     vl_api_control_ping_t *mp;
11085     M (CONTROL_PING, control_ping);
11086     S;
11087   }
11088   W;
11089 }
11090
11091
11092 static int
11093 api_interface_name_renumber (vat_main_t * vam)
11094 {
11095   unformat_input_t *line_input = vam->input;
11096   vl_api_interface_name_renumber_t *mp;
11097   u32 sw_if_index = ~0;
11098   f64 timeout;
11099   u32 new_show_dev_instance = ~0;
11100
11101   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11102     {
11103       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11104                     &sw_if_index))
11105         ;
11106       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11107         ;
11108       else if (unformat (line_input, "new_show_dev_instance %d",
11109                          &new_show_dev_instance))
11110         ;
11111       else
11112         break;
11113     }
11114
11115   if (sw_if_index == ~0)
11116     {
11117       errmsg ("missing interface name or sw_if_index\n");
11118       return -99;
11119     }
11120
11121   if (new_show_dev_instance == ~0)
11122     {
11123       errmsg ("missing new_show_dev_instance\n");
11124       return -99;
11125     }
11126
11127   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11128
11129   mp->sw_if_index = ntohl (sw_if_index);
11130   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11131
11132   S;
11133   W;
11134 }
11135
11136 static int
11137 api_want_ip4_arp_events (vat_main_t * vam)
11138 {
11139   unformat_input_t *line_input = vam->input;
11140   vl_api_want_ip4_arp_events_t *mp;
11141   f64 timeout;
11142   ip4_address_t address;
11143   int address_set = 0;
11144   u32 enable_disable = 1;
11145
11146   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11147     {
11148       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11149         address_set = 1;
11150       else if (unformat (line_input, "del"))
11151         enable_disable = 0;
11152       else
11153         break;
11154     }
11155
11156   if (address_set == 0)
11157     {
11158       errmsg ("missing addresses\n");
11159       return -99;
11160     }
11161
11162   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11163   mp->enable_disable = enable_disable;
11164   mp->pid = getpid ();
11165   mp->address = address.as_u32;
11166
11167   S;
11168   W;
11169 }
11170
11171 static int
11172 api_want_ip6_nd_events (vat_main_t * vam)
11173 {
11174   unformat_input_t *line_input = vam->input;
11175   vl_api_want_ip6_nd_events_t *mp;
11176   f64 timeout;
11177   ip6_address_t address;
11178   int address_set = 0;
11179   u32 enable_disable = 1;
11180
11181   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11182     {
11183       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11184         address_set = 1;
11185       else if (unformat (line_input, "del"))
11186         enable_disable = 0;
11187       else
11188         break;
11189     }
11190
11191   if (address_set == 0)
11192     {
11193       errmsg ("missing addresses\n");
11194       return -99;
11195     }
11196
11197   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11198   mp->enable_disable = enable_disable;
11199   mp->pid = getpid ();
11200   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11201
11202   S;
11203   W;
11204 }
11205
11206 static int
11207 api_input_acl_set_interface (vat_main_t * vam)
11208 {
11209   unformat_input_t *i = vam->input;
11210   vl_api_input_acl_set_interface_t *mp;
11211   f64 timeout;
11212   u32 sw_if_index;
11213   int sw_if_index_set;
11214   u32 ip4_table_index = ~0;
11215   u32 ip6_table_index = ~0;
11216   u32 l2_table_index = ~0;
11217   u8 is_add = 1;
11218
11219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11220     {
11221       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11222         sw_if_index_set = 1;
11223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11224         sw_if_index_set = 1;
11225       else if (unformat (i, "del"))
11226         is_add = 0;
11227       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11228         ;
11229       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11230         ;
11231       else if (unformat (i, "l2-table %d", &l2_table_index))
11232         ;
11233       else
11234         {
11235           clib_warning ("parse error '%U'", format_unformat_error, i);
11236           return -99;
11237         }
11238     }
11239
11240   if (sw_if_index_set == 0)
11241     {
11242       errmsg ("missing interface name or sw_if_index\n");
11243       return -99;
11244     }
11245
11246   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11247
11248   mp->sw_if_index = ntohl (sw_if_index);
11249   mp->ip4_table_index = ntohl (ip4_table_index);
11250   mp->ip6_table_index = ntohl (ip6_table_index);
11251   mp->l2_table_index = ntohl (l2_table_index);
11252   mp->is_add = is_add;
11253
11254   S;
11255   W;
11256   /* NOTREACHED */
11257   return 0;
11258 }
11259
11260 static int
11261 api_ip_address_dump (vat_main_t * vam)
11262 {
11263   unformat_input_t *i = vam->input;
11264   vl_api_ip_address_dump_t *mp;
11265   u32 sw_if_index = ~0;
11266   u8 sw_if_index_set = 0;
11267   u8 ipv4_set = 0;
11268   u8 ipv6_set = 0;
11269   f64 timeout;
11270
11271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11272     {
11273       if (unformat (i, "sw_if_index %d", &sw_if_index))
11274         sw_if_index_set = 1;
11275       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11276         sw_if_index_set = 1;
11277       else if (unformat (i, "ipv4"))
11278         ipv4_set = 1;
11279       else if (unformat (i, "ipv6"))
11280         ipv6_set = 1;
11281       else
11282         break;
11283     }
11284
11285   if (ipv4_set && ipv6_set)
11286     {
11287       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11288       return -99;
11289     }
11290
11291   if ((!ipv4_set) && (!ipv6_set))
11292     {
11293       errmsg ("no ipv4 nor ipv6 flag set\n");
11294       return -99;
11295     }
11296
11297   if (sw_if_index_set == 0)
11298     {
11299       errmsg ("missing interface name or sw_if_index\n");
11300       return -99;
11301     }
11302
11303   vam->current_sw_if_index = sw_if_index;
11304   vam->is_ipv6 = ipv6_set;
11305
11306   M (IP_ADDRESS_DUMP, ip_address_dump);
11307   mp->sw_if_index = ntohl (sw_if_index);
11308   mp->is_ipv6 = ipv6_set;
11309   S;
11310
11311   /* Use a control ping for synchronization */
11312   {
11313     vl_api_control_ping_t *mp;
11314     M (CONTROL_PING, control_ping);
11315     S;
11316   }
11317   W;
11318 }
11319
11320 static int
11321 api_ip_dump (vat_main_t * vam)
11322 {
11323   vl_api_ip_dump_t *mp;
11324   unformat_input_t *in = vam->input;
11325   int ipv4_set = 0;
11326   int ipv6_set = 0;
11327   int is_ipv6;
11328   f64 timeout;
11329   int i;
11330
11331   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11332     {
11333       if (unformat (in, "ipv4"))
11334         ipv4_set = 1;
11335       else if (unformat (in, "ipv6"))
11336         ipv6_set = 1;
11337       else
11338         break;
11339     }
11340
11341   if (ipv4_set && ipv6_set)
11342     {
11343       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11344       return -99;
11345     }
11346
11347   if ((!ipv4_set) && (!ipv6_set))
11348     {
11349       errmsg ("no ipv4 nor ipv6 flag set\n");
11350       return -99;
11351     }
11352
11353   is_ipv6 = ipv6_set;
11354   vam->is_ipv6 = is_ipv6;
11355
11356   /* free old data */
11357   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11358     {
11359       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11360     }
11361   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11362
11363   M (IP_DUMP, ip_dump);
11364   mp->is_ipv6 = ipv6_set;
11365   S;
11366
11367   /* Use a control ping for synchronization */
11368   {
11369     vl_api_control_ping_t *mp;
11370     M (CONTROL_PING, control_ping);
11371     S;
11372   }
11373   W;
11374 }
11375
11376 static int
11377 api_ipsec_spd_add_del (vat_main_t * vam)
11378 {
11379 #if DPDK > 0
11380   unformat_input_t *i = vam->input;
11381   vl_api_ipsec_spd_add_del_t *mp;
11382   f64 timeout;
11383   u32 spd_id = ~0;
11384   u8 is_add = 1;
11385
11386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11387     {
11388       if (unformat (i, "spd_id %d", &spd_id))
11389         ;
11390       else if (unformat (i, "del"))
11391         is_add = 0;
11392       else
11393         {
11394           clib_warning ("parse error '%U'", format_unformat_error, i);
11395           return -99;
11396         }
11397     }
11398   if (spd_id == ~0)
11399     {
11400       errmsg ("spd_id must be set\n");
11401       return -99;
11402     }
11403
11404   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11405
11406   mp->spd_id = ntohl (spd_id);
11407   mp->is_add = is_add;
11408
11409   S;
11410   W;
11411   /* NOTREACHED */
11412   return 0;
11413 #else
11414   clib_warning ("unsupported (no dpdk)");
11415   return -99;
11416 #endif
11417 }
11418
11419 static int
11420 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11421 {
11422 #if DPDK > 0
11423   unformat_input_t *i = vam->input;
11424   vl_api_ipsec_interface_add_del_spd_t *mp;
11425   f64 timeout;
11426   u32 sw_if_index;
11427   u8 sw_if_index_set = 0;
11428   u32 spd_id = (u32) ~ 0;
11429   u8 is_add = 1;
11430
11431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11432     {
11433       if (unformat (i, "del"))
11434         is_add = 0;
11435       else if (unformat (i, "spd_id %d", &spd_id))
11436         ;
11437       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11438         sw_if_index_set = 1;
11439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11440         sw_if_index_set = 1;
11441       else
11442         {
11443           clib_warning ("parse error '%U'", format_unformat_error, i);
11444           return -99;
11445         }
11446
11447     }
11448
11449   if (spd_id == (u32) ~ 0)
11450     {
11451       errmsg ("spd_id must be set\n");
11452       return -99;
11453     }
11454
11455   if (sw_if_index_set == 0)
11456     {
11457       errmsg ("missing interface name or sw_if_index\n");
11458       return -99;
11459     }
11460
11461   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11462
11463   mp->spd_id = ntohl (spd_id);
11464   mp->sw_if_index = ntohl (sw_if_index);
11465   mp->is_add = is_add;
11466
11467   S;
11468   W;
11469   /* NOTREACHED */
11470   return 0;
11471 #else
11472   clib_warning ("unsupported (no dpdk)");
11473   return -99;
11474 #endif
11475 }
11476
11477 static int
11478 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11479 {
11480 #if DPDK > 0
11481   unformat_input_t *i = vam->input;
11482   vl_api_ipsec_spd_add_del_entry_t *mp;
11483   f64 timeout;
11484   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11485   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11486   i32 priority = 0;
11487   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11488   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11489   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11490   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11491
11492   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11493   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11494   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11495   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11496   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11497   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11498
11499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11500     {
11501       if (unformat (i, "del"))
11502         is_add = 0;
11503       if (unformat (i, "outbound"))
11504         is_outbound = 1;
11505       if (unformat (i, "inbound"))
11506         is_outbound = 0;
11507       else if (unformat (i, "spd_id %d", &spd_id))
11508         ;
11509       else if (unformat (i, "sa_id %d", &sa_id))
11510         ;
11511       else if (unformat (i, "priority %d", &priority))
11512         ;
11513       else if (unformat (i, "protocol %d", &protocol))
11514         ;
11515       else if (unformat (i, "lport_start %d", &lport_start))
11516         ;
11517       else if (unformat (i, "lport_stop %d", &lport_stop))
11518         ;
11519       else if (unformat (i, "rport_start %d", &rport_start))
11520         ;
11521       else if (unformat (i, "rport_stop %d", &rport_stop))
11522         ;
11523       else
11524         if (unformat
11525             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11526         {
11527           is_ipv6 = 0;
11528           is_ip_any = 0;
11529         }
11530       else
11531         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11532         {
11533           is_ipv6 = 0;
11534           is_ip_any = 0;
11535         }
11536       else
11537         if (unformat
11538             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11539         {
11540           is_ipv6 = 0;
11541           is_ip_any = 0;
11542         }
11543       else
11544         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11545         {
11546           is_ipv6 = 0;
11547           is_ip_any = 0;
11548         }
11549       else
11550         if (unformat
11551             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11552         {
11553           is_ipv6 = 1;
11554           is_ip_any = 0;
11555         }
11556       else
11557         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11558         {
11559           is_ipv6 = 1;
11560           is_ip_any = 0;
11561         }
11562       else
11563         if (unformat
11564             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11565         {
11566           is_ipv6 = 1;
11567           is_ip_any = 0;
11568         }
11569       else
11570         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11571         {
11572           is_ipv6 = 1;
11573           is_ip_any = 0;
11574         }
11575       else
11576         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11577         {
11578           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11579             {
11580               clib_warning ("unsupported action: 'resolve'");
11581               return -99;
11582             }
11583         }
11584       else
11585         {
11586           clib_warning ("parse error '%U'", format_unformat_error, i);
11587           return -99;
11588         }
11589
11590     }
11591
11592   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11593
11594   mp->spd_id = ntohl (spd_id);
11595   mp->priority = ntohl (priority);
11596   mp->is_outbound = is_outbound;
11597
11598   mp->is_ipv6 = is_ipv6;
11599   if (is_ipv6 || is_ip_any)
11600     {
11601       clib_memcpy (mp->remote_address_start, &raddr6_start,
11602                    sizeof (ip6_address_t));
11603       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11604                    sizeof (ip6_address_t));
11605       clib_memcpy (mp->local_address_start, &laddr6_start,
11606                    sizeof (ip6_address_t));
11607       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11608                    sizeof (ip6_address_t));
11609     }
11610   else
11611     {
11612       clib_memcpy (mp->remote_address_start, &raddr4_start,
11613                    sizeof (ip4_address_t));
11614       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11615                    sizeof (ip4_address_t));
11616       clib_memcpy (mp->local_address_start, &laddr4_start,
11617                    sizeof (ip4_address_t));
11618       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11619                    sizeof (ip4_address_t));
11620     }
11621   mp->protocol = (u8) protocol;
11622   mp->local_port_start = ntohs ((u16) lport_start);
11623   mp->local_port_stop = ntohs ((u16) lport_stop);
11624   mp->remote_port_start = ntohs ((u16) rport_start);
11625   mp->remote_port_stop = ntohs ((u16) rport_stop);
11626   mp->policy = (u8) policy;
11627   mp->sa_id = ntohl (sa_id);
11628   mp->is_add = is_add;
11629   mp->is_ip_any = is_ip_any;
11630   S;
11631   W;
11632   /* NOTREACHED */
11633   return 0;
11634 #else
11635   clib_warning ("unsupported (no dpdk)");
11636   return -99;
11637 #endif
11638 }
11639
11640 static int
11641 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11642 {
11643 #if DPDK > 0
11644   unformat_input_t *i = vam->input;
11645   vl_api_ipsec_sad_add_del_entry_t *mp;
11646   f64 timeout;
11647   u32 sad_id = 0, spi = 0;
11648   u8 *ck = 0, *ik = 0;
11649   u8 is_add = 1;
11650
11651   u8 protocol = IPSEC_PROTOCOL_AH;
11652   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11653   u32 crypto_alg = 0, integ_alg = 0;
11654   ip4_address_t tun_src4;
11655   ip4_address_t tun_dst4;
11656   ip6_address_t tun_src6;
11657   ip6_address_t tun_dst6;
11658
11659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11660     {
11661       if (unformat (i, "del"))
11662         is_add = 0;
11663       else if (unformat (i, "sad_id %d", &sad_id))
11664         ;
11665       else if (unformat (i, "spi %d", &spi))
11666         ;
11667       else if (unformat (i, "esp"))
11668         protocol = IPSEC_PROTOCOL_ESP;
11669       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11670         {
11671           is_tunnel = 1;
11672           is_tunnel_ipv6 = 0;
11673         }
11674       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11675         {
11676           is_tunnel = 1;
11677           is_tunnel_ipv6 = 0;
11678         }
11679       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11680         {
11681           is_tunnel = 1;
11682           is_tunnel_ipv6 = 1;
11683         }
11684       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11685         {
11686           is_tunnel = 1;
11687           is_tunnel_ipv6 = 1;
11688         }
11689       else
11690         if (unformat
11691             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11692         {
11693           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11694               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11695             {
11696               clib_warning ("unsupported crypto-alg: '%U'",
11697                             format_ipsec_crypto_alg, crypto_alg);
11698               return -99;
11699             }
11700         }
11701       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11702         ;
11703       else
11704         if (unformat
11705             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11706         {
11707           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11708               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11709             {
11710               clib_warning ("unsupported integ-alg: '%U'",
11711                             format_ipsec_integ_alg, integ_alg);
11712               return -99;
11713             }
11714         }
11715       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11716         ;
11717       else
11718         {
11719           clib_warning ("parse error '%U'", format_unformat_error, i);
11720           return -99;
11721         }
11722
11723     }
11724
11725   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11726
11727   mp->sad_id = ntohl (sad_id);
11728   mp->is_add = is_add;
11729   mp->protocol = protocol;
11730   mp->spi = ntohl (spi);
11731   mp->is_tunnel = is_tunnel;
11732   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11733   mp->crypto_algorithm = crypto_alg;
11734   mp->integrity_algorithm = integ_alg;
11735   mp->crypto_key_length = vec_len (ck);
11736   mp->integrity_key_length = vec_len (ik);
11737
11738   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11739     mp->crypto_key_length = sizeof (mp->crypto_key);
11740
11741   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11742     mp->integrity_key_length = sizeof (mp->integrity_key);
11743
11744   if (ck)
11745     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11746   if (ik)
11747     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11748
11749   if (is_tunnel)
11750     {
11751       if (is_tunnel_ipv6)
11752         {
11753           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11754                        sizeof (ip6_address_t));
11755           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11756                        sizeof (ip6_address_t));
11757         }
11758       else
11759         {
11760           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11761                        sizeof (ip4_address_t));
11762           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11763                        sizeof (ip4_address_t));
11764         }
11765     }
11766
11767   S;
11768   W;
11769   /* NOTREACHED */
11770   return 0;
11771 #else
11772   clib_warning ("unsupported (no dpdk)");
11773   return -99;
11774 #endif
11775 }
11776
11777 static int
11778 api_ipsec_sa_set_key (vat_main_t * vam)
11779 {
11780 #if DPDK > 0
11781   unformat_input_t *i = vam->input;
11782   vl_api_ipsec_sa_set_key_t *mp;
11783   f64 timeout;
11784   u32 sa_id;
11785   u8 *ck = 0, *ik = 0;
11786
11787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11788     {
11789       if (unformat (i, "sa_id %d", &sa_id))
11790         ;
11791       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11792         ;
11793       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11794         ;
11795       else
11796         {
11797           clib_warning ("parse error '%U'", format_unformat_error, i);
11798           return -99;
11799         }
11800     }
11801
11802   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11803
11804   mp->sa_id = ntohl (sa_id);
11805   mp->crypto_key_length = vec_len (ck);
11806   mp->integrity_key_length = vec_len (ik);
11807
11808   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11809     mp->crypto_key_length = sizeof (mp->crypto_key);
11810
11811   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11812     mp->integrity_key_length = sizeof (mp->integrity_key);
11813
11814   if (ck)
11815     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11816   if (ik)
11817     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11818
11819   S;
11820   W;
11821   /* NOTREACHED */
11822   return 0;
11823 #else
11824   clib_warning ("unsupported (no dpdk)");
11825   return -99;
11826 #endif
11827 }
11828
11829 static int
11830 api_ikev2_profile_add_del (vat_main_t * vam)
11831 {
11832 #if DPDK > 0
11833   unformat_input_t *i = vam->input;
11834   vl_api_ikev2_profile_add_del_t *mp;
11835   f64 timeout;
11836   u8 is_add = 1;
11837   u8 *name = 0;
11838
11839   const char *valid_chars = "a-zA-Z0-9_";
11840
11841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11842     {
11843       if (unformat (i, "del"))
11844         is_add = 0;
11845       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11846         vec_add1 (name, 0);
11847       else
11848         {
11849           errmsg ("parse error '%U'", format_unformat_error, i);
11850           return -99;
11851         }
11852     }
11853
11854   if (!vec_len (name))
11855     {
11856       errmsg ("profile name must be specified");
11857       return -99;
11858     }
11859
11860   if (vec_len (name) > 64)
11861     {
11862       errmsg ("profile name too long");
11863       return -99;
11864     }
11865
11866   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11867
11868   clib_memcpy (mp->name, name, vec_len (name));
11869   mp->is_add = is_add;
11870   vec_free (name);
11871
11872   S;
11873   W;
11874   /* NOTREACHED */
11875   return 0;
11876 #else
11877   clib_warning ("unsupported (no dpdk)");
11878   return -99;
11879 #endif
11880 }
11881
11882 static int
11883 api_ikev2_profile_set_auth (vat_main_t * vam)
11884 {
11885 #if DPDK > 0
11886   unformat_input_t *i = vam->input;
11887   vl_api_ikev2_profile_set_auth_t *mp;
11888   f64 timeout;
11889   u8 *name = 0;
11890   u8 *data = 0;
11891   u32 auth_method = 0;
11892   u8 is_hex = 0;
11893
11894   const char *valid_chars = "a-zA-Z0-9_";
11895
11896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11897     {
11898       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11899         vec_add1 (name, 0);
11900       else if (unformat (i, "auth_method %U",
11901                          unformat_ikev2_auth_method, &auth_method))
11902         ;
11903       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11904         is_hex = 1;
11905       else if (unformat (i, "auth_data %v", &data))
11906         ;
11907       else
11908         {
11909           errmsg ("parse error '%U'", format_unformat_error, i);
11910           return -99;
11911         }
11912     }
11913
11914   if (!vec_len (name))
11915     {
11916       errmsg ("profile name must be specified");
11917       return -99;
11918     }
11919
11920   if (vec_len (name) > 64)
11921     {
11922       errmsg ("profile name too long");
11923       return -99;
11924     }
11925
11926   if (!vec_len (data))
11927     {
11928       errmsg ("auth_data must be specified");
11929       return -99;
11930     }
11931
11932   if (!auth_method)
11933     {
11934       errmsg ("auth_method must be specified");
11935       return -99;
11936     }
11937
11938   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11939
11940   mp->is_hex = is_hex;
11941   mp->auth_method = (u8) auth_method;
11942   mp->data_len = vec_len (data);
11943   clib_memcpy (mp->name, name, vec_len (name));
11944   clib_memcpy (mp->data, data, vec_len (data));
11945   vec_free (name);
11946   vec_free (data);
11947
11948   S;
11949   W;
11950   /* NOTREACHED */
11951   return 0;
11952 #else
11953   clib_warning ("unsupported (no dpdk)");
11954   return -99;
11955 #endif
11956 }
11957
11958 static int
11959 api_ikev2_profile_set_id (vat_main_t * vam)
11960 {
11961 #if DPDK > 0
11962   unformat_input_t *i = vam->input;
11963   vl_api_ikev2_profile_set_id_t *mp;
11964   f64 timeout;
11965   u8 *name = 0;
11966   u8 *data = 0;
11967   u8 is_local = 0;
11968   u32 id_type = 0;
11969   ip4_address_t ip4;
11970
11971   const char *valid_chars = "a-zA-Z0-9_";
11972
11973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11974     {
11975       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11976         vec_add1 (name, 0);
11977       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11978         ;
11979       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11980         {
11981           data = vec_new (u8, 4);
11982           clib_memcpy (data, ip4.as_u8, 4);
11983         }
11984       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11985         ;
11986       else if (unformat (i, "id_data %v", &data))
11987         ;
11988       else if (unformat (i, "local"))
11989         is_local = 1;
11990       else if (unformat (i, "remote"))
11991         is_local = 0;
11992       else
11993         {
11994           errmsg ("parse error '%U'", format_unformat_error, i);
11995           return -99;
11996         }
11997     }
11998
11999   if (!vec_len (name))
12000     {
12001       errmsg ("profile name must be specified");
12002       return -99;
12003     }
12004
12005   if (vec_len (name) > 64)
12006     {
12007       errmsg ("profile name too long");
12008       return -99;
12009     }
12010
12011   if (!vec_len (data))
12012     {
12013       errmsg ("id_data must be specified");
12014       return -99;
12015     }
12016
12017   if (!id_type)
12018     {
12019       errmsg ("id_type must be specified");
12020       return -99;
12021     }
12022
12023   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12024
12025   mp->is_local = is_local;
12026   mp->id_type = (u8) id_type;
12027   mp->data_len = vec_len (data);
12028   clib_memcpy (mp->name, name, vec_len (name));
12029   clib_memcpy (mp->data, data, vec_len (data));
12030   vec_free (name);
12031   vec_free (data);
12032
12033   S;
12034   W;
12035   /* NOTREACHED */
12036   return 0;
12037 #else
12038   clib_warning ("unsupported (no dpdk)");
12039   return -99;
12040 #endif
12041 }
12042
12043 static int
12044 api_ikev2_profile_set_ts (vat_main_t * vam)
12045 {
12046 #if DPDK > 0
12047   unformat_input_t *i = vam->input;
12048   vl_api_ikev2_profile_set_ts_t *mp;
12049   f64 timeout;
12050   u8 *name = 0;
12051   u8 is_local = 0;
12052   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12053   ip4_address_t start_addr, end_addr;
12054
12055   const char *valid_chars = "a-zA-Z0-9_";
12056
12057   start_addr.as_u32 = 0;
12058   end_addr.as_u32 = (u32) ~ 0;
12059
12060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12061     {
12062       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12063         vec_add1 (name, 0);
12064       else if (unformat (i, "protocol %d", &proto))
12065         ;
12066       else if (unformat (i, "start_port %d", &start_port))
12067         ;
12068       else if (unformat (i, "end_port %d", &end_port))
12069         ;
12070       else
12071         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12072         ;
12073       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12074         ;
12075       else if (unformat (i, "local"))
12076         is_local = 1;
12077       else if (unformat (i, "remote"))
12078         is_local = 0;
12079       else
12080         {
12081           errmsg ("parse error '%U'", format_unformat_error, i);
12082           return -99;
12083         }
12084     }
12085
12086   if (!vec_len (name))
12087     {
12088       errmsg ("profile name must be specified");
12089       return -99;
12090     }
12091
12092   if (vec_len (name) > 64)
12093     {
12094       errmsg ("profile name too long");
12095       return -99;
12096     }
12097
12098   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12099
12100   mp->is_local = is_local;
12101   mp->proto = (u8) proto;
12102   mp->start_port = (u16) start_port;
12103   mp->end_port = (u16) end_port;
12104   mp->start_addr = start_addr.as_u32;
12105   mp->end_addr = end_addr.as_u32;
12106   clib_memcpy (mp->name, name, vec_len (name));
12107   vec_free (name);
12108
12109   S;
12110   W;
12111   /* NOTREACHED */
12112   return 0;
12113 #else
12114   clib_warning ("unsupported (no dpdk)");
12115   return -99;
12116 #endif
12117 }
12118
12119 static int
12120 api_ikev2_set_local_key (vat_main_t * vam)
12121 {
12122 #if DPDK > 0
12123   unformat_input_t *i = vam->input;
12124   vl_api_ikev2_set_local_key_t *mp;
12125   f64 timeout;
12126   u8 *file = 0;
12127
12128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12129     {
12130       if (unformat (i, "file %v", &file))
12131         vec_add1 (file, 0);
12132       else
12133         {
12134           errmsg ("parse error '%U'", format_unformat_error, i);
12135           return -99;
12136         }
12137     }
12138
12139   if (!vec_len (file))
12140     {
12141       errmsg ("RSA key file must be specified");
12142       return -99;
12143     }
12144
12145   if (vec_len (file) > 256)
12146     {
12147       errmsg ("file name too long");
12148       return -99;
12149     }
12150
12151   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12152
12153   clib_memcpy (mp->key_file, file, vec_len (file));
12154   vec_free (file);
12155
12156   S;
12157   W;
12158   /* NOTREACHED */
12159   return 0;
12160 #else
12161   clib_warning ("unsupported (no dpdk)");
12162   return -99;
12163 #endif
12164 }
12165
12166 /*
12167  * MAP
12168  */
12169 static int
12170 api_map_add_domain (vat_main_t * vam)
12171 {
12172   unformat_input_t *i = vam->input;
12173   vl_api_map_add_domain_t *mp;
12174   f64 timeout;
12175
12176   ip4_address_t ip4_prefix;
12177   ip6_address_t ip6_prefix;
12178   ip6_address_t ip6_src;
12179   u32 num_m_args = 0;
12180   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12181     0, psid_length = 0;
12182   u8 is_translation = 0;
12183   u32 mtu = 0;
12184   u32 ip6_src_len = 128;
12185
12186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12187     {
12188       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12189                     &ip4_prefix, &ip4_prefix_len))
12190         num_m_args++;
12191       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12192                          &ip6_prefix, &ip6_prefix_len))
12193         num_m_args++;
12194       else
12195         if (unformat
12196             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12197              &ip6_src_len))
12198         num_m_args++;
12199       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12200         num_m_args++;
12201       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12202         num_m_args++;
12203       else if (unformat (i, "psid-offset %d", &psid_offset))
12204         num_m_args++;
12205       else if (unformat (i, "psid-len %d", &psid_length))
12206         num_m_args++;
12207       else if (unformat (i, "mtu %d", &mtu))
12208         num_m_args++;
12209       else if (unformat (i, "map-t"))
12210         is_translation = 1;
12211       else
12212         {
12213           clib_warning ("parse error '%U'", format_unformat_error, i);
12214           return -99;
12215         }
12216     }
12217
12218   if (num_m_args < 3)
12219     {
12220       errmsg ("mandatory argument(s) missing\n");
12221       return -99;
12222     }
12223
12224   /* Construct the API message */
12225   M (MAP_ADD_DOMAIN, map_add_domain);
12226
12227   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12228   mp->ip4_prefix_len = ip4_prefix_len;
12229
12230   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12231   mp->ip6_prefix_len = ip6_prefix_len;
12232
12233   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12234   mp->ip6_src_prefix_len = ip6_src_len;
12235
12236   mp->ea_bits_len = ea_bits_len;
12237   mp->psid_offset = psid_offset;
12238   mp->psid_length = psid_length;
12239   mp->is_translation = is_translation;
12240   mp->mtu = htons (mtu);
12241
12242   /* send it... */
12243   S;
12244
12245   /* Wait for a reply, return good/bad news  */
12246   W;
12247 }
12248
12249 static int
12250 api_map_del_domain (vat_main_t * vam)
12251 {
12252   unformat_input_t *i = vam->input;
12253   vl_api_map_del_domain_t *mp;
12254   f64 timeout;
12255
12256   u32 num_m_args = 0;
12257   u32 index;
12258
12259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12260     {
12261       if (unformat (i, "index %d", &index))
12262         num_m_args++;
12263       else
12264         {
12265           clib_warning ("parse error '%U'", format_unformat_error, i);
12266           return -99;
12267         }
12268     }
12269
12270   if (num_m_args != 1)
12271     {
12272       errmsg ("mandatory argument(s) missing\n");
12273       return -99;
12274     }
12275
12276   /* Construct the API message */
12277   M (MAP_DEL_DOMAIN, map_del_domain);
12278
12279   mp->index = ntohl (index);
12280
12281   /* send it... */
12282   S;
12283
12284   /* Wait for a reply, return good/bad news  */
12285   W;
12286 }
12287
12288 static int
12289 api_map_add_del_rule (vat_main_t * vam)
12290 {
12291   unformat_input_t *i = vam->input;
12292   vl_api_map_add_del_rule_t *mp;
12293   f64 timeout;
12294   u8 is_add = 1;
12295   ip6_address_t ip6_dst;
12296   u32 num_m_args = 0, index, psid = 0;
12297
12298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12299     {
12300       if (unformat (i, "index %d", &index))
12301         num_m_args++;
12302       else if (unformat (i, "psid %d", &psid))
12303         num_m_args++;
12304       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12305         num_m_args++;
12306       else if (unformat (i, "del"))
12307         {
12308           is_add = 0;
12309         }
12310       else
12311         {
12312           clib_warning ("parse error '%U'", format_unformat_error, i);
12313           return -99;
12314         }
12315     }
12316
12317   /* Construct the API message */
12318   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12319
12320   mp->index = ntohl (index);
12321   mp->is_add = is_add;
12322   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12323   mp->psid = ntohs (psid);
12324
12325   /* send it... */
12326   S;
12327
12328   /* Wait for a reply, return good/bad news  */
12329   W;
12330 }
12331
12332 static int
12333 api_map_domain_dump (vat_main_t * vam)
12334 {
12335   vl_api_map_domain_dump_t *mp;
12336   f64 timeout;
12337
12338   /* Construct the API message */
12339   M (MAP_DOMAIN_DUMP, map_domain_dump);
12340
12341   /* send it... */
12342   S;
12343
12344   /* Use a control ping for synchronization */
12345   {
12346     vl_api_control_ping_t *mp;
12347     M (CONTROL_PING, control_ping);
12348     S;
12349   }
12350   W;
12351 }
12352
12353 static int
12354 api_map_rule_dump (vat_main_t * vam)
12355 {
12356   unformat_input_t *i = vam->input;
12357   vl_api_map_rule_dump_t *mp;
12358   f64 timeout;
12359   u32 domain_index = ~0;
12360
12361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12362     {
12363       if (unformat (i, "index %u", &domain_index))
12364         ;
12365       else
12366         break;
12367     }
12368
12369   if (domain_index == ~0)
12370     {
12371       clib_warning ("parse error: domain index expected");
12372       return -99;
12373     }
12374
12375   /* Construct the API message */
12376   M (MAP_RULE_DUMP, map_rule_dump);
12377
12378   mp->domain_index = htonl (domain_index);
12379
12380   /* send it... */
12381   S;
12382
12383   /* Use a control ping for synchronization */
12384   {
12385     vl_api_control_ping_t *mp;
12386     M (CONTROL_PING, control_ping);
12387     S;
12388   }
12389   W;
12390 }
12391
12392 static void vl_api_map_add_domain_reply_t_handler
12393   (vl_api_map_add_domain_reply_t * mp)
12394 {
12395   vat_main_t *vam = &vat_main;
12396   i32 retval = ntohl (mp->retval);
12397
12398   if (vam->async_mode)
12399     {
12400       vam->async_errors += (retval < 0);
12401     }
12402   else
12403     {
12404       vam->retval = retval;
12405       vam->result_ready = 1;
12406     }
12407 }
12408
12409 static void vl_api_map_add_domain_reply_t_handler_json
12410   (vl_api_map_add_domain_reply_t * mp)
12411 {
12412   vat_main_t *vam = &vat_main;
12413   vat_json_node_t node;
12414
12415   vat_json_init_object (&node);
12416   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12417   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12418
12419   vat_json_print (vam->ofp, &node);
12420   vat_json_free (&node);
12421
12422   vam->retval = ntohl (mp->retval);
12423   vam->result_ready = 1;
12424 }
12425
12426 static int
12427 api_get_first_msg_id (vat_main_t * vam)
12428 {
12429   vl_api_get_first_msg_id_t *mp;
12430   f64 timeout;
12431   unformat_input_t *i = vam->input;
12432   u8 *name;
12433   u8 name_set = 0;
12434
12435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12436     {
12437       if (unformat (i, "client %s", &name))
12438         name_set = 1;
12439       else
12440         break;
12441     }
12442
12443   if (name_set == 0)
12444     {
12445       errmsg ("missing client name\n");
12446       return -99;
12447     }
12448   vec_add1 (name, 0);
12449
12450   if (vec_len (name) > 63)
12451     {
12452       errmsg ("client name too long\n");
12453       return -99;
12454     }
12455
12456   M (GET_FIRST_MSG_ID, get_first_msg_id);
12457   clib_memcpy (mp->name, name, vec_len (name));
12458   S;
12459   W;
12460   /* NOTREACHED */
12461   return 0;
12462 }
12463
12464 static int
12465 api_cop_interface_enable_disable (vat_main_t * vam)
12466 {
12467   unformat_input_t *line_input = vam->input;
12468   vl_api_cop_interface_enable_disable_t *mp;
12469   f64 timeout;
12470   u32 sw_if_index = ~0;
12471   u8 enable_disable = 1;
12472
12473   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12474     {
12475       if (unformat (line_input, "disable"))
12476         enable_disable = 0;
12477       if (unformat (line_input, "enable"))
12478         enable_disable = 1;
12479       else if (unformat (line_input, "%U", unformat_sw_if_index,
12480                          vam, &sw_if_index))
12481         ;
12482       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12483         ;
12484       else
12485         break;
12486     }
12487
12488   if (sw_if_index == ~0)
12489     {
12490       errmsg ("missing interface name or sw_if_index\n");
12491       return -99;
12492     }
12493
12494   /* Construct the API message */
12495   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12496   mp->sw_if_index = ntohl (sw_if_index);
12497   mp->enable_disable = enable_disable;
12498
12499   /* send it... */
12500   S;
12501   /* Wait for the reply */
12502   W;
12503 }
12504
12505 static int
12506 api_cop_whitelist_enable_disable (vat_main_t * vam)
12507 {
12508   unformat_input_t *line_input = vam->input;
12509   vl_api_cop_whitelist_enable_disable_t *mp;
12510   f64 timeout;
12511   u32 sw_if_index = ~0;
12512   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12513   u32 fib_id = 0;
12514
12515   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12516     {
12517       if (unformat (line_input, "ip4"))
12518         ip4 = 1;
12519       else if (unformat (line_input, "ip6"))
12520         ip6 = 1;
12521       else if (unformat (line_input, "default"))
12522         default_cop = 1;
12523       else if (unformat (line_input, "%U", unformat_sw_if_index,
12524                          vam, &sw_if_index))
12525         ;
12526       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12527         ;
12528       else if (unformat (line_input, "fib-id %d", &fib_id))
12529         ;
12530       else
12531         break;
12532     }
12533
12534   if (sw_if_index == ~0)
12535     {
12536       errmsg ("missing interface name or sw_if_index\n");
12537       return -99;
12538     }
12539
12540   /* Construct the API message */
12541   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12542   mp->sw_if_index = ntohl (sw_if_index);
12543   mp->fib_id = ntohl (fib_id);
12544   mp->ip4 = ip4;
12545   mp->ip6 = ip6;
12546   mp->default_cop = default_cop;
12547
12548   /* send it... */
12549   S;
12550   /* Wait for the reply */
12551   W;
12552 }
12553
12554 static int
12555 api_get_node_graph (vat_main_t * vam)
12556 {
12557   vl_api_get_node_graph_t *mp;
12558   f64 timeout;
12559
12560   M (GET_NODE_GRAPH, get_node_graph);
12561
12562   /* send it... */
12563   S;
12564   /* Wait for the reply */
12565   W;
12566 }
12567
12568 /* *INDENT-OFF* */
12569 /** Used for parsing LISP eids */
12570 typedef CLIB_PACKED(struct{
12571   u8 addr[16];   /**< eid address */
12572   u32 len;       /**< prefix length if IP */
12573   u8 type;      /**< type of eid */
12574 }) lisp_eid_vat_t;
12575 /* *INDENT-ON* */
12576
12577 static uword
12578 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12579 {
12580   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12581
12582   memset (a, 0, sizeof (a[0]));
12583
12584   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12585     {
12586       a->type = 0;              /* ipv4 type */
12587     }
12588   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12589     {
12590       a->type = 1;              /* ipv6 type */
12591     }
12592   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12593     {
12594       a->type = 2;              /* mac type */
12595     }
12596   else
12597     {
12598       return 0;
12599     }
12600
12601   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12602     {
12603       return 0;
12604     }
12605
12606   return 1;
12607 }
12608
12609 static int
12610 lisp_eid_size_vat (u8 type)
12611 {
12612   switch (type)
12613     {
12614     case 0:
12615       return 4;
12616     case 1:
12617       return 16;
12618     case 2:
12619       return 6;
12620     }
12621   return 0;
12622 }
12623
12624 static void
12625 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12626 {
12627   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12628 }
12629
12630 /* *INDENT-OFF* */
12631 /** Used for transferring locators via VPP API */
12632 typedef CLIB_PACKED(struct
12633 {
12634   u32 sw_if_index; /**< locator sw_if_index */
12635   u8 priority; /**< locator priority */
12636   u8 weight;   /**< locator weight */
12637 }) ls_locator_t;
12638 /* *INDENT-ON* */
12639
12640 static int
12641 api_lisp_add_del_locator_set (vat_main_t * vam)
12642 {
12643   unformat_input_t *input = vam->input;
12644   vl_api_lisp_add_del_locator_set_t *mp;
12645   f64 timeout = ~0;
12646   u8 is_add = 1;
12647   u8 *locator_set_name = NULL;
12648   u8 locator_set_name_set = 0;
12649   ls_locator_t locator, *locators = 0;
12650   u32 sw_if_index, priority, weight;
12651   u32 data_len = 0;
12652
12653   /* Parse args required to build the message */
12654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12655     {
12656       if (unformat (input, "del"))
12657         {
12658           is_add = 0;
12659         }
12660       else if (unformat (input, "locator-set %s", &locator_set_name))
12661         {
12662           locator_set_name_set = 1;
12663         }
12664       else if (unformat (input, "sw_if_index %u p %u w %u",
12665                          &sw_if_index, &priority, &weight))
12666         {
12667           locator.sw_if_index = htonl (sw_if_index);
12668           locator.priority = priority;
12669           locator.weight = weight;
12670           vec_add1 (locators, locator);
12671         }
12672       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12673                          vam, &sw_if_index, &priority, &weight))
12674         {
12675           locator.sw_if_index = htonl (sw_if_index);
12676           locator.priority = priority;
12677           locator.weight = weight;
12678           vec_add1 (locators, locator);
12679         }
12680       else
12681         break;
12682     }
12683
12684   if (locator_set_name_set == 0)
12685     {
12686       errmsg ("missing locator-set name");
12687       vec_free (locators);
12688       return -99;
12689     }
12690
12691   if (vec_len (locator_set_name) > 64)
12692     {
12693       errmsg ("locator-set name too long\n");
12694       vec_free (locator_set_name);
12695       vec_free (locators);
12696       return -99;
12697     }
12698   vec_add1 (locator_set_name, 0);
12699
12700   data_len = sizeof (ls_locator_t) * vec_len (locators);
12701
12702   /* Construct the API message */
12703   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12704
12705   mp->is_add = is_add;
12706   clib_memcpy (mp->locator_set_name, locator_set_name,
12707                vec_len (locator_set_name));
12708   vec_free (locator_set_name);
12709
12710   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12711   if (locators)
12712     clib_memcpy (mp->locators, locators, data_len);
12713   vec_free (locators);
12714
12715   /* send it... */
12716   S;
12717
12718   /* Wait for a reply... */
12719   W;
12720
12721   /* NOTREACHED */
12722   return 0;
12723 }
12724
12725 static int
12726 api_lisp_add_del_locator (vat_main_t * vam)
12727 {
12728   unformat_input_t *input = vam->input;
12729   vl_api_lisp_add_del_locator_t *mp;
12730   f64 timeout = ~0;
12731   u32 tmp_if_index = ~0;
12732   u32 sw_if_index = ~0;
12733   u8 sw_if_index_set = 0;
12734   u8 sw_if_index_if_name_set = 0;
12735   u32 priority = ~0;
12736   u8 priority_set = 0;
12737   u32 weight = ~0;
12738   u8 weight_set = 0;
12739   u8 is_add = 1;
12740   u8 *locator_set_name = NULL;
12741   u8 locator_set_name_set = 0;
12742
12743   /* Parse args required to build the message */
12744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12745     {
12746       if (unformat (input, "del"))
12747         {
12748           is_add = 0;
12749         }
12750       else if (unformat (input, "locator-set %s", &locator_set_name))
12751         {
12752           locator_set_name_set = 1;
12753         }
12754       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12755                          &tmp_if_index))
12756         {
12757           sw_if_index_if_name_set = 1;
12758           sw_if_index = tmp_if_index;
12759         }
12760       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12761         {
12762           sw_if_index_set = 1;
12763           sw_if_index = tmp_if_index;
12764         }
12765       else if (unformat (input, "p %d", &priority))
12766         {
12767           priority_set = 1;
12768         }
12769       else if (unformat (input, "w %d", &weight))
12770         {
12771           weight_set = 1;
12772         }
12773       else
12774         break;
12775     }
12776
12777   if (locator_set_name_set == 0)
12778     {
12779       errmsg ("missing locator-set name");
12780       return -99;
12781     }
12782
12783   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12784     {
12785       errmsg ("missing sw_if_index");
12786       vec_free (locator_set_name);
12787       return -99;
12788     }
12789
12790   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12791     {
12792       errmsg ("cannot use both params interface name and sw_if_index");
12793       vec_free (locator_set_name);
12794       return -99;
12795     }
12796
12797   if (priority_set == 0)
12798     {
12799       errmsg ("missing locator-set priority\n");
12800       vec_free (locator_set_name);
12801       return -99;
12802     }
12803
12804   if (weight_set == 0)
12805     {
12806       errmsg ("missing locator-set weight\n");
12807       vec_free (locator_set_name);
12808       return -99;
12809     }
12810
12811   if (vec_len (locator_set_name) > 64)
12812     {
12813       errmsg ("locator-set name too long\n");
12814       vec_free (locator_set_name);
12815       return -99;
12816     }
12817   vec_add1 (locator_set_name, 0);
12818
12819   /* Construct the API message */
12820   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12821
12822   mp->is_add = is_add;
12823   mp->sw_if_index = ntohl (sw_if_index);
12824   mp->priority = priority;
12825   mp->weight = weight;
12826   clib_memcpy (mp->locator_set_name, locator_set_name,
12827                vec_len (locator_set_name));
12828   vec_free (locator_set_name);
12829
12830   /* send it... */
12831   S;
12832
12833   /* Wait for a reply... */
12834   W;
12835
12836   /* NOTREACHED */
12837   return 0;
12838 }
12839
12840 static int
12841 api_lisp_add_del_local_eid (vat_main_t * vam)
12842 {
12843   unformat_input_t *input = vam->input;
12844   vl_api_lisp_add_del_local_eid_t *mp;
12845   f64 timeout = ~0;
12846   u8 is_add = 1;
12847   u8 eid_set = 0;
12848   lisp_eid_vat_t _eid, *eid = &_eid;
12849   u8 *locator_set_name = 0;
12850   u8 locator_set_name_set = 0;
12851   u32 vni = 0;
12852
12853   /* Parse args required to build the message */
12854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12855     {
12856       if (unformat (input, "del"))
12857         {
12858           is_add = 0;
12859         }
12860       else if (unformat (input, "vni %d", &vni))
12861         {
12862           ;
12863         }
12864       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12865         {
12866           eid_set = 1;
12867         }
12868       else if (unformat (input, "locator-set %s", &locator_set_name))
12869         {
12870           locator_set_name_set = 1;
12871         }
12872       else
12873         break;
12874     }
12875
12876   if (locator_set_name_set == 0)
12877     {
12878       errmsg ("missing locator-set name\n");
12879       return -99;
12880     }
12881
12882   if (0 == eid_set)
12883     {
12884       errmsg ("EID address not set!");
12885       vec_free (locator_set_name);
12886       return -99;
12887     }
12888
12889   if (vec_len (locator_set_name) > 64)
12890     {
12891       errmsg ("locator-set name too long\n");
12892       vec_free (locator_set_name);
12893       return -99;
12894     }
12895   vec_add1 (locator_set_name, 0);
12896
12897   /* Construct the API message */
12898   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12899
12900   mp->is_add = is_add;
12901   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12902   mp->eid_type = eid->type;
12903   mp->prefix_len = eid->len;
12904   mp->vni = clib_host_to_net_u32 (vni);
12905   clib_memcpy (mp->locator_set_name, locator_set_name,
12906                vec_len (locator_set_name));
12907
12908   vec_free (locator_set_name);
12909
12910   /* send it... */
12911   S;
12912
12913   /* Wait for a reply... */
12914   W;
12915
12916   /* NOTREACHED */
12917   return 0;
12918 }
12919
12920 /* *INDENT-OFF* */
12921 /** Used for transferring locators via VPP API */
12922 typedef CLIB_PACKED(struct
12923 {
12924   u8 is_ip4; /**< is locator an IPv4 address? */
12925   u8 priority; /**< locator priority */
12926   u8 weight;   /**< locator weight */
12927   u8 addr[16]; /**< IPv4/IPv6 address */
12928 }) rloc_t;
12929 /* *INDENT-ON* */
12930
12931 static int
12932 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12933 {
12934   unformat_input_t *input = vam->input;
12935   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12936   f64 timeout = ~0;
12937   u8 is_add = 1;
12938   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12939   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12940   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12941   u32 action = ~0, p, w;
12942   ip4_address_t rmt_rloc4, lcl_rloc4;
12943   ip6_address_t rmt_rloc6, lcl_rloc6;
12944   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12945
12946   memset (&rloc, 0, sizeof (rloc));
12947
12948   /* Parse args required to build the message */
12949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12950     {
12951       if (unformat (input, "del"))
12952         {
12953           is_add = 0;
12954         }
12955       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12956         {
12957           rmt_eid_set = 1;
12958         }
12959       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12960         {
12961           lcl_eid_set = 1;
12962         }
12963       else if (unformat (input, "p %d w %d", &p, &w))
12964         {
12965           if (!curr_rloc)
12966             {
12967               errmsg ("No RLOC configured for setting priority/weight!");
12968               return -99;
12969             }
12970           curr_rloc->priority = p;
12971           curr_rloc->weight = w;
12972         }
12973       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12974                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12975         {
12976           rloc.is_ip4 = 1;
12977
12978           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12979           rloc.priority = rloc.weight = 0;
12980           vec_add1 (lcl_locs, rloc);
12981
12982           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12983           vec_add1 (rmt_locs, rloc);
12984           /* priority and weight saved in rmt loc */
12985           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12986         }
12987       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12988                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12989         {
12990           rloc.is_ip4 = 0;
12991           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12992           rloc.priority = rloc.weight = 0;
12993           vec_add1 (lcl_locs, rloc);
12994
12995           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12996           vec_add1 (rmt_locs, rloc);
12997           /* priority and weight saved in rmt loc */
12998           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12999         }
13000       else if (unformat (input, "action %d", &action))
13001         {
13002           ;
13003         }
13004       else
13005         {
13006           clib_warning ("parse error '%U'", format_unformat_error, input);
13007           return -99;
13008         }
13009     }
13010
13011   if (!rmt_eid_set)
13012     {
13013       errmsg ("remote eid addresses not set\n");
13014       return -99;
13015     }
13016
13017   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13018     {
13019       errmsg ("eid types don't match\n");
13020       return -99;
13021     }
13022
13023   if (0 == rmt_locs && (u32) ~ 0 == action)
13024     {
13025       errmsg ("action not set for negative mapping\n");
13026       return -99;
13027     }
13028
13029   /* Construct the API message */
13030   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13031
13032   mp->is_add = is_add;
13033   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13034   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13035   mp->eid_type = rmt_eid->type;
13036   mp->rmt_len = rmt_eid->len;
13037   mp->lcl_len = lcl_eid->len;
13038   mp->action = action;
13039
13040   if (0 != rmt_locs && 0 != lcl_locs)
13041     {
13042       mp->loc_num = vec_len (rmt_locs);
13043       clib_memcpy (mp->lcl_locs, lcl_locs,
13044                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13045       clib_memcpy (mp->rmt_locs, rmt_locs,
13046                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13047     }
13048   vec_free (lcl_locs);
13049   vec_free (rmt_locs);
13050
13051   /* send it... */
13052   S;
13053
13054   /* Wait for a reply... */
13055   W;
13056
13057   /* NOTREACHED */
13058   return 0;
13059 }
13060
13061 static int
13062 api_lisp_add_del_map_resolver (vat_main_t * vam)
13063 {
13064   unformat_input_t *input = vam->input;
13065   vl_api_lisp_add_del_map_resolver_t *mp;
13066   f64 timeout = ~0;
13067   u8 is_add = 1;
13068   u8 ipv4_set = 0;
13069   u8 ipv6_set = 0;
13070   ip4_address_t ipv4;
13071   ip6_address_t ipv6;
13072
13073   /* Parse args required to build the message */
13074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13075     {
13076       if (unformat (input, "del"))
13077         {
13078           is_add = 0;
13079         }
13080       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13081         {
13082           ipv4_set = 1;
13083         }
13084       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13085         {
13086           ipv6_set = 1;
13087         }
13088       else
13089         break;
13090     }
13091
13092   if (ipv4_set && ipv6_set)
13093     {
13094       errmsg ("both eid v4 and v6 addresses set\n");
13095       return -99;
13096     }
13097
13098   if (!ipv4_set && !ipv6_set)
13099     {
13100       errmsg ("eid addresses not set\n");
13101       return -99;
13102     }
13103
13104   /* Construct the API message */
13105   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13106
13107   mp->is_add = is_add;
13108   if (ipv6_set)
13109     {
13110       mp->is_ipv6 = 1;
13111       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13112     }
13113   else
13114     {
13115       mp->is_ipv6 = 0;
13116       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13117     }
13118
13119   /* send it... */
13120   S;
13121
13122   /* Wait for a reply... */
13123   W;
13124
13125   /* NOTREACHED */
13126   return 0;
13127 }
13128
13129 static int
13130 api_lisp_gpe_enable_disable (vat_main_t * vam)
13131 {
13132   unformat_input_t *input = vam->input;
13133   vl_api_lisp_gpe_enable_disable_t *mp;
13134   f64 timeout = ~0;
13135   u8 is_set = 0;
13136   u8 is_en = 1;
13137
13138   /* Parse args required to build the message */
13139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13140     {
13141       if (unformat (input, "enable"))
13142         {
13143           is_set = 1;
13144           is_en = 1;
13145         }
13146       else if (unformat (input, "disable"))
13147         {
13148           is_set = 1;
13149           is_en = 0;
13150         }
13151       else
13152         break;
13153     }
13154
13155   if (is_set == 0)
13156     {
13157       errmsg ("Value not set\n");
13158       return -99;
13159     }
13160
13161   /* Construct the API message */
13162   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13163
13164   mp->is_en = is_en;
13165
13166   /* send it... */
13167   S;
13168
13169   /* Wait for a reply... */
13170   W;
13171
13172   /* NOTREACHED */
13173   return 0;
13174 }
13175
13176 static int
13177 api_lisp_enable_disable (vat_main_t * vam)
13178 {
13179   unformat_input_t *input = vam->input;
13180   vl_api_lisp_enable_disable_t *mp;
13181   f64 timeout = ~0;
13182   u8 is_set = 0;
13183   u8 is_en = 0;
13184
13185   /* Parse args required to build the message */
13186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13187     {
13188       if (unformat (input, "enable"))
13189         {
13190           is_set = 1;
13191           is_en = 1;
13192         }
13193       else if (unformat (input, "disable"))
13194         {
13195           is_set = 1;
13196         }
13197       else
13198         break;
13199     }
13200
13201   if (!is_set)
13202     {
13203       errmsg ("Value not set\n");
13204       return -99;
13205     }
13206
13207   /* Construct the API message */
13208   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13209
13210   mp->is_en = is_en;
13211
13212   /* send it... */
13213   S;
13214
13215   /* Wait for a reply... */
13216   W;
13217
13218   /* NOTREACHED */
13219   return 0;
13220 }
13221
13222 static int
13223 api_show_lisp_map_request_mode (vat_main_t * vam)
13224 {
13225   f64 timeout = ~0;
13226   vl_api_show_lisp_map_request_mode_t *mp;
13227
13228   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13229
13230   /* send */
13231   S;
13232
13233   /* wait for reply */
13234   W;
13235
13236   return 0;
13237 }
13238
13239 static int
13240 api_lisp_map_request_mode (vat_main_t * vam)
13241 {
13242   f64 timeout = ~0;
13243   unformat_input_t *input = vam->input;
13244   vl_api_lisp_map_request_mode_t *mp;
13245   u8 mode = 0;
13246
13247   /* Parse args required to build the message */
13248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13249     {
13250       if (unformat (input, "dst-only"))
13251         mode = 0;
13252       else if (unformat (input, "src-dst"))
13253         mode = 1;
13254       else
13255         {
13256           errmsg ("parse error '%U'", format_unformat_error, input);
13257           return -99;
13258         }
13259     }
13260
13261   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13262
13263   mp->mode = mode;
13264
13265   /* send */
13266   S;
13267
13268   /* wait for reply */
13269   W;
13270
13271   /* notreached */
13272   return 0;
13273 }
13274
13275 /**
13276  * Enable/disable LISP proxy ITR.
13277  *
13278  * @param vam vpp API test context
13279  * @return return code
13280  */
13281 static int
13282 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13283 {
13284   f64 timeout = ~0;
13285   u8 ls_name_set = 0;
13286   unformat_input_t *input = vam->input;
13287   vl_api_lisp_pitr_set_locator_set_t *mp;
13288   u8 is_add = 1;
13289   u8 *ls_name = 0;
13290
13291   /* Parse args required to build the message */
13292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13293     {
13294       if (unformat (input, "del"))
13295         is_add = 0;
13296       else if (unformat (input, "locator-set %s", &ls_name))
13297         ls_name_set = 1;
13298       else
13299         {
13300           errmsg ("parse error '%U'", format_unformat_error, input);
13301           return -99;
13302         }
13303     }
13304
13305   if (!ls_name_set)
13306     {
13307       errmsg ("locator-set name not set!");
13308       return -99;
13309     }
13310
13311   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13312
13313   mp->is_add = is_add;
13314   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13315   vec_free (ls_name);
13316
13317   /* send */
13318   S;
13319
13320   /* wait for reply */
13321   W;
13322
13323   /* notreached */
13324   return 0;
13325 }
13326
13327 static int
13328 api_show_lisp_pitr (vat_main_t * vam)
13329 {
13330   vl_api_show_lisp_pitr_t *mp;
13331   f64 timeout = ~0;
13332
13333   if (!vam->json_output)
13334     {
13335       fformat (vam->ofp, "%=20s\n", "lisp status:");
13336     }
13337
13338   M (SHOW_LISP_PITR, show_lisp_pitr);
13339   /* send it... */
13340   S;
13341
13342   /* Wait for a reply... */
13343   W;
13344
13345   /* NOTREACHED */
13346   return 0;
13347 }
13348
13349 /**
13350  * Add/delete mapping between vni and vrf
13351  */
13352 static int
13353 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13354 {
13355   f64 timeout = ~0;
13356   unformat_input_t *input = vam->input;
13357   vl_api_lisp_eid_table_add_del_map_t *mp;
13358   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13359   u32 vni, vrf, bd_index;
13360
13361   /* Parse args required to build the message */
13362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13363     {
13364       if (unformat (input, "del"))
13365         is_add = 0;
13366       else if (unformat (input, "vrf %d", &vrf))
13367         vrf_set = 1;
13368       else if (unformat (input, "bd_index %d", &bd_index))
13369         bd_index_set = 1;
13370       else if (unformat (input, "vni %d", &vni))
13371         vni_set = 1;
13372       else
13373         break;
13374     }
13375
13376   if (!vni_set || (!vrf_set && !bd_index_set))
13377     {
13378       errmsg ("missing arguments!");
13379       return -99;
13380     }
13381
13382   if (vrf_set && bd_index_set)
13383     {
13384       errmsg ("error: both vrf and bd entered!");
13385       return -99;
13386     }
13387
13388   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13389
13390   mp->is_add = is_add;
13391   mp->vni = htonl (vni);
13392   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13393   mp->is_l2 = bd_index_set;
13394
13395   /* send */
13396   S;
13397
13398   /* wait for reply */
13399   W;
13400
13401   /* notreached */
13402   return 0;
13403 }
13404
13405 uword
13406 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13407 {
13408   u32 *action = va_arg (*args, u32 *);
13409   u8 *s = 0;
13410
13411   if (unformat (input, "%s", &s))
13412     {
13413       if (!strcmp ((char *) s, "no-action"))
13414         action[0] = 0;
13415       else if (!strcmp ((char *) s, "natively-forward"))
13416         action[0] = 1;
13417       else if (!strcmp ((char *) s, "send-map-request"))
13418         action[0] = 2;
13419       else if (!strcmp ((char *) s, "drop"))
13420         action[0] = 3;
13421       else
13422         {
13423           clib_warning ("invalid action: '%s'", s);
13424           action[0] = 3;
13425         }
13426     }
13427   else
13428     return 0;
13429
13430   vec_free (s);
13431   return 1;
13432 }
13433
13434 /**
13435  * Add/del remote mapping to/from LISP control plane
13436  *
13437  * @param vam vpp API test context
13438  * @return return code
13439  */
13440 static int
13441 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13442 {
13443   unformat_input_t *input = vam->input;
13444   vl_api_lisp_add_del_remote_mapping_t *mp;
13445   f64 timeout = ~0;
13446   u32 vni = 0;
13447   lisp_eid_vat_t _eid, *eid = &_eid;
13448   lisp_eid_vat_t _seid, *seid = &_seid;
13449   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13450   u32 action = ~0, p, w, data_len;
13451   ip4_address_t rloc4;
13452   ip6_address_t rloc6;
13453   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13454
13455   memset (&rloc, 0, sizeof (rloc));
13456
13457   /* Parse args required to build the message */
13458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13459     {
13460       if (unformat (input, "del-all"))
13461         {
13462           del_all = 1;
13463         }
13464       else if (unformat (input, "del"))
13465         {
13466           is_add = 0;
13467         }
13468       else if (unformat (input, "add"))
13469         {
13470           is_add = 1;
13471         }
13472       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13473         {
13474           eid_set = 1;
13475         }
13476       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13477         {
13478           seid_set = 1;
13479         }
13480       else if (unformat (input, "vni %d", &vni))
13481         {
13482           ;
13483         }
13484       else if (unformat (input, "p %d w %d", &p, &w))
13485         {
13486           if (!curr_rloc)
13487             {
13488               errmsg ("No RLOC configured for setting priority/weight!");
13489               return -99;
13490             }
13491           curr_rloc->priority = p;
13492           curr_rloc->weight = w;
13493         }
13494       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13495         {
13496           rloc.is_ip4 = 1;
13497           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13498           vec_add1 (rlocs, rloc);
13499           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13500         }
13501       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13502         {
13503           rloc.is_ip4 = 0;
13504           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13505           vec_add1 (rlocs, rloc);
13506           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13507         }
13508       else if (unformat (input, "action %U",
13509                          unformat_negative_mapping_action, &action))
13510         {
13511           ;
13512         }
13513       else
13514         {
13515           clib_warning ("parse error '%U'", format_unformat_error, input);
13516           return -99;
13517         }
13518     }
13519
13520   if (0 == eid_set)
13521     {
13522       errmsg ("missing params!");
13523       return -99;
13524     }
13525
13526   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13527     {
13528       errmsg ("no action set for negative map-reply!");
13529       return -99;
13530     }
13531
13532   data_len = vec_len (rlocs) * sizeof (rloc_t);
13533
13534   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13535   mp->is_add = is_add;
13536   mp->vni = htonl (vni);
13537   mp->action = (u8) action;
13538   mp->is_src_dst = seid_set;
13539   mp->eid_len = eid->len;
13540   mp->seid_len = seid->len;
13541   mp->del_all = del_all;
13542   mp->eid_type = eid->type;
13543   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13544   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13545
13546   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13547   clib_memcpy (mp->rlocs, rlocs, data_len);
13548   vec_free (rlocs);
13549
13550   /* send it... */
13551   S;
13552
13553   /* Wait for a reply... */
13554   W;
13555
13556   /* NOTREACHED */
13557   return 0;
13558 }
13559
13560 /**
13561  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13562  * forwarding entries in data-plane accordingly.
13563  *
13564  * @param vam vpp API test context
13565  * @return return code
13566  */
13567 static int
13568 api_lisp_add_del_adjacency (vat_main_t * vam)
13569 {
13570   unformat_input_t *input = vam->input;
13571   vl_api_lisp_add_del_adjacency_t *mp;
13572   f64 timeout = ~0;
13573   u32 vni = 0;
13574   ip4_address_t leid4, reid4;
13575   ip6_address_t leid6, reid6;
13576   u8 reid_mac[6] = { 0 };
13577   u8 leid_mac[6] = { 0 };
13578   u8 reid_type, leid_type;
13579   u32 leid_len = 0, reid_len = 0, len;
13580   u8 is_add = 1;
13581
13582   leid_type = reid_type = (u8) ~ 0;
13583
13584   /* Parse args required to build the message */
13585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13586     {
13587       if (unformat (input, "del"))
13588         {
13589           is_add = 0;
13590         }
13591       else if (unformat (input, "add"))
13592         {
13593           is_add = 1;
13594         }
13595       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13596                          &reid4, &len))
13597         {
13598           reid_type = 0;        /* ipv4 */
13599           reid_len = len;
13600         }
13601       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13602                          &reid6, &len))
13603         {
13604           reid_type = 1;        /* ipv6 */
13605           reid_len = len;
13606         }
13607       else if (unformat (input, "reid %U", unformat_ethernet_address,
13608                          reid_mac))
13609         {
13610           reid_type = 2;        /* mac */
13611         }
13612       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13613                          &leid4, &len))
13614         {
13615           leid_type = 0;        /* ipv4 */
13616           leid_len = len;
13617         }
13618       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13619                          &leid6, &len))
13620         {
13621           leid_type = 1;        /* ipv6 */
13622           leid_len = len;
13623         }
13624       else if (unformat (input, "leid %U", unformat_ethernet_address,
13625                          leid_mac))
13626         {
13627           leid_type = 2;        /* mac */
13628         }
13629       else if (unformat (input, "vni %d", &vni))
13630         {
13631           ;
13632         }
13633       else
13634         {
13635           errmsg ("parse error '%U'", format_unformat_error, input);
13636           return -99;
13637         }
13638     }
13639
13640   if ((u8) ~ 0 == reid_type)
13641     {
13642       errmsg ("missing params!");
13643       return -99;
13644     }
13645
13646   if (leid_type != reid_type)
13647     {
13648       errmsg ("remote and local EIDs are of different types!");
13649       return -99;
13650     }
13651
13652   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13653   mp->is_add = is_add;
13654   mp->vni = htonl (vni);
13655   mp->leid_len = leid_len;
13656   mp->reid_len = reid_len;
13657   mp->eid_type = reid_type;
13658
13659   switch (mp->eid_type)
13660     {
13661     case 0:
13662       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13663       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13664       break;
13665     case 1:
13666       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13667       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13668       break;
13669     case 2:
13670       clib_memcpy (mp->leid, leid_mac, 6);
13671       clib_memcpy (mp->reid, reid_mac, 6);
13672       break;
13673     default:
13674       errmsg ("unknown EID type %d!", mp->eid_type);
13675       return 0;
13676     }
13677
13678   /* send it... */
13679   S;
13680
13681   /* Wait for a reply... */
13682   W;
13683
13684   /* NOTREACHED */
13685   return 0;
13686 }
13687
13688 static int
13689 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13690 {
13691   unformat_input_t *input = vam->input;
13692   vl_api_lisp_gpe_add_del_iface_t *mp;
13693   f64 timeout = ~0;
13694   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13695   u32 dp_table = 0, vni = 0;
13696
13697   /* Parse args required to build the message */
13698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13699     {
13700       if (unformat (input, "up"))
13701         {
13702           action_set = 1;
13703           is_add = 1;
13704         }
13705       else if (unformat (input, "down"))
13706         {
13707           action_set = 1;
13708           is_add = 0;
13709         }
13710       else if (unformat (input, "table_id %d", &dp_table))
13711         {
13712           dp_table_set = 1;
13713         }
13714       else if (unformat (input, "bd_id %d", &dp_table))
13715         {
13716           dp_table_set = 1;
13717           is_l2 = 1;
13718         }
13719       else if (unformat (input, "vni %d", &vni))
13720         {
13721           vni_set = 1;
13722         }
13723       else
13724         break;
13725     }
13726
13727   if (action_set == 0)
13728     {
13729       errmsg ("Action not set\n");
13730       return -99;
13731     }
13732   if (dp_table_set == 0 || vni_set == 0)
13733     {
13734       errmsg ("vni and dp_table must be set\n");
13735       return -99;
13736     }
13737
13738   /* Construct the API message */
13739   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13740
13741   mp->is_add = is_add;
13742   mp->dp_table = dp_table;
13743   mp->is_l2 = is_l2;
13744   mp->vni = vni;
13745
13746   /* send it... */
13747   S;
13748
13749   /* Wait for a reply... */
13750   W;
13751
13752   /* NOTREACHED */
13753   return 0;
13754 }
13755
13756 /**
13757  * Add/del map request itr rlocs from LISP control plane and updates
13758  *
13759  * @param vam vpp API test context
13760  * @return return code
13761  */
13762 static int
13763 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13764 {
13765   unformat_input_t *input = vam->input;
13766   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13767   f64 timeout = ~0;
13768   u8 *locator_set_name = 0;
13769   u8 locator_set_name_set = 0;
13770   u8 is_add = 1;
13771
13772   /* Parse args required to build the message */
13773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13774     {
13775       if (unformat (input, "del"))
13776         {
13777           is_add = 0;
13778         }
13779       else if (unformat (input, "%_%v%_", &locator_set_name))
13780         {
13781           locator_set_name_set = 1;
13782         }
13783       else
13784         {
13785           clib_warning ("parse error '%U'", format_unformat_error, input);
13786           return -99;
13787         }
13788     }
13789
13790   if (is_add && !locator_set_name_set)
13791     {
13792       errmsg ("itr-rloc is not set!");
13793       return -99;
13794     }
13795
13796   if (is_add && vec_len (locator_set_name) > 64)
13797     {
13798       errmsg ("itr-rloc locator-set name too long\n");
13799       vec_free (locator_set_name);
13800       return -99;
13801     }
13802
13803   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13804   mp->is_add = is_add;
13805   if (is_add)
13806     {
13807       clib_memcpy (mp->locator_set_name, locator_set_name,
13808                    vec_len (locator_set_name));
13809     }
13810   else
13811     {
13812       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13813     }
13814   vec_free (locator_set_name);
13815
13816   /* send it... */
13817   S;
13818
13819   /* Wait for a reply... */
13820   W;
13821
13822   /* NOTREACHED */
13823   return 0;
13824 }
13825
13826 static int
13827 api_lisp_locator_dump (vat_main_t * vam)
13828 {
13829   unformat_input_t *input = vam->input;
13830   vl_api_lisp_locator_dump_t *mp;
13831   f64 timeout = ~0;
13832   u8 is_index_set = 0, is_name_set = 0;
13833   u8 *ls_name = 0;
13834   u32 ls_index = ~0;
13835
13836   /* Parse args required to build the message */
13837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13838     {
13839       if (unformat (input, "ls_name %_%v%_", &ls_name))
13840         {
13841           is_name_set = 1;
13842         }
13843       else if (unformat (input, "ls_index %d", &ls_index))
13844         {
13845           is_index_set = 1;
13846         }
13847       else
13848         {
13849           errmsg ("parse error '%U'", format_unformat_error, input);
13850           return -99;
13851         }
13852     }
13853
13854   if (!is_index_set && !is_name_set)
13855     {
13856       errmsg ("error: expected one of index or name!\n");
13857       return -99;
13858     }
13859
13860   if (is_index_set && is_name_set)
13861     {
13862       errmsg ("error: only one param expected!\n");
13863       return -99;
13864     }
13865
13866   if (vec_len (ls_name) > 62)
13867     {
13868       errmsg ("error: locator set name too long!");
13869       return -99;
13870     }
13871
13872   if (!vam->json_output)
13873     {
13874       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13875                "weight");
13876     }
13877
13878   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13879   mp->is_index_set = is_index_set;
13880
13881   if (is_index_set)
13882     mp->ls_index = clib_host_to_net_u32 (ls_index);
13883   else
13884     {
13885       vec_add1 (ls_name, 0);
13886       strncpy ((char *) mp->ls_name, (char *) ls_name,
13887                sizeof (mp->ls_name) - 1);
13888     }
13889
13890   /* send it... */
13891   S;
13892
13893   /* Use a control ping for synchronization */
13894   {
13895     vl_api_control_ping_t *mp;
13896     M (CONTROL_PING, control_ping);
13897     S;
13898   }
13899   /* Wait for a reply... */
13900   W;
13901
13902   /* NOTREACHED */
13903   return 0;
13904 }
13905
13906 static int
13907 api_lisp_locator_set_dump (vat_main_t * vam)
13908 {
13909   vl_api_lisp_locator_set_dump_t *mp;
13910   unformat_input_t *input = vam->input;
13911   f64 timeout = ~0;
13912   u8 filter = 0;
13913
13914   /* Parse args required to build the message */
13915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13916     {
13917       if (unformat (input, "local"))
13918         {
13919           filter = 1;
13920         }
13921       else if (unformat (input, "remote"))
13922         {
13923           filter = 2;
13924         }
13925       else
13926         {
13927           errmsg ("parse error '%U'", format_unformat_error, input);
13928           return -99;
13929         }
13930     }
13931
13932   if (!vam->json_output)
13933     {
13934       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13935     }
13936
13937   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13938
13939   mp->filter = filter;
13940
13941   /* send it... */
13942   S;
13943
13944   /* Use a control ping for synchronization */
13945   {
13946     vl_api_control_ping_t *mp;
13947     M (CONTROL_PING, control_ping);
13948     S;
13949   }
13950   /* Wait for a reply... */
13951   W;
13952
13953   /* NOTREACHED */
13954   return 0;
13955 }
13956
13957 static int
13958 api_lisp_eid_table_map_dump (vat_main_t * vam)
13959 {
13960   u8 is_l2 = 0;
13961   u8 mode_set = 0;
13962   unformat_input_t *input = vam->input;
13963   vl_api_lisp_eid_table_map_dump_t *mp;
13964   f64 timeout = ~0;
13965
13966   /* Parse args required to build the message */
13967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13968     {
13969       if (unformat (input, "l2"))
13970         {
13971           is_l2 = 1;
13972           mode_set = 1;
13973         }
13974       else if (unformat (input, "l3"))
13975         {
13976           is_l2 = 0;
13977           mode_set = 1;
13978         }
13979       else
13980         {
13981           errmsg ("parse error '%U'", format_unformat_error, input);
13982           return -99;
13983         }
13984     }
13985
13986   if (!mode_set)
13987     {
13988       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13989       return -99;
13990     }
13991
13992   if (!vam->json_output)
13993     {
13994       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13995     }
13996
13997   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13998   mp->is_l2 = is_l2;
13999
14000   /* send it... */
14001   S;
14002
14003   /* Use a control ping for synchronization */
14004   {
14005     vl_api_control_ping_t *mp;
14006     M (CONTROL_PING, control_ping);
14007     S;
14008   }
14009   /* Wait for a reply... */
14010   W;
14011
14012   /* NOTREACHED */
14013   return 0;
14014 }
14015
14016 static int
14017 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14018 {
14019   vl_api_lisp_eid_table_vni_dump_t *mp;
14020   f64 timeout = ~0;
14021
14022   if (!vam->json_output)
14023     {
14024       fformat (vam->ofp, "VNI\n");
14025     }
14026
14027   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14028
14029   /* send it... */
14030   S;
14031
14032   /* Use a control ping for synchronization */
14033   {
14034     vl_api_control_ping_t *mp;
14035     M (CONTROL_PING, control_ping);
14036     S;
14037   }
14038   /* Wait for a reply... */
14039   W;
14040
14041   /* NOTREACHED */
14042   return 0;
14043 }
14044
14045 static int
14046 api_lisp_eid_table_dump (vat_main_t * vam)
14047 {
14048   unformat_input_t *i = vam->input;
14049   vl_api_lisp_eid_table_dump_t *mp;
14050   f64 timeout = ~0;
14051   struct in_addr ip4;
14052   struct in6_addr ip6;
14053   u8 mac[6];
14054   u8 eid_type = ~0, eid_set = 0;
14055   u32 prefix_length = ~0, t, vni = 0;
14056   u8 filter = 0;
14057
14058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14059     {
14060       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14061         {
14062           eid_set = 1;
14063           eid_type = 0;
14064           prefix_length = t;
14065         }
14066       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14067         {
14068           eid_set = 1;
14069           eid_type = 1;
14070           prefix_length = t;
14071         }
14072       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14073         {
14074           eid_set = 1;
14075           eid_type = 2;
14076         }
14077       else if (unformat (i, "vni %d", &t))
14078         {
14079           vni = t;
14080         }
14081       else if (unformat (i, "local"))
14082         {
14083           filter = 1;
14084         }
14085       else if (unformat (i, "remote"))
14086         {
14087           filter = 2;
14088         }
14089       else
14090         {
14091           errmsg ("parse error '%U'", format_unformat_error, i);
14092           return -99;
14093         }
14094     }
14095
14096   if (!vam->json_output)
14097     {
14098       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14099                "ls_index", "ttl", "authoritative");
14100     }
14101
14102   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14103
14104   mp->filter = filter;
14105   if (eid_set)
14106     {
14107       mp->eid_set = 1;
14108       mp->vni = htonl (vni);
14109       mp->eid_type = eid_type;
14110       switch (eid_type)
14111         {
14112         case 0:
14113           mp->prefix_length = prefix_length;
14114           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14115           break;
14116         case 1:
14117           mp->prefix_length = prefix_length;
14118           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14119           break;
14120         case 2:
14121           clib_memcpy (mp->eid, mac, sizeof (mac));
14122           break;
14123         default:
14124           errmsg ("unknown EID type %d!", eid_type);
14125           return -99;
14126         }
14127     }
14128
14129   /* send it... */
14130   S;
14131
14132   /* Use a control ping for synchronization */
14133   {
14134     vl_api_control_ping_t *mp;
14135     M (CONTROL_PING, control_ping);
14136     S;
14137   }
14138
14139   /* Wait for a reply... */
14140   W;
14141
14142   /* NOTREACHED */
14143   return 0;
14144 }
14145
14146 static int
14147 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14148 {
14149   vl_api_lisp_gpe_tunnel_dump_t *mp;
14150   f64 timeout = ~0;
14151
14152   if (!vam->json_output)
14153     {
14154       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14155                "%=16s%=16s%=16s%=16s%=16s\n",
14156                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14157                "Decap next", "Lisp version", "Flags", "Next protocol",
14158                "ver_res", "res", "iid");
14159     }
14160
14161   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14162   /* send it... */
14163   S;
14164
14165   /* Use a control ping for synchronization */
14166   {
14167     vl_api_control_ping_t *mp;
14168     M (CONTROL_PING, control_ping);
14169     S;
14170   }
14171   /* Wait for a reply... */
14172   W;
14173
14174   /* NOTREACHED */
14175   return 0;
14176 }
14177
14178 static int
14179 api_lisp_adjacencies_get (vat_main_t * vam)
14180 {
14181   unformat_input_t *i = vam->input;
14182   vl_api_lisp_adjacencies_get_t *mp;
14183   f64 timeout = ~0;
14184   u8 vni_set = 0;
14185   u32 vni = ~0;
14186
14187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14188     {
14189       if (unformat (i, "vni %d", &vni))
14190         {
14191           vni_set = 1;
14192         }
14193       else
14194         {
14195           errmsg ("parse error '%U'\n", format_unformat_error, i);
14196           return -99;
14197         }
14198     }
14199
14200   if (!vni_set)
14201     {
14202       errmsg ("vni not set!\n");
14203       return -99;
14204     }
14205
14206   if (!vam->json_output)
14207     {
14208       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14209     }
14210
14211   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14212   mp->vni = clib_host_to_net_u32 (vni);
14213
14214   /* send it... */
14215   S;
14216
14217   /* Wait for a reply... */
14218   W;
14219
14220   /* NOTREACHED */
14221   return 0;
14222 }
14223
14224 static int
14225 api_lisp_map_resolver_dump (vat_main_t * vam)
14226 {
14227   vl_api_lisp_map_resolver_dump_t *mp;
14228   f64 timeout = ~0;
14229
14230   if (!vam->json_output)
14231     {
14232       fformat (vam->ofp, "%=20s\n", "Map resolver");
14233     }
14234
14235   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14236   /* send it... */
14237   S;
14238
14239   /* Use a control ping for synchronization */
14240   {
14241     vl_api_control_ping_t *mp;
14242     M (CONTROL_PING, control_ping);
14243     S;
14244   }
14245   /* Wait for a reply... */
14246   W;
14247
14248   /* NOTREACHED */
14249   return 0;
14250 }
14251
14252 static int
14253 api_show_lisp_status (vat_main_t * vam)
14254 {
14255   vl_api_show_lisp_status_t *mp;
14256   f64 timeout = ~0;
14257
14258   if (!vam->json_output)
14259     {
14260       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14261     }
14262
14263   M (SHOW_LISP_STATUS, show_lisp_status);
14264   /* send it... */
14265   S;
14266   /* Wait for a reply... */
14267   W;
14268
14269   /* NOTREACHED */
14270   return 0;
14271 }
14272
14273 static int
14274 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14275 {
14276   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14277   f64 timeout = ~0;
14278
14279   if (!vam->json_output)
14280     {
14281       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14282     }
14283
14284   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14285   /* send it... */
14286   S;
14287   /* Wait for a reply... */
14288   W;
14289
14290   /* NOTREACHED */
14291   return 0;
14292 }
14293
14294 static int
14295 api_af_packet_create (vat_main_t * vam)
14296 {
14297   unformat_input_t *i = vam->input;
14298   vl_api_af_packet_create_t *mp;
14299   f64 timeout;
14300   u8 *host_if_name = 0;
14301   u8 hw_addr[6];
14302   u8 random_hw_addr = 1;
14303
14304   memset (hw_addr, 0, sizeof (hw_addr));
14305
14306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14307     {
14308       if (unformat (i, "name %s", &host_if_name))
14309         vec_add1 (host_if_name, 0);
14310       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14311         random_hw_addr = 0;
14312       else
14313         break;
14314     }
14315
14316   if (!vec_len (host_if_name))
14317     {
14318       errmsg ("host-interface name must be specified");
14319       return -99;
14320     }
14321
14322   if (vec_len (host_if_name) > 64)
14323     {
14324       errmsg ("host-interface name too long");
14325       return -99;
14326     }
14327
14328   M (AF_PACKET_CREATE, af_packet_create);
14329
14330   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14331   clib_memcpy (mp->hw_addr, hw_addr, 6);
14332   mp->use_random_hw_addr = random_hw_addr;
14333   vec_free (host_if_name);
14334
14335   S;
14336   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14337   /* NOTREACHED */
14338   return 0;
14339 }
14340
14341 static int
14342 api_af_packet_delete (vat_main_t * vam)
14343 {
14344   unformat_input_t *i = vam->input;
14345   vl_api_af_packet_delete_t *mp;
14346   f64 timeout;
14347   u8 *host_if_name = 0;
14348
14349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14350     {
14351       if (unformat (i, "name %s", &host_if_name))
14352         vec_add1 (host_if_name, 0);
14353       else
14354         break;
14355     }
14356
14357   if (!vec_len (host_if_name))
14358     {
14359       errmsg ("host-interface name must be specified");
14360       return -99;
14361     }
14362
14363   if (vec_len (host_if_name) > 64)
14364     {
14365       errmsg ("host-interface name too long");
14366       return -99;
14367     }
14368
14369   M (AF_PACKET_DELETE, af_packet_delete);
14370
14371   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14372   vec_free (host_if_name);
14373
14374   S;
14375   W;
14376   /* NOTREACHED */
14377   return 0;
14378 }
14379
14380 static int
14381 api_policer_add_del (vat_main_t * vam)
14382 {
14383   unformat_input_t *i = vam->input;
14384   vl_api_policer_add_del_t *mp;
14385   f64 timeout;
14386   u8 is_add = 1;
14387   u8 *name = 0;
14388   u32 cir = 0;
14389   u32 eir = 0;
14390   u64 cb = 0;
14391   u64 eb = 0;
14392   u8 rate_type = 0;
14393   u8 round_type = 0;
14394   u8 type = 0;
14395   u8 color_aware = 0;
14396   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14397
14398   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14399   conform_action.dscp = 0;
14400   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14401   exceed_action.dscp = 0;
14402   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14403   violate_action.dscp = 0;
14404
14405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14406     {
14407       if (unformat (i, "del"))
14408         is_add = 0;
14409       else if (unformat (i, "name %s", &name))
14410         vec_add1 (name, 0);
14411       else if (unformat (i, "cir %u", &cir))
14412         ;
14413       else if (unformat (i, "eir %u", &eir))
14414         ;
14415       else if (unformat (i, "cb %u", &cb))
14416         ;
14417       else if (unformat (i, "eb %u", &eb))
14418         ;
14419       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14420                          &rate_type))
14421         ;
14422       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14423                          &round_type))
14424         ;
14425       else if (unformat (i, "type %U", unformat_policer_type, &type))
14426         ;
14427       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14428                          &conform_action))
14429         ;
14430       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14431                          &exceed_action))
14432         ;
14433       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14434                          &violate_action))
14435         ;
14436       else if (unformat (i, "color-aware"))
14437         color_aware = 1;
14438       else
14439         break;
14440     }
14441
14442   if (!vec_len (name))
14443     {
14444       errmsg ("policer name must be specified");
14445       return -99;
14446     }
14447
14448   if (vec_len (name) > 64)
14449     {
14450       errmsg ("policer name too long");
14451       return -99;
14452     }
14453
14454   M (POLICER_ADD_DEL, policer_add_del);
14455
14456   clib_memcpy (mp->name, name, vec_len (name));
14457   vec_free (name);
14458   mp->is_add = is_add;
14459   mp->cir = cir;
14460   mp->eir = eir;
14461   mp->cb = cb;
14462   mp->eb = eb;
14463   mp->rate_type = rate_type;
14464   mp->round_type = round_type;
14465   mp->type = type;
14466   mp->conform_action_type = conform_action.action_type;
14467   mp->conform_dscp = conform_action.dscp;
14468   mp->exceed_action_type = exceed_action.action_type;
14469   mp->exceed_dscp = exceed_action.dscp;
14470   mp->violate_action_type = violate_action.action_type;
14471   mp->violate_dscp = violate_action.dscp;
14472   mp->color_aware = color_aware;
14473
14474   S;
14475   W;
14476   /* NOTREACHED */
14477   return 0;
14478 }
14479
14480 static int
14481 api_policer_dump (vat_main_t * vam)
14482 {
14483   unformat_input_t *i = vam->input;
14484   vl_api_policer_dump_t *mp;
14485   f64 timeout = ~0;
14486   u8 *match_name = 0;
14487   u8 match_name_valid = 0;
14488
14489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14490     {
14491       if (unformat (i, "name %s", &match_name))
14492         {
14493           vec_add1 (match_name, 0);
14494           match_name_valid = 1;
14495         }
14496       else
14497         break;
14498     }
14499
14500   M (POLICER_DUMP, policer_dump);
14501   mp->match_name_valid = match_name_valid;
14502   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14503   vec_free (match_name);
14504   /* send it... */
14505   S;
14506
14507   /* Use a control ping for synchronization */
14508   {
14509     vl_api_control_ping_t *mp;
14510     M (CONTROL_PING, control_ping);
14511     S;
14512   }
14513   /* Wait for a reply... */
14514   W;
14515
14516   /* NOTREACHED */
14517   return 0;
14518 }
14519
14520 static int
14521 api_policer_classify_set_interface (vat_main_t * vam)
14522 {
14523   unformat_input_t *i = vam->input;
14524   vl_api_policer_classify_set_interface_t *mp;
14525   f64 timeout;
14526   u32 sw_if_index;
14527   int sw_if_index_set;
14528   u32 ip4_table_index = ~0;
14529   u32 ip6_table_index = ~0;
14530   u32 l2_table_index = ~0;
14531   u8 is_add = 1;
14532
14533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14534     {
14535       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14536         sw_if_index_set = 1;
14537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14538         sw_if_index_set = 1;
14539       else if (unformat (i, "del"))
14540         is_add = 0;
14541       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14542         ;
14543       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14544         ;
14545       else if (unformat (i, "l2-table %d", &l2_table_index))
14546         ;
14547       else
14548         {
14549           clib_warning ("parse error '%U'", format_unformat_error, i);
14550           return -99;
14551         }
14552     }
14553
14554   if (sw_if_index_set == 0)
14555     {
14556       errmsg ("missing interface name or sw_if_index\n");
14557       return -99;
14558     }
14559
14560   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14561
14562   mp->sw_if_index = ntohl (sw_if_index);
14563   mp->ip4_table_index = ntohl (ip4_table_index);
14564   mp->ip6_table_index = ntohl (ip6_table_index);
14565   mp->l2_table_index = ntohl (l2_table_index);
14566   mp->is_add = is_add;
14567
14568   S;
14569   W;
14570   /* NOTREACHED */
14571   return 0;
14572 }
14573
14574 static int
14575 api_policer_classify_dump (vat_main_t * vam)
14576 {
14577   unformat_input_t *i = vam->input;
14578   vl_api_policer_classify_dump_t *mp;
14579   f64 timeout = ~0;
14580   u8 type = POLICER_CLASSIFY_N_TABLES;
14581
14582   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14583     ;
14584   else
14585     {
14586       errmsg ("classify table type must be specified\n");
14587       return -99;
14588     }
14589
14590   if (!vam->json_output)
14591     {
14592       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14593     }
14594
14595   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14596   mp->type = type;
14597   /* send it... */
14598   S;
14599
14600   /* Use a control ping for synchronization */
14601   {
14602     vl_api_control_ping_t *mp;
14603     M (CONTROL_PING, control_ping);
14604     S;
14605   }
14606   /* Wait for a reply... */
14607   W;
14608
14609   /* NOTREACHED */
14610   return 0;
14611 }
14612
14613 static int
14614 api_netmap_create (vat_main_t * vam)
14615 {
14616   unformat_input_t *i = vam->input;
14617   vl_api_netmap_create_t *mp;
14618   f64 timeout;
14619   u8 *if_name = 0;
14620   u8 hw_addr[6];
14621   u8 random_hw_addr = 1;
14622   u8 is_pipe = 0;
14623   u8 is_master = 0;
14624
14625   memset (hw_addr, 0, sizeof (hw_addr));
14626
14627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14628     {
14629       if (unformat (i, "name %s", &if_name))
14630         vec_add1 (if_name, 0);
14631       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14632         random_hw_addr = 0;
14633       else if (unformat (i, "pipe"))
14634         is_pipe = 1;
14635       else if (unformat (i, "master"))
14636         is_master = 1;
14637       else if (unformat (i, "slave"))
14638         is_master = 0;
14639       else
14640         break;
14641     }
14642
14643   if (!vec_len (if_name))
14644     {
14645       errmsg ("interface name must be specified");
14646       return -99;
14647     }
14648
14649   if (vec_len (if_name) > 64)
14650     {
14651       errmsg ("interface name too long");
14652       return -99;
14653     }
14654
14655   M (NETMAP_CREATE, netmap_create);
14656
14657   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14658   clib_memcpy (mp->hw_addr, hw_addr, 6);
14659   mp->use_random_hw_addr = random_hw_addr;
14660   mp->is_pipe = is_pipe;
14661   mp->is_master = is_master;
14662   vec_free (if_name);
14663
14664   S;
14665   W;
14666   /* NOTREACHED */
14667   return 0;
14668 }
14669
14670 static int
14671 api_netmap_delete (vat_main_t * vam)
14672 {
14673   unformat_input_t *i = vam->input;
14674   vl_api_netmap_delete_t *mp;
14675   f64 timeout;
14676   u8 *if_name = 0;
14677
14678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (i, "name %s", &if_name))
14681         vec_add1 (if_name, 0);
14682       else
14683         break;
14684     }
14685
14686   if (!vec_len (if_name))
14687     {
14688       errmsg ("interface name must be specified");
14689       return -99;
14690     }
14691
14692   if (vec_len (if_name) > 64)
14693     {
14694       errmsg ("interface name too long");
14695       return -99;
14696     }
14697
14698   M (NETMAP_DELETE, netmap_delete);
14699
14700   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14701   vec_free (if_name);
14702
14703   S;
14704   W;
14705   /* NOTREACHED */
14706   return 0;
14707 }
14708
14709 static void vl_api_mpls_eth_tunnel_details_t_handler
14710   (vl_api_mpls_eth_tunnel_details_t * mp)
14711 {
14712   vat_main_t *vam = &vat_main;
14713   i32 i;
14714   i32 len = ntohl (mp->nlabels);
14715
14716   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14717            ntohl (mp->tunnel_index),
14718            format_ethernet_address, &mp->tunnel_dst_mac,
14719            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14720   for (i = 0; i < len; i++)
14721     {
14722       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14723     }
14724   fformat (vam->ofp, "\n");
14725   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14726            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14727 }
14728
14729 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14730   (vl_api_mpls_eth_tunnel_details_t * mp)
14731 {
14732   vat_main_t *vam = &vat_main;
14733   vat_json_node_t *node = NULL;
14734   struct in_addr ip4;
14735   i32 i;
14736   i32 len = ntohl (mp->nlabels);
14737
14738   if (VAT_JSON_ARRAY != vam->json_tree.type)
14739     {
14740       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14741       vat_json_init_array (&vam->json_tree);
14742     }
14743   node = vat_json_array_add (&vam->json_tree);
14744
14745   vat_json_init_object (node);
14746   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14747   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14748   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14749   vat_json_object_add_uint (node, "inner_fib_index",
14750                             ntohl (mp->inner_fib_index));
14751   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14752   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14753   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14754   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14755   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14756                                    format (0, "%U", format_ethernet_address,
14757                                            &mp->tunnel_dst_mac));
14758   vat_json_object_add_uint (node, "tx_sw_if_index",
14759                             ntohl (mp->tx_sw_if_index));
14760   vat_json_object_add_uint (node, "label_count", len);
14761   for (i = 0; i < len; i++)
14762     {
14763       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14764     }
14765 }
14766
14767 static int
14768 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14769 {
14770   vl_api_mpls_eth_tunnel_dump_t *mp;
14771   f64 timeout;
14772   i32 index = -1;
14773
14774   /* Parse args required to build the message */
14775   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14776     {
14777       if (!unformat (vam->input, "tunnel_index %d", &index))
14778         {
14779           index = -1;
14780           break;
14781         }
14782     }
14783
14784   fformat (vam->ofp, "  tunnel_index %d\n", index);
14785
14786   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14787   mp->tunnel_index = htonl (index);
14788   S;
14789
14790   /* Use a control ping for synchronization */
14791   {
14792     vl_api_control_ping_t *mp;
14793     M (CONTROL_PING, control_ping);
14794     S;
14795   }
14796   W;
14797 }
14798
14799 static void vl_api_mpls_fib_encap_details_t_handler
14800   (vl_api_mpls_fib_encap_details_t * mp)
14801 {
14802   vat_main_t *vam = &vat_main;
14803   i32 i;
14804   i32 len = ntohl (mp->nlabels);
14805
14806   fformat (vam->ofp, "table %d, dest %U, label ",
14807            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14808   for (i = 0; i < len; i++)
14809     {
14810       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14811     }
14812   fformat (vam->ofp, "\n");
14813 }
14814
14815 static void vl_api_mpls_fib_encap_details_t_handler_json
14816   (vl_api_mpls_fib_encap_details_t * mp)
14817 {
14818   vat_main_t *vam = &vat_main;
14819   vat_json_node_t *node = NULL;
14820   i32 i;
14821   i32 len = ntohl (mp->nlabels);
14822   struct in_addr ip4;
14823
14824   if (VAT_JSON_ARRAY != vam->json_tree.type)
14825     {
14826       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14827       vat_json_init_array (&vam->json_tree);
14828     }
14829   node = vat_json_array_add (&vam->json_tree);
14830
14831   vat_json_init_object (node);
14832   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14833   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14834   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14835   vat_json_object_add_ip4 (node, "dest", ip4);
14836   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14837   vat_json_object_add_uint (node, "label_count", len);
14838   for (i = 0; i < len; i++)
14839     {
14840       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14841     }
14842 }
14843
14844 static int
14845 api_mpls_fib_encap_dump (vat_main_t * vam)
14846 {
14847   vl_api_mpls_fib_encap_dump_t *mp;
14848   f64 timeout;
14849
14850   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14851   S;
14852
14853   /* Use a control ping for synchronization */
14854   {
14855     vl_api_control_ping_t *mp;
14856     M (CONTROL_PING, control_ping);
14857     S;
14858   }
14859   W;
14860 }
14861
14862 static void
14863 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14864 {
14865   vat_main_t *vam = &vat_main;
14866
14867   fformat (vam->ofp,
14868            "table-id %d, label %u, ess_bit %u\n",
14869            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14870 }
14871
14872 static void vl_api_mpls_fib_details_t_handler_json
14873   (vl_api_mpls_fib_details_t * mp)
14874 {
14875   vat_main_t *vam = &vat_main;
14876   vat_json_node_t *node = NULL;
14877
14878   if (VAT_JSON_ARRAY != vam->json_tree.type)
14879     {
14880       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14881       vat_json_init_array (&vam->json_tree);
14882     }
14883   node = vat_json_array_add (&vam->json_tree);
14884
14885   vat_json_init_object (node);
14886   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14887   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14888   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14889 }
14890
14891 static int
14892 api_mpls_fib_dump (vat_main_t * vam)
14893 {
14894   vl_api_mpls_fib_dump_t *mp;
14895   f64 timeout;
14896
14897   M (MPLS_FIB_DUMP, mpls_fib_dump);
14898   S;
14899
14900   /* Use a control ping for synchronization */
14901   {
14902     vl_api_control_ping_t *mp;
14903     M (CONTROL_PING, control_ping);
14904     S;
14905   }
14906   W;
14907 }
14908
14909 int
14910 api_classify_table_ids (vat_main_t * vam)
14911 {
14912   vl_api_classify_table_ids_t *mp;
14913   f64 timeout;
14914
14915   /* Construct the API message */
14916   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14917   mp->context = 0;
14918
14919   S;
14920   W;
14921   /* NOTREACHED */
14922   return 0;
14923 }
14924
14925 int
14926 api_classify_table_by_interface (vat_main_t * vam)
14927 {
14928   unformat_input_t *input = vam->input;
14929   vl_api_classify_table_by_interface_t *mp;
14930   f64 timeout;
14931
14932   u32 sw_if_index = ~0;
14933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14934     {
14935       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14936         ;
14937       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14938         ;
14939       else
14940         break;
14941     }
14942   if (sw_if_index == ~0)
14943     {
14944       errmsg ("missing interface name or sw_if_index\n");
14945       return -99;
14946     }
14947
14948   /* Construct the API message */
14949   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14950   mp->context = 0;
14951   mp->sw_if_index = ntohl (sw_if_index);
14952
14953   S;
14954   W;
14955   /* NOTREACHED */
14956   return 0;
14957 }
14958
14959 int
14960 api_classify_table_info (vat_main_t * vam)
14961 {
14962   unformat_input_t *input = vam->input;
14963   vl_api_classify_table_info_t *mp;
14964   f64 timeout;
14965
14966   u32 table_id = ~0;
14967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14968     {
14969       if (unformat (input, "table_id %d", &table_id))
14970         ;
14971       else
14972         break;
14973     }
14974   if (table_id == ~0)
14975     {
14976       errmsg ("missing table id\n");
14977       return -99;
14978     }
14979
14980   /* Construct the API message */
14981   M (CLASSIFY_TABLE_INFO, classify_table_info);
14982   mp->context = 0;
14983   mp->table_id = ntohl (table_id);
14984
14985   S;
14986   W;
14987   /* NOTREACHED */
14988   return 0;
14989 }
14990
14991 int
14992 api_classify_session_dump (vat_main_t * vam)
14993 {
14994   unformat_input_t *input = vam->input;
14995   vl_api_classify_session_dump_t *mp;
14996   f64 timeout;
14997
14998   u32 table_id = ~0;
14999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15000     {
15001       if (unformat (input, "table_id %d", &table_id))
15002         ;
15003       else
15004         break;
15005     }
15006   if (table_id == ~0)
15007     {
15008       errmsg ("missing table id\n");
15009       return -99;
15010     }
15011
15012   /* Construct the API message */
15013   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15014   mp->context = 0;
15015   mp->table_id = ntohl (table_id);
15016   S;
15017
15018   /* Use a control ping for synchronization */
15019   {
15020     vl_api_control_ping_t *mp;
15021     M (CONTROL_PING, control_ping);
15022     S;
15023   }
15024   W;
15025   /* NOTREACHED */
15026   return 0;
15027 }
15028
15029 static void
15030 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15031 {
15032   vat_main_t *vam = &vat_main;
15033
15034   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15035            "src_address %U, vrf_id %d, path_mtu %u, "
15036            "template_interval %u, udp_checksum %d\n",
15037            format_ip4_address, mp->collector_address,
15038            ntohs (mp->collector_port),
15039            format_ip4_address, mp->src_address,
15040            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15041            ntohl (mp->template_interval), mp->udp_checksum);
15042
15043   vam->retval = 0;
15044   vam->result_ready = 1;
15045 }
15046
15047 static void
15048   vl_api_ipfix_exporter_details_t_handler_json
15049   (vl_api_ipfix_exporter_details_t * mp)
15050 {
15051   vat_main_t *vam = &vat_main;
15052   vat_json_node_t node;
15053   struct in_addr collector_address;
15054   struct in_addr src_address;
15055
15056   vat_json_init_object (&node);
15057   clib_memcpy (&collector_address, &mp->collector_address,
15058                sizeof (collector_address));
15059   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15060   vat_json_object_add_uint (&node, "collector_port",
15061                             ntohs (mp->collector_port));
15062   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15063   vat_json_object_add_ip4 (&node, "src_address", src_address);
15064   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15065   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15066   vat_json_object_add_uint (&node, "template_interval",
15067                             ntohl (mp->template_interval));
15068   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15069
15070   vat_json_print (vam->ofp, &node);
15071   vat_json_free (&node);
15072   vam->retval = 0;
15073   vam->result_ready = 1;
15074 }
15075
15076 int
15077 api_ipfix_exporter_dump (vat_main_t * vam)
15078 {
15079   vl_api_ipfix_exporter_dump_t *mp;
15080   f64 timeout;
15081
15082   /* Construct the API message */
15083   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15084   mp->context = 0;
15085
15086   S;
15087   W;
15088   /* NOTREACHED */
15089   return 0;
15090 }
15091
15092 static int
15093 api_ipfix_classify_stream_dump (vat_main_t * vam)
15094 {
15095   vl_api_ipfix_classify_stream_dump_t *mp;
15096   f64 timeout;
15097
15098   /* Construct the API message */
15099   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15100   mp->context = 0;
15101
15102   S;
15103   W;
15104   /* NOTREACHED */
15105   return 0;
15106 }
15107
15108 static void
15109   vl_api_ipfix_classify_stream_details_t_handler
15110   (vl_api_ipfix_classify_stream_details_t * mp)
15111 {
15112   vat_main_t *vam = &vat_main;
15113   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15114            ntohl (mp->domain_id), ntohs (mp->src_port));
15115   vam->retval = 0;
15116   vam->result_ready = 1;
15117 }
15118
15119 static void
15120   vl_api_ipfix_classify_stream_details_t_handler_json
15121   (vl_api_ipfix_classify_stream_details_t * mp)
15122 {
15123   vat_main_t *vam = &vat_main;
15124   vat_json_node_t node;
15125
15126   vat_json_init_object (&node);
15127   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15128   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15129
15130   vat_json_print (vam->ofp, &node);
15131   vat_json_free (&node);
15132   vam->retval = 0;
15133   vam->result_ready = 1;
15134 }
15135
15136 static int
15137 api_ipfix_classify_table_dump (vat_main_t * vam)
15138 {
15139   vl_api_ipfix_classify_table_dump_t *mp;
15140   f64 timeout;
15141
15142   if (!vam->json_output)
15143     {
15144       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15145                "transport_protocol");
15146     }
15147
15148   /* Construct the API message */
15149   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15150
15151   /* send it... */
15152   S;
15153
15154   /* Use a control ping for synchronization */
15155   {
15156     vl_api_control_ping_t *mp;
15157     M (CONTROL_PING, control_ping);
15158     S;
15159   }
15160   W;
15161 }
15162
15163 static void
15164   vl_api_ipfix_classify_table_details_t_handler
15165   (vl_api_ipfix_classify_table_details_t * mp)
15166 {
15167   vat_main_t *vam = &vat_main;
15168   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15169            mp->transport_protocol);
15170 }
15171
15172 static void
15173   vl_api_ipfix_classify_table_details_t_handler_json
15174   (vl_api_ipfix_classify_table_details_t * mp)
15175 {
15176   vat_json_node_t *node = NULL;
15177   vat_main_t *vam = &vat_main;
15178
15179   if (VAT_JSON_ARRAY != vam->json_tree.type)
15180     {
15181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15182       vat_json_init_array (&vam->json_tree);
15183     }
15184
15185   node = vat_json_array_add (&vam->json_tree);
15186   vat_json_init_object (node);
15187
15188   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15189   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15190   vat_json_object_add_uint (node, "transport_protocol",
15191                             mp->transport_protocol);
15192 }
15193
15194 int
15195 api_pg_create_interface (vat_main_t * vam)
15196 {
15197   unformat_input_t *input = vam->input;
15198   vl_api_pg_create_interface_t *mp;
15199   f64 timeout;
15200
15201   u32 if_id = ~0;
15202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15203     {
15204       if (unformat (input, "if_id %d", &if_id))
15205         ;
15206       else
15207         break;
15208     }
15209   if (if_id == ~0)
15210     {
15211       errmsg ("missing pg interface index\n");
15212       return -99;
15213     }
15214
15215   /* Construct the API message */
15216   M (PG_CREATE_INTERFACE, pg_create_interface);
15217   mp->context = 0;
15218   mp->interface_id = ntohl (if_id);
15219
15220   S;
15221   W;
15222   /* NOTREACHED */
15223   return 0;
15224 }
15225
15226 int
15227 api_pg_capture (vat_main_t * vam)
15228 {
15229   unformat_input_t *input = vam->input;
15230   vl_api_pg_capture_t *mp;
15231   f64 timeout;
15232
15233   u32 if_id = ~0;
15234   u8 enable = 1;
15235   u32 count = 1;
15236   u8 pcap_file_set = 0;
15237   u8 *pcap_file = 0;
15238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15239     {
15240       if (unformat (input, "if_id %d", &if_id))
15241         ;
15242       else if (unformat (input, "pcap %s", &pcap_file))
15243         pcap_file_set = 1;
15244       else if (unformat (input, "count %d", &count))
15245         ;
15246       else if (unformat (input, "disable"))
15247         enable = 0;
15248       else
15249         break;
15250     }
15251   if (if_id == ~0)
15252     {
15253       errmsg ("missing pg interface index\n");
15254       return -99;
15255     }
15256   if (pcap_file_set > 0)
15257     {
15258       if (vec_len (pcap_file) > 255)
15259         {
15260           errmsg ("pcap file name is too long\n");
15261           return -99;
15262         }
15263     }
15264
15265   u32 name_len = vec_len (pcap_file);
15266   /* Construct the API message */
15267   M (PG_CAPTURE, pg_capture);
15268   mp->context = 0;
15269   mp->interface_id = ntohl (if_id);
15270   mp->is_enabled = enable;
15271   mp->count = ntohl (count);
15272   mp->pcap_name_length = ntohl (name_len);
15273   if (pcap_file_set != 0)
15274     {
15275       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15276     }
15277   vec_free (pcap_file);
15278
15279   S;
15280   W;
15281   /* NOTREACHED */
15282   return 0;
15283 }
15284
15285 int
15286 api_pg_enable_disable (vat_main_t * vam)
15287 {
15288   unformat_input_t *input = vam->input;
15289   vl_api_pg_enable_disable_t *mp;
15290   f64 timeout;
15291
15292   u8 enable = 1;
15293   u8 stream_name_set = 0;
15294   u8 *stream_name = 0;
15295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15296     {
15297       if (unformat (input, "stream %s", &stream_name))
15298         stream_name_set = 1;
15299       else if (unformat (input, "disable"))
15300         enable = 0;
15301       else
15302         break;
15303     }
15304
15305   if (stream_name_set > 0)
15306     {
15307       if (vec_len (stream_name) > 255)
15308         {
15309           errmsg ("stream name too long\n");
15310           return -99;
15311         }
15312     }
15313
15314   u32 name_len = vec_len (stream_name);
15315   /* Construct the API message */
15316   M (PG_ENABLE_DISABLE, pg_enable_disable);
15317   mp->context = 0;
15318   mp->is_enabled = enable;
15319   if (stream_name_set != 0)
15320     {
15321       mp->stream_name_length = ntohl (name_len);
15322       clib_memcpy (mp->stream_name, stream_name, name_len);
15323     }
15324   vec_free (stream_name);
15325
15326   S;
15327   W;
15328   /* NOTREACHED */
15329   return 0;
15330 }
15331
15332 int
15333 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15334 {
15335   unformat_input_t *input = vam->input;
15336   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15337   f64 timeout;
15338
15339   u16 *low_ports = 0;
15340   u16 *high_ports = 0;
15341   u16 this_low;
15342   u16 this_hi;
15343   ip4_address_t ip4_addr;
15344   ip6_address_t ip6_addr;
15345   u32 length;
15346   u32 tmp, tmp2;
15347   u8 prefix_set = 0;
15348   u32 vrf_id = ~0;
15349   u8 is_add = 1;
15350   u8 is_ipv6 = 0;
15351
15352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15353     {
15354       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15355         {
15356           prefix_set = 1;
15357         }
15358       else
15359         if (unformat
15360             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15361         {
15362           prefix_set = 1;
15363           is_ipv6 = 1;
15364         }
15365       else if (unformat (input, "vrf %d", &vrf_id))
15366         ;
15367       else if (unformat (input, "del"))
15368         is_add = 0;
15369       else if (unformat (input, "port %d", &tmp))
15370         {
15371           if (tmp == 0 || tmp > 65535)
15372             {
15373               errmsg ("port %d out of range", tmp);
15374               return -99;
15375             }
15376           this_low = tmp;
15377           this_hi = this_low + 1;
15378           vec_add1 (low_ports, this_low);
15379           vec_add1 (high_ports, this_hi);
15380         }
15381       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15382         {
15383           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15384             {
15385               errmsg ("incorrect range parameters\n");
15386               return -99;
15387             }
15388           this_low = tmp;
15389           /* Note: in debug CLI +1 is added to high before
15390              passing to real fn that does "the work"
15391              (ip_source_and_port_range_check_add_del).
15392              This fn is a wrapper around the binary API fn a
15393              control plane will call, which expects this increment
15394              to have occurred. Hence letting the binary API control
15395              plane fn do the increment for consistency between VAT
15396              and other control planes.
15397            */
15398           this_hi = tmp2;
15399           vec_add1 (low_ports, this_low);
15400           vec_add1 (high_ports, this_hi);
15401         }
15402       else
15403         break;
15404     }
15405
15406   if (prefix_set == 0)
15407     {
15408       errmsg ("<address>/<mask> not specified\n");
15409       return -99;
15410     }
15411
15412   if (vrf_id == ~0)
15413     {
15414       errmsg ("VRF ID required, not specified\n");
15415       return -99;
15416     }
15417
15418   if (vrf_id == 0)
15419     {
15420       errmsg
15421         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15422       return -99;
15423     }
15424
15425   if (vec_len (low_ports) == 0)
15426     {
15427       errmsg ("At least one port or port range required\n");
15428       return -99;
15429     }
15430
15431   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15432      ip_source_and_port_range_check_add_del);
15433
15434   mp->is_add = is_add;
15435
15436   if (is_ipv6)
15437     {
15438       mp->is_ipv6 = 1;
15439       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15440     }
15441   else
15442     {
15443       mp->is_ipv6 = 0;
15444       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15445     }
15446
15447   mp->mask_length = length;
15448   mp->number_of_ranges = vec_len (low_ports);
15449
15450   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15451   vec_free (low_ports);
15452
15453   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15454   vec_free (high_ports);
15455
15456   mp->vrf_id = ntohl (vrf_id);
15457
15458   S;
15459   W;
15460   /* NOTREACHED */
15461   return 0;
15462 }
15463
15464 int
15465 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15466 {
15467   unformat_input_t *input = vam->input;
15468   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15469   f64 timeout;
15470   u32 sw_if_index = ~0;
15471   int vrf_set = 0;
15472   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15473   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15474   u8 is_add = 1;
15475
15476   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15477     {
15478       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15479         ;
15480       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15481         ;
15482       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15483         vrf_set = 1;
15484       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15485         vrf_set = 1;
15486       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15487         vrf_set = 1;
15488       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15489         vrf_set = 1;
15490       else if (unformat (input, "del"))
15491         is_add = 0;
15492       else
15493         break;
15494     }
15495
15496   if (sw_if_index == ~0)
15497     {
15498       errmsg ("Interface required but not specified\n");
15499       return -99;
15500     }
15501
15502   if (vrf_set == 0)
15503     {
15504       errmsg ("VRF ID required but not specified\n");
15505       return -99;
15506     }
15507
15508   if (tcp_out_vrf_id == 0
15509       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15510     {
15511       errmsg
15512         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15513       return -99;
15514     }
15515
15516   /* Construct the API message */
15517   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15518      ip_source_and_port_range_check_interface_add_del);
15519
15520   mp->sw_if_index = ntohl (sw_if_index);
15521   mp->is_add = is_add;
15522   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15523   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15524   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15525   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15526
15527   /* send it... */
15528   S;
15529
15530   /* Wait for a reply... */
15531   W;
15532 }
15533
15534 static int
15535 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15536 {
15537   unformat_input_t *i = vam->input;
15538   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15539   f64 timeout;
15540   u32 local_sa_id = 0;
15541   u32 remote_sa_id = 0;
15542   ip4_address_t src_address;
15543   ip4_address_t dst_address;
15544   u8 is_add = 1;
15545
15546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15547     {
15548       if (unformat (i, "local_sa %d", &local_sa_id))
15549         ;
15550       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15551         ;
15552       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15553         ;
15554       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15555         ;
15556       else if (unformat (i, "del"))
15557         is_add = 0;
15558       else
15559         {
15560           clib_warning ("parse error '%U'", format_unformat_error, i);
15561           return -99;
15562         }
15563     }
15564
15565   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15566
15567   mp->local_sa_id = ntohl (local_sa_id);
15568   mp->remote_sa_id = ntohl (remote_sa_id);
15569   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15570   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15571   mp->is_add = is_add;
15572
15573   S;
15574   W;
15575   /* NOTREACHED */
15576   return 0;
15577 }
15578
15579 static int
15580 api_punt (vat_main_t * vam)
15581 {
15582   unformat_input_t *i = vam->input;
15583   vl_api_punt_t *mp;
15584   f64 timeout;
15585   u32 ipv = ~0;
15586   u32 protocol = ~0;
15587   u32 port = ~0;
15588   int is_add = 1;
15589
15590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15591     {
15592       if (unformat (i, "ip %d", &ipv))
15593         ;
15594       else if (unformat (i, "protocol %d", &protocol))
15595         ;
15596       else if (unformat (i, "port %d", &port))
15597         ;
15598       else if (unformat (i, "del"))
15599         is_add = 0;
15600       else
15601         {
15602           clib_warning ("parse error '%U'", format_unformat_error, i);
15603           return -99;
15604         }
15605     }
15606
15607   M (PUNT, punt);
15608
15609   mp->is_add = (u8) is_add;
15610   mp->ipv = (u8) ipv;
15611   mp->l4_protocol = (u8) protocol;
15612   mp->l4_port = htons ((u16) port);
15613
15614   S;
15615   W;
15616   /* NOTREACHED */
15617   return 0;
15618 }
15619
15620 static void vl_api_ipsec_gre_tunnel_details_t_handler
15621   (vl_api_ipsec_gre_tunnel_details_t * mp)
15622 {
15623   vat_main_t *vam = &vat_main;
15624
15625   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15626            ntohl (mp->sw_if_index),
15627            format_ip4_address, &mp->src_address,
15628            format_ip4_address, &mp->dst_address,
15629            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15630 }
15631
15632 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15633   (vl_api_ipsec_gre_tunnel_details_t * mp)
15634 {
15635   vat_main_t *vam = &vat_main;
15636   vat_json_node_t *node = NULL;
15637   struct in_addr ip4;
15638
15639   if (VAT_JSON_ARRAY != vam->json_tree.type)
15640     {
15641       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15642       vat_json_init_array (&vam->json_tree);
15643     }
15644   node = vat_json_array_add (&vam->json_tree);
15645
15646   vat_json_init_object (node);
15647   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15648   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15649   vat_json_object_add_ip4 (node, "src_address", ip4);
15650   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15651   vat_json_object_add_ip4 (node, "dst_address", ip4);
15652   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15653   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15654 }
15655
15656 static int
15657 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15658 {
15659   unformat_input_t *i = vam->input;
15660   vl_api_ipsec_gre_tunnel_dump_t *mp;
15661   f64 timeout;
15662   u32 sw_if_index;
15663   u8 sw_if_index_set = 0;
15664
15665   /* Parse args required to build the message */
15666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15667     {
15668       if (unformat (i, "sw_if_index %d", &sw_if_index))
15669         sw_if_index_set = 1;
15670       else
15671         break;
15672     }
15673
15674   if (sw_if_index_set == 0)
15675     {
15676       sw_if_index = ~0;
15677     }
15678
15679   if (!vam->json_output)
15680     {
15681       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15682                "sw_if_index", "src_address", "dst_address",
15683                "local_sa_id", "remote_sa_id");
15684     }
15685
15686   /* Get list of gre-tunnel interfaces */
15687   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15688
15689   mp->sw_if_index = htonl (sw_if_index);
15690
15691   S;
15692
15693   /* Use a control ping for synchronization */
15694   {
15695     vl_api_control_ping_t *mp;
15696     M (CONTROL_PING, control_ping);
15697     S;
15698   }
15699   W;
15700 }
15701
15702 static int
15703 api_delete_subif (vat_main_t * vam)
15704 {
15705   unformat_input_t *i = vam->input;
15706   vl_api_delete_subif_t *mp;
15707   f64 timeout;
15708   u32 sw_if_index = ~0;
15709
15710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15711     {
15712       if (unformat (i, "sw_if_index %d", &sw_if_index))
15713         ;
15714       else
15715         break;
15716     }
15717
15718   if (sw_if_index == ~0)
15719     {
15720       errmsg ("missing sw_if_index\n");
15721       return -99;
15722     }
15723
15724   /* Construct the API message */
15725   M (DELETE_SUBIF, delete_subif);
15726   mp->sw_if_index = ntohl (sw_if_index);
15727
15728   S;
15729   W;
15730 }
15731
15732 #define foreach_pbb_vtr_op      \
15733 _("disable",  L2_VTR_DISABLED)  \
15734 _("pop",  L2_VTR_POP_2)         \
15735 _("push",  L2_VTR_PUSH_2)
15736
15737 static int
15738 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15739 {
15740   unformat_input_t *i = vam->input;
15741   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15742   f64 timeout;
15743   u32 sw_if_index = ~0, vtr_op = ~0;
15744   u16 outer_tag = ~0;
15745   u8 dmac[6], smac[6];
15746   u8 dmac_set = 0, smac_set = 0;
15747   u16 vlanid = 0;
15748   u32 sid = ~0;
15749   u32 tmp;
15750
15751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15752     {
15753       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15754         ;
15755       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15756         ;
15757       else if (unformat (i, "vtr_op %d", &vtr_op))
15758         ;
15759 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15760       foreach_pbb_vtr_op
15761 #undef _
15762         else if (unformat (i, "translate_pbb_stag"))
15763         {
15764           if (unformat (i, "%d", &tmp))
15765             {
15766               vtr_op = L2_VTR_TRANSLATE_2_1;
15767               outer_tag = tmp;
15768             }
15769           else
15770             {
15771               errmsg
15772                 ("translate_pbb_stag operation requires outer tag definition\n");
15773               return -99;
15774             }
15775         }
15776       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15777         dmac_set++;
15778       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15779         smac_set++;
15780       else if (unformat (i, "sid %d", &sid))
15781         ;
15782       else if (unformat (i, "vlanid %d", &tmp))
15783         vlanid = tmp;
15784       else
15785         {
15786           clib_warning ("parse error '%U'", format_unformat_error, i);
15787           return -99;
15788         }
15789     }
15790
15791   if ((sw_if_index == ~0) || (vtr_op == ~0))
15792     {
15793       errmsg ("missing sw_if_index or vtr operation\n");
15794       return -99;
15795     }
15796   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15797       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15798     {
15799       errmsg
15800         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15801       return -99;
15802     }
15803
15804   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15805   mp->sw_if_index = ntohl (sw_if_index);
15806   mp->vtr_op = ntohl (vtr_op);
15807   mp->outer_tag = ntohs (outer_tag);
15808   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15809   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15810   mp->b_vlanid = ntohs (vlanid);
15811   mp->i_sid = ntohl (sid);
15812
15813   S;
15814   W;
15815   /* NOTREACHED */
15816   return 0;
15817 }
15818
15819 static int
15820 api_flow_classify_set_interface (vat_main_t * vam)
15821 {
15822   unformat_input_t *i = vam->input;
15823   vl_api_flow_classify_set_interface_t *mp;
15824   f64 timeout;
15825   u32 sw_if_index;
15826   int sw_if_index_set;
15827   u32 ip4_table_index = ~0;
15828   u32 ip6_table_index = ~0;
15829   u8 is_add = 1;
15830
15831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15832     {
15833       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15834         sw_if_index_set = 1;
15835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15836         sw_if_index_set = 1;
15837       else if (unformat (i, "del"))
15838         is_add = 0;
15839       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15840         ;
15841       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15842         ;
15843       else
15844         {
15845           clib_warning ("parse error '%U'", format_unformat_error, i);
15846           return -99;
15847         }
15848     }
15849
15850   if (sw_if_index_set == 0)
15851     {
15852       errmsg ("missing interface name or sw_if_index\n");
15853       return -99;
15854     }
15855
15856   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
15857
15858   mp->sw_if_index = ntohl (sw_if_index);
15859   mp->ip4_table_index = ntohl (ip4_table_index);
15860   mp->ip6_table_index = ntohl (ip6_table_index);
15861   mp->is_add = is_add;
15862
15863   S;
15864   W;
15865   /* NOTREACHED */
15866   return 0;
15867 }
15868
15869 static int
15870 api_flow_classify_dump (vat_main_t * vam)
15871 {
15872   unformat_input_t *i = vam->input;
15873   vl_api_flow_classify_dump_t *mp;
15874   f64 timeout = ~0;
15875   u8 type = FLOW_CLASSIFY_N_TABLES;
15876
15877   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
15878     ;
15879   else
15880     {
15881       errmsg ("classify table type must be specified\n");
15882       return -99;
15883     }
15884
15885   if (!vam->json_output)
15886     {
15887       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15888     }
15889
15890   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
15891   mp->type = type;
15892   /* send it... */
15893   S;
15894
15895   /* Use a control ping for synchronization */
15896   {
15897     vl_api_control_ping_t *mp;
15898     M (CONTROL_PING, control_ping);
15899     S;
15900   }
15901   /* Wait for a reply... */
15902   W;
15903
15904   /* NOTREACHED */
15905   return 0;
15906 }
15907
15908 static int
15909 q_or_quit (vat_main_t * vam)
15910 {
15911   longjmp (vam->jump_buf, 1);
15912   return 0;                     /* not so much */
15913 }
15914
15915 static int
15916 q (vat_main_t * vam)
15917 {
15918   return q_or_quit (vam);
15919 }
15920
15921 static int
15922 quit (vat_main_t * vam)
15923 {
15924   return q_or_quit (vam);
15925 }
15926
15927 static int
15928 comment (vat_main_t * vam)
15929 {
15930   return 0;
15931 }
15932
15933 static int
15934 cmd_cmp (void *a1, void *a2)
15935 {
15936   u8 **c1 = a1;
15937   u8 **c2 = a2;
15938
15939   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15940 }
15941
15942 static int
15943 help (vat_main_t * vam)
15944 {
15945   u8 **cmds = 0;
15946   u8 *name = 0;
15947   hash_pair_t *p;
15948   unformat_input_t *i = vam->input;
15949   int j;
15950
15951   if (unformat (i, "%s", &name))
15952     {
15953       uword *hs;
15954
15955       vec_add1 (name, 0);
15956
15957       hs = hash_get_mem (vam->help_by_name, name);
15958       if (hs)
15959         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15960       else
15961         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15962       vec_free (name);
15963       return 0;
15964     }
15965
15966   fformat (vam->ofp, "Help is available for the following:\n");
15967
15968     /* *INDENT-OFF* */
15969     hash_foreach_pair (p, vam->function_by_name,
15970     ({
15971       vec_add1 (cmds, (u8 *)(p->key));
15972     }));
15973     /* *INDENT-ON* */
15974
15975   vec_sort_with_function (cmds, cmd_cmp);
15976
15977   for (j = 0; j < vec_len (cmds); j++)
15978     fformat (vam->ofp, "%s\n", cmds[j]);
15979
15980   vec_free (cmds);
15981   return 0;
15982 }
15983
15984 static int
15985 set (vat_main_t * vam)
15986 {
15987   u8 *name = 0, *value = 0;
15988   unformat_input_t *i = vam->input;
15989
15990   if (unformat (i, "%s", &name))
15991     {
15992       /* The input buffer is a vector, not a string. */
15993       value = vec_dup (i->buffer);
15994       vec_delete (value, i->index, 0);
15995       /* Almost certainly has a trailing newline */
15996       if (value[vec_len (value) - 1] == '\n')
15997         value[vec_len (value) - 1] = 0;
15998       /* Make sure it's a proper string, one way or the other */
15999       vec_add1 (value, 0);
16000       (void) clib_macro_set_value (&vam->macro_main,
16001                                    (char *) name, (char *) value);
16002     }
16003   else
16004     errmsg ("usage: set <name> <value>\n");
16005
16006   vec_free (name);
16007   vec_free (value);
16008   return 0;
16009 }
16010
16011 static int
16012 unset (vat_main_t * vam)
16013 {
16014   u8 *name = 0;
16015
16016   if (unformat (vam->input, "%s", &name))
16017     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16018       errmsg ("unset: %s wasn't set\n", name);
16019   vec_free (name);
16020   return 0;
16021 }
16022
16023 typedef struct
16024 {
16025   u8 *name;
16026   u8 *value;
16027 } macro_sort_t;
16028
16029
16030 static int
16031 macro_sort_cmp (void *a1, void *a2)
16032 {
16033   macro_sort_t *s1 = a1;
16034   macro_sort_t *s2 = a2;
16035
16036   return strcmp ((char *) (s1->name), (char *) (s2->name));
16037 }
16038
16039 static int
16040 dump_macro_table (vat_main_t * vam)
16041 {
16042   macro_sort_t *sort_me = 0, *sm;
16043   int i;
16044   hash_pair_t *p;
16045
16046     /* *INDENT-OFF* */
16047     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16048     ({
16049       vec_add2 (sort_me, sm, 1);
16050       sm->name = (u8 *)(p->key);
16051       sm->value = (u8 *) (p->value[0]);
16052     }));
16053     /* *INDENT-ON* */
16054
16055   vec_sort_with_function (sort_me, macro_sort_cmp);
16056
16057   if (vec_len (sort_me))
16058     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16059   else
16060     fformat (vam->ofp, "The macro table is empty...\n");
16061
16062   for (i = 0; i < vec_len (sort_me); i++)
16063     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16064   return 0;
16065 }
16066
16067 static int
16068 dump_node_table (vat_main_t * vam)
16069 {
16070   int i, j;
16071   vlib_node_t *node, *next_node;
16072
16073   if (vec_len (vam->graph_nodes) == 0)
16074     {
16075       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16076       return 0;
16077     }
16078
16079   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16080     {
16081       node = vam->graph_nodes[i];
16082       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16083       for (j = 0; j < vec_len (node->next_nodes); j++)
16084         {
16085           if (node->next_nodes[j] != ~0)
16086             {
16087               next_node = vam->graph_nodes[node->next_nodes[j]];
16088               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16089             }
16090         }
16091     }
16092   return 0;
16093 }
16094
16095 static int
16096 search_node_table (vat_main_t * vam)
16097 {
16098   unformat_input_t *line_input = vam->input;
16099   u8 *node_to_find;
16100   int j;
16101   vlib_node_t *node, *next_node;
16102   uword *p;
16103
16104   if (vam->graph_node_index_by_name == 0)
16105     {
16106       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16107       return 0;
16108     }
16109
16110   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16111     {
16112       if (unformat (line_input, "%s", &node_to_find))
16113         {
16114           vec_add1 (node_to_find, 0);
16115           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16116           if (p == 0)
16117             {
16118               fformat (vam->ofp, "%s not found...\n", node_to_find);
16119               goto out;
16120             }
16121           node = vam->graph_nodes[p[0]];
16122           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16123           for (j = 0; j < vec_len (node->next_nodes); j++)
16124             {
16125               if (node->next_nodes[j] != ~0)
16126                 {
16127                   next_node = vam->graph_nodes[node->next_nodes[j]];
16128                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16129                 }
16130             }
16131         }
16132
16133       else
16134         {
16135           clib_warning ("parse error '%U'", format_unformat_error,
16136                         line_input);
16137           return -99;
16138         }
16139
16140     out:
16141       vec_free (node_to_find);
16142
16143     }
16144
16145   return 0;
16146 }
16147
16148
16149 static int
16150 script (vat_main_t * vam)
16151 {
16152   u8 *s = 0;
16153   char *save_current_file;
16154   unformat_input_t save_input;
16155   jmp_buf save_jump_buf;
16156   u32 save_line_number;
16157
16158   FILE *new_fp, *save_ifp;
16159
16160   if (unformat (vam->input, "%s", &s))
16161     {
16162       new_fp = fopen ((char *) s, "r");
16163       if (new_fp == 0)
16164         {
16165           errmsg ("Couldn't open script file %s\n", s);
16166           vec_free (s);
16167           return -99;
16168         }
16169     }
16170   else
16171     {
16172       errmsg ("Missing script name\n");
16173       return -99;
16174     }
16175
16176   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16177   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16178   save_ifp = vam->ifp;
16179   save_line_number = vam->input_line_number;
16180   save_current_file = (char *) vam->current_file;
16181
16182   vam->input_line_number = 0;
16183   vam->ifp = new_fp;
16184   vam->current_file = s;
16185   do_one_file (vam);
16186
16187   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16188   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16189   vam->ifp = save_ifp;
16190   vam->input_line_number = save_line_number;
16191   vam->current_file = (u8 *) save_current_file;
16192   vec_free (s);
16193
16194   return 0;
16195 }
16196
16197 static int
16198 echo (vat_main_t * vam)
16199 {
16200   fformat (vam->ofp, "%v", vam->input->buffer);
16201   return 0;
16202 }
16203
16204 /* List of API message constructors, CLI names map to api_xxx */
16205 #define foreach_vpe_api_msg                                             \
16206 _(create_loopback,"[mac <mac-addr>]")                                   \
16207 _(sw_interface_dump,"")                                                 \
16208 _(sw_interface_set_flags,                                               \
16209   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16210 _(sw_interface_add_del_address,                                         \
16211   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16212 _(sw_interface_set_table,                                               \
16213   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16214 _(sw_interface_set_mpls_enable,                                                \
16215   "<intfc> | sw_if_index [disable | dis]")                                \
16216 _(sw_interface_set_vpath,                                               \
16217   "<intfc> | sw_if_index <id> enable | disable")                        \
16218 _(sw_interface_set_l2_xconnect,                                         \
16219   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16220   "enable | disable")                                                   \
16221 _(sw_interface_set_l2_bridge,                                           \
16222   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16223   "[shg <split-horizon-group>] [bvi]\n"                                 \
16224   "enable | disable")                                                   \
16225 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16226   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16227   "profile <profile-id>\n")                                             \
16228 _(sw_interface_set_dpdk_hqos_subport,                                   \
16229   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16230   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16231 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16232   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16233 _(bridge_domain_add_del,                                                \
16234   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16235 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16236 _(l2fib_add_del,                                                        \
16237   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16238 _(l2_flags,                                                             \
16239   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16240 _(bridge_flags,                                                         \
16241   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16242 _(tap_connect,                                                          \
16243   "tapname <name> mac <mac-addr> | random-mac")                         \
16244 _(tap_modify,                                                           \
16245   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16246 _(tap_delete,                                                           \
16247   "<vpp-if-name> | sw_if_index <id>")                                   \
16248 _(sw_interface_tap_dump, "")                                            \
16249 _(ip_add_del_route,                                                     \
16250   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16251   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16252   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16253   "[multipath] [count <n>]")                                            \
16254 _(mpls_route_add_del,                                                   \
16255   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16256   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16257   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16258   "[multipath] [count <n>]")                                            \
16259 _(mpls_ip_bind_unbind,                                                  \
16260   "<label> <addr/len>")                                                 \
16261 _(proxy_arp_add_del,                                                    \
16262   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16263 _(proxy_arp_intfc_enable_disable,                                       \
16264   "<intfc> | sw_if_index <id> enable | disable")                        \
16265 _(mpls_add_del_encap,                                                   \
16266   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16267 _(sw_interface_set_unnumbered,                                          \
16268   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16269 _(ip_neighbor_add_del,                                                  \
16270   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16271   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16272 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16273 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16274 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16275   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16276   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16277   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16278 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16279 _(reset_fib, "vrf <n> [ipv6]")                                          \
16280 _(dhcp_proxy_config,                                                    \
16281   "svr <v46-address> src <v46-address>\n"                               \
16282    "insert-cid <n> [del]")                                              \
16283 _(dhcp_proxy_config_2,                                                  \
16284   "svr <v46-address> src <v46-address>\n"                               \
16285    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16286 _(dhcp_proxy_set_vss,                                                   \
16287   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16288 _(dhcp_client_config,                                                   \
16289   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16290 _(set_ip_flow_hash,                                                     \
16291   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16292 _(sw_interface_ip6_enable_disable,                                      \
16293   "<intfc> | sw_if_index <id> enable | disable")                        \
16294 _(sw_interface_ip6_set_link_local_address,                              \
16295   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16296 _(sw_interface_ip6nd_ra_prefix,                                         \
16297   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16298   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16299   "[nolink] [isno]")                                                    \
16300 _(sw_interface_ip6nd_ra_config,                                         \
16301   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16302   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16303   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16304 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16305 _(l2_patch_add_del,                                                     \
16306   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16307   "enable | disable")                                                   \
16308 _(mpls_ethernet_add_del_tunnel,                                         \
16309   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16310   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16311 _(mpls_ethernet_add_del_tunnel_2,                                       \
16312   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16313   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16314 _(sr_tunnel_add_del,                                                    \
16315   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16316   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16317   "[policy <policy_name>]")                                             \
16318 _(sr_policy_add_del,                                                    \
16319   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16320 _(sr_multicast_map_add_del,                                             \
16321   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16322 _(classify_add_del_table,                                               \
16323   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16324   "[del] mask <mask-value>\n"                                           \
16325   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
16326 _(classify_add_del_session,                                             \
16327   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16328   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16329   "  [l3 [ip4|ip6]]")                                                   \
16330 _(classify_set_interface_ip_table,                                      \
16331   "<intfc> | sw_if_index <nn> table <nn>")                              \
16332 _(classify_set_interface_l2_tables,                                     \
16333   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16334   "  [other-table <nn>]")                                               \
16335 _(get_node_index, "node <node-name")                                    \
16336 _(add_node_next, "node <node-name> next <next-node-name>")              \
16337 _(l2tpv3_create_tunnel,                                                 \
16338   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16339   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16340   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16341 _(l2tpv3_set_tunnel_cookies,                                            \
16342   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16343   "[new_remote_cookie <nn>]\n")                                         \
16344 _(l2tpv3_interface_enable_disable,                                      \
16345   "<intfc> | sw_if_index <nn> enable | disable")                        \
16346 _(l2tpv3_set_lookup_key,                                                \
16347   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16348 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16349 _(vxlan_add_del_tunnel,                                                 \
16350   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16351   " [decap-next l2|ip4|ip6] [del]")                                     \
16352 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16353 _(gre_add_del_tunnel,                                                   \
16354   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16355 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16356 _(l2_fib_clear_table, "")                                               \
16357 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16358 _(l2_interface_vlan_tag_rewrite,                                        \
16359   "<intfc> | sw_if_index <nn> \n"                                       \
16360   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16361   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16362 _(create_vhost_user_if,                                                 \
16363         "socket <filename> [server] [renumber <dev_instance>] "         \
16364         "[mac <mac_address>]")                                          \
16365 _(modify_vhost_user_if,                                                 \
16366         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16367         "[server] [renumber <dev_instance>]")                           \
16368 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16369 _(sw_interface_vhost_user_dump, "")                                     \
16370 _(show_version, "")                                                     \
16371 _(vxlan_gpe_add_del_tunnel,                                             \
16372   "local <addr> remote <addr> vni <nn>\n"                               \
16373     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16374   "[next-ethernet] [next-nsh]\n")                                       \
16375 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16376 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16377 _(interface_name_renumber,                                              \
16378   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16379 _(input_acl_set_interface,                                              \
16380   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16381   "  [l2-table <nn>] [del]")                                            \
16382 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16383 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16384 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16385 _(ip_dump, "ipv4 | ipv6")                                               \
16386 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16387 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16388   "  spid_id <n> ")                                                     \
16389 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16390   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16391   "  integ_alg <alg> integ_key <hex>")                                  \
16392 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16393   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16394   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16395   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16396 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16397 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16398 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16399   "(auth_data 0x<data> | auth_data <data>)")                            \
16400 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16401   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16402 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16403   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16404   "(local|remote)")                                                     \
16405 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16406 _(delete_loopback,"sw_if_index <nn>")                                   \
16407 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16408 _(map_add_domain,                                                       \
16409   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16410   "ip6-src <ip6addr> "                                                  \
16411   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16412 _(map_del_domain, "index <n>")                                          \
16413 _(map_add_del_rule,                                                     \
16414   "index <n> psid <n> dst <ip6addr> [del]")                             \
16415 _(map_domain_dump, "")                                                  \
16416 _(map_rule_dump, "index <map-domain>")                                  \
16417 _(want_interface_events,  "enable|disable")                             \
16418 _(want_stats,"enable|disable")                                          \
16419 _(get_first_msg_id, "client <name>")                                    \
16420 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16421 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16422   "fib-id <nn> [ip4][ip6][default]")                                    \
16423 _(get_node_graph, " ")                                                  \
16424 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16425 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16426 _(ioam_disable, "")                                                \
16427 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16428                             " sw_if_index <sw_if_index> p <priority> "  \
16429                             "w <weight>] [del]")                        \
16430 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16431                         "iface <intf> | sw_if_index <sw_if_index> "     \
16432                         "p <priority> w <weight> [del]")                \
16433 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16434                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16435                           "locator-set <locator_name> [del]")           \
16436 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16437   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16438 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16439 _(lisp_gpe_enable_disable, "enable|disable")                            \
16440 _(lisp_enable_disable, "enable|disable")                                \
16441 _(lisp_gpe_add_del_iface, "up|down")                                    \
16442 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16443                                "[seid <seid>] "                         \
16444                                "rloc <locator> p <prio> "               \
16445                                "w <weight> [rloc <loc> ... ] "          \
16446                                "action <action> [del-all]")             \
16447 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16448                           "<local-eid>")                                \
16449 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16450 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16451 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16452 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16453 _(lisp_locator_set_dump, "[local | remote]")                            \
16454 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16455 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16456                        "[local] | [remote]")                            \
16457 _(lisp_eid_table_vni_dump, "")                                          \
16458 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16459 _(lisp_gpe_tunnel_dump, "")                                             \
16460 _(lisp_map_resolver_dump, "")                                           \
16461 _(lisp_adjacencies_get, "vni <vni>")                                    \
16462 _(show_lisp_status, "")                                                 \
16463 _(lisp_get_map_request_itr_rlocs, "")                                   \
16464 _(show_lisp_pitr, "")                                                   \
16465 _(show_lisp_map_request_mode, "")                                       \
16466 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16467 _(af_packet_delete, "name <host interface name>")                       \
16468 _(policer_add_del, "name <policer name> <params> [del]")                \
16469 _(policer_dump, "[name <policer name>]")                                \
16470 _(policer_classify_set_interface,                                       \
16471   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16472   "  [l2-table <nn>] [del]")                                            \
16473 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16474 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16475     "[master|slave]")                                                   \
16476 _(netmap_delete, "name <interface name>")                               \
16477 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16478 _(mpls_fib_encap_dump, "")                                              \
16479 _(mpls_fib_dump, "")                                                    \
16480 _(classify_table_ids, "")                                               \
16481 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16482 _(classify_table_info, "table_id <nn>")                                 \
16483 _(classify_session_dump, "table_id <nn>")                               \
16484 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16485     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16486     "[template_interval <nn>] [udp_checksum]")                          \
16487 _(ipfix_exporter_dump, "")                                              \
16488 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16489 _(ipfix_classify_stream_dump, "")                                       \
16490 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16491 _(ipfix_classify_table_dump, "")                                        \
16492 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16493 _(pg_create_interface, "if_id <nn>")                                    \
16494 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16495 _(pg_enable_disable, "[stream <id>] disable")                           \
16496 _(ip_source_and_port_range_check_add_del,                               \
16497   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16498 _(ip_source_and_port_range_check_interface_add_del,                     \
16499   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16500   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16501 _(ipsec_gre_add_del_tunnel,                                             \
16502   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16503 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16504 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
16505 _(l2_interface_pbb_tag_rewrite,                                         \
16506   "<intfc> | sw_if_index <nn> \n"                                       \
16507   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16508   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16509 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16510 _(flow_classify_set_interface,                                          \
16511   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16512 _(flow_classify_dump, "type [ip4|ip6]")
16513
16514 /* List of command functions, CLI names map directly to functions */
16515 #define foreach_cli_function                                    \
16516 _(comment, "usage: comment <ignore-rest-of-line>")              \
16517 _(dump_interface_table, "usage: dump_interface_table")          \
16518 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16519 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16520 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16521 _(dump_stats_table, "usage: dump_stats_table")                  \
16522 _(dump_macro_table, "usage: dump_macro_table ")                 \
16523 _(dump_node_table, "usage: dump_node_table")                    \
16524 _(echo, "usage: echo <message>")                                \
16525 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16526 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16527 _(help, "usage: help")                                          \
16528 _(q, "usage: quit")                                             \
16529 _(quit, "usage: quit")                                          \
16530 _(search_node_table, "usage: search_node_table <name>...")      \
16531 _(set, "usage: set <variable-name> <value>")                    \
16532 _(script, "usage: script <file-name>")                          \
16533 _(unset, "usage: unset <variable-name>")
16534
16535 #define _(N,n)                                  \
16536     static void vl_api_##n##_t_handler_uni      \
16537     (vl_api_##n##_t * mp)                       \
16538     {                                           \
16539         vat_main_t * vam = &vat_main;           \
16540         if (vam->json_output) {                 \
16541             vl_api_##n##_t_handler_json(mp);    \
16542         } else {                                \
16543             vl_api_##n##_t_handler(mp);         \
16544         }                                       \
16545     }
16546 foreach_vpe_api_reply_msg;
16547 #undef _
16548
16549 void
16550 vat_api_hookup (vat_main_t * vam)
16551 {
16552 #define _(N,n)                                                  \
16553     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16554                            vl_api_##n##_t_handler_uni,          \
16555                            vl_noop_handler,                     \
16556                            vl_api_##n##_t_endian,               \
16557                            vl_api_##n##_t_print,                \
16558                            sizeof(vl_api_##n##_t), 1);
16559   foreach_vpe_api_reply_msg;
16560 #undef _
16561
16562   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16563
16564   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16565
16566   vam->function_by_name = hash_create_string (0, sizeof (uword));
16567
16568   vam->help_by_name = hash_create_string (0, sizeof (uword));
16569
16570   /* API messages we can send */
16571 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16572   foreach_vpe_api_msg;
16573 #undef _
16574
16575   /* Help strings */
16576 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16577   foreach_vpe_api_msg;
16578 #undef _
16579
16580   /* CLI functions */
16581 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16582   foreach_cli_function;
16583 #undef _
16584
16585   /* Help strings */
16586 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16587   foreach_cli_function;
16588 #undef _
16589 }
16590
16591 #undef vl_api_version
16592 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16593 #include <vpp-api/vpe.api.h>
16594 #undef vl_api_version
16595
16596 void
16597 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16598 {
16599   /*
16600    * Send the main API signature in slot 0. This bit of code must
16601    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16602    */
16603   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16604 }
16605
16606 /*
16607  * fd.io coding-style-patch-verification: ON
16608  *
16609  * Local Variables:
16610  * eval: (c-set-style "gnu")
16611  * End:
16612  */