fec31588128cea35b4e135501c2db68a00fc8a64
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53
54 #include "vat/json_format.h"
55
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp-api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp-api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp-api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 uword
75 unformat_sw_if_index (unformat_input_t * input, va_list * args)
76 {
77   vat_main_t *vam = va_arg (*args, vat_main_t *);
78   u32 *result = va_arg (*args, u32 *);
79   u8 *if_name;
80   uword *p;
81
82   if (!unformat (input, "%s", &if_name))
83     return 0;
84
85   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
86   if (p == 0)
87     return 0;
88   *result = p[0];
89   return 1;
90 }
91
92 /* Parse an IP4 address %d.%d.%d.%d. */
93 uword
94 unformat_ip4_address (unformat_input_t * input, va_list * args)
95 {
96   u8 *result = va_arg (*args, u8 *);
97   unsigned a[4];
98
99   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
100     return 0;
101
102   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
103     return 0;
104
105   result[0] = a[0];
106   result[1] = a[1];
107   result[2] = a[2];
108   result[3] = a[3];
109
110   return 1;
111 }
112
113
114 uword
115 unformat_ethernet_address (unformat_input_t * input, va_list * args)
116 {
117   u8 *result = va_arg (*args, u8 *);
118   u32 i, a[6];
119
120   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
121                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
122     return 0;
123
124   /* Check range. */
125   for (i = 0; i < 6; i++)
126     if (a[i] >= (1 << 8))
127       return 0;
128
129   for (i = 0; i < 6; i++)
130     result[i] = a[i];
131
132   return 1;
133 }
134
135 /* Returns ethernet type as an int in host byte order. */
136 uword
137 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
138                                         va_list * args)
139 {
140   u16 *result = va_arg (*args, u16 *);
141   int type;
142
143   /* Numeric type. */
144   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
145     {
146       if (type >= (1 << 16))
147         return 0;
148       *result = type;
149       return 1;
150     }
151   return 0;
152 }
153
154 /* Parse an IP6 address. */
155 uword
156 unformat_ip6_address (unformat_input_t * input, va_list * args)
157 {
158   ip6_address_t *result = va_arg (*args, ip6_address_t *);
159   u16 hex_quads[8];
160   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
161   uword c, n_colon, double_colon_index;
162
163   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
164   double_colon_index = ARRAY_LEN (hex_quads);
165   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
166     {
167       hex_digit = 16;
168       if (c >= '0' && c <= '9')
169         hex_digit = c - '0';
170       else if (c >= 'a' && c <= 'f')
171         hex_digit = c + 10 - 'a';
172       else if (c >= 'A' && c <= 'F')
173         hex_digit = c + 10 - 'A';
174       else if (c == ':' && n_colon < 2)
175         n_colon++;
176       else
177         {
178           unformat_put_input (input);
179           break;
180         }
181
182       /* Too many hex quads. */
183       if (n_hex_quads >= ARRAY_LEN (hex_quads))
184         return 0;
185
186       if (hex_digit < 16)
187         {
188           hex_quad = (hex_quad << 4) | hex_digit;
189
190           /* Hex quad must fit in 16 bits. */
191           if (n_hex_digits >= 4)
192             return 0;
193
194           n_colon = 0;
195           n_hex_digits++;
196         }
197
198       /* Save position of :: */
199       if (n_colon == 2)
200         {
201           /* More than one :: ? */
202           if (double_colon_index < ARRAY_LEN (hex_quads))
203             return 0;
204           double_colon_index = n_hex_quads;
205         }
206
207       if (n_colon > 0 && n_hex_digits > 0)
208         {
209           hex_quads[n_hex_quads++] = hex_quad;
210           hex_quad = 0;
211           n_hex_digits = 0;
212         }
213     }
214
215   if (n_hex_digits > 0)
216     hex_quads[n_hex_quads++] = hex_quad;
217
218   {
219     word i;
220
221     /* Expand :: to appropriate number of zero hex quads. */
222     if (double_colon_index < ARRAY_LEN (hex_quads))
223       {
224         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
225
226         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
227           hex_quads[n_zero + i] = hex_quads[i];
228
229         for (i = 0; i < n_zero; i++)
230           hex_quads[double_colon_index + i] = 0;
231
232         n_hex_quads = ARRAY_LEN (hex_quads);
233       }
234
235     /* Too few hex quads given. */
236     if (n_hex_quads < ARRAY_LEN (hex_quads))
237       return 0;
238
239     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
240       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
241
242     return 1;
243   }
244 }
245
246 uword
247 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
248 {
249 #if DPDK > 0
250   u32 *r = va_arg (*args, u32 *);
251
252   if (0);
253 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254   foreach_ipsec_policy_action
255 #undef _
256     else
257     return 0;
258   return 1;
259 #else
260   return 0;
261 #endif
262 }
263
264 uword
265 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
266 {
267 #if DPDK > 0
268   u32 *r = va_arg (*args, u32 *);
269
270   if (0);
271 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
272   foreach_ipsec_crypto_alg
273 #undef _
274     else
275     return 0;
276   return 1;
277 #else
278   return 0;
279 #endif
280 }
281
282 u8 *
283 format_ipsec_crypto_alg (u8 * s, va_list * args)
284 {
285 #if DPDK > 0
286   u32 i = va_arg (*args, u32);
287   u8 *t = 0;
288
289   switch (i)
290     {
291 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
292       foreach_ipsec_crypto_alg
293 #undef _
294     default:
295       return format (s, "unknown");
296     }
297   return format (s, "%s", t);
298 #else
299   return format (s, "Unimplemented");
300 #endif
301 }
302
303 uword
304 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
305 {
306 #if DPDK > 0
307   u32 *r = va_arg (*args, u32 *);
308
309   if (0);
310 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
311   foreach_ipsec_integ_alg
312 #undef _
313     else
314     return 0;
315   return 1;
316 #else
317   return 0;
318 #endif
319 }
320
321 u8 *
322 format_ipsec_integ_alg (u8 * s, va_list * args)
323 {
324 #if DPDK > 0
325   u32 i = va_arg (*args, u32);
326   u8 *t = 0;
327
328   switch (i)
329     {
330 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
331       foreach_ipsec_integ_alg
332 #undef _
333     default:
334       return format (s, "unknown");
335     }
336   return format (s, "%s", t);
337 #else
338   return format (s, "Unsupported");
339 #endif
340 }
341
342 uword
343 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
344 {
345 #if DPDK > 0
346   u32 *r = va_arg (*args, u32 *);
347
348   if (0);
349 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
350   foreach_ikev2_auth_method
351 #undef _
352     else
353     return 0;
354   return 1;
355 #else
356   return 0;
357 #endif
358 }
359
360 uword
361 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
362 {
363 #if DPDK > 0
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
368   foreach_ikev2_id_type
369 #undef _
370     else
371     return 0;
372   return 1;
373 #else
374   return 0;
375 #endif
376 }
377
378 uword
379 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
380 {
381   u8 *r = va_arg (*args, u8 *);
382
383   if (unformat (input, "kbps"))
384     *r = SSE2_QOS_RATE_KBPS;
385   else if (unformat (input, "pps"))
386     *r = SSE2_QOS_RATE_PPS;
387   else
388     return 0;
389   return 1;
390 }
391
392 uword
393 unformat_policer_round_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "closest"))
398     *r = SSE2_QOS_ROUND_TO_CLOSEST;
399   else if (unformat (input, "up"))
400     *r = SSE2_QOS_ROUND_TO_UP;
401   else if (unformat (input, "down"))
402     *r = SSE2_QOS_ROUND_TO_DOWN;
403   else
404     return 0;
405   return 1;
406 }
407
408 uword
409 unformat_policer_type (unformat_input_t * input, va_list * args)
410 {
411   u8 *r = va_arg (*args, u8 *);
412
413   if (unformat (input, "1r2c"))
414     *r = SSE2_QOS_POLICER_TYPE_1R2C;
415   else if (unformat (input, "1r3c"))
416     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
417   else if (unformat (input, "2r3c-2698"))
418     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
419   else if (unformat (input, "2r3c-4115"))
420     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
421   else if (unformat (input, "2r3c-mef5cf1"))
422     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
423   else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_dscp (unformat_input_t * input, va_list * va)
430 {
431   u8 *r = va_arg (*va, u8 *);
432
433   if (0);
434 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
435   foreach_vnet_dscp
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_policer_action_type (unformat_input_t * input, va_list * va)
444 {
445   sse2_qos_pol_action_params_st *a
446     = va_arg (*va, sse2_qos_pol_action_params_st *);
447
448   if (unformat (input, "drop"))
449     a->action_type = SSE2_QOS_ACTION_DROP;
450   else if (unformat (input, "transmit"))
451     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
452   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
453     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
454   else
455     return 0;
456   return 1;
457 }
458
459 uword
460 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
461 {
462   u32 *r = va_arg (*va, u32 *);
463   u32 tid;
464
465   if (unformat (input, "ip4"))
466     tid = POLICER_CLASSIFY_TABLE_IP4;
467   else if (unformat (input, "ip6"))
468     tid = POLICER_CLASSIFY_TABLE_IP6;
469   else if (unformat (input, "l2"))
470     tid = POLICER_CLASSIFY_TABLE_L2;
471   else
472     return 0;
473
474   *r = tid;
475   return 1;
476 }
477
478 uword
479 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
480 {
481   u32 *r = va_arg (*va, u32 *);
482   u32 tid;
483
484   if (unformat (input, "ip4"))
485     tid = FLOW_CLASSIFY_TABLE_IP4;
486   else if (unformat (input, "ip6"))
487     tid = FLOW_CLASSIFY_TABLE_IP6;
488   else
489     return 0;
490
491   *r = tid;
492   return 1;
493 }
494
495 u8 *
496 format_ip4_address (u8 * s, va_list * args)
497 {
498   u8 *a = va_arg (*args, u8 *);
499   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
500 }
501
502 u8 *
503 format_ip6_address (u8 * s, va_list * args)
504 {
505   ip6_address_t *a = va_arg (*args, ip6_address_t *);
506   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
507
508   i_max_n_zero = ARRAY_LEN (a->as_u16);
509   max_n_zeros = 0;
510   i_first_zero = i_max_n_zero;
511   n_zeros = 0;
512   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
513     {
514       u32 is_zero = a->as_u16[i] == 0;
515       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
516         {
517           i_first_zero = i;
518           n_zeros = 0;
519         }
520       n_zeros += is_zero;
521       if ((!is_zero && n_zeros > max_n_zeros)
522           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
523         {
524           i_max_n_zero = i_first_zero;
525           max_n_zeros = n_zeros;
526           i_first_zero = ARRAY_LEN (a->as_u16);
527           n_zeros = 0;
528         }
529     }
530
531   last_double_colon = 0;
532   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
533     {
534       if (i == i_max_n_zero && max_n_zeros > 1)
535         {
536           s = format (s, "::");
537           i += max_n_zeros - 1;
538           last_double_colon = 1;
539         }
540       else
541         {
542           s = format (s, "%s%x",
543                       (last_double_colon || i == 0) ? "" : ":",
544                       clib_net_to_host_u16 (a->as_u16[i]));
545           last_double_colon = 0;
546         }
547     }
548
549   return s;
550 }
551
552 /* Format an IP46 address. */
553 u8 *
554 format_ip46_address (u8 * s, va_list * args)
555 {
556   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
557   ip46_type_t type = va_arg (*args, ip46_type_t);
558   int is_ip4 = 1;
559
560   switch (type)
561     {
562     case IP46_TYPE_ANY:
563       is_ip4 = ip46_address_is_ip4 (ip46);
564       break;
565     case IP46_TYPE_IP4:
566       is_ip4 = 1;
567       break;
568     case IP46_TYPE_IP6:
569       is_ip4 = 0;
570       break;
571     }
572
573   return is_ip4 ?
574     format (s, "%U", format_ip4_address, &ip46->ip4) :
575     format (s, "%U", format_ip6_address, &ip46->ip6);
576 }
577
578 u8 *
579 format_ethernet_address (u8 * s, va_list * args)
580 {
581   u8 *a = va_arg (*args, u8 *);
582
583   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
584                  a[0], a[1], a[2], a[3], a[4], a[5]);
585 }
586
587 void
588 increment_v4_address (ip4_address_t * a)
589 {
590   u32 v;
591
592   v = ntohl (a->as_u32) + 1;
593   a->as_u32 = ntohl (v);
594 }
595
596 void
597 increment_v6_address (ip6_address_t * a)
598 {
599   u64 v0, v1;
600
601   v0 = clib_net_to_host_u64 (a->as_u64[0]);
602   v1 = clib_net_to_host_u64 (a->as_u64[1]);
603
604   v1 += 1;
605   if (v1 == 0)
606     v0 += 1;
607   a->as_u64[0] = clib_net_to_host_u64 (v0);
608   a->as_u64[1] = clib_net_to_host_u64 (v1);
609 }
610
611 void
612 increment_mac_address (u64 * mac)
613 {
614   u64 tmp = *mac;
615
616   tmp = clib_net_to_host_u64 (tmp);
617   tmp += 1 << 16;               /* skip unused (least significant) octets */
618   tmp = clib_host_to_net_u64 (tmp);
619   *mac = tmp;
620 }
621
622 static void vl_api_create_loopback_reply_t_handler
623   (vl_api_create_loopback_reply_t * mp)
624 {
625   vat_main_t *vam = &vat_main;
626   i32 retval = ntohl (mp->retval);
627
628   vam->retval = retval;
629   vam->regenerate_interface_table = 1;
630   vam->sw_if_index = ntohl (mp->sw_if_index);
631   vam->result_ready = 1;
632 }
633
634 static void vl_api_create_loopback_reply_t_handler_json
635   (vl_api_create_loopback_reply_t * mp)
636 {
637   vat_main_t *vam = &vat_main;
638   vat_json_node_t node;
639
640   vat_json_init_object (&node);
641   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
642   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
643
644   vat_json_print (vam->ofp, &node);
645   vat_json_free (&node);
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_af_packet_create_reply_t_handler
651   (vl_api_af_packet_create_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_af_packet_create_reply_t_handler_json
663   (vl_api_af_packet_create_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_vlan_subif_reply_t_handler
680   (vl_api_create_vlan_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_vlan_subif_reply_t_handler_json
692   (vl_api_create_vlan_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_create_subif_reply_t_handler
709   (vl_api_create_subif_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->sw_if_index = ntohl (mp->sw_if_index);
717   vam->result_ready = 1;
718 }
719
720 static void vl_api_create_subif_reply_t_handler_json
721   (vl_api_create_subif_reply_t * mp)
722 {
723   vat_main_t *vam = &vat_main;
724   vat_json_node_t node;
725
726   vat_json_init_object (&node);
727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
729
730   vat_json_print (vam->ofp, &node);
731   vat_json_free (&node);
732
733   vam->retval = ntohl (mp->retval);
734   vam->result_ready = 1;
735 }
736
737 static void vl_api_interface_name_renumber_reply_t_handler
738   (vl_api_interface_name_renumber_reply_t * mp)
739 {
740   vat_main_t *vam = &vat_main;
741   i32 retval = ntohl (mp->retval);
742
743   vam->retval = retval;
744   vam->regenerate_interface_table = 1;
745   vam->result_ready = 1;
746 }
747
748 static void vl_api_interface_name_renumber_reply_t_handler_json
749   (vl_api_interface_name_renumber_reply_t * mp)
750 {
751   vat_main_t *vam = &vat_main;
752   vat_json_node_t node;
753
754   vat_json_init_object (&node);
755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
756
757   vat_json_print (vam->ofp, &node);
758   vat_json_free (&node);
759
760   vam->retval = ntohl (mp->retval);
761   vam->result_ready = 1;
762 }
763
764 /*
765  * Special-case: build the interface table, maintain
766  * the next loopback sw_if_index vbl.
767  */
768 static void vl_api_sw_interface_details_t_handler
769   (vl_api_sw_interface_details_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   u8 *s = format (0, "%s%c", mp->interface_name, 0);
773
774   hash_set_mem (vam->sw_if_index_by_interface_name, s,
775                 ntohl (mp->sw_if_index));
776
777   /* In sub interface case, fill the sub interface table entry */
778   if (mp->sw_if_index != mp->sup_sw_if_index)
779     {
780       sw_interface_subif_t *sub = NULL;
781
782       vec_add2 (vam->sw_if_subif_table, sub, 1);
783
784       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
785       strncpy ((char *) sub->interface_name, (char *) s,
786                vec_len (sub->interface_name));
787       sub->sw_if_index = ntohl (mp->sw_if_index);
788       sub->sub_id = ntohl (mp->sub_id);
789
790       sub->sub_dot1ad = mp->sub_dot1ad;
791       sub->sub_number_of_tags = mp->sub_number_of_tags;
792       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
793       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
794       sub->sub_exact_match = mp->sub_exact_match;
795       sub->sub_default = mp->sub_default;
796       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
797       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
798
799       /* vlan tag rewrite */
800       sub->vtr_op = ntohl (mp->vtr_op);
801       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
802       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
803       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
804     }
805 }
806
807 static void vl_api_sw_interface_details_t_handler_json
808   (vl_api_sw_interface_details_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t *node = NULL;
812
813   if (VAT_JSON_ARRAY != vam->json_tree.type)
814     {
815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
816       vat_json_init_array (&vam->json_tree);
817     }
818   node = vat_json_array_add (&vam->json_tree);
819
820   vat_json_init_object (node);
821   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
822   vat_json_object_add_uint (node, "sup_sw_if_index",
823                             ntohl (mp->sup_sw_if_index));
824   vat_json_object_add_uint (node, "l2_address_length",
825                             ntohl (mp->l2_address_length));
826   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
827                              sizeof (mp->l2_address));
828   vat_json_object_add_string_copy (node, "interface_name",
829                                    mp->interface_name);
830   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
831   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
832   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
833   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
834   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
835   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
836   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
837   vat_json_object_add_uint (node, "sub_number_of_tags",
838                             mp->sub_number_of_tags);
839   vat_json_object_add_uint (node, "sub_outer_vlan_id",
840                             ntohs (mp->sub_outer_vlan_id));
841   vat_json_object_add_uint (node, "sub_inner_vlan_id",
842                             ntohs (mp->sub_inner_vlan_id));
843   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
844   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
845   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
846                             mp->sub_outer_vlan_id_any);
847   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
848                             mp->sub_inner_vlan_id_any);
849   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
850   vat_json_object_add_uint (node, "vtr_push_dot1q",
851                             ntohl (mp->vtr_push_dot1q));
852   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
853   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
854 }
855
856 static void vl_api_sw_interface_set_flags_t_handler
857   (vl_api_sw_interface_set_flags_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   if (vam->interface_event_display)
861     errmsg ("interface flags: sw_if_index %d %s %s\n",
862             ntohl (mp->sw_if_index),
863             mp->admin_up_down ? "admin-up" : "admin-down",
864             mp->link_up_down ? "link-up" : "link-down");
865 }
866
867 static void vl_api_sw_interface_set_flags_t_handler_json
868   (vl_api_sw_interface_set_flags_t * mp)
869 {
870   /* JSON output not supported */
871 }
872
873 static void
874 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   i32 retval = ntohl (mp->retval);
878
879   vam->retval = retval;
880   vam->shmem_result = (u8 *) mp->reply_in_shmem;
881   vam->result_ready = 1;
882 }
883
884 static void
885 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   vat_json_node_t node;
889   api_main_t *am = &api_main;
890   void *oldheap;
891   u8 *reply;
892
893   vat_json_init_object (&node);
894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
895   vat_json_object_add_uint (&node, "reply_in_shmem",
896                             ntohl (mp->reply_in_shmem));
897   /* Toss the shared-memory original... */
898   pthread_mutex_lock (&am->vlib_rp->mutex);
899   oldheap = svm_push_data_heap (am->vlib_rp);
900
901   reply = (u8 *) (mp->reply_in_shmem);
902   vec_free (reply);
903
904   svm_pop_heap (oldheap);
905   pthread_mutex_unlock (&am->vlib_rp->mutex);
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 static void
915 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   i32 retval = ntohl (mp->retval);
919
920   vam->retval = retval;
921   vam->cmd_reply = mp->reply;
922   vam->result_ready = 1;
923 }
924
925 static void
926 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_string_copy (&node, "reply", mp->reply);
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_classify_add_del_table_reply_t_handler
943   (vl_api_classify_add_del_table_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947   if (vam->async_mode)
948     {
949       vam->async_errors += (retval < 0);
950     }
951   else
952     {
953       vam->retval = retval;
954       if (retval == 0 &&
955           ((mp->new_table_index != 0xFFFFFFFF) ||
956            (mp->skip_n_vectors != 0xFFFFFFFF) ||
957            (mp->match_n_vectors != 0xFFFFFFFF)))
958         /*
959          * Note: this is just barely thread-safe, depends on
960          * the main thread spinning waiting for an answer...
961          */
962         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
963                 ntohl (mp->new_table_index),
964                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
965       vam->result_ready = 1;
966     }
967 }
968
969 static void vl_api_classify_add_del_table_reply_t_handler_json
970   (vl_api_classify_add_del_table_reply_t * mp)
971 {
972   vat_main_t *vam = &vat_main;
973   vat_json_node_t node;
974
975   vat_json_init_object (&node);
976   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
977   vat_json_object_add_uint (&node, "new_table_index",
978                             ntohl (mp->new_table_index));
979   vat_json_object_add_uint (&node, "skip_n_vectors",
980                             ntohl (mp->skip_n_vectors));
981   vat_json_object_add_uint (&node, "match_n_vectors",
982                             ntohl (mp->match_n_vectors));
983
984   vat_json_print (vam->ofp, &node);
985   vat_json_free (&node);
986
987   vam->retval = ntohl (mp->retval);
988   vam->result_ready = 1;
989 }
990
991 static void vl_api_get_node_index_reply_t_handler
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   i32 retval = ntohl (mp->retval);
996   if (vam->async_mode)
997     {
998       vam->async_errors += (retval < 0);
999     }
1000   else
1001     {
1002       vam->retval = retval;
1003       if (retval == 0)
1004         errmsg ("node index %d\n", ntohl (mp->node_index));
1005       vam->result_ready = 1;
1006     }
1007 }
1008
1009 static void vl_api_get_node_index_reply_t_handler_json
1010   (vl_api_get_node_index_reply_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t node;
1014
1015   vat_json_init_object (&node);
1016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1017   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1018
1019   vat_json_print (vam->ofp, &node);
1020   vat_json_free (&node);
1021
1022   vam->retval = ntohl (mp->retval);
1023   vam->result_ready = 1;
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031   if (vam->async_mode)
1032     {
1033       vam->async_errors += (retval < 0);
1034     }
1035   else
1036     {
1037       vam->retval = retval;
1038       if (retval == 0)
1039         errmsg ("next node index %d\n", ntohl (mp->next_index));
1040       vam->result_ready = 1;
1041     }
1042 }
1043
1044 static void vl_api_get_next_index_reply_t_handler_json
1045   (vl_api_get_next_index_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049
1050   vat_json_init_object (&node);
1051   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1052   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1053
1054   vat_json_print (vam->ofp, &node);
1055   vat_json_free (&node);
1056
1057   vam->retval = ntohl (mp->retval);
1058   vam->result_ready = 1;
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   i32 retval = ntohl (mp->retval);
1066   if (vam->async_mode)
1067     {
1068       vam->async_errors += (retval < 0);
1069     }
1070   else
1071     {
1072       vam->retval = retval;
1073       if (retval == 0)
1074         errmsg ("next index %d\n", ntohl (mp->next_index));
1075       vam->result_ready = 1;
1076     }
1077 }
1078
1079 static void vl_api_add_node_next_reply_t_handler_json
1080   (vl_api_add_node_next_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   vat_json_node_t node;
1084
1085   vat_json_init_object (&node);
1086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1087   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1088
1089   vat_json_print (vam->ofp, &node);
1090   vat_json_free (&node);
1091
1092   vam->retval = ntohl (mp->retval);
1093   vam->result_ready = 1;
1094 }
1095
1096 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1097   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   i32 retval = ntohl (mp->retval);
1101   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1102
1103   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1104     {
1105       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1106     }
1107   vam->retval = retval;
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1112   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   vat_json_node_t node;
1116
1117   vat_json_init_object (&node);
1118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1119   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1120                             ntohl (mp->tunnel_sw_if_index));
1121
1122   vat_json_print (vam->ofp, &node);
1123   vat_json_free (&node);
1124
1125   vam->retval = ntohl (mp->retval);
1126   vam->result_ready = 1;
1127 }
1128
1129
1130 static void vl_api_show_version_reply_t_handler
1131   (vl_api_show_version_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   i32 retval = ntohl (mp->retval);
1135
1136   if (retval >= 0)
1137     {
1138       errmsg ("        program: %s\n", mp->program);
1139       errmsg ("        version: %s\n", mp->version);
1140       errmsg ("     build date: %s\n", mp->build_date);
1141       errmsg ("build directory: %s\n", mp->build_directory);
1142     }
1143   vam->retval = retval;
1144   vam->result_ready = 1;
1145 }
1146
1147 static void vl_api_show_version_reply_t_handler_json
1148   (vl_api_show_version_reply_t * mp)
1149 {
1150   vat_main_t *vam = &vat_main;
1151   vat_json_node_t node;
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "program", mp->program);
1156   vat_json_object_add_string_copy (&node, "version", mp->version);
1157   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1158   vat_json_object_add_string_copy (&node, "build_directory",
1159                                    mp->build_directory);
1160
1161   vat_json_print (vam->ofp, &node);
1162   vat_json_free (&node);
1163
1164   vam->retval = ntohl (mp->retval);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void
1169 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1173           mp->mac_ip ? "mac/ip binding" : "address resolution",
1174           format_ip4_address, &mp->address,
1175           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1176 }
1177
1178 static void
1179 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1180 {
1181   /* JSON output not supported */
1182 }
1183
1184 static void
1185 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1189           mp->mac_ip ? "mac/ip binding" : "address resolution",
1190           format_ip6_address, mp->address,
1191           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1192 }
1193
1194 static void
1195 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1196 {
1197   /* JSON output not supported */
1198 }
1199
1200 /*
1201  * Special-case: build the bridge domain table, maintain
1202  * the next bd id vbl.
1203  */
1204 static void vl_api_bridge_domain_details_t_handler
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1209
1210   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1211            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1212
1213   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1214            ntohl (mp->bd_id), mp->learn, mp->forward,
1215            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1216
1217   if (n_sw_ifs)
1218     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1219              "Interface Name");
1220 }
1221
1222 static void vl_api_bridge_domain_details_t_handler_json
1223   (vl_api_bridge_domain_details_t * mp)
1224 {
1225   vat_main_t *vam = &vat_main;
1226   vat_json_node_t *node, *array = NULL;
1227
1228   if (VAT_JSON_ARRAY != vam->json_tree.type)
1229     {
1230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1231       vat_json_init_array (&vam->json_tree);
1232     }
1233   node = vat_json_array_add (&vam->json_tree);
1234
1235   vat_json_init_object (node);
1236   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1237   vat_json_object_add_uint (node, "flood", mp->flood);
1238   vat_json_object_add_uint (node, "forward", mp->forward);
1239   vat_json_object_add_uint (node, "learn", mp->learn);
1240   vat_json_object_add_uint (node, "bvi_sw_if_index",
1241                             ntohl (mp->bvi_sw_if_index));
1242   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1243   array = vat_json_object_add (node, "sw_if");
1244   vat_json_init_array (array);
1245 }
1246
1247 /*
1248  * Special-case: build the bridge domain sw if table.
1249  */
1250 static void vl_api_bridge_domain_sw_if_details_t_handler
1251   (vl_api_bridge_domain_sw_if_details_t * mp)
1252 {
1253   vat_main_t *vam = &vat_main;
1254   hash_pair_t *p;
1255   u8 *sw_if_name = 0;
1256   u32 sw_if_index;
1257
1258   sw_if_index = ntohl (mp->sw_if_index);
1259   /* *INDENT-OFF* */
1260   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1261   ({
1262     if ((u32) p->value[0] == sw_if_index)
1263       {
1264         sw_if_name = (u8 *)(p->key);
1265         break;
1266       }
1267   }));
1268   /* *INDENT-ON* */
1269
1270   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1271            mp->shg, sw_if_name ? (char *) sw_if_name :
1272            "sw_if_index not found!");
1273 }
1274
1275 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1276   (vl_api_bridge_domain_sw_if_details_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   vat_json_node_t *node = NULL;
1280   uword last_index = 0;
1281
1282   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1283   ASSERT (vec_len (vam->json_tree.array) >= 1);
1284   last_index = vec_len (vam->json_tree.array) - 1;
1285   node = &vam->json_tree.array[last_index];
1286   node = vat_json_object_get_element (node, "sw_if");
1287   ASSERT (NULL != node);
1288   node = vat_json_array_add (node);
1289
1290   vat_json_init_object (node);
1291   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1292   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1293   vat_json_object_add_uint (node, "shg", mp->shg);
1294 }
1295
1296 static void vl_api_control_ping_reply_t_handler
1297   (vl_api_control_ping_reply_t * mp)
1298 {
1299   vat_main_t *vam = &vat_main;
1300   i32 retval = ntohl (mp->retval);
1301   if (vam->async_mode)
1302     {
1303       vam->async_errors += (retval < 0);
1304     }
1305   else
1306     {
1307       vam->retval = retval;
1308       vam->result_ready = 1;
1309     }
1310 }
1311
1312 static void vl_api_control_ping_reply_t_handler_json
1313   (vl_api_control_ping_reply_t * mp)
1314 {
1315   vat_main_t *vam = &vat_main;
1316   i32 retval = ntohl (mp->retval);
1317
1318   if (VAT_JSON_NONE != vam->json_tree.type)
1319     {
1320       vat_json_print (vam->ofp, &vam->json_tree);
1321       vat_json_free (&vam->json_tree);
1322       vam->json_tree.type = VAT_JSON_NONE;
1323     }
1324   else
1325     {
1326       /* just print [] */
1327       vat_json_init_array (&vam->json_tree);
1328       vat_json_print (vam->ofp, &vam->json_tree);
1329       vam->json_tree.type = VAT_JSON_NONE;
1330     }
1331
1332   vam->retval = retval;
1333   vam->result_ready = 1;
1334 }
1335
1336 static void
1337 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   i32 retval = ntohl (mp->retval);
1341   if (vam->async_mode)
1342     {
1343       vam->async_errors += (retval < 0);
1344     }
1345   else
1346     {
1347       vam->retval = retval;
1348       vam->result_ready = 1;
1349     }
1350 }
1351
1352 static void vl_api_l2_flags_reply_t_handler_json
1353   (vl_api_l2_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   vat_json_node_t node;
1357
1358   vat_json_init_object (&node);
1359   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1360   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1361                             ntohl (mp->resulting_feature_bitmap));
1362
1363   vat_json_print (vam->ofp, &node);
1364   vat_json_free (&node);
1365
1366   vam->retval = ntohl (mp->retval);
1367   vam->result_ready = 1;
1368 }
1369
1370 static void vl_api_bridge_flags_reply_t_handler
1371   (vl_api_bridge_flags_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   i32 retval = ntohl (mp->retval);
1375   if (vam->async_mode)
1376     {
1377       vam->async_errors += (retval < 0);
1378     }
1379   else
1380     {
1381       vam->retval = retval;
1382       vam->result_ready = 1;
1383     }
1384 }
1385
1386 static void vl_api_bridge_flags_reply_t_handler_json
1387   (vl_api_bridge_flags_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   vat_json_node_t node;
1391
1392   vat_json_init_object (&node);
1393   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1394   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1395                             ntohl (mp->resulting_feature_bitmap));
1396
1397   vat_json_print (vam->ofp, &node);
1398   vat_json_free (&node);
1399
1400   vam->retval = ntohl (mp->retval);
1401   vam->result_ready = 1;
1402 }
1403
1404 static void vl_api_tap_connect_reply_t_handler
1405   (vl_api_tap_connect_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   i32 retval = ntohl (mp->retval);
1409   if (vam->async_mode)
1410     {
1411       vam->async_errors += (retval < 0);
1412     }
1413   else
1414     {
1415       vam->retval = retval;
1416       vam->sw_if_index = ntohl (mp->sw_if_index);
1417       vam->result_ready = 1;
1418     }
1419
1420 }
1421
1422 static void vl_api_tap_connect_reply_t_handler_json
1423   (vl_api_tap_connect_reply_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   vat_json_node_t node;
1427
1428   vat_json_init_object (&node);
1429   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1430   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1431
1432   vat_json_print (vam->ofp, &node);
1433   vat_json_free (&node);
1434
1435   vam->retval = ntohl (mp->retval);
1436   vam->result_ready = 1;
1437
1438 }
1439
1440 static void
1441 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   i32 retval = ntohl (mp->retval);
1445   if (vam->async_mode)
1446     {
1447       vam->async_errors += (retval < 0);
1448     }
1449   else
1450     {
1451       vam->retval = retval;
1452       vam->sw_if_index = ntohl (mp->sw_if_index);
1453       vam->result_ready = 1;
1454     }
1455 }
1456
1457 static void vl_api_tap_modify_reply_t_handler_json
1458   (vl_api_tap_modify_reply_t * mp)
1459 {
1460   vat_main_t *vam = &vat_main;
1461   vat_json_node_t node;
1462
1463   vat_json_init_object (&node);
1464   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1465   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1466
1467   vat_json_print (vam->ofp, &node);
1468   vat_json_free (&node);
1469
1470   vam->retval = ntohl (mp->retval);
1471   vam->result_ready = 1;
1472 }
1473
1474 static void
1475 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   i32 retval = ntohl (mp->retval);
1479   if (vam->async_mode)
1480     {
1481       vam->async_errors += (retval < 0);
1482     }
1483   else
1484     {
1485       vam->retval = retval;
1486       vam->result_ready = 1;
1487     }
1488 }
1489
1490 static void vl_api_tap_delete_reply_t_handler_json
1491   (vl_api_tap_delete_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   vat_json_node_t node;
1495
1496   vat_json_init_object (&node);
1497   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1498
1499   vat_json_print (vam->ofp, &node);
1500   vat_json_free (&node);
1501
1502   vam->retval = ntohl (mp->retval);
1503   vam->result_ready = 1;
1504 }
1505
1506 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1507   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   i32 retval = ntohl (mp->retval);
1511   if (vam->async_mode)
1512     {
1513       vam->async_errors += (retval < 0);
1514     }
1515   else
1516     {
1517       vam->retval = retval;
1518       vam->result_ready = 1;
1519     }
1520 }
1521
1522 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1523   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   vat_json_node_t node;
1527
1528   vat_json_init_object (&node);
1529   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1530   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1531                             ntohl (mp->tunnel_sw_if_index));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1541   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1542 {
1543   vat_main_t *vam = &vat_main;
1544   i32 retval = ntohl (mp->retval);
1545   if (vam->async_mode)
1546     {
1547       vam->async_errors += (retval < 0);
1548     }
1549   else
1550     {
1551       vam->retval = retval;
1552       vam->sw_if_index = ntohl (mp->sw_if_index);
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1558   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   vat_json_node_t node;
1562
1563   vat_json_init_object (&node);
1564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1565   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574
1575 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1576   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   i32 retval = ntohl (mp->retval);
1580   if (vam->async_mode)
1581     {
1582       vam->async_errors += (retval < 0);
1583     }
1584   else
1585     {
1586       vam->retval = retval;
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1592   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   vat_json_node_t node;
1596
1597   vat_json_init_object (&node);
1598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1599   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1609   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623 }
1624
1625 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1626   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   vat_json_node_t node;
1630
1631   vat_json_init_object (&node);
1632   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1633   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1634
1635   vat_json_print (vam->ofp, &node);
1636   vat_json_free (&node);
1637
1638   vam->retval = ntohl (mp->retval);
1639   vam->result_ready = 1;
1640 }
1641
1642 static void vl_api_gre_add_del_tunnel_reply_t_handler
1643   (vl_api_gre_add_del_tunnel_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   i32 retval = ntohl (mp->retval);
1647   if (vam->async_mode)
1648     {
1649       vam->async_errors += (retval < 0);
1650     }
1651   else
1652     {
1653       vam->retval = retval;
1654       vam->sw_if_index = ntohl (mp->sw_if_index);
1655       vam->result_ready = 1;
1656     }
1657 }
1658
1659 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1660   (vl_api_gre_add_del_tunnel_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   vat_json_node_t node;
1664
1665   vat_json_init_object (&node);
1666   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1667   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1668
1669   vat_json_print (vam->ofp, &node);
1670   vat_json_free (&node);
1671
1672   vam->retval = ntohl (mp->retval);
1673   vam->result_ready = 1;
1674 }
1675
1676 static void vl_api_create_vhost_user_if_reply_t_handler
1677   (vl_api_create_vhost_user_if_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   i32 retval = ntohl (mp->retval);
1681   if (vam->async_mode)
1682     {
1683       vam->async_errors += (retval < 0);
1684     }
1685   else
1686     {
1687       vam->retval = retval;
1688       vam->sw_if_index = ntohl (mp->sw_if_index);
1689       vam->result_ready = 1;
1690     }
1691 }
1692
1693 static void vl_api_create_vhost_user_if_reply_t_handler_json
1694   (vl_api_create_vhost_user_if_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   vat_json_node_t node;
1698
1699   vat_json_init_object (&node);
1700   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1701   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1702
1703   vat_json_print (vam->ofp, &node);
1704   vat_json_free (&node);
1705
1706   vam->retval = ntohl (mp->retval);
1707   vam->result_ready = 1;
1708 }
1709
1710 static void vl_api_ip_address_details_t_handler
1711   (vl_api_ip_address_details_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   static ip_address_details_t empty_ip_address_details = { {0} };
1715   ip_address_details_t *address = NULL;
1716   ip_details_t *current_ip_details = NULL;
1717   ip_details_t *details = NULL;
1718
1719   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1720
1721   if (!details || vam->current_sw_if_index >= vec_len (details)
1722       || !details[vam->current_sw_if_index].present)
1723     {
1724       errmsg ("ip address details arrived but not stored\n");
1725       errmsg ("ip_dump should be called first\n");
1726       return;
1727     }
1728
1729   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1730
1731 #define addresses (current_ip_details->addr)
1732
1733   vec_validate_init_empty (addresses, vec_len (addresses),
1734                            empty_ip_address_details);
1735
1736   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1737
1738   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1739   address->prefix_length = mp->prefix_length;
1740 #undef addresses
1741 }
1742
1743 static void vl_api_ip_address_details_t_handler_json
1744   (vl_api_ip_address_details_t * mp)
1745 {
1746   vat_main_t *vam = &vat_main;
1747   vat_json_node_t *node = NULL;
1748   struct in6_addr ip6;
1749   struct in_addr ip4;
1750
1751   if (VAT_JSON_ARRAY != vam->json_tree.type)
1752     {
1753       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1754       vat_json_init_array (&vam->json_tree);
1755     }
1756   node = vat_json_array_add (&vam->json_tree);
1757
1758   vat_json_init_object (node);
1759   if (vam->is_ipv6)
1760     {
1761       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1762       vat_json_object_add_ip6 (node, "ip", ip6);
1763     }
1764   else
1765     {
1766       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1767       vat_json_object_add_ip4 (node, "ip", ip4);
1768     }
1769   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1770 }
1771
1772 static void
1773 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   static ip_details_t empty_ip_details = { 0 };
1777   ip_details_t *ip = NULL;
1778   u32 sw_if_index = ~0;
1779
1780   sw_if_index = ntohl (mp->sw_if_index);
1781
1782   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1783                            sw_if_index, empty_ip_details);
1784
1785   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1786                          sw_if_index);
1787
1788   ip->present = 1;
1789 }
1790
1791 static void
1792 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795
1796   if (VAT_JSON_ARRAY != vam->json_tree.type)
1797     {
1798       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1799       vat_json_init_array (&vam->json_tree);
1800     }
1801   vat_json_array_add_uint (&vam->json_tree,
1802                            clib_net_to_host_u32 (mp->sw_if_index));
1803 }
1804
1805 static void vl_api_map_domain_details_t_handler_json
1806   (vl_api_map_domain_details_t * mp)
1807 {
1808   vat_json_node_t *node = NULL;
1809   vat_main_t *vam = &vat_main;
1810   struct in6_addr ip6;
1811   struct in_addr ip4;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "domain_index",
1823                             clib_net_to_host_u32 (mp->domain_index));
1824   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1825   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1826   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1827   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1828   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1829   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1830   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1831   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1832   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1833   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1834   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1835   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1836   vat_json_object_add_uint (node, "flags", mp->flags);
1837   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1838   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1839 }
1840
1841 static void vl_api_map_domain_details_t_handler
1842   (vl_api_map_domain_details_t * mp)
1843 {
1844   vat_main_t *vam = &vat_main;
1845
1846   if (mp->is_translation)
1847     {
1848       fformat (vam->ofp,
1849                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1850                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1851                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1852                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1853                clib_net_to_host_u32 (mp->domain_index));
1854     }
1855   else
1856     {
1857       fformat (vam->ofp,
1858                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1859                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1860                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1861                format_ip6_address, mp->ip6_src,
1862                clib_net_to_host_u32 (mp->domain_index));
1863     }
1864   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1865            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1866            mp->is_translation ? "map-t" : "");
1867 }
1868
1869 static void vl_api_map_rule_details_t_handler_json
1870   (vl_api_map_rule_details_t * mp)
1871 {
1872   struct in6_addr ip6;
1873   vat_json_node_t *node = NULL;
1874   vat_main_t *vam = &vat_main;
1875
1876   if (VAT_JSON_ARRAY != vam->json_tree.type)
1877     {
1878       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1879       vat_json_init_array (&vam->json_tree);
1880     }
1881
1882   node = vat_json_array_add (&vam->json_tree);
1883   vat_json_init_object (node);
1884
1885   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1886   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1887   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1888 }
1889
1890 static void
1891 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1895            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1896 }
1897
1898 static void
1899 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1903           "router_addr %U host_mac %U\n",
1904           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1905           format_ip4_address, &mp->host_address,
1906           format_ip4_address, &mp->router_address,
1907           format_ethernet_address, mp->host_mac);
1908 }
1909
1910 static void vl_api_dhcp_compl_event_t_handler_json
1911   (vl_api_dhcp_compl_event_t * mp)
1912 {
1913   /* JSON output not supported */
1914 }
1915
1916 static void
1917 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1918                               u32 counter)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   static u64 default_counter = 0;
1922
1923   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1924                            NULL);
1925   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1926                            sw_if_index, default_counter);
1927   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1928 }
1929
1930 static void
1931 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1932                                 interface_counter_t counter)
1933 {
1934   vat_main_t *vam = &vat_main;
1935   static interface_counter_t default_counter = { 0, };
1936
1937   vec_validate_init_empty (vam->combined_interface_counters,
1938                            vnet_counter_type, NULL);
1939   vec_validate_init_empty (vam->combined_interface_counters
1940                            [vnet_counter_type], sw_if_index, default_counter);
1941   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1942 }
1943
1944 static void vl_api_vnet_interface_counters_t_handler
1945   (vl_api_vnet_interface_counters_t * mp)
1946 {
1947   /* not supported */
1948 }
1949
1950 static void vl_api_vnet_interface_counters_t_handler_json
1951   (vl_api_vnet_interface_counters_t * mp)
1952 {
1953   interface_counter_t counter;
1954   vlib_counter_t *v;
1955   u64 *v_packets;
1956   u64 packets;
1957   u32 count;
1958   u32 first_sw_if_index;
1959   int i;
1960
1961   count = ntohl (mp->count);
1962   first_sw_if_index = ntohl (mp->first_sw_if_index);
1963
1964   if (!mp->is_combined)
1965     {
1966       v_packets = (u64 *) & mp->data;
1967       for (i = 0; i < count; i++)
1968         {
1969           packets =
1970             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1971           set_simple_interface_counter (mp->vnet_counter_type,
1972                                         first_sw_if_index + i, packets);
1973           v_packets++;
1974         }
1975     }
1976   else
1977     {
1978       v = (vlib_counter_t *) & mp->data;
1979       for (i = 0; i < count; i++)
1980         {
1981           counter.packets =
1982             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1983           counter.bytes =
1984             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1985           set_combined_interface_counter (mp->vnet_counter_type,
1986                                           first_sw_if_index + i, counter);
1987           v++;
1988         }
1989     }
1990 }
1991
1992 static u32
1993 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   u32 i;
1997
1998   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1999     {
2000       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2001         {
2002           return i;
2003         }
2004     }
2005   return ~0;
2006 }
2007
2008 static u32
2009 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2010 {
2011   vat_main_t *vam = &vat_main;
2012   u32 i;
2013
2014   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2015     {
2016       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2017         {
2018           return i;
2019         }
2020     }
2021   return ~0;
2022 }
2023
2024 static void vl_api_vnet_ip4_fib_counters_t_handler
2025   (vl_api_vnet_ip4_fib_counters_t * mp)
2026 {
2027   /* not supported */
2028 }
2029
2030 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2031   (vl_api_vnet_ip4_fib_counters_t * mp)
2032 {
2033   vat_main_t *vam = &vat_main;
2034   vl_api_ip4_fib_counter_t *v;
2035   ip4_fib_counter_t *counter;
2036   struct in_addr ip4;
2037   u32 vrf_id;
2038   u32 vrf_index;
2039   u32 count;
2040   int i;
2041
2042   vrf_id = ntohl (mp->vrf_id);
2043   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2044   if (~0 == vrf_index)
2045     {
2046       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2047       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2048       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2049       vec_validate (vam->ip4_fib_counters, vrf_index);
2050       vam->ip4_fib_counters[vrf_index] = NULL;
2051     }
2052
2053   vec_free (vam->ip4_fib_counters[vrf_index]);
2054   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2055   count = ntohl (mp->count);
2056   for (i = 0; i < count; i++)
2057     {
2058       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2059       counter = &vam->ip4_fib_counters[vrf_index][i];
2060       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2061       counter->address = ip4;
2062       counter->address_length = v->address_length;
2063       counter->packets = clib_net_to_host_u64 (v->packets);
2064       counter->bytes = clib_net_to_host_u64 (v->bytes);
2065       v++;
2066     }
2067 }
2068
2069 static void vl_api_vnet_ip6_fib_counters_t_handler
2070   (vl_api_vnet_ip6_fib_counters_t * mp)
2071 {
2072   /* not supported */
2073 }
2074
2075 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2076   (vl_api_vnet_ip6_fib_counters_t * mp)
2077 {
2078   vat_main_t *vam = &vat_main;
2079   vl_api_ip6_fib_counter_t *v;
2080   ip6_fib_counter_t *counter;
2081   struct in6_addr ip6;
2082   u32 vrf_id;
2083   u32 vrf_index;
2084   u32 count;
2085   int i;
2086
2087   vrf_id = ntohl (mp->vrf_id);
2088   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2089   if (~0 == vrf_index)
2090     {
2091       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2092       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2093       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2094       vec_validate (vam->ip6_fib_counters, vrf_index);
2095       vam->ip6_fib_counters[vrf_index] = NULL;
2096     }
2097
2098   vec_free (vam->ip6_fib_counters[vrf_index]);
2099   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2100   count = ntohl (mp->count);
2101   for (i = 0; i < count; i++)
2102     {
2103       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2104       counter = &vam->ip6_fib_counters[vrf_index][i];
2105       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2106       counter->address = ip6;
2107       counter->address_length = v->address_length;
2108       counter->packets = clib_net_to_host_u64 (v->packets);
2109       counter->bytes = clib_net_to_host_u64 (v->bytes);
2110       v++;
2111     }
2112 }
2113
2114 static void vl_api_get_first_msg_id_reply_t_handler
2115   (vl_api_get_first_msg_id_reply_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   i32 retval = ntohl (mp->retval);
2119
2120   if (vam->async_mode)
2121     {
2122       vam->async_errors += (retval < 0);
2123     }
2124   else
2125     {
2126       vam->retval = retval;
2127       vam->result_ready = 1;
2128     }
2129   if (retval >= 0)
2130     {
2131       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2132     }
2133 }
2134
2135 static void vl_api_get_first_msg_id_reply_t_handler_json
2136   (vl_api_get_first_msg_id_reply_t * mp)
2137 {
2138   vat_main_t *vam = &vat_main;
2139   vat_json_node_t node;
2140
2141   vat_json_init_object (&node);
2142   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2143   vat_json_object_add_uint (&node, "first_msg_id",
2144                             (uint) ntohs (mp->first_msg_id));
2145
2146   vat_json_print (vam->ofp, &node);
2147   vat_json_free (&node);
2148
2149   vam->retval = ntohl (mp->retval);
2150   vam->result_ready = 1;
2151 }
2152
2153 static void vl_api_get_node_graph_reply_t_handler
2154   (vl_api_get_node_graph_reply_t * mp)
2155 {
2156   vat_main_t *vam = &vat_main;
2157   api_main_t *am = &api_main;
2158   i32 retval = ntohl (mp->retval);
2159   u8 *pvt_copy, *reply;
2160   void *oldheap;
2161   vlib_node_t *node;
2162   int i;
2163
2164   if (vam->async_mode)
2165     {
2166       vam->async_errors += (retval < 0);
2167     }
2168   else
2169     {
2170       vam->retval = retval;
2171       vam->result_ready = 1;
2172     }
2173
2174   /* "Should never happen..." */
2175   if (retval != 0)
2176     return;
2177
2178   reply = (u8 *) (mp->reply_in_shmem);
2179   pvt_copy = vec_dup (reply);
2180
2181   /* Toss the shared-memory original... */
2182   pthread_mutex_lock (&am->vlib_rp->mutex);
2183   oldheap = svm_push_data_heap (am->vlib_rp);
2184
2185   vec_free (reply);
2186
2187   svm_pop_heap (oldheap);
2188   pthread_mutex_unlock (&am->vlib_rp->mutex);
2189
2190   if (vam->graph_nodes)
2191     {
2192       hash_free (vam->graph_node_index_by_name);
2193
2194       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2195         {
2196           node = vam->graph_nodes[i];
2197           vec_free (node->name);
2198           vec_free (node->next_nodes);
2199           vec_free (node);
2200         }
2201       vec_free (vam->graph_nodes);
2202     }
2203
2204   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2205   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2206   vec_free (pvt_copy);
2207
2208   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2209     {
2210       node = vam->graph_nodes[i];
2211       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2212     }
2213 }
2214
2215 static void vl_api_get_node_graph_reply_t_handler_json
2216   (vl_api_get_node_graph_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   api_main_t *am = &api_main;
2220   void *oldheap;
2221   vat_json_node_t node;
2222   u8 *reply;
2223
2224   /* $$$$ make this real? */
2225   vat_json_init_object (&node);
2226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2227   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2228
2229   reply = (u8 *) (mp->reply_in_shmem);
2230
2231   /* Toss the shared-memory original... */
2232   pthread_mutex_lock (&am->vlib_rp->mutex);
2233   oldheap = svm_push_data_heap (am->vlib_rp);
2234
2235   vec_free (reply);
2236
2237   svm_pop_heap (oldheap);
2238   pthread_mutex_unlock (&am->vlib_rp->mutex);
2239
2240   vat_json_print (vam->ofp, &node);
2241   vat_json_free (&node);
2242
2243   vam->retval = ntohl (mp->retval);
2244   vam->result_ready = 1;
2245 }
2246
2247 static void
2248 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *s = 0;
2252
2253   if (mp->local)
2254     {
2255       s = format (s, "%=16d%=16d%=16d\n",
2256                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2257     }
2258   else
2259     {
2260       s = format (s, "%=16U%=16d%=16d\n",
2261                   mp->is_ipv6 ? format_ip6_address :
2262                   format_ip4_address,
2263                   mp->ip_address, mp->priority, mp->weight);
2264     }
2265
2266   fformat (vam->ofp, "%v", s);
2267   vec_free (s);
2268 }
2269
2270 static void
2271 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2272                                             mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t *node = NULL;
2276   struct in6_addr ip6;
2277   struct in_addr ip4;
2278
2279   if (VAT_JSON_ARRAY != vam->json_tree.type)
2280     {
2281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2282       vat_json_init_array (&vam->json_tree);
2283     }
2284   node = vat_json_array_add (&vam->json_tree);
2285   vat_json_init_object (node);
2286
2287   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2288   vat_json_object_add_uint (node, "priority", mp->priority);
2289   vat_json_object_add_uint (node, "weight", mp->weight);
2290
2291   if (mp->local)
2292     vat_json_object_add_uint (node, "sw_if_index",
2293                               clib_net_to_host_u32 (mp->sw_if_index));
2294   else
2295     {
2296       if (mp->is_ipv6)
2297         {
2298           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2299           vat_json_object_add_ip6 (node, "address", ip6);
2300         }
2301       else
2302         {
2303           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2304           vat_json_object_add_ip4 (node, "address", ip4);
2305         }
2306     }
2307 }
2308
2309 static void
2310 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2311                                            mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   u8 *ls_name = 0;
2315
2316   ls_name = format (0, "%s", mp->ls_name);
2317
2318   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2319            ls_name);
2320   vec_free (ls_name);
2321 }
2322
2323 static void
2324   vl_api_lisp_locator_set_details_t_handler_json
2325   (vl_api_lisp_locator_set_details_t * mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t *node = 0;
2329   u8 *ls_name = 0;
2330
2331   ls_name = format (0, "%s", mp->ls_name);
2332   vec_add1 (ls_name, 0);
2333
2334   if (VAT_JSON_ARRAY != vam->json_tree.type)
2335     {
2336       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2337       vat_json_init_array (&vam->json_tree);
2338     }
2339   node = vat_json_array_add (&vam->json_tree);
2340
2341   vat_json_init_object (node);
2342   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2343   vat_json_object_add_uint (node, "ls_index",
2344                             clib_net_to_host_u32 (mp->ls_index));
2345   vec_free (ls_name);
2346 }
2347
2348 static u8 *
2349 format_lisp_flat_eid (u8 * s, va_list * args)
2350 {
2351   u32 type = va_arg (*args, u32);
2352   u8 *eid = va_arg (*args, u8 *);
2353   u32 eid_len = va_arg (*args, u32);
2354
2355   switch (type)
2356     {
2357     case 0:
2358       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2359     case 1:
2360       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2361     case 2:
2362       return format (s, "%U", format_ethernet_address, eid);
2363     }
2364   return 0;
2365 }
2366
2367 static u8 *
2368 format_lisp_eid_vat (u8 * s, va_list * args)
2369 {
2370   u32 type = va_arg (*args, u32);
2371   u8 *eid = va_arg (*args, u8 *);
2372   u32 eid_len = va_arg (*args, u32);
2373   u8 *seid = va_arg (*args, u8 *);
2374   u32 seid_len = va_arg (*args, u32);
2375   u32 is_src_dst = va_arg (*args, u32);
2376
2377   if (is_src_dst)
2378     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2379
2380   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2381
2382   return s;
2383 }
2384
2385 static void
2386 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2387 {
2388   vat_main_t *vam = &vat_main;
2389   u8 *s = 0, *eid = 0;
2390
2391   if (~0 == mp->locator_set_index)
2392     s = format (0, "action: %d", mp->action);
2393   else
2394     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2395
2396   eid = format (0, "%U", format_lisp_eid_vat,
2397                 mp->eid_type,
2398                 mp->eid,
2399                 mp->eid_prefix_len,
2400                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2401   vec_add1 (eid, 0);
2402
2403   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2404            clib_net_to_host_u32 (mp->vni),
2405            eid,
2406            mp->is_local ? "local" : "remote",
2407            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2408   vec_free (s);
2409   vec_free (eid);
2410 }
2411
2412 static void
2413 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2414                                               * mp)
2415 {
2416   vat_main_t *vam = &vat_main;
2417   vat_json_node_t *node = 0;
2418   u8 *eid = 0;
2419
2420   if (VAT_JSON_ARRAY != vam->json_tree.type)
2421     {
2422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2423       vat_json_init_array (&vam->json_tree);
2424     }
2425   node = vat_json_array_add (&vam->json_tree);
2426
2427   vat_json_init_object (node);
2428   if (~0 == mp->locator_set_index)
2429     vat_json_object_add_uint (node, "action", mp->action);
2430   else
2431     vat_json_object_add_uint (node, "locator_set_index",
2432                               clib_net_to_host_u32 (mp->locator_set_index));
2433
2434   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2435   eid = format (0, "%U", format_lisp_eid_vat,
2436                 mp->eid_type,
2437                 mp->eid,
2438                 mp->eid_prefix_len,
2439                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2440   vec_add1 (eid, 0);
2441   vat_json_object_add_string_copy (node, "eid", eid);
2442   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2443   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2444   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2445   vec_free (eid);
2446 }
2447
2448 static void
2449   vl_api_lisp_eid_table_map_details_t_handler
2450   (vl_api_lisp_eid_table_map_details_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453
2454   u8 *line = format (0, "%=10d%=10d",
2455                      clib_net_to_host_u32 (mp->vni),
2456                      clib_net_to_host_u32 (mp->dp_table));
2457   fformat (vam->ofp, "%v\n", line);
2458   vec_free (line);
2459 }
2460
2461 static void
2462   vl_api_lisp_eid_table_map_details_t_handler_json
2463   (vl_api_lisp_eid_table_map_details_t * mp)
2464 {
2465   vat_main_t *vam = &vat_main;
2466   vat_json_node_t *node = NULL;
2467
2468   if (VAT_JSON_ARRAY != vam->json_tree.type)
2469     {
2470       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2471       vat_json_init_array (&vam->json_tree);
2472     }
2473   node = vat_json_array_add (&vam->json_tree);
2474   vat_json_init_object (node);
2475   vat_json_object_add_uint (node, "dp_table",
2476                             clib_net_to_host_u32 (mp->dp_table));
2477   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2478 }
2479
2480 static void
2481   vl_api_lisp_eid_table_vni_details_t_handler
2482   (vl_api_lisp_eid_table_vni_details_t * mp)
2483 {
2484   vat_main_t *vam = &vat_main;
2485
2486   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2487   fformat (vam->ofp, "%v\n", line);
2488   vec_free (line);
2489 }
2490
2491 static void
2492   vl_api_lisp_eid_table_vni_details_t_handler_json
2493   (vl_api_lisp_eid_table_vni_details_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   vat_json_node_t *node = NULL;
2497
2498   if (VAT_JSON_ARRAY != vam->json_tree.type)
2499     {
2500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2501       vat_json_init_array (&vam->json_tree);
2502     }
2503   node = vat_json_array_add (&vam->json_tree);
2504   vat_json_init_object (node);
2505   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2506 }
2507
2508 static u8 *
2509 format_decap_next (u8 * s, va_list * args)
2510 {
2511   u32 next_index = va_arg (*args, u32);
2512
2513   switch (next_index)
2514     {
2515     case LISP_GPE_INPUT_NEXT_DROP:
2516       return format (s, "drop");
2517     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2518       return format (s, "ip4");
2519     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2520       return format (s, "ip6");
2521     default:
2522       return format (s, "unknown %d", next_index);
2523     }
2524   return s;
2525 }
2526
2527 static void
2528 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2529                                           mp)
2530 {
2531   vat_main_t *vam = &vat_main;
2532   u8 *iid_str;
2533   u8 *flag_str = NULL;
2534
2535   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2536
2537 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2538   foreach_lisp_gpe_flag_bit;
2539 #undef _
2540
2541   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2542            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2543            mp->tunnels,
2544            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2545            mp->source_ip,
2546            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2547            mp->destination_ip,
2548            ntohl (mp->encap_fib_id),
2549            ntohl (mp->decap_fib_id),
2550            format_decap_next, ntohl (mp->dcap_next),
2551            mp->ver_res >> 6,
2552            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2553
2554   vec_free (iid_str);
2555 }
2556
2557 static void
2558   vl_api_lisp_gpe_tunnel_details_t_handler_json
2559   (vl_api_lisp_gpe_tunnel_details_t * mp)
2560 {
2561   vat_main_t *vam = &vat_main;
2562   vat_json_node_t *node = NULL;
2563   struct in6_addr ip6;
2564   struct in_addr ip4;
2565   u8 *next_decap_str;
2566
2567   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2568
2569   if (VAT_JSON_ARRAY != vam->json_tree.type)
2570     {
2571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2572       vat_json_init_array (&vam->json_tree);
2573     }
2574   node = vat_json_array_add (&vam->json_tree);
2575
2576   vat_json_init_object (node);
2577   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2578   if (mp->is_ipv6)
2579     {
2580       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2581       vat_json_object_add_ip6 (node, "source address", ip6);
2582       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2583       vat_json_object_add_ip6 (node, "destination address", ip6);
2584     }
2585   else
2586     {
2587       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2588       vat_json_object_add_ip4 (node, "source address", ip4);
2589       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2590       vat_json_object_add_ip4 (node, "destination address", ip4);
2591     }
2592   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2593   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2594   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2595   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2596   vat_json_object_add_uint (node, "flags", mp->flags);
2597   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2598   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2599   vat_json_object_add_uint (node, "res", mp->res);
2600   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2601
2602   vec_free (next_decap_str);
2603 }
2604
2605 static void
2606 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2607                                             * mp)
2608 {
2609   vat_main_t *vam = &vat_main;
2610
2611   fformat (vam->ofp, "%=20U\n",
2612            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2613            mp->ip_address);
2614 }
2615
2616 static void
2617   vl_api_lisp_map_resolver_details_t_handler_json
2618   (vl_api_lisp_map_resolver_details_t * mp)
2619 {
2620   vat_main_t *vam = &vat_main;
2621   vat_json_node_t *node = NULL;
2622   struct in6_addr ip6;
2623   struct in_addr ip4;
2624
2625   if (VAT_JSON_ARRAY != vam->json_tree.type)
2626     {
2627       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2628       vat_json_init_array (&vam->json_tree);
2629     }
2630   node = vat_json_array_add (&vam->json_tree);
2631
2632   vat_json_init_object (node);
2633   if (mp->is_ipv6)
2634     {
2635       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2636       vat_json_object_add_ip6 (node, "map resolver", ip6);
2637     }
2638   else
2639     {
2640       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2641       vat_json_object_add_ip4 (node, "map resolver", ip4);
2642     }
2643 }
2644
2645 static void
2646   vl_api_show_lisp_status_reply_t_handler
2647   (vl_api_show_lisp_status_reply_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650   i32 retval = ntohl (mp->retval);
2651
2652   if (0 <= retval)
2653     {
2654       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2655                mp->feature_status ? "enabled" : "disabled",
2656                mp->gpe_status ? "enabled" : "disabled");
2657     }
2658
2659   vam->retval = retval;
2660   vam->result_ready = 1;
2661 }
2662
2663 static void
2664   vl_api_show_lisp_status_reply_t_handler_json
2665   (vl_api_show_lisp_status_reply_t * mp)
2666 {
2667   vat_main_t *vam = &vat_main;
2668   vat_json_node_t node;
2669   u8 *gpe_status = NULL;
2670   u8 *feature_status = NULL;
2671
2672   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2673   feature_status = format (0, "%s",
2674                            mp->feature_status ? "enabled" : "disabled");
2675   vec_add1 (gpe_status, 0);
2676   vec_add1 (feature_status, 0);
2677
2678   vat_json_init_object (&node);
2679   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2680   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2681
2682   vec_free (gpe_status);
2683   vec_free (feature_status);
2684
2685   vat_json_print (vam->ofp, &node);
2686   vat_json_free (&node);
2687
2688   vam->retval = ntohl (mp->retval);
2689   vam->result_ready = 1;
2690 }
2691
2692 static void
2693   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2694   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2695 {
2696   vat_main_t *vam = &vat_main;
2697   i32 retval = ntohl (mp->retval);
2698
2699   if (retval >= 0)
2700     {
2701       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2702     }
2703
2704   vam->retval = retval;
2705   vam->result_ready = 1;
2706 }
2707
2708 static void
2709   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2710   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713   vat_json_node_t *node = NULL;
2714
2715   if (VAT_JSON_ARRAY != vam->json_tree.type)
2716     {
2717       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2718       vat_json_init_array (&vam->json_tree);
2719     }
2720   node = vat_json_array_add (&vam->json_tree);
2721
2722   vat_json_init_object (node);
2723   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2724
2725   vat_json_print (vam->ofp, node);
2726   vat_json_free (node);
2727
2728   vam->retval = ntohl (mp->retval);
2729   vam->result_ready = 1;
2730 }
2731
2732 static u8 *
2733 format_lisp_map_request_mode (u8 * s, va_list * args)
2734 {
2735   u32 mode = va_arg (*args, u32);
2736
2737   switch (mode)
2738     {
2739     case 0:
2740       return format (0, "dst-only");
2741     case 1:
2742       return format (0, "src-dst");
2743     }
2744   return 0;
2745 }
2746
2747 static void
2748   vl_api_show_lisp_map_request_mode_reply_t_handler
2749   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752   i32 retval = ntohl (mp->retval);
2753
2754   if (0 <= retval)
2755     {
2756       u32 mode = mp->mode;
2757       fformat (vam->ofp, "map_request_mode: %U\n",
2758                format_lisp_map_request_mode, mode);
2759     }
2760
2761   vam->retval = retval;
2762   vam->result_ready = 1;
2763 }
2764
2765 static void
2766   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2767   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2768 {
2769   vat_main_t *vam = &vat_main;
2770   vat_json_node_t node;
2771   u8 *s = 0;
2772   u32 mode;
2773
2774   mode = mp->mode;
2775   s = format (0, "%U", format_lisp_map_request_mode, mode);
2776   vec_add1 (s, 0);
2777
2778   vat_json_init_object (&node);
2779   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2780   vat_json_print (vam->ofp, &node);
2781   vat_json_free (&node);
2782
2783   vec_free (s);
2784   vam->retval = ntohl (mp->retval);
2785   vam->result_ready = 1;
2786 }
2787
2788 static void
2789 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   i32 retval = ntohl (mp->retval);
2793
2794   if (0 <= retval)
2795     {
2796       fformat (vam->ofp, "%-20s%-16s\n",
2797                mp->status ? "enabled" : "disabled",
2798                mp->status ? (char *) mp->locator_set_name : "");
2799     }
2800
2801   vam->retval = retval;
2802   vam->result_ready = 1;
2803 }
2804
2805 static void
2806 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2807                                             mp)
2808 {
2809   vat_main_t *vam = &vat_main;
2810   vat_json_node_t node;
2811   u8 *status = 0;
2812
2813   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2814   vec_add1 (status, 0);
2815
2816   vat_json_init_object (&node);
2817   vat_json_object_add_string_copy (&node, "status", status);
2818   if (mp->status)
2819     {
2820       vat_json_object_add_string_copy (&node, "locator_set",
2821                                        mp->locator_set_name);
2822     }
2823
2824   vec_free (status);
2825
2826   vat_json_print (vam->ofp, &node);
2827   vat_json_free (&node);
2828
2829   vam->retval = ntohl (mp->retval);
2830   vam->result_ready = 1;
2831 }
2832
2833 static u8 *
2834 format_policer_type (u8 * s, va_list * va)
2835 {
2836   u32 i = va_arg (*va, u32);
2837
2838   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2839     s = format (s, "1r2c");
2840   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2841     s = format (s, "1r3c");
2842   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2843     s = format (s, "2r3c-2698");
2844   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2845     s = format (s, "2r3c-4115");
2846   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2847     s = format (s, "2r3c-mef5cf1");
2848   else
2849     s = format (s, "ILLEGAL");
2850   return s;
2851 }
2852
2853 static u8 *
2854 format_policer_rate_type (u8 * s, va_list * va)
2855 {
2856   u32 i = va_arg (*va, u32);
2857
2858   if (i == SSE2_QOS_RATE_KBPS)
2859     s = format (s, "kbps");
2860   else if (i == SSE2_QOS_RATE_PPS)
2861     s = format (s, "pps");
2862   else
2863     s = format (s, "ILLEGAL");
2864   return s;
2865 }
2866
2867 static u8 *
2868 format_policer_round_type (u8 * s, va_list * va)
2869 {
2870   u32 i = va_arg (*va, u32);
2871
2872   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2873     s = format (s, "closest");
2874   else if (i == SSE2_QOS_ROUND_TO_UP)
2875     s = format (s, "up");
2876   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2877     s = format (s, "down");
2878   else
2879     s = format (s, "ILLEGAL");
2880   return s;
2881 }
2882
2883 static u8 *
2884 format_policer_action_type (u8 * s, va_list * va)
2885 {
2886   u32 i = va_arg (*va, u32);
2887
2888   if (i == SSE2_QOS_ACTION_DROP)
2889     s = format (s, "drop");
2890   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2891     s = format (s, "transmit");
2892   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2893     s = format (s, "mark-and-transmit");
2894   else
2895     s = format (s, "ILLEGAL");
2896   return s;
2897 }
2898
2899 static u8 *
2900 format_dscp (u8 * s, va_list * va)
2901 {
2902   u32 i = va_arg (*va, u32);
2903   char *t = 0;
2904
2905   switch (i)
2906     {
2907 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2908       foreach_vnet_dscp
2909 #undef _
2910     default:
2911       return format (s, "ILLEGAL");
2912     }
2913   s = format (s, "%s", t);
2914   return s;
2915 }
2916
2917 static void
2918 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2922
2923   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2924     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2925   else
2926     conform_dscp_str = format (0, "");
2927
2928   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2929     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2930   else
2931     exceed_dscp_str = format (0, "");
2932
2933   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2934     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2935   else
2936     violate_dscp_str = format (0, "");
2937
2938   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2939            "rate type %U, round type %U, %s rate, %s color-aware, "
2940            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2941            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2942            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2943            mp->name,
2944            format_policer_type, mp->type,
2945            ntohl (mp->cir),
2946            ntohl (mp->eir),
2947            clib_net_to_host_u64 (mp->cb),
2948            clib_net_to_host_u64 (mp->eb),
2949            format_policer_rate_type, mp->rate_type,
2950            format_policer_round_type, mp->round_type,
2951            mp->single_rate ? "single" : "dual",
2952            mp->color_aware ? "is" : "not",
2953            ntohl (mp->cir_tokens_per_period),
2954            ntohl (mp->pir_tokens_per_period),
2955            ntohl (mp->scale),
2956            ntohl (mp->current_limit),
2957            ntohl (mp->current_bucket),
2958            ntohl (mp->extended_limit),
2959            ntohl (mp->extended_bucket),
2960            clib_net_to_host_u64 (mp->last_update_time),
2961            format_policer_action_type, mp->conform_action_type,
2962            conform_dscp_str,
2963            format_policer_action_type, mp->exceed_action_type,
2964            exceed_dscp_str,
2965            format_policer_action_type, mp->violate_action_type,
2966            violate_dscp_str);
2967
2968   vec_free (conform_dscp_str);
2969   vec_free (exceed_dscp_str);
2970   vec_free (violate_dscp_str);
2971 }
2972
2973 static void vl_api_policer_details_t_handler_json
2974   (vl_api_policer_details_t * mp)
2975 {
2976   vat_main_t *vam = &vat_main;
2977   vat_json_node_t *node;
2978   u8 *rate_type_str, *round_type_str, *type_str;
2979   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2980
2981   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2982   round_type_str =
2983     format (0, "%U", format_policer_round_type, mp->round_type);
2984   type_str = format (0, "%U", format_policer_type, mp->type);
2985   conform_action_str = format (0, "%U", format_policer_action_type,
2986                                mp->conform_action_type);
2987   exceed_action_str = format (0, "%U", format_policer_action_type,
2988                               mp->exceed_action_type);
2989   violate_action_str = format (0, "%U", format_policer_action_type,
2990                                mp->violate_action_type);
2991
2992   if (VAT_JSON_ARRAY != vam->json_tree.type)
2993     {
2994       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2995       vat_json_init_array (&vam->json_tree);
2996     }
2997   node = vat_json_array_add (&vam->json_tree);
2998
2999   vat_json_init_object (node);
3000   vat_json_object_add_string_copy (node, "name", mp->name);
3001   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3002   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3003   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3004   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3005   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3006   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3007   vat_json_object_add_string_copy (node, "type", type_str);
3008   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3009   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3010   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3011   vat_json_object_add_uint (node, "cir_tokens_per_period",
3012                             ntohl (mp->cir_tokens_per_period));
3013   vat_json_object_add_uint (node, "eir_tokens_per_period",
3014                             ntohl (mp->pir_tokens_per_period));
3015   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3016   vat_json_object_add_uint (node, "current_bucket",
3017                             ntohl (mp->current_bucket));
3018   vat_json_object_add_uint (node, "extended_limit",
3019                             ntohl (mp->extended_limit));
3020   vat_json_object_add_uint (node, "extended_bucket",
3021                             ntohl (mp->extended_bucket));
3022   vat_json_object_add_uint (node, "last_update_time",
3023                             ntohl (mp->last_update_time));
3024   vat_json_object_add_string_copy (node, "conform_action",
3025                                    conform_action_str);
3026   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3027     {
3028       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3029       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3030       vec_free (dscp_str);
3031     }
3032   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3033   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3034     {
3035       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3036       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3037       vec_free (dscp_str);
3038     }
3039   vat_json_object_add_string_copy (node, "violate_action",
3040                                    violate_action_str);
3041   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3042     {
3043       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3044       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3045       vec_free (dscp_str);
3046     }
3047
3048   vec_free (rate_type_str);
3049   vec_free (round_type_str);
3050   vec_free (type_str);
3051   vec_free (conform_action_str);
3052   vec_free (exceed_action_str);
3053   vec_free (violate_action_str);
3054 }
3055
3056 static void
3057 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3058                                            mp)
3059 {
3060   vat_main_t *vam = &vat_main;
3061   int i, count = ntohl (mp->count);
3062
3063   if (count > 0)
3064     fformat (vam->ofp, "classify table ids (%d) : ", count);
3065   for (i = 0; i < count; i++)
3066     {
3067       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3068       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3069     }
3070   vam->retval = ntohl (mp->retval);
3071   vam->result_ready = 1;
3072 }
3073
3074 static void
3075   vl_api_classify_table_ids_reply_t_handler_json
3076   (vl_api_classify_table_ids_reply_t * mp)
3077 {
3078   vat_main_t *vam = &vat_main;
3079   int i, count = ntohl (mp->count);
3080
3081   if (count > 0)
3082     {
3083       vat_json_node_t node;
3084
3085       vat_json_init_object (&node);
3086       for (i = 0; i < count; i++)
3087         {
3088           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3089         }
3090       vat_json_print (vam->ofp, &node);
3091       vat_json_free (&node);
3092     }
3093   vam->retval = ntohl (mp->retval);
3094   vam->result_ready = 1;
3095 }
3096
3097 static void
3098   vl_api_classify_table_by_interface_reply_t_handler
3099   (vl_api_classify_table_by_interface_reply_t * mp)
3100 {
3101   vat_main_t *vam = &vat_main;
3102   u32 table_id;
3103
3104   table_id = ntohl (mp->l2_table_id);
3105   if (table_id != ~0)
3106     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3107   else
3108     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3109   table_id = ntohl (mp->ip4_table_id);
3110   if (table_id != ~0)
3111     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3112   else
3113     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3114   table_id = ntohl (mp->ip6_table_id);
3115   if (table_id != ~0)
3116     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3117   else
3118     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3119   vam->retval = ntohl (mp->retval);
3120   vam->result_ready = 1;
3121 }
3122
3123 static void
3124   vl_api_classify_table_by_interface_reply_t_handler_json
3125   (vl_api_classify_table_by_interface_reply_t * mp)
3126 {
3127   vat_main_t *vam = &vat_main;
3128   vat_json_node_t node;
3129
3130   vat_json_init_object (&node);
3131
3132   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3133   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3134   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3135
3136   vat_json_print (vam->ofp, &node);
3137   vat_json_free (&node);
3138
3139   vam->retval = ntohl (mp->retval);
3140   vam->result_ready = 1;
3141 }
3142
3143 static void vl_api_policer_add_del_reply_t_handler
3144   (vl_api_policer_add_del_reply_t * mp)
3145 {
3146   vat_main_t *vam = &vat_main;
3147   i32 retval = ntohl (mp->retval);
3148   if (vam->async_mode)
3149     {
3150       vam->async_errors += (retval < 0);
3151     }
3152   else
3153     {
3154       vam->retval = retval;
3155       vam->result_ready = 1;
3156       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3157         /*
3158          * Note: this is just barely thread-safe, depends on
3159          * the main thread spinning waiting for an answer...
3160          */
3161         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3162     }
3163 }
3164
3165 static void vl_api_policer_add_del_reply_t_handler_json
3166   (vl_api_policer_add_del_reply_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169   vat_json_node_t node;
3170
3171   vat_json_init_object (&node);
3172   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3173   vat_json_object_add_uint (&node, "policer_index",
3174                             ntohl (mp->policer_index));
3175
3176   vat_json_print (vam->ofp, &node);
3177   vat_json_free (&node);
3178
3179   vam->retval = ntohl (mp->retval);
3180   vam->result_ready = 1;
3181 }
3182
3183 /* Format hex dump. */
3184 u8 *
3185 format_hex_bytes (u8 * s, va_list * va)
3186 {
3187   u8 *bytes = va_arg (*va, u8 *);
3188   int n_bytes = va_arg (*va, int);
3189   uword i;
3190
3191   /* Print short or long form depending on byte count. */
3192   uword short_form = n_bytes <= 32;
3193   uword indent = format_get_indent (s);
3194
3195   if (n_bytes == 0)
3196     return s;
3197
3198   for (i = 0; i < n_bytes; i++)
3199     {
3200       if (!short_form && (i % 32) == 0)
3201         s = format (s, "%08x: ", i);
3202       s = format (s, "%02x", bytes[i]);
3203       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3204         s = format (s, "\n%U", format_white_space, indent);
3205     }
3206
3207   return s;
3208 }
3209
3210 static void
3211 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3212                                             * mp)
3213 {
3214   vat_main_t *vam = &vat_main;
3215   i32 retval = ntohl (mp->retval);
3216   if (retval == 0)
3217     {
3218       fformat (vam->ofp, "classify table info :\n");
3219       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3220                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3221                ntohl (mp->miss_next_index));
3222       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3223                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3224                ntohl (mp->match_n_vectors));
3225       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3226                ntohl (mp->mask_length));
3227     }
3228   vam->retval = retval;
3229   vam->result_ready = 1;
3230 }
3231
3232 static void
3233   vl_api_classify_table_info_reply_t_handler_json
3234   (vl_api_classify_table_info_reply_t * mp)
3235 {
3236   vat_main_t *vam = &vat_main;
3237   vat_json_node_t node;
3238
3239   i32 retval = ntohl (mp->retval);
3240   if (retval == 0)
3241     {
3242       vat_json_init_object (&node);
3243
3244       vat_json_object_add_int (&node, "sessions",
3245                                ntohl (mp->active_sessions));
3246       vat_json_object_add_int (&node, "nexttbl",
3247                                ntohl (mp->next_table_index));
3248       vat_json_object_add_int (&node, "nextnode",
3249                                ntohl (mp->miss_next_index));
3250       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3251       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3252       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3253       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3254                       ntohl (mp->mask_length), 0);
3255       vat_json_object_add_string_copy (&node, "mask", s);
3256
3257       vat_json_print (vam->ofp, &node);
3258       vat_json_free (&node);
3259     }
3260   vam->retval = ntohl (mp->retval);
3261   vam->result_ready = 1;
3262 }
3263
3264 static void
3265 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3266                                            mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269
3270   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3271            ntohl (mp->hit_next_index), ntohl (mp->advance),
3272            ntohl (mp->opaque_index));
3273   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3274            ntohl (mp->match_length));
3275 }
3276
3277 static void
3278   vl_api_classify_session_details_t_handler_json
3279   (vl_api_classify_session_details_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   vat_json_node_t *node = NULL;
3283
3284   if (VAT_JSON_ARRAY != vam->json_tree.type)
3285     {
3286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3287       vat_json_init_array (&vam->json_tree);
3288     }
3289   node = vat_json_array_add (&vam->json_tree);
3290
3291   vat_json_init_object (node);
3292   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3293   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3294   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3295   u8 *s =
3296     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3297             0);
3298   vat_json_object_add_string_copy (node, "match", s);
3299 }
3300
3301 static void vl_api_pg_create_interface_reply_t_handler
3302   (vl_api_pg_create_interface_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305
3306   vam->retval = ntohl (mp->retval);
3307   vam->result_ready = 1;
3308 }
3309
3310 static void vl_api_pg_create_interface_reply_t_handler_json
3311   (vl_api_pg_create_interface_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314   vat_json_node_t node;
3315
3316   i32 retval = ntohl (mp->retval);
3317   if (retval == 0)
3318     {
3319       vat_json_init_object (&node);
3320
3321       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3322
3323       vat_json_print (vam->ofp, &node);
3324       vat_json_free (&node);
3325     }
3326   vam->retval = ntohl (mp->retval);
3327   vam->result_ready = 1;
3328 }
3329
3330 static void vl_api_policer_classify_details_t_handler
3331   (vl_api_policer_classify_details_t * mp)
3332 {
3333   vat_main_t *vam = &vat_main;
3334
3335   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3336            ntohl (mp->table_index));
3337 }
3338
3339 static void vl_api_policer_classify_details_t_handler_json
3340   (vl_api_policer_classify_details_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t *node;
3344
3345   if (VAT_JSON_ARRAY != vam->json_tree.type)
3346     {
3347       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3348       vat_json_init_array (&vam->json_tree);
3349     }
3350   node = vat_json_array_add (&vam->json_tree);
3351
3352   vat_json_init_object (node);
3353   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3354   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3355 }
3356
3357 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3358   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361   i32 retval = ntohl (mp->retval);
3362   if (vam->async_mode)
3363     {
3364       vam->async_errors += (retval < 0);
3365     }
3366   else
3367     {
3368       vam->retval = retval;
3369       vam->sw_if_index = ntohl (mp->sw_if_index);
3370       vam->result_ready = 1;
3371     }
3372 }
3373
3374 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3375   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3376 {
3377   vat_main_t *vam = &vat_main;
3378   vat_json_node_t node;
3379
3380   vat_json_init_object (&node);
3381   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3382   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3383
3384   vat_json_print (vam->ofp, &node);
3385   vat_json_free (&node);
3386
3387   vam->retval = ntohl (mp->retval);
3388   vam->result_ready = 1;
3389 }
3390
3391 static void vl_api_flow_classify_details_t_handler
3392   (vl_api_flow_classify_details_t * mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395
3396   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3397            ntohl (mp->table_index));
3398 }
3399
3400 static void vl_api_flow_classify_details_t_handler_json
3401   (vl_api_flow_classify_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404   vat_json_node_t *node;
3405
3406   if (VAT_JSON_ARRAY != vam->json_tree.type)
3407     {
3408       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3409       vat_json_init_array (&vam->json_tree);
3410     }
3411   node = vat_json_array_add (&vam->json_tree);
3412
3413   vat_json_init_object (node);
3414   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3415   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3416 }
3417
3418
3419
3420 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3421 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3422 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3423 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3424
3425 /*
3426  * Generate boilerplate reply handlers, which
3427  * dig the return value out of the xxx_reply_t API message,
3428  * stick it into vam->retval, and set vam->result_ready
3429  *
3430  * Could also do this by pointing N message decode slots at
3431  * a single function, but that could break in subtle ways.
3432  */
3433
3434 #define foreach_standard_reply_retval_handler           \
3435 _(sw_interface_set_flags_reply)                         \
3436 _(sw_interface_add_del_address_reply)                   \
3437 _(sw_interface_set_table_reply)                         \
3438 _(sw_interface_set_vpath_reply)                         \
3439 _(sw_interface_set_l2_bridge_reply)                     \
3440 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3441 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3442 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3443 _(bridge_domain_add_del_reply)                          \
3444 _(sw_interface_set_l2_xconnect_reply)                   \
3445 _(l2fib_add_del_reply)                                  \
3446 _(ip_add_del_route_reply)                               \
3447 _(proxy_arp_add_del_reply)                              \
3448 _(proxy_arp_intfc_enable_disable_reply)                 \
3449 _(mpls_add_del_encap_reply)                             \
3450 _(mpls_add_del_decap_reply)                             \
3451 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3452 _(sw_interface_set_unnumbered_reply)                    \
3453 _(ip_neighbor_add_del_reply)                            \
3454 _(reset_vrf_reply)                                      \
3455 _(oam_add_del_reply)                                    \
3456 _(reset_fib_reply)                                      \
3457 _(dhcp_proxy_config_reply)                              \
3458 _(dhcp_proxy_config_2_reply)                            \
3459 _(dhcp_proxy_set_vss_reply)                             \
3460 _(dhcp_client_config_reply)                             \
3461 _(set_ip_flow_hash_reply)                               \
3462 _(sw_interface_ip6_enable_disable_reply)                \
3463 _(sw_interface_ip6_set_link_local_address_reply)        \
3464 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3465 _(sw_interface_ip6nd_ra_config_reply)                   \
3466 _(set_arp_neighbor_limit_reply)                         \
3467 _(l2_patch_add_del_reply)                               \
3468 _(sr_tunnel_add_del_reply)                              \
3469 _(sr_policy_add_del_reply)                              \
3470 _(sr_multicast_map_add_del_reply)                       \
3471 _(classify_add_del_session_reply)                       \
3472 _(classify_set_interface_ip_table_reply)                \
3473 _(classify_set_interface_l2_tables_reply)               \
3474 _(l2tpv3_set_tunnel_cookies_reply)                      \
3475 _(l2tpv3_interface_enable_disable_reply)                \
3476 _(l2tpv3_set_lookup_key_reply)                          \
3477 _(l2_fib_clear_table_reply)                             \
3478 _(l2_interface_efp_filter_reply)                        \
3479 _(l2_interface_vlan_tag_rewrite_reply)                  \
3480 _(modify_vhost_user_if_reply)                           \
3481 _(delete_vhost_user_if_reply)                           \
3482 _(want_ip4_arp_events_reply)                            \
3483 _(want_ip6_nd_events_reply)                             \
3484 _(input_acl_set_interface_reply)                        \
3485 _(ipsec_spd_add_del_reply)                              \
3486 _(ipsec_interface_add_del_spd_reply)                    \
3487 _(ipsec_spd_add_del_entry_reply)                        \
3488 _(ipsec_sad_add_del_entry_reply)                        \
3489 _(ipsec_sa_set_key_reply)                               \
3490 _(ikev2_profile_add_del_reply)                          \
3491 _(ikev2_profile_set_auth_reply)                         \
3492 _(ikev2_profile_set_id_reply)                           \
3493 _(ikev2_profile_set_ts_reply)                           \
3494 _(ikev2_set_local_key_reply)                            \
3495 _(delete_loopback_reply)                                \
3496 _(bd_ip_mac_add_del_reply)                              \
3497 _(map_del_domain_reply)                                 \
3498 _(map_add_del_rule_reply)                               \
3499 _(want_interface_events_reply)                          \
3500 _(want_stats_reply)                                     \
3501 _(cop_interface_enable_disable_reply)                   \
3502 _(cop_whitelist_enable_disable_reply)                   \
3503 _(sw_interface_clear_stats_reply)                       \
3504 _(ioam_enable_reply)                              \
3505 _(ioam_disable_reply)                              \
3506 _(lisp_add_del_locator_reply)                           \
3507 _(lisp_add_del_local_eid_reply)                         \
3508 _(lisp_add_del_remote_mapping_reply)                    \
3509 _(lisp_add_del_adjacency_reply)                         \
3510 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3511 _(lisp_add_del_map_resolver_reply)                      \
3512 _(lisp_gpe_enable_disable_reply)                        \
3513 _(lisp_gpe_add_del_iface_reply)                         \
3514 _(lisp_enable_disable_reply)                            \
3515 _(lisp_pitr_set_locator_set_reply)                      \
3516 _(lisp_map_request_mode_reply)                          \
3517 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3518 _(lisp_eid_table_add_del_map_reply)                     \
3519 _(vxlan_gpe_add_del_tunnel_reply)                       \
3520 _(af_packet_delete_reply)                               \
3521 _(policer_classify_set_interface_reply)                 \
3522 _(netmap_create_reply)                                  \
3523 _(netmap_delete_reply)                                  \
3524 _(set_ipfix_exporter_reply)                             \
3525 _(set_ipfix_classify_stream_reply)                      \
3526 _(ipfix_classify_table_add_del_reply)                   \
3527 _(flow_classify_set_interface_reply)                    \
3528 _(pg_capture_reply)                                     \
3529 _(pg_enable_disable_reply)                              \
3530 _(ip_source_and_port_range_check_add_del_reply)         \
3531 _(ip_source_and_port_range_check_interface_add_del_reply)\
3532 _(delete_subif_reply)                                   \
3533 _(l2_interface_pbb_tag_rewrite_reply)                   \
3534 _(punt_reply)
3535
3536 #define _(n)                                    \
3537     static void vl_api_##n##_t_handler          \
3538     (vl_api_##n##_t * mp)                       \
3539     {                                           \
3540         vat_main_t * vam = &vat_main;           \
3541         i32 retval = ntohl(mp->retval);         \
3542         if (vam->async_mode) {                  \
3543             vam->async_errors += (retval < 0);  \
3544         } else {                                \
3545             vam->retval = retval;               \
3546             vam->result_ready = 1;              \
3547         }                                       \
3548     }
3549 foreach_standard_reply_retval_handler;
3550 #undef _
3551
3552 #define _(n)                                    \
3553     static void vl_api_##n##_t_handler_json     \
3554     (vl_api_##n##_t * mp)                       \
3555     {                                           \
3556         vat_main_t * vam = &vat_main;           \
3557         vat_json_node_t node;                   \
3558         vat_json_init_object(&node);            \
3559         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3560         vat_json_print(vam->ofp, &node);        \
3561         vam->retval = ntohl(mp->retval);        \
3562         vam->result_ready = 1;                  \
3563     }
3564 foreach_standard_reply_retval_handler;
3565 #undef _
3566
3567 /*
3568  * Table of message reply handlers, must include boilerplate handlers
3569  * we just generated
3570  */
3571
3572 #define foreach_vpe_api_reply_msg                                       \
3573 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3574 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3575 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3576 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3577 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3578 _(CLI_REPLY, cli_reply)                                                 \
3579 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3580 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3581   sw_interface_add_del_address_reply)                                   \
3582 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3583 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3584 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3585   sw_interface_set_l2_xconnect_reply)                                   \
3586 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3587   sw_interface_set_l2_bridge_reply)                                     \
3588 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3589   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3590 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3591   sw_interface_set_dpdk_hqos_subport_reply)                             \
3592 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3593   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3594 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3595 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3596 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3597 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3598 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3599 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3600 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3601 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3602 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3603 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3604 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3605 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3606 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3607   proxy_arp_intfc_enable_disable_reply)                                 \
3608 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3609 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3610 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3611 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3612   mpls_ethernet_add_del_tunnel_reply)                                   \
3613 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3614   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3615 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3616   sw_interface_set_unnumbered_reply)                                    \
3617 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3618 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3619 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3620 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3621 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3622 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3623 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3624 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3625 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3626 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3627 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3628 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3629   sw_interface_ip6_enable_disable_reply)                                \
3630 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3631   sw_interface_ip6_set_link_local_address_reply)                        \
3632 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3633   sw_interface_ip6nd_ra_prefix_reply)                                   \
3634 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3635   sw_interface_ip6nd_ra_config_reply)                                   \
3636 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3637 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3638 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3639 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3640 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3641 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3642 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3643 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3644 classify_set_interface_ip_table_reply)                                  \
3645 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3646   classify_set_interface_l2_tables_reply)                               \
3647 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3648 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3649 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3650 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3651 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3652   l2tpv3_interface_enable_disable_reply)                                \
3653 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3654 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3655 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3656 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3657 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3658 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3659 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3660 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3661 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3662 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3663 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3664 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3665 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3666 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3667 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3668 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3669 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3670 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3671 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3672 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3673 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3674 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3675 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3676 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3677 _(IP_DETAILS, ip_details)                                               \
3678 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3679 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3680 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3681 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3682 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3683 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3684 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3685 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3686 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3687 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3688 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3689 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3690 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3691 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3692 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3693 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3694 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3695 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3696 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3697 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3698 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3699 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3700 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3701 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3702 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3703 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3704 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3705 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3706 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3707 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3708 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3709 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3710 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3711 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3712 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3713 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3714 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3715 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3716 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3717 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3718 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3719 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3720 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3721 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3722 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3723 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3724 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3725 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3726 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3727 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3728 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3729 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3730   lisp_add_del_map_request_itr_rlocs_reply)                             \
3731 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3732   lisp_get_map_request_itr_rlocs_reply)                                 \
3733 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3734 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3735 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3736 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3737 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3738 _(POLICER_DETAILS, policer_details)                                     \
3739 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3740 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3741 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3742 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3743 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3744 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3745 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3746 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3747 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3748 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3749 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3750 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3751 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3752 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3753 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3754 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3755 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3756 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3757 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3758 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3759 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3760 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3761 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3762 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3763 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3764  ip_source_and_port_range_check_add_del_reply)                          \
3765 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3766  ip_source_and_port_range_check_interface_add_del_reply)                \
3767 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3768 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3769 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3770 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3771 _(PUNT_REPLY, punt_reply)
3772
3773 /* M: construct, but don't yet send a message */
3774
3775 #define M(T,t)                                  \
3776 do {                                            \
3777     vam->result_ready = 0;                      \
3778     mp = vl_msg_api_alloc(sizeof(*mp));         \
3779     memset (mp, 0, sizeof (*mp));               \
3780     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3781     mp->client_index = vam->my_client_index;    \
3782 } while(0);
3783
3784 #define M2(T,t,n)                               \
3785 do {                                            \
3786     vam->result_ready = 0;                      \
3787     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3788     memset (mp, 0, sizeof (*mp));               \
3789     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3790     mp->client_index = vam->my_client_index;    \
3791 } while(0);
3792
3793
3794 /* S: send a message */
3795 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3796
3797 /* W: wait for results, with timeout */
3798 #define W                                       \
3799 do {                                            \
3800     timeout = vat_time_now (vam) + 1.0;         \
3801                                                 \
3802     while (vat_time_now (vam) < timeout) {      \
3803         if (vam->result_ready == 1) {           \
3804             return (vam->retval);               \
3805         }                                       \
3806     }                                           \
3807     return -99;                                 \
3808 } while(0);
3809
3810 /* W2: wait for results, with timeout */
3811 #define W2(body)                                \
3812 do {                                            \
3813     timeout = vat_time_now (vam) + 1.0;         \
3814                                                 \
3815     while (vat_time_now (vam) < timeout) {      \
3816         if (vam->result_ready == 1) {           \
3817           (body);                               \
3818           return (vam->retval);                 \
3819         }                                       \
3820     }                                           \
3821     return -99;                                 \
3822 } while(0);
3823
3824 typedef struct
3825 {
3826   u8 *name;
3827   u32 value;
3828 } name_sort_t;
3829
3830
3831 #define STR_VTR_OP_CASE(op)     \
3832     case L2_VTR_ ## op:         \
3833         return "" # op;
3834
3835 static const char *
3836 str_vtr_op (u32 vtr_op)
3837 {
3838   switch (vtr_op)
3839     {
3840       STR_VTR_OP_CASE (DISABLED);
3841       STR_VTR_OP_CASE (PUSH_1);
3842       STR_VTR_OP_CASE (PUSH_2);
3843       STR_VTR_OP_CASE (POP_1);
3844       STR_VTR_OP_CASE (POP_2);
3845       STR_VTR_OP_CASE (TRANSLATE_1_1);
3846       STR_VTR_OP_CASE (TRANSLATE_1_2);
3847       STR_VTR_OP_CASE (TRANSLATE_2_1);
3848       STR_VTR_OP_CASE (TRANSLATE_2_2);
3849     }
3850
3851   return "UNKNOWN";
3852 }
3853
3854 static int
3855 dump_sub_interface_table (vat_main_t * vam)
3856 {
3857   const sw_interface_subif_t *sub = NULL;
3858
3859   if (vam->json_output)
3860     {
3861       clib_warning
3862         ("JSON output supported only for VPE API calls and dump_stats_table");
3863       return -99;
3864     }
3865
3866   fformat (vam->ofp,
3867            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3868            "Interface", "sw_if_index",
3869            "sub id", "dot1ad", "tags", "outer id",
3870            "inner id", "exact", "default", "outer any", "inner any");
3871
3872   vec_foreach (sub, vam->sw_if_subif_table)
3873   {
3874     fformat (vam->ofp,
3875              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3876              sub->interface_name,
3877              sub->sw_if_index,
3878              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3879              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3880              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3881              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3882     if (sub->vtr_op != L2_VTR_DISABLED)
3883       {
3884         fformat (vam->ofp,
3885                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3886                  "tag1: %d tag2: %d ]\n",
3887                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3888                  sub->vtr_tag1, sub->vtr_tag2);
3889       }
3890   }
3891
3892   return 0;
3893 }
3894
3895 static int
3896 name_sort_cmp (void *a1, void *a2)
3897 {
3898   name_sort_t *n1 = a1;
3899   name_sort_t *n2 = a2;
3900
3901   return strcmp ((char *) n1->name, (char *) n2->name);
3902 }
3903
3904 static int
3905 dump_interface_table (vat_main_t * vam)
3906 {
3907   hash_pair_t *p;
3908   name_sort_t *nses = 0, *ns;
3909
3910   if (vam->json_output)
3911     {
3912       clib_warning
3913         ("JSON output supported only for VPE API calls and dump_stats_table");
3914       return -99;
3915     }
3916
3917   /* *INDENT-OFF* */
3918   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3919   ({
3920     vec_add2 (nses, ns, 1);
3921     ns->name = (u8 *)(p->key);
3922     ns->value = (u32) p->value[0];
3923   }));
3924   /* *INDENT-ON* */
3925
3926   vec_sort_with_function (nses, name_sort_cmp);
3927
3928   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3929   vec_foreach (ns, nses)
3930   {
3931     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3932   }
3933   vec_free (nses);
3934   return 0;
3935 }
3936
3937 static int
3938 dump_ip_table (vat_main_t * vam, int is_ipv6)
3939 {
3940   const ip_details_t *det = NULL;
3941   const ip_address_details_t *address = NULL;
3942   u32 i = ~0;
3943
3944   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3945
3946   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3947   {
3948     i++;
3949     if (!det->present)
3950       {
3951         continue;
3952       }
3953     fformat (vam->ofp, "%-12d\n", i);
3954     fformat (vam->ofp,
3955              "            %-30s%-13s\n", "Address", "Prefix length");
3956     if (!det->addr)
3957       {
3958         continue;
3959       }
3960     vec_foreach (address, det->addr)
3961     {
3962       fformat (vam->ofp,
3963                "            %-30U%-13d\n",
3964                is_ipv6 ? format_ip6_address : format_ip4_address,
3965                address->ip, address->prefix_length);
3966     }
3967   }
3968
3969   return 0;
3970 }
3971
3972 static int
3973 dump_ipv4_table (vat_main_t * vam)
3974 {
3975   if (vam->json_output)
3976     {
3977       clib_warning
3978         ("JSON output supported only for VPE API calls and dump_stats_table");
3979       return -99;
3980     }
3981
3982   return dump_ip_table (vam, 0);
3983 }
3984
3985 static int
3986 dump_ipv6_table (vat_main_t * vam)
3987 {
3988   if (vam->json_output)
3989     {
3990       clib_warning
3991         ("JSON output supported only for VPE API calls and dump_stats_table");
3992       return -99;
3993     }
3994
3995   return dump_ip_table (vam, 1);
3996 }
3997
3998 static char *
3999 counter_type_to_str (u8 counter_type, u8 is_combined)
4000 {
4001   if (!is_combined)
4002     {
4003       switch (counter_type)
4004         {
4005         case VNET_INTERFACE_COUNTER_DROP:
4006           return "drop";
4007         case VNET_INTERFACE_COUNTER_PUNT:
4008           return "punt";
4009         case VNET_INTERFACE_COUNTER_IP4:
4010           return "ip4";
4011         case VNET_INTERFACE_COUNTER_IP6:
4012           return "ip6";
4013         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4014           return "rx-no-buf";
4015         case VNET_INTERFACE_COUNTER_RX_MISS:
4016           return "rx-miss";
4017         case VNET_INTERFACE_COUNTER_RX_ERROR:
4018           return "rx-error";
4019         case VNET_INTERFACE_COUNTER_TX_ERROR:
4020           return "tx-error";
4021         default:
4022           return "INVALID-COUNTER-TYPE";
4023         }
4024     }
4025   else
4026     {
4027       switch (counter_type)
4028         {
4029         case VNET_INTERFACE_COUNTER_RX:
4030           return "rx";
4031         case VNET_INTERFACE_COUNTER_TX:
4032           return "tx";
4033         default:
4034           return "INVALID-COUNTER-TYPE";
4035         }
4036     }
4037 }
4038
4039 static int
4040 dump_stats_table (vat_main_t * vam)
4041 {
4042   vat_json_node_t node;
4043   vat_json_node_t *msg_array;
4044   vat_json_node_t *msg;
4045   vat_json_node_t *counter_array;
4046   vat_json_node_t *counter;
4047   interface_counter_t c;
4048   u64 packets;
4049   ip4_fib_counter_t *c4;
4050   ip6_fib_counter_t *c6;
4051   int i, j;
4052
4053   if (!vam->json_output)
4054     {
4055       clib_warning ("dump_stats_table supported only in JSON format");
4056       return -99;
4057     }
4058
4059   vat_json_init_object (&node);
4060
4061   /* interface counters */
4062   msg_array = vat_json_object_add (&node, "interface_counters");
4063   vat_json_init_array (msg_array);
4064   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4065     {
4066       msg = vat_json_array_add (msg_array);
4067       vat_json_init_object (msg);
4068       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4069                                        (u8 *) counter_type_to_str (i, 0));
4070       vat_json_object_add_int (msg, "is_combined", 0);
4071       counter_array = vat_json_object_add (msg, "data");
4072       vat_json_init_array (counter_array);
4073       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4074         {
4075           packets = vam->simple_interface_counters[i][j];
4076           vat_json_array_add_uint (counter_array, packets);
4077         }
4078     }
4079   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4080     {
4081       msg = vat_json_array_add (msg_array);
4082       vat_json_init_object (msg);
4083       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4084                                        (u8 *) counter_type_to_str (i, 1));
4085       vat_json_object_add_int (msg, "is_combined", 1);
4086       counter_array = vat_json_object_add (msg, "data");
4087       vat_json_init_array (counter_array);
4088       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4089         {
4090           c = vam->combined_interface_counters[i][j];
4091           counter = vat_json_array_add (counter_array);
4092           vat_json_init_object (counter);
4093           vat_json_object_add_uint (counter, "packets", c.packets);
4094           vat_json_object_add_uint (counter, "bytes", c.bytes);
4095         }
4096     }
4097
4098   /* ip4 fib counters */
4099   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4100   vat_json_init_array (msg_array);
4101   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4102     {
4103       msg = vat_json_array_add (msg_array);
4104       vat_json_init_object (msg);
4105       vat_json_object_add_uint (msg, "vrf_id",
4106                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4107       counter_array = vat_json_object_add (msg, "c");
4108       vat_json_init_array (counter_array);
4109       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4110         {
4111           counter = vat_json_array_add (counter_array);
4112           vat_json_init_object (counter);
4113           c4 = &vam->ip4_fib_counters[i][j];
4114           vat_json_object_add_ip4 (counter, "address", c4->address);
4115           vat_json_object_add_uint (counter, "address_length",
4116                                     c4->address_length);
4117           vat_json_object_add_uint (counter, "packets", c4->packets);
4118           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4119         }
4120     }
4121
4122   /* ip6 fib counters */
4123   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4124   vat_json_init_array (msg_array);
4125   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4126     {
4127       msg = vat_json_array_add (msg_array);
4128       vat_json_init_object (msg);
4129       vat_json_object_add_uint (msg, "vrf_id",
4130                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4131       counter_array = vat_json_object_add (msg, "c");
4132       vat_json_init_array (counter_array);
4133       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4134         {
4135           counter = vat_json_array_add (counter_array);
4136           vat_json_init_object (counter);
4137           c6 = &vam->ip6_fib_counters[i][j];
4138           vat_json_object_add_ip6 (counter, "address", c6->address);
4139           vat_json_object_add_uint (counter, "address_length",
4140                                     c6->address_length);
4141           vat_json_object_add_uint (counter, "packets", c6->packets);
4142           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4143         }
4144     }
4145
4146   vat_json_print (vam->ofp, &node);
4147   vat_json_free (&node);
4148
4149   return 0;
4150 }
4151
4152 int
4153 exec (vat_main_t * vam)
4154 {
4155   api_main_t *am = &api_main;
4156   vl_api_cli_request_t *mp;
4157   f64 timeout;
4158   void *oldheap;
4159   u8 *cmd = 0;
4160   unformat_input_t *i = vam->input;
4161
4162   if (vec_len (i->buffer) == 0)
4163     return -1;
4164
4165   if (vam->exec_mode == 0 && unformat (i, "mode"))
4166     {
4167       vam->exec_mode = 1;
4168       return 0;
4169     }
4170   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4171     {
4172       vam->exec_mode = 0;
4173       return 0;
4174     }
4175
4176
4177   M (CLI_REQUEST, cli_request);
4178
4179   /*
4180    * Copy cmd into shared memory.
4181    * In order for the CLI command to work, it
4182    * must be a vector ending in \n, not a C-string ending
4183    * in \n\0.
4184    */
4185   pthread_mutex_lock (&am->vlib_rp->mutex);
4186   oldheap = svm_push_data_heap (am->vlib_rp);
4187
4188   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4189   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4190
4191   svm_pop_heap (oldheap);
4192   pthread_mutex_unlock (&am->vlib_rp->mutex);
4193
4194   mp->cmd_in_shmem = (u64) cmd;
4195   S;
4196   timeout = vat_time_now (vam) + 10.0;
4197
4198   while (vat_time_now (vam) < timeout)
4199     {
4200       if (vam->result_ready == 1)
4201         {
4202           u8 *free_me;
4203           if (vam->shmem_result != NULL)
4204             fformat (vam->ofp, "%s", vam->shmem_result);
4205           pthread_mutex_lock (&am->vlib_rp->mutex);
4206           oldheap = svm_push_data_heap (am->vlib_rp);
4207
4208           free_me = (u8 *) vam->shmem_result;
4209           vec_free (free_me);
4210
4211           svm_pop_heap (oldheap);
4212           pthread_mutex_unlock (&am->vlib_rp->mutex);
4213           return 0;
4214         }
4215     }
4216   return -99;
4217 }
4218
4219 /*
4220  * Future replacement of exec() that passes CLI buffers directly in
4221  * the API messages instead of an additional shared memory area.
4222  */
4223 static int
4224 exec_inband (vat_main_t * vam)
4225 {
4226   vl_api_cli_inband_t *mp;
4227   f64 timeout;
4228   unformat_input_t *i = vam->input;
4229
4230   if (vec_len (i->buffer) == 0)
4231     return -1;
4232
4233   if (vam->exec_mode == 0 && unformat (i, "mode"))
4234     {
4235       vam->exec_mode = 1;
4236       return 0;
4237     }
4238   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4239     {
4240       vam->exec_mode = 0;
4241       return 0;
4242     }
4243
4244   /*
4245    * In order for the CLI command to work, it
4246    * must be a vector ending in \n, not a C-string ending
4247    * in \n\0.
4248    */
4249   u32 len = vec_len (vam->input->buffer);
4250   M2 (CLI_INBAND, cli_inband, len);
4251   clib_memcpy (mp->cmd, vam->input->buffer, len);
4252   mp->length = htonl (len);
4253
4254   S;
4255   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4256 }
4257
4258 static int
4259 api_create_loopback (vat_main_t * vam)
4260 {
4261   unformat_input_t *i = vam->input;
4262   vl_api_create_loopback_t *mp;
4263   f64 timeout;
4264   u8 mac_address[6];
4265   u8 mac_set = 0;
4266
4267   memset (mac_address, 0, sizeof (mac_address));
4268
4269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4270     {
4271       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4272         mac_set = 1;
4273       else
4274         break;
4275     }
4276
4277   /* Construct the API message */
4278   M (CREATE_LOOPBACK, create_loopback);
4279   if (mac_set)
4280     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4281
4282   S;
4283   W;
4284 }
4285
4286 static int
4287 api_delete_loopback (vat_main_t * vam)
4288 {
4289   unformat_input_t *i = vam->input;
4290   vl_api_delete_loopback_t *mp;
4291   f64 timeout;
4292   u32 sw_if_index = ~0;
4293
4294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4295     {
4296       if (unformat (i, "sw_if_index %d", &sw_if_index))
4297         ;
4298       else
4299         break;
4300     }
4301
4302   if (sw_if_index == ~0)
4303     {
4304       errmsg ("missing sw_if_index\n");
4305       return -99;
4306     }
4307
4308   /* Construct the API message */
4309   M (DELETE_LOOPBACK, delete_loopback);
4310   mp->sw_if_index = ntohl (sw_if_index);
4311
4312   S;
4313   W;
4314 }
4315
4316 static int
4317 api_want_stats (vat_main_t * vam)
4318 {
4319   unformat_input_t *i = vam->input;
4320   vl_api_want_stats_t *mp;
4321   f64 timeout;
4322   int enable = -1;
4323
4324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4325     {
4326       if (unformat (i, "enable"))
4327         enable = 1;
4328       else if (unformat (i, "disable"))
4329         enable = 0;
4330       else
4331         break;
4332     }
4333
4334   if (enable == -1)
4335     {
4336       errmsg ("missing enable|disable\n");
4337       return -99;
4338     }
4339
4340   M (WANT_STATS, want_stats);
4341   mp->enable_disable = enable;
4342
4343   S;
4344   W;
4345 }
4346
4347 static int
4348 api_want_interface_events (vat_main_t * vam)
4349 {
4350   unformat_input_t *i = vam->input;
4351   vl_api_want_interface_events_t *mp;
4352   f64 timeout;
4353   int enable = -1;
4354
4355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4356     {
4357       if (unformat (i, "enable"))
4358         enable = 1;
4359       else if (unformat (i, "disable"))
4360         enable = 0;
4361       else
4362         break;
4363     }
4364
4365   if (enable == -1)
4366     {
4367       errmsg ("missing enable|disable\n");
4368       return -99;
4369     }
4370
4371   M (WANT_INTERFACE_EVENTS, want_interface_events);
4372   mp->enable_disable = enable;
4373
4374   vam->interface_event_display = enable;
4375
4376   S;
4377   W;
4378 }
4379
4380
4381 /* Note: non-static, called once to set up the initial intfc table */
4382 int
4383 api_sw_interface_dump (vat_main_t * vam)
4384 {
4385   vl_api_sw_interface_dump_t *mp;
4386   f64 timeout;
4387   hash_pair_t *p;
4388   name_sort_t *nses = 0, *ns;
4389   sw_interface_subif_t *sub = NULL;
4390
4391   /* Toss the old name table */
4392   /* *INDENT-OFF* */
4393   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4394   ({
4395     vec_add2 (nses, ns, 1);
4396     ns->name = (u8 *)(p->key);
4397     ns->value = (u32) p->value[0];
4398   }));
4399   /* *INDENT-ON* */
4400
4401   hash_free (vam->sw_if_index_by_interface_name);
4402
4403   vec_foreach (ns, nses) vec_free (ns->name);
4404
4405   vec_free (nses);
4406
4407   vec_foreach (sub, vam->sw_if_subif_table)
4408   {
4409     vec_free (sub->interface_name);
4410   }
4411   vec_free (vam->sw_if_subif_table);
4412
4413   /* recreate the interface name hash table */
4414   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4415
4416   /* Get list of ethernets */
4417   M (SW_INTERFACE_DUMP, sw_interface_dump);
4418   mp->name_filter_valid = 1;
4419   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4420   S;
4421
4422   /* and local / loopback interfaces */
4423   M (SW_INTERFACE_DUMP, sw_interface_dump);
4424   mp->name_filter_valid = 1;
4425   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4426   S;
4427
4428   /* and packet-generator interfaces */
4429   M (SW_INTERFACE_DUMP, sw_interface_dump);
4430   mp->name_filter_valid = 1;
4431   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4432   S;
4433
4434   /* and vxlan-gpe tunnel interfaces */
4435   M (SW_INTERFACE_DUMP, sw_interface_dump);
4436   mp->name_filter_valid = 1;
4437   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4438            sizeof (mp->name_filter) - 1);
4439   S;
4440
4441   /* and vxlan tunnel interfaces */
4442   M (SW_INTERFACE_DUMP, sw_interface_dump);
4443   mp->name_filter_valid = 1;
4444   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4445   S;
4446
4447   /* and host (af_packet) interfaces */
4448   M (SW_INTERFACE_DUMP, sw_interface_dump);
4449   mp->name_filter_valid = 1;
4450   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4451   S;
4452
4453   /* and l2tpv3 tunnel interfaces */
4454   M (SW_INTERFACE_DUMP, sw_interface_dump);
4455   mp->name_filter_valid = 1;
4456   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4457            sizeof (mp->name_filter) - 1);
4458   S;
4459
4460   /* and GRE tunnel interfaces */
4461   M (SW_INTERFACE_DUMP, sw_interface_dump);
4462   mp->name_filter_valid = 1;
4463   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4464   S;
4465
4466   /* and LISP-GPE interfaces */
4467   M (SW_INTERFACE_DUMP, sw_interface_dump);
4468   mp->name_filter_valid = 1;
4469   strncpy ((char *) mp->name_filter, "lisp_gpe",
4470            sizeof (mp->name_filter) - 1);
4471   S;
4472
4473   /* and IPSEC tunnel interfaces */
4474   M (SW_INTERFACE_DUMP, sw_interface_dump);
4475   mp->name_filter_valid = 1;
4476   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4477   S;
4478
4479   /* Use a control ping for synchronization */
4480   {
4481     vl_api_control_ping_t *mp;
4482     M (CONTROL_PING, control_ping);
4483     S;
4484   }
4485   W;
4486 }
4487
4488 static int
4489 api_sw_interface_set_flags (vat_main_t * vam)
4490 {
4491   unformat_input_t *i = vam->input;
4492   vl_api_sw_interface_set_flags_t *mp;
4493   f64 timeout;
4494   u32 sw_if_index;
4495   u8 sw_if_index_set = 0;
4496   u8 admin_up = 0, link_up = 0;
4497
4498   /* Parse args required to build the message */
4499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4500     {
4501       if (unformat (i, "admin-up"))
4502         admin_up = 1;
4503       else if (unformat (i, "admin-down"))
4504         admin_up = 0;
4505       else if (unformat (i, "link-up"))
4506         link_up = 1;
4507       else if (unformat (i, "link-down"))
4508         link_up = 0;
4509       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4510         sw_if_index_set = 1;
4511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4512         sw_if_index_set = 1;
4513       else
4514         break;
4515     }
4516
4517   if (sw_if_index_set == 0)
4518     {
4519       errmsg ("missing interface name or sw_if_index\n");
4520       return -99;
4521     }
4522
4523   /* Construct the API message */
4524   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4525   mp->sw_if_index = ntohl (sw_if_index);
4526   mp->admin_up_down = admin_up;
4527   mp->link_up_down = link_up;
4528
4529   /* send it... */
4530   S;
4531
4532   /* Wait for a reply, return the good/bad news... */
4533   W;
4534 }
4535
4536 static int
4537 api_sw_interface_clear_stats (vat_main_t * vam)
4538 {
4539   unformat_input_t *i = vam->input;
4540   vl_api_sw_interface_clear_stats_t *mp;
4541   f64 timeout;
4542   u32 sw_if_index;
4543   u8 sw_if_index_set = 0;
4544
4545   /* Parse args required to build the message */
4546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4547     {
4548       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4549         sw_if_index_set = 1;
4550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4551         sw_if_index_set = 1;
4552       else
4553         break;
4554     }
4555
4556   /* Construct the API message */
4557   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4558
4559   if (sw_if_index_set == 1)
4560     mp->sw_if_index = ntohl (sw_if_index);
4561   else
4562     mp->sw_if_index = ~0;
4563
4564   /* send it... */
4565   S;
4566
4567   /* Wait for a reply, return the good/bad news... */
4568   W;
4569 }
4570
4571 static int
4572 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4573 {
4574   unformat_input_t *i = vam->input;
4575   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4576   f64 timeout;
4577   u32 sw_if_index;
4578   u8 sw_if_index_set = 0;
4579   u32 subport;
4580   u8 subport_set = 0;
4581   u32 pipe;
4582   u8 pipe_set = 0;
4583   u32 profile;
4584   u8 profile_set = 0;
4585
4586   /* Parse args required to build the message */
4587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4588     {
4589       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4590         sw_if_index_set = 1;
4591       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4592         sw_if_index_set = 1;
4593       else if (unformat (i, "subport %u", &subport))
4594         subport_set = 1;
4595       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4596         sw_if_index_set = 1;
4597       else if (unformat (i, "pipe %u", &pipe))
4598         pipe_set = 1;
4599       else if (unformat (i, "profile %u", &profile))
4600         profile_set = 1;
4601       else
4602         break;
4603     }
4604
4605   if (sw_if_index_set == 0)
4606     {
4607       errmsg ("missing interface name or sw_if_index\n");
4608       return -99;
4609     }
4610
4611   if (subport_set == 0)
4612     {
4613       errmsg ("missing subport \n");
4614       return -99;
4615     }
4616
4617   if (pipe_set == 0)
4618     {
4619       errmsg ("missing pipe\n");
4620       return -99;
4621     }
4622
4623   if (profile_set == 0)
4624     {
4625       errmsg ("missing profile\n");
4626       return -99;
4627     }
4628
4629   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4630
4631   mp->sw_if_index = ntohl (sw_if_index);
4632   mp->subport = ntohl (subport);
4633   mp->pipe = ntohl (pipe);
4634   mp->profile = ntohl (profile);
4635
4636
4637   S;
4638   W;
4639   /* NOTREACHED */
4640   return 0;
4641 }
4642
4643 static int
4644 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4645 {
4646   unformat_input_t *i = vam->input;
4647   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4648   f64 timeout;
4649   u32 sw_if_index;
4650   u8 sw_if_index_set = 0;
4651   u32 subport;
4652   u8 subport_set = 0;
4653   u32 tb_rate = 1250000000;     /* 10GbE */
4654   u32 tb_size = 1000000;
4655   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4656   u32 tc_period = 10;
4657
4658   /* Parse args required to build the message */
4659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4660     {
4661       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4662         sw_if_index_set = 1;
4663       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4664         sw_if_index_set = 1;
4665       else if (unformat (i, "subport %u", &subport))
4666         subport_set = 1;
4667       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4668         sw_if_index_set = 1;
4669       else if (unformat (i, "rate %u", &tb_rate))
4670         {
4671           u32 tc_id;
4672
4673           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4674                tc_id++)
4675             tc_rate[tc_id] = tb_rate;
4676         }
4677       else if (unformat (i, "bktsize %u", &tb_size))
4678         ;
4679       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4680         ;
4681       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4682         ;
4683       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4684         ;
4685       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4686         ;
4687       else if (unformat (i, "period %u", &tc_period))
4688         ;
4689       else
4690         break;
4691     }
4692
4693   if (sw_if_index_set == 0)
4694     {
4695       errmsg ("missing interface name or sw_if_index\n");
4696       return -99;
4697     }
4698
4699   if (subport_set == 0)
4700     {
4701       errmsg ("missing subport \n");
4702       return -99;
4703     }
4704
4705   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4706
4707   mp->sw_if_index = ntohl (sw_if_index);
4708   mp->subport = ntohl (subport);
4709   mp->tb_rate = ntohl (tb_rate);
4710   mp->tb_size = ntohl (tb_size);
4711   mp->tc_rate[0] = ntohl (tc_rate[0]);
4712   mp->tc_rate[1] = ntohl (tc_rate[1]);
4713   mp->tc_rate[2] = ntohl (tc_rate[2]);
4714   mp->tc_rate[3] = ntohl (tc_rate[3]);
4715   mp->tc_period = ntohl (tc_period);
4716
4717   S;
4718   W;
4719   /* NOTREACHED */
4720   return 0;
4721 }
4722
4723 static int
4724 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4725 {
4726   unformat_input_t *i = vam->input;
4727   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4728   f64 timeout;
4729   u32 sw_if_index;
4730   u8 sw_if_index_set = 0;
4731   u8 entry_set = 0;
4732   u8 tc_set = 0;
4733   u8 queue_set = 0;
4734   u32 entry, tc, queue;
4735
4736   /* Parse args required to build the message */
4737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4738     {
4739       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4740         sw_if_index_set = 1;
4741       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4742         sw_if_index_set = 1;
4743       else if (unformat (i, "entry %d", &entry))
4744         entry_set = 1;
4745       else if (unformat (i, "tc %d", &tc))
4746         tc_set = 1;
4747       else if (unformat (i, "queue %d", &queue))
4748         queue_set = 1;
4749       else
4750         break;
4751     }
4752
4753   if (sw_if_index_set == 0)
4754     {
4755       errmsg ("missing interface name or sw_if_index\n");
4756       return -99;
4757     }
4758
4759   if (entry_set == 0)
4760     {
4761       errmsg ("missing entry \n");
4762       return -99;
4763     }
4764
4765   if (tc_set == 0)
4766     {
4767       errmsg ("missing traffic class \n");
4768       return -99;
4769     }
4770
4771   if (queue_set == 0)
4772     {
4773       errmsg ("missing queue \n");
4774       return -99;
4775     }
4776
4777   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4778
4779   mp->sw_if_index = ntohl (sw_if_index);
4780   mp->entry = ntohl (entry);
4781   mp->tc = ntohl (tc);
4782   mp->queue = ntohl (queue);
4783
4784   S;
4785   W;
4786   /* NOTREACHED */
4787   return 0;
4788 }
4789
4790 static int
4791 api_sw_interface_add_del_address (vat_main_t * vam)
4792 {
4793   unformat_input_t *i = vam->input;
4794   vl_api_sw_interface_add_del_address_t *mp;
4795   f64 timeout;
4796   u32 sw_if_index;
4797   u8 sw_if_index_set = 0;
4798   u8 is_add = 1, del_all = 0;
4799   u32 address_length = 0;
4800   u8 v4_address_set = 0;
4801   u8 v6_address_set = 0;
4802   ip4_address_t v4address;
4803   ip6_address_t v6address;
4804
4805   /* Parse args required to build the message */
4806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4807     {
4808       if (unformat (i, "del-all"))
4809         del_all = 1;
4810       else if (unformat (i, "del"))
4811         is_add = 0;
4812       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4813         sw_if_index_set = 1;
4814       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4815         sw_if_index_set = 1;
4816       else if (unformat (i, "%U/%d",
4817                          unformat_ip4_address, &v4address, &address_length))
4818         v4_address_set = 1;
4819       else if (unformat (i, "%U/%d",
4820                          unformat_ip6_address, &v6address, &address_length))
4821         v6_address_set = 1;
4822       else
4823         break;
4824     }
4825
4826   if (sw_if_index_set == 0)
4827     {
4828       errmsg ("missing interface name or sw_if_index\n");
4829       return -99;
4830     }
4831   if (v4_address_set && v6_address_set)
4832     {
4833       errmsg ("both v4 and v6 addresses set\n");
4834       return -99;
4835     }
4836   if (!v4_address_set && !v6_address_set && !del_all)
4837     {
4838       errmsg ("no addresses set\n");
4839       return -99;
4840     }
4841
4842   /* Construct the API message */
4843   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4844
4845   mp->sw_if_index = ntohl (sw_if_index);
4846   mp->is_add = is_add;
4847   mp->del_all = del_all;
4848   if (v6_address_set)
4849     {
4850       mp->is_ipv6 = 1;
4851       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4852     }
4853   else
4854     {
4855       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4856     }
4857   mp->address_length = address_length;
4858
4859   /* send it... */
4860   S;
4861
4862   /* Wait for a reply, return good/bad news  */
4863   W;
4864 }
4865
4866 static int
4867 api_sw_interface_set_table (vat_main_t * vam)
4868 {
4869   unformat_input_t *i = vam->input;
4870   vl_api_sw_interface_set_table_t *mp;
4871   f64 timeout;
4872   u32 sw_if_index, vrf_id = 0;
4873   u8 sw_if_index_set = 0;
4874   u8 is_ipv6 = 0;
4875
4876   /* Parse args required to build the message */
4877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4878     {
4879       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4880         sw_if_index_set = 1;
4881       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4882         sw_if_index_set = 1;
4883       else if (unformat (i, "vrf %d", &vrf_id))
4884         ;
4885       else if (unformat (i, "ipv6"))
4886         is_ipv6 = 1;
4887       else
4888         break;
4889     }
4890
4891   if (sw_if_index_set == 0)
4892     {
4893       errmsg ("missing interface name or sw_if_index\n");
4894       return -99;
4895     }
4896
4897   /* Construct the API message */
4898   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4899
4900   mp->sw_if_index = ntohl (sw_if_index);
4901   mp->is_ipv6 = is_ipv6;
4902   mp->vrf_id = ntohl (vrf_id);
4903
4904   /* send it... */
4905   S;
4906
4907   /* Wait for a reply... */
4908   W;
4909 }
4910
4911 static int
4912 api_sw_interface_set_vpath (vat_main_t * vam)
4913 {
4914   unformat_input_t *i = vam->input;
4915   vl_api_sw_interface_set_vpath_t *mp;
4916   f64 timeout;
4917   u32 sw_if_index = 0;
4918   u8 sw_if_index_set = 0;
4919   u8 is_enable = 0;
4920
4921   /* Parse args required to build the message */
4922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4923     {
4924       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4925         sw_if_index_set = 1;
4926       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4927         sw_if_index_set = 1;
4928       else if (unformat (i, "enable"))
4929         is_enable = 1;
4930       else if (unformat (i, "disable"))
4931         is_enable = 0;
4932       else
4933         break;
4934     }
4935
4936   if (sw_if_index_set == 0)
4937     {
4938       errmsg ("missing interface name or sw_if_index\n");
4939       return -99;
4940     }
4941
4942   /* Construct the API message */
4943   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4944
4945   mp->sw_if_index = ntohl (sw_if_index);
4946   mp->enable = is_enable;
4947
4948   /* send it... */
4949   S;
4950
4951   /* Wait for a reply... */
4952   W;
4953 }
4954
4955 static int
4956 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4957 {
4958   unformat_input_t *i = vam->input;
4959   vl_api_sw_interface_set_l2_xconnect_t *mp;
4960   f64 timeout;
4961   u32 rx_sw_if_index;
4962   u8 rx_sw_if_index_set = 0;
4963   u32 tx_sw_if_index;
4964   u8 tx_sw_if_index_set = 0;
4965   u8 enable = 1;
4966
4967   /* Parse args required to build the message */
4968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4969     {
4970       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4971         rx_sw_if_index_set = 1;
4972       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4973         tx_sw_if_index_set = 1;
4974       else if (unformat (i, "rx"))
4975         {
4976           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4977             {
4978               if (unformat (i, "%U", unformat_sw_if_index, vam,
4979                             &rx_sw_if_index))
4980                 rx_sw_if_index_set = 1;
4981             }
4982           else
4983             break;
4984         }
4985       else if (unformat (i, "tx"))
4986         {
4987           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4988             {
4989               if (unformat (i, "%U", unformat_sw_if_index, vam,
4990                             &tx_sw_if_index))
4991                 tx_sw_if_index_set = 1;
4992             }
4993           else
4994             break;
4995         }
4996       else if (unformat (i, "enable"))
4997         enable = 1;
4998       else if (unformat (i, "disable"))
4999         enable = 0;
5000       else
5001         break;
5002     }
5003
5004   if (rx_sw_if_index_set == 0)
5005     {
5006       errmsg ("missing rx interface name or rx_sw_if_index\n");
5007       return -99;
5008     }
5009
5010   if (enable && (tx_sw_if_index_set == 0))
5011     {
5012       errmsg ("missing tx interface name or tx_sw_if_index\n");
5013       return -99;
5014     }
5015
5016   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5017
5018   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5019   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5020   mp->enable = enable;
5021
5022   S;
5023   W;
5024   /* NOTREACHED */
5025   return 0;
5026 }
5027
5028 static int
5029 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5030 {
5031   unformat_input_t *i = vam->input;
5032   vl_api_sw_interface_set_l2_bridge_t *mp;
5033   f64 timeout;
5034   u32 rx_sw_if_index;
5035   u8 rx_sw_if_index_set = 0;
5036   u32 bd_id;
5037   u8 bd_id_set = 0;
5038   u8 bvi = 0;
5039   u32 shg = 0;
5040   u8 enable = 1;
5041
5042   /* Parse args required to build the message */
5043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5044     {
5045       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5046         rx_sw_if_index_set = 1;
5047       else if (unformat (i, "bd_id %d", &bd_id))
5048         bd_id_set = 1;
5049       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5050         rx_sw_if_index_set = 1;
5051       else if (unformat (i, "shg %d", &shg))
5052         ;
5053       else if (unformat (i, "bvi"))
5054         bvi = 1;
5055       else if (unformat (i, "enable"))
5056         enable = 1;
5057       else if (unformat (i, "disable"))
5058         enable = 0;
5059       else
5060         break;
5061     }
5062
5063   if (rx_sw_if_index_set == 0)
5064     {
5065       errmsg ("missing rx interface name or sw_if_index\n");
5066       return -99;
5067     }
5068
5069   if (enable && (bd_id_set == 0))
5070     {
5071       errmsg ("missing bridge domain\n");
5072       return -99;
5073     }
5074
5075   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5076
5077   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5078   mp->bd_id = ntohl (bd_id);
5079   mp->shg = (u8) shg;
5080   mp->bvi = bvi;
5081   mp->enable = enable;
5082
5083   S;
5084   W;
5085   /* NOTREACHED */
5086   return 0;
5087 }
5088
5089 static int
5090 api_bridge_domain_dump (vat_main_t * vam)
5091 {
5092   unformat_input_t *i = vam->input;
5093   vl_api_bridge_domain_dump_t *mp;
5094   f64 timeout;
5095   u32 bd_id = ~0;
5096
5097   /* Parse args required to build the message */
5098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5099     {
5100       if (unformat (i, "bd_id %d", &bd_id))
5101         ;
5102       else
5103         break;
5104     }
5105
5106   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5107   mp->bd_id = ntohl (bd_id);
5108   S;
5109
5110   /* Use a control ping for synchronization */
5111   {
5112     vl_api_control_ping_t *mp;
5113     M (CONTROL_PING, control_ping);
5114     S;
5115   }
5116
5117   W;
5118   /* NOTREACHED */
5119   return 0;
5120 }
5121
5122 static int
5123 api_bridge_domain_add_del (vat_main_t * vam)
5124 {
5125   unformat_input_t *i = vam->input;
5126   vl_api_bridge_domain_add_del_t *mp;
5127   f64 timeout;
5128   u32 bd_id = ~0;
5129   u8 is_add = 1;
5130   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5131
5132   /* Parse args required to build the message */
5133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5134     {
5135       if (unformat (i, "bd_id %d", &bd_id))
5136         ;
5137       else if (unformat (i, "flood %d", &flood))
5138         ;
5139       else if (unformat (i, "uu-flood %d", &uu_flood))
5140         ;
5141       else if (unformat (i, "forward %d", &forward))
5142         ;
5143       else if (unformat (i, "learn %d", &learn))
5144         ;
5145       else if (unformat (i, "arp-term %d", &arp_term))
5146         ;
5147       else if (unformat (i, "del"))
5148         {
5149           is_add = 0;
5150           flood = uu_flood = forward = learn = 0;
5151         }
5152       else
5153         break;
5154     }
5155
5156   if (bd_id == ~0)
5157     {
5158       errmsg ("missing bridge domain\n");
5159       return -99;
5160     }
5161
5162   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5163
5164   mp->bd_id = ntohl (bd_id);
5165   mp->flood = flood;
5166   mp->uu_flood = uu_flood;
5167   mp->forward = forward;
5168   mp->learn = learn;
5169   mp->arp_term = arp_term;
5170   mp->is_add = is_add;
5171
5172   S;
5173   W;
5174   /* NOTREACHED */
5175   return 0;
5176 }
5177
5178 static int
5179 api_l2fib_add_del (vat_main_t * vam)
5180 {
5181   unformat_input_t *i = vam->input;
5182   vl_api_l2fib_add_del_t *mp;
5183   f64 timeout;
5184   u64 mac = 0;
5185   u8 mac_set = 0;
5186   u32 bd_id;
5187   u8 bd_id_set = 0;
5188   u32 sw_if_index;
5189   u8 sw_if_index_set = 0;
5190   u8 is_add = 1;
5191   u8 static_mac = 0;
5192   u8 filter_mac = 0;
5193   u8 bvi_mac = 0;
5194   int count = 1;
5195   f64 before = 0;
5196   int j;
5197
5198   /* Parse args required to build the message */
5199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5200     {
5201       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5202         mac_set = 1;
5203       else if (unformat (i, "bd_id %d", &bd_id))
5204         bd_id_set = 1;
5205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5206         sw_if_index_set = 1;
5207       else if (unformat (i, "sw_if"))
5208         {
5209           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5210             {
5211               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5212                 sw_if_index_set = 1;
5213             }
5214           else
5215             break;
5216         }
5217       else if (unformat (i, "static"))
5218         static_mac = 1;
5219       else if (unformat (i, "filter"))
5220         {
5221           filter_mac = 1;
5222           static_mac = 1;
5223         }
5224       else if (unformat (i, "bvi"))
5225         {
5226           bvi_mac = 1;
5227           static_mac = 1;
5228         }
5229       else if (unformat (i, "del"))
5230         is_add = 0;
5231       else if (unformat (i, "count %d", &count))
5232         ;
5233       else
5234         break;
5235     }
5236
5237   if (mac_set == 0)
5238     {
5239       errmsg ("missing mac address\n");
5240       return -99;
5241     }
5242
5243   if (bd_id_set == 0)
5244     {
5245       errmsg ("missing bridge domain\n");
5246       return -99;
5247     }
5248
5249   if (is_add && (sw_if_index_set == 0))
5250     {
5251       errmsg ("missing interface name or sw_if_index\n");
5252       return -99;
5253     }
5254
5255   if (count > 1)
5256     {
5257       /* Turn on async mode */
5258       vam->async_mode = 1;
5259       vam->async_errors = 0;
5260       before = vat_time_now (vam);
5261     }
5262
5263   for (j = 0; j < count; j++)
5264     {
5265       M (L2FIB_ADD_DEL, l2fib_add_del);
5266
5267       mp->mac = mac;
5268       mp->bd_id = ntohl (bd_id);
5269       mp->is_add = is_add;
5270
5271       if (is_add)
5272         {
5273           mp->sw_if_index = ntohl (sw_if_index);
5274           mp->static_mac = static_mac;
5275           mp->filter_mac = filter_mac;
5276           mp->bvi_mac = bvi_mac;
5277         }
5278       increment_mac_address (&mac);
5279       /* send it... */
5280       S;
5281     }
5282
5283   if (count > 1)
5284     {
5285       vl_api_control_ping_t *mp;
5286       f64 after;
5287
5288       /* Shut off async mode */
5289       vam->async_mode = 0;
5290
5291       M (CONTROL_PING, control_ping);
5292       S;
5293
5294       timeout = vat_time_now (vam) + 1.0;
5295       while (vat_time_now (vam) < timeout)
5296         if (vam->result_ready == 1)
5297           goto out;
5298       vam->retval = -99;
5299
5300     out:
5301       if (vam->retval == -99)
5302         errmsg ("timeout\n");
5303
5304       if (vam->async_errors > 0)
5305         {
5306           errmsg ("%d asynchronous errors\n", vam->async_errors);
5307           vam->retval = -98;
5308         }
5309       vam->async_errors = 0;
5310       after = vat_time_now (vam);
5311
5312       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5313                count, after - before, count / (after - before));
5314     }
5315   else
5316     {
5317       /* Wait for a reply... */
5318       W;
5319     }
5320   /* Return the good/bad news */
5321   return (vam->retval);
5322 }
5323
5324 static int
5325 api_l2_flags (vat_main_t * vam)
5326 {
5327   unformat_input_t *i = vam->input;
5328   vl_api_l2_flags_t *mp;
5329   f64 timeout;
5330   u32 sw_if_index;
5331   u32 feature_bitmap = 0;
5332   u8 sw_if_index_set = 0;
5333
5334   /* Parse args required to build the message */
5335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5336     {
5337       if (unformat (i, "sw_if_index %d", &sw_if_index))
5338         sw_if_index_set = 1;
5339       else if (unformat (i, "sw_if"))
5340         {
5341           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5342             {
5343               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5344                 sw_if_index_set = 1;
5345             }
5346           else
5347             break;
5348         }
5349       else if (unformat (i, "learn"))
5350         feature_bitmap |= L2INPUT_FEAT_LEARN;
5351       else if (unformat (i, "forward"))
5352         feature_bitmap |= L2INPUT_FEAT_FWD;
5353       else if (unformat (i, "flood"))
5354         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5355       else if (unformat (i, "uu-flood"))
5356         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5357       else
5358         break;
5359     }
5360
5361   if (sw_if_index_set == 0)
5362     {
5363       errmsg ("missing interface name or sw_if_index\n");
5364       return -99;
5365     }
5366
5367   M (L2_FLAGS, l2_flags);
5368
5369   mp->sw_if_index = ntohl (sw_if_index);
5370   mp->feature_bitmap = ntohl (feature_bitmap);
5371
5372   S;
5373   W;
5374   /* NOTREACHED */
5375   return 0;
5376 }
5377
5378 static int
5379 api_bridge_flags (vat_main_t * vam)
5380 {
5381   unformat_input_t *i = vam->input;
5382   vl_api_bridge_flags_t *mp;
5383   f64 timeout;
5384   u32 bd_id;
5385   u8 bd_id_set = 0;
5386   u8 is_set = 1;
5387   u32 flags = 0;
5388
5389   /* Parse args required to build the message */
5390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5391     {
5392       if (unformat (i, "bd_id %d", &bd_id))
5393         bd_id_set = 1;
5394       else if (unformat (i, "learn"))
5395         flags |= L2_LEARN;
5396       else if (unformat (i, "forward"))
5397         flags |= L2_FWD;
5398       else if (unformat (i, "flood"))
5399         flags |= L2_FLOOD;
5400       else if (unformat (i, "uu-flood"))
5401         flags |= L2_UU_FLOOD;
5402       else if (unformat (i, "arp-term"))
5403         flags |= L2_ARP_TERM;
5404       else if (unformat (i, "off"))
5405         is_set = 0;
5406       else if (unformat (i, "disable"))
5407         is_set = 0;
5408       else
5409         break;
5410     }
5411
5412   if (bd_id_set == 0)
5413     {
5414       errmsg ("missing bridge domain\n");
5415       return -99;
5416     }
5417
5418   M (BRIDGE_FLAGS, bridge_flags);
5419
5420   mp->bd_id = ntohl (bd_id);
5421   mp->feature_bitmap = ntohl (flags);
5422   mp->is_set = is_set;
5423
5424   S;
5425   W;
5426   /* NOTREACHED */
5427   return 0;
5428 }
5429
5430 static int
5431 api_bd_ip_mac_add_del (vat_main_t * vam)
5432 {
5433   unformat_input_t *i = vam->input;
5434   vl_api_bd_ip_mac_add_del_t *mp;
5435   f64 timeout;
5436   u32 bd_id;
5437   u8 is_ipv6 = 0;
5438   u8 is_add = 1;
5439   u8 bd_id_set = 0;
5440   u8 ip_set = 0;
5441   u8 mac_set = 0;
5442   ip4_address_t v4addr;
5443   ip6_address_t v6addr;
5444   u8 macaddr[6];
5445
5446
5447   /* Parse args required to build the message */
5448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5449     {
5450       if (unformat (i, "bd_id %d", &bd_id))
5451         {
5452           bd_id_set++;
5453         }
5454       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5455         {
5456           ip_set++;
5457         }
5458       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5459         {
5460           ip_set++;
5461           is_ipv6++;
5462         }
5463       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5464         {
5465           mac_set++;
5466         }
5467       else if (unformat (i, "del"))
5468         is_add = 0;
5469       else
5470         break;
5471     }
5472
5473   if (bd_id_set == 0)
5474     {
5475       errmsg ("missing bridge domain\n");
5476       return -99;
5477     }
5478   else if (ip_set == 0)
5479     {
5480       errmsg ("missing IP address\n");
5481       return -99;
5482     }
5483   else if (mac_set == 0)
5484     {
5485       errmsg ("missing MAC address\n");
5486       return -99;
5487     }
5488
5489   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5490
5491   mp->bd_id = ntohl (bd_id);
5492   mp->is_ipv6 = is_ipv6;
5493   mp->is_add = is_add;
5494   if (is_ipv6)
5495     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5496   else
5497     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5498   clib_memcpy (mp->mac_address, macaddr, 6);
5499   S;
5500   W;
5501   /* NOTREACHED */
5502   return 0;
5503 }
5504
5505 static int
5506 api_tap_connect (vat_main_t * vam)
5507 {
5508   unformat_input_t *i = vam->input;
5509   vl_api_tap_connect_t *mp;
5510   f64 timeout;
5511   u8 mac_address[6];
5512   u8 random_mac = 1;
5513   u8 name_set = 0;
5514   u8 *tap_name;
5515
5516   memset (mac_address, 0, sizeof (mac_address));
5517
5518   /* Parse args required to build the message */
5519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5520     {
5521       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5522         {
5523           random_mac = 0;
5524         }
5525       else if (unformat (i, "random-mac"))
5526         random_mac = 1;
5527       else if (unformat (i, "tapname %s", &tap_name))
5528         name_set = 1;
5529       else
5530         break;
5531     }
5532
5533   if (name_set == 0)
5534     {
5535       errmsg ("missing tap name\n");
5536       return -99;
5537     }
5538   if (vec_len (tap_name) > 63)
5539     {
5540       errmsg ("tap name too long\n");
5541     }
5542   vec_add1 (tap_name, 0);
5543
5544   /* Construct the API message */
5545   M (TAP_CONNECT, tap_connect);
5546
5547   mp->use_random_mac = random_mac;
5548   clib_memcpy (mp->mac_address, mac_address, 6);
5549   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5550   vec_free (tap_name);
5551
5552   /* send it... */
5553   S;
5554
5555   /* Wait for a reply... */
5556   W;
5557 }
5558
5559 static int
5560 api_tap_modify (vat_main_t * vam)
5561 {
5562   unformat_input_t *i = vam->input;
5563   vl_api_tap_modify_t *mp;
5564   f64 timeout;
5565   u8 mac_address[6];
5566   u8 random_mac = 1;
5567   u8 name_set = 0;
5568   u8 *tap_name;
5569   u32 sw_if_index = ~0;
5570   u8 sw_if_index_set = 0;
5571
5572   memset (mac_address, 0, sizeof (mac_address));
5573
5574   /* Parse args required to build the message */
5575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5576     {
5577       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5578         sw_if_index_set = 1;
5579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5580         sw_if_index_set = 1;
5581       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5582         {
5583           random_mac = 0;
5584         }
5585       else if (unformat (i, "random-mac"))
5586         random_mac = 1;
5587       else if (unformat (i, "tapname %s", &tap_name))
5588         name_set = 1;
5589       else
5590         break;
5591     }
5592
5593   if (sw_if_index_set == 0)
5594     {
5595       errmsg ("missing vpp interface name");
5596       return -99;
5597     }
5598   if (name_set == 0)
5599     {
5600       errmsg ("missing tap name\n");
5601       return -99;
5602     }
5603   if (vec_len (tap_name) > 63)
5604     {
5605       errmsg ("tap name too long\n");
5606     }
5607   vec_add1 (tap_name, 0);
5608
5609   /* Construct the API message */
5610   M (TAP_MODIFY, tap_modify);
5611
5612   mp->use_random_mac = random_mac;
5613   mp->sw_if_index = ntohl (sw_if_index);
5614   clib_memcpy (mp->mac_address, mac_address, 6);
5615   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5616   vec_free (tap_name);
5617
5618   /* send it... */
5619   S;
5620
5621   /* Wait for a reply... */
5622   W;
5623 }
5624
5625 static int
5626 api_tap_delete (vat_main_t * vam)
5627 {
5628   unformat_input_t *i = vam->input;
5629   vl_api_tap_delete_t *mp;
5630   f64 timeout;
5631   u32 sw_if_index = ~0;
5632   u8 sw_if_index_set = 0;
5633
5634   /* Parse args required to build the message */
5635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5636     {
5637       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5638         sw_if_index_set = 1;
5639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5640         sw_if_index_set = 1;
5641       else
5642         break;
5643     }
5644
5645   if (sw_if_index_set == 0)
5646     {
5647       errmsg ("missing vpp interface name");
5648       return -99;
5649     }
5650
5651   /* Construct the API message */
5652   M (TAP_DELETE, tap_delete);
5653
5654   mp->sw_if_index = ntohl (sw_if_index);
5655
5656   /* send it... */
5657   S;
5658
5659   /* Wait for a reply... */
5660   W;
5661 }
5662
5663 static int
5664 api_ip_add_del_route (vat_main_t * vam)
5665 {
5666   unformat_input_t *i = vam->input;
5667   vl_api_ip_add_del_route_t *mp;
5668   f64 timeout;
5669   u32 sw_if_index = ~0, vrf_id = 0;
5670   u8 sw_if_index_set = 0;
5671   u8 is_ipv6 = 0;
5672   u8 is_local = 0, is_drop = 0;
5673   u8 create_vrf_if_needed = 0;
5674   u8 is_add = 1;
5675   u8 next_hop_weight = 1;
5676   u8 not_last = 0;
5677   u8 is_multipath = 0;
5678   u8 address_set = 0;
5679   u8 address_length_set = 0;
5680   u32 lookup_in_vrf = 0;
5681   u32 resolve_attempts = 0;
5682   u32 dst_address_length = 0;
5683   u8 next_hop_set = 0;
5684   ip4_address_t v4_dst_address, v4_next_hop_address;
5685   ip6_address_t v6_dst_address, v6_next_hop_address;
5686   int count = 1;
5687   int j;
5688   f64 before = 0;
5689   u32 random_add_del = 0;
5690   u32 *random_vector = 0;
5691   uword *random_hash;
5692   u32 random_seed = 0xdeaddabe;
5693   u32 classify_table_index = ~0;
5694   u8 is_classify = 0;
5695   u8 resolve_host = 0, resolve_attached = 0;
5696
5697   /* Parse args required to build the message */
5698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5699     {
5700       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5701         sw_if_index_set = 1;
5702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5703         sw_if_index_set = 1;
5704       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5705         {
5706           address_set = 1;
5707           is_ipv6 = 0;
5708         }
5709       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5710         {
5711           address_set = 1;
5712           is_ipv6 = 1;
5713         }
5714       else if (unformat (i, "/%d", &dst_address_length))
5715         {
5716           address_length_set = 1;
5717         }
5718
5719       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5720                                          &v4_next_hop_address))
5721         {
5722           next_hop_set = 1;
5723         }
5724       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5725                                          &v6_next_hop_address))
5726         {
5727           next_hop_set = 1;
5728         }
5729       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5730         ;
5731       else if (unformat (i, "weight %d", &next_hop_weight))
5732         ;
5733       else if (unformat (i, "drop"))
5734         {
5735           is_drop = 1;
5736         }
5737       else if (unformat (i, "local"))
5738         {
5739           is_local = 1;
5740         }
5741       else if (unformat (i, "classify %d", &classify_table_index))
5742         {
5743           is_classify = 1;
5744         }
5745       else if (unformat (i, "del"))
5746         is_add = 0;
5747       else if (unformat (i, "add"))
5748         is_add = 1;
5749       else if (unformat (i, "not-last"))
5750         not_last = 1;
5751       else if (unformat (i, "resolve-via-host"))
5752         resolve_host = 1;
5753       else if (unformat (i, "resolve-via-attached"))
5754         resolve_attached = 1;
5755       else if (unformat (i, "multipath"))
5756         is_multipath = 1;
5757       else if (unformat (i, "vrf %d", &vrf_id))
5758         ;
5759       else if (unformat (i, "create-vrf"))
5760         create_vrf_if_needed = 1;
5761       else if (unformat (i, "count %d", &count))
5762         ;
5763       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5764         ;
5765       else if (unformat (i, "random"))
5766         random_add_del = 1;
5767       else if (unformat (i, "seed %d", &random_seed))
5768         ;
5769       else
5770         {
5771           clib_warning ("parse error '%U'", format_unformat_error, i);
5772           return -99;
5773         }
5774     }
5775
5776   if (resolve_attempts > 0 && sw_if_index_set == 0)
5777     {
5778       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5779       return -99;
5780     }
5781
5782   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5783     {
5784       errmsg ("next hop / local / drop / classify not set\n");
5785       return -99;
5786     }
5787
5788   if (address_set == 0)
5789     {
5790       errmsg ("missing addresses\n");
5791       return -99;
5792     }
5793
5794   if (address_length_set == 0)
5795     {
5796       errmsg ("missing address length\n");
5797       return -99;
5798     }
5799
5800   /* Generate a pile of unique, random routes */
5801   if (random_add_del)
5802     {
5803       u32 this_random_address;
5804       random_hash = hash_create (count, sizeof (uword));
5805
5806       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5807       for (j = 0; j <= count; j++)
5808         {
5809           do
5810             {
5811               this_random_address = random_u32 (&random_seed);
5812               this_random_address =
5813                 clib_host_to_net_u32 (this_random_address);
5814             }
5815           while (hash_get (random_hash, this_random_address));
5816           vec_add1 (random_vector, this_random_address);
5817           hash_set (random_hash, this_random_address, 1);
5818         }
5819       hash_free (random_hash);
5820       v4_dst_address.as_u32 = random_vector[0];
5821     }
5822
5823   if (count > 1)
5824     {
5825       /* Turn on async mode */
5826       vam->async_mode = 1;
5827       vam->async_errors = 0;
5828       before = vat_time_now (vam);
5829     }
5830
5831   for (j = 0; j < count; j++)
5832     {
5833       /* Construct the API message */
5834       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5835
5836       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5837       mp->vrf_id = ntohl (vrf_id);
5838       if (resolve_attempts > 0)
5839         {
5840           mp->resolve_attempts = ntohl (resolve_attempts);
5841           mp->resolve_if_needed = 1;
5842         }
5843       mp->create_vrf_if_needed = create_vrf_if_needed;
5844
5845       mp->is_add = is_add;
5846       mp->is_drop = is_drop;
5847       mp->is_ipv6 = is_ipv6;
5848       mp->is_local = is_local;
5849       mp->is_classify = is_classify;
5850       mp->is_multipath = is_multipath;
5851       mp->is_resolve_host = resolve_host;
5852       mp->is_resolve_attached = resolve_attached;
5853       mp->not_last = not_last;
5854       mp->next_hop_weight = next_hop_weight;
5855       mp->dst_address_length = dst_address_length;
5856       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5857       mp->classify_table_index = ntohl (classify_table_index);
5858
5859       if (is_ipv6)
5860         {
5861           clib_memcpy (mp->dst_address, &v6_dst_address,
5862                        sizeof (v6_dst_address));
5863           if (next_hop_set)
5864             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5865                          sizeof (v6_next_hop_address));
5866           increment_v6_address (&v6_dst_address);
5867         }
5868       else
5869         {
5870           clib_memcpy (mp->dst_address, &v4_dst_address,
5871                        sizeof (v4_dst_address));
5872           if (next_hop_set)
5873             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5874                          sizeof (v4_next_hop_address));
5875           if (random_add_del)
5876             v4_dst_address.as_u32 = random_vector[j + 1];
5877           else
5878             increment_v4_address (&v4_dst_address);
5879         }
5880       /* send it... */
5881       S;
5882       /* If we receive SIGTERM, stop now... */
5883       if (vam->do_exit)
5884         break;
5885     }
5886
5887   /* When testing multiple add/del ops, use a control-ping to sync */
5888   if (count > 1)
5889     {
5890       vl_api_control_ping_t *mp;
5891       f64 after;
5892
5893       /* Shut off async mode */
5894       vam->async_mode = 0;
5895
5896       M (CONTROL_PING, control_ping);
5897       S;
5898
5899       timeout = vat_time_now (vam) + 1.0;
5900       while (vat_time_now (vam) < timeout)
5901         if (vam->result_ready == 1)
5902           goto out;
5903       vam->retval = -99;
5904
5905     out:
5906       if (vam->retval == -99)
5907         errmsg ("timeout\n");
5908
5909       if (vam->async_errors > 0)
5910         {
5911           errmsg ("%d asynchronous errors\n", vam->async_errors);
5912           vam->retval = -98;
5913         }
5914       vam->async_errors = 0;
5915       after = vat_time_now (vam);
5916
5917       /* slim chance, but we might have eaten SIGTERM on the first iteration */
5918       if (j > 0)
5919         count = j;
5920
5921       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5922                count, after - before, count / (after - before));
5923     }
5924   else
5925     {
5926       /* Wait for a reply... */
5927       W;
5928     }
5929
5930   /* Return the good/bad news */
5931   return (vam->retval);
5932 }
5933
5934 static int
5935 api_proxy_arp_add_del (vat_main_t * vam)
5936 {
5937   unformat_input_t *i = vam->input;
5938   vl_api_proxy_arp_add_del_t *mp;
5939   f64 timeout;
5940   u32 vrf_id = 0;
5941   u8 is_add = 1;
5942   ip4_address_t lo, hi;
5943   u8 range_set = 0;
5944
5945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5946     {
5947       if (unformat (i, "vrf %d", &vrf_id))
5948         ;
5949       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5950                          unformat_ip4_address, &hi))
5951         range_set = 1;
5952       else if (unformat (i, "del"))
5953         is_add = 0;
5954       else
5955         {
5956           clib_warning ("parse error '%U'", format_unformat_error, i);
5957           return -99;
5958         }
5959     }
5960
5961   if (range_set == 0)
5962     {
5963       errmsg ("address range not set\n");
5964       return -99;
5965     }
5966
5967   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5968
5969   mp->vrf_id = ntohl (vrf_id);
5970   mp->is_add = is_add;
5971   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5972   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5973
5974   S;
5975   W;
5976   /* NOTREACHED */
5977   return 0;
5978 }
5979
5980 static int
5981 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5982 {
5983   unformat_input_t *i = vam->input;
5984   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5985   f64 timeout;
5986   u32 sw_if_index;
5987   u8 enable = 1;
5988   u8 sw_if_index_set = 0;
5989
5990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5991     {
5992       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5993         sw_if_index_set = 1;
5994       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5995         sw_if_index_set = 1;
5996       else if (unformat (i, "enable"))
5997         enable = 1;
5998       else if (unformat (i, "disable"))
5999         enable = 0;
6000       else
6001         {
6002           clib_warning ("parse error '%U'", format_unformat_error, i);
6003           return -99;
6004         }
6005     }
6006
6007   if (sw_if_index_set == 0)
6008     {
6009       errmsg ("missing interface name or sw_if_index\n");
6010       return -99;
6011     }
6012
6013   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6014
6015   mp->sw_if_index = ntohl (sw_if_index);
6016   mp->enable_disable = enable;
6017
6018   S;
6019   W;
6020   /* NOTREACHED */
6021   return 0;
6022 }
6023
6024 static int
6025 api_mpls_add_del_decap (vat_main_t * vam)
6026 {
6027   unformat_input_t *i = vam->input;
6028   vl_api_mpls_add_del_decap_t *mp;
6029   f64 timeout;
6030   u32 rx_vrf_id = 0;
6031   u32 tx_vrf_id = 0;
6032   u32 label = 0;
6033   u8 is_add = 1;
6034   u8 s_bit = 1;
6035   u32 next_index = 1;
6036
6037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6038     {
6039       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6040         ;
6041       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
6042         ;
6043       else if (unformat (i, "label %d", &label))
6044         ;
6045       else if (unformat (i, "next-index %d", &next_index))
6046         ;
6047       else if (unformat (i, "del"))
6048         is_add = 0;
6049       else if (unformat (i, "s-bit-clear"))
6050         s_bit = 0;
6051       else
6052         {
6053           clib_warning ("parse error '%U'", format_unformat_error, i);
6054           return -99;
6055         }
6056     }
6057
6058   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
6059
6060   mp->rx_vrf_id = ntohl (rx_vrf_id);
6061   mp->tx_vrf_id = ntohl (tx_vrf_id);
6062   mp->label = ntohl (label);
6063   mp->next_index = ntohl (next_index);
6064   mp->s_bit = s_bit;
6065   mp->is_add = is_add;
6066
6067   S;
6068   W;
6069   /* NOTREACHED */
6070   return 0;
6071 }
6072
6073 static int
6074 api_mpls_add_del_encap (vat_main_t * vam)
6075 {
6076   unformat_input_t *i = vam->input;
6077   vl_api_mpls_add_del_encap_t *mp;
6078   f64 timeout;
6079   u32 vrf_id = 0;
6080   u32 *labels = 0;
6081   u32 label;
6082   ip4_address_t dst_address;
6083   u8 is_add = 1;
6084
6085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6086     {
6087       if (unformat (i, "vrf %d", &vrf_id))
6088         ;
6089       else if (unformat (i, "label %d", &label))
6090         vec_add1 (labels, ntohl (label));
6091       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6092         ;
6093       else if (unformat (i, "del"))
6094         is_add = 0;
6095       else
6096         {
6097           clib_warning ("parse error '%U'", format_unformat_error, i);
6098           return -99;
6099         }
6100     }
6101
6102   if (vec_len (labels) == 0)
6103     {
6104       errmsg ("missing encap label stack\n");
6105       return -99;
6106     }
6107
6108   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6109       sizeof (u32) * vec_len (labels));
6110
6111   mp->vrf_id = ntohl (vrf_id);
6112   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6113   mp->is_add = is_add;
6114   mp->nlabels = vec_len (labels);
6115   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6116
6117   vec_free (labels);
6118
6119   S;
6120   W;
6121   /* NOTREACHED */
6122   return 0;
6123 }
6124
6125 static int
6126 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
6127 {
6128   unformat_input_t *i = vam->input;
6129   vl_api_mpls_gre_add_del_tunnel_t *mp;
6130   f64 timeout;
6131   u32 inner_vrf_id = 0;
6132   u32 outer_vrf_id = 0;
6133   ip4_address_t src_address;
6134   ip4_address_t dst_address;
6135   ip4_address_t intfc_address;
6136   u32 tmp;
6137   u8 intfc_address_length = 0;
6138   u8 is_add = 1;
6139   u8 l2_only = 0;
6140
6141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6142     {
6143       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6144         ;
6145       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6146         ;
6147       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
6148         ;
6149       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6150         ;
6151       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6152                          &intfc_address, &tmp))
6153         intfc_address_length = tmp;
6154       else if (unformat (i, "l2-only"))
6155         l2_only = 1;
6156       else if (unformat (i, "del"))
6157         is_add = 0;
6158       else
6159         {
6160           clib_warning ("parse error '%U'", format_unformat_error, i);
6161           return -99;
6162         }
6163     }
6164
6165   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
6166
6167   mp->inner_vrf_id = ntohl (inner_vrf_id);
6168   mp->outer_vrf_id = ntohl (outer_vrf_id);
6169   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
6170   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6171   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
6172   mp->intfc_address_length = intfc_address_length;
6173   mp->l2_only = l2_only;
6174   mp->is_add = is_add;
6175
6176   S;
6177   W;
6178   /* NOTREACHED */
6179   return 0;
6180 }
6181
6182 static int
6183 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6184 {
6185   unformat_input_t *i = vam->input;
6186   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6187   f64 timeout;
6188   u32 inner_vrf_id = 0;
6189   ip4_address_t intfc_address;
6190   u8 dst_mac_address[6];
6191   int dst_set = 1;
6192   u32 tmp;
6193   u8 intfc_address_length = 0;
6194   u8 is_add = 1;
6195   u8 l2_only = 0;
6196   u32 tx_sw_if_index;
6197   int tx_sw_if_index_set = 0;
6198
6199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6200     {
6201       if (unformat (i, "vrf %d", &inner_vrf_id))
6202         ;
6203       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6204                          &intfc_address, &tmp))
6205         intfc_address_length = tmp;
6206       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6207         tx_sw_if_index_set = 1;
6208       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6209         tx_sw_if_index_set = 1;
6210       else if (unformat (i, "dst %U", unformat_ethernet_address,
6211                          dst_mac_address))
6212         dst_set = 1;
6213       else if (unformat (i, "l2-only"))
6214         l2_only = 1;
6215       else if (unformat (i, "del"))
6216         is_add = 0;
6217       else
6218         {
6219           clib_warning ("parse error '%U'", format_unformat_error, i);
6220           return -99;
6221         }
6222     }
6223
6224   if (!dst_set)
6225     {
6226       errmsg ("dst (mac address) not set\n");
6227       return -99;
6228     }
6229   if (!tx_sw_if_index_set)
6230     {
6231       errmsg ("tx-intfc not set\n");
6232       return -99;
6233     }
6234
6235   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6236
6237   mp->vrf_id = ntohl (inner_vrf_id);
6238   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6239   mp->adj_address_length = intfc_address_length;
6240   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6241                sizeof (dst_mac_address));
6242   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6243   mp->l2_only = l2_only;
6244   mp->is_add = is_add;
6245
6246   S;
6247   W;
6248   /* NOTREACHED */
6249   return 0;
6250 }
6251
6252 static int
6253 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6254 {
6255   unformat_input_t *i = vam->input;
6256   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6257   f64 timeout;
6258   u32 inner_vrf_id = 0;
6259   u32 outer_vrf_id = 0;
6260   ip4_address_t adj_address;
6261   int adj_address_set = 0;
6262   ip4_address_t next_hop_address;
6263   int next_hop_address_set = 0;
6264   u32 tmp;
6265   u8 adj_address_length = 0;
6266   u8 l2_only = 0;
6267   u8 is_add = 1;
6268   u32 resolve_attempts = 5;
6269   u8 resolve_if_needed = 1;
6270
6271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6272     {
6273       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6274         ;
6275       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6276         ;
6277       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6278                          &adj_address, &tmp))
6279         {
6280           adj_address_length = tmp;
6281           adj_address_set = 1;
6282         }
6283       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6284                          &next_hop_address))
6285         next_hop_address_set = 1;
6286       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6287         ;
6288       else if (unformat (i, "resolve-if-needed %d", &tmp))
6289         resolve_if_needed = tmp;
6290       else if (unformat (i, "l2-only"))
6291         l2_only = 1;
6292       else if (unformat (i, "del"))
6293         is_add = 0;
6294       else
6295         {
6296           clib_warning ("parse error '%U'", format_unformat_error, i);
6297           return -99;
6298         }
6299     }
6300
6301   if (!adj_address_set)
6302     {
6303       errmsg ("adjacency address/mask not set\n");
6304       return -99;
6305     }
6306   if (!next_hop_address_set)
6307     {
6308       errmsg ("ip4 next hop address (in outer fib) not set\n");
6309       return -99;
6310     }
6311
6312   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6313
6314   mp->inner_vrf_id = ntohl (inner_vrf_id);
6315   mp->outer_vrf_id = ntohl (outer_vrf_id);
6316   mp->resolve_attempts = ntohl (resolve_attempts);
6317   mp->resolve_if_needed = resolve_if_needed;
6318   mp->is_add = is_add;
6319   mp->l2_only = l2_only;
6320   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6321   mp->adj_address_length = adj_address_length;
6322   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6323                sizeof (next_hop_address));
6324
6325   S;
6326   W;
6327   /* NOTREACHED */
6328   return 0;
6329 }
6330
6331 static int
6332 api_sw_interface_set_unnumbered (vat_main_t * vam)
6333 {
6334   unformat_input_t *i = vam->input;
6335   vl_api_sw_interface_set_unnumbered_t *mp;
6336   f64 timeout;
6337   u32 sw_if_index;
6338   u32 unnum_sw_index = ~0;
6339   u8 is_add = 1;
6340   u8 sw_if_index_set = 0;
6341
6342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6343     {
6344       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6345         sw_if_index_set = 1;
6346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6347         sw_if_index_set = 1;
6348       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6349         ;
6350       else if (unformat (i, "del"))
6351         is_add = 0;
6352       else
6353         {
6354           clib_warning ("parse error '%U'", format_unformat_error, i);
6355           return -99;
6356         }
6357     }
6358
6359   if (sw_if_index_set == 0)
6360     {
6361       errmsg ("missing interface name or sw_if_index\n");
6362       return -99;
6363     }
6364
6365   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6366
6367   mp->sw_if_index = ntohl (sw_if_index);
6368   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6369   mp->is_add = is_add;
6370
6371   S;
6372   W;
6373   /* NOTREACHED */
6374   return 0;
6375 }
6376
6377 static int
6378 api_ip_neighbor_add_del (vat_main_t * vam)
6379 {
6380   unformat_input_t *i = vam->input;
6381   vl_api_ip_neighbor_add_del_t *mp;
6382   f64 timeout;
6383   u32 sw_if_index;
6384   u8 sw_if_index_set = 0;
6385   u32 vrf_id = 0;
6386   u8 is_add = 1;
6387   u8 is_static = 0;
6388   u8 mac_address[6];
6389   u8 mac_set = 0;
6390   u8 v4_address_set = 0;
6391   u8 v6_address_set = 0;
6392   ip4_address_t v4address;
6393   ip6_address_t v6address;
6394
6395   memset (mac_address, 0, sizeof (mac_address));
6396
6397   /* Parse args required to build the message */
6398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6399     {
6400       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6401         {
6402           mac_set = 1;
6403         }
6404       else if (unformat (i, "del"))
6405         is_add = 0;
6406       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6407         sw_if_index_set = 1;
6408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6409         sw_if_index_set = 1;
6410       else if (unformat (i, "is_static"))
6411         is_static = 1;
6412       else if (unformat (i, "vrf %d", &vrf_id))
6413         ;
6414       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6415         v4_address_set = 1;
6416       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6417         v6_address_set = 1;
6418       else
6419         {
6420           clib_warning ("parse error '%U'", format_unformat_error, i);
6421           return -99;
6422         }
6423     }
6424
6425   if (sw_if_index_set == 0)
6426     {
6427       errmsg ("missing interface name or sw_if_index\n");
6428       return -99;
6429     }
6430   if (v4_address_set && v6_address_set)
6431     {
6432       errmsg ("both v4 and v6 addresses set\n");
6433       return -99;
6434     }
6435   if (!v4_address_set && !v6_address_set)
6436     {
6437       errmsg ("no address set\n");
6438       return -99;
6439     }
6440
6441   /* Construct the API message */
6442   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6443
6444   mp->sw_if_index = ntohl (sw_if_index);
6445   mp->is_add = is_add;
6446   mp->vrf_id = ntohl (vrf_id);
6447   mp->is_static = is_static;
6448   if (mac_set)
6449     clib_memcpy (mp->mac_address, mac_address, 6);
6450   if (v6_address_set)
6451     {
6452       mp->is_ipv6 = 1;
6453       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6454     }
6455   else
6456     {
6457       /* mp->is_ipv6 = 0; via memset in M macro above */
6458       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6459     }
6460
6461   /* send it... */
6462   S;
6463
6464   /* Wait for a reply, return good/bad news  */
6465   W;
6466
6467   /* NOTREACHED */
6468   return 0;
6469 }
6470
6471 static int
6472 api_reset_vrf (vat_main_t * vam)
6473 {
6474   unformat_input_t *i = vam->input;
6475   vl_api_reset_vrf_t *mp;
6476   f64 timeout;
6477   u32 vrf_id = 0;
6478   u8 is_ipv6 = 0;
6479   u8 vrf_id_set = 0;
6480
6481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6482     {
6483       if (unformat (i, "vrf %d", &vrf_id))
6484         vrf_id_set = 1;
6485       else if (unformat (i, "ipv6"))
6486         is_ipv6 = 1;
6487       else
6488         {
6489           clib_warning ("parse error '%U'", format_unformat_error, i);
6490           return -99;
6491         }
6492     }
6493
6494   if (vrf_id_set == 0)
6495     {
6496       errmsg ("missing vrf id\n");
6497       return -99;
6498     }
6499
6500   M (RESET_VRF, reset_vrf);
6501
6502   mp->vrf_id = ntohl (vrf_id);
6503   mp->is_ipv6 = is_ipv6;
6504
6505   S;
6506   W;
6507   /* NOTREACHED */
6508   return 0;
6509 }
6510
6511 static int
6512 api_create_vlan_subif (vat_main_t * vam)
6513 {
6514   unformat_input_t *i = vam->input;
6515   vl_api_create_vlan_subif_t *mp;
6516   f64 timeout;
6517   u32 sw_if_index;
6518   u8 sw_if_index_set = 0;
6519   u32 vlan_id;
6520   u8 vlan_id_set = 0;
6521
6522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6523     {
6524       if (unformat (i, "sw_if_index %d", &sw_if_index))
6525         sw_if_index_set = 1;
6526       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6527         sw_if_index_set = 1;
6528       else if (unformat (i, "vlan %d", &vlan_id))
6529         vlan_id_set = 1;
6530       else
6531         {
6532           clib_warning ("parse error '%U'", format_unformat_error, i);
6533           return -99;
6534         }
6535     }
6536
6537   if (sw_if_index_set == 0)
6538     {
6539       errmsg ("missing interface name or sw_if_index\n");
6540       return -99;
6541     }
6542
6543   if (vlan_id_set == 0)
6544     {
6545       errmsg ("missing vlan_id\n");
6546       return -99;
6547     }
6548   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6549
6550   mp->sw_if_index = ntohl (sw_if_index);
6551   mp->vlan_id = ntohl (vlan_id);
6552
6553   S;
6554   W;
6555   /* NOTREACHED */
6556   return 0;
6557 }
6558
6559 #define foreach_create_subif_bit                \
6560 _(no_tags)                                      \
6561 _(one_tag)                                      \
6562 _(two_tags)                                     \
6563 _(dot1ad)                                       \
6564 _(exact_match)                                  \
6565 _(default_sub)                                  \
6566 _(outer_vlan_id_any)                            \
6567 _(inner_vlan_id_any)
6568
6569 static int
6570 api_create_subif (vat_main_t * vam)
6571 {
6572   unformat_input_t *i = vam->input;
6573   vl_api_create_subif_t *mp;
6574   f64 timeout;
6575   u32 sw_if_index;
6576   u8 sw_if_index_set = 0;
6577   u32 sub_id;
6578   u8 sub_id_set = 0;
6579   u32 no_tags = 0;
6580   u32 one_tag = 0;
6581   u32 two_tags = 0;
6582   u32 dot1ad = 0;
6583   u32 exact_match = 0;
6584   u32 default_sub = 0;
6585   u32 outer_vlan_id_any = 0;
6586   u32 inner_vlan_id_any = 0;
6587   u32 tmp;
6588   u16 outer_vlan_id = 0;
6589   u16 inner_vlan_id = 0;
6590
6591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6592     {
6593       if (unformat (i, "sw_if_index %d", &sw_if_index))
6594         sw_if_index_set = 1;
6595       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "sub_id %d", &sub_id))
6598         sub_id_set = 1;
6599       else if (unformat (i, "outer_vlan_id %d", &tmp))
6600         outer_vlan_id = tmp;
6601       else if (unformat (i, "inner_vlan_id %d", &tmp))
6602         inner_vlan_id = tmp;
6603
6604 #define _(a) else if (unformat (i, #a)) a = 1 ;
6605       foreach_create_subif_bit
6606 #undef _
6607         else
6608         {
6609           clib_warning ("parse error '%U'", format_unformat_error, i);
6610           return -99;
6611         }
6612     }
6613
6614   if (sw_if_index_set == 0)
6615     {
6616       errmsg ("missing interface name or sw_if_index\n");
6617       return -99;
6618     }
6619
6620   if (sub_id_set == 0)
6621     {
6622       errmsg ("missing sub_id\n");
6623       return -99;
6624     }
6625   M (CREATE_SUBIF, create_subif);
6626
6627   mp->sw_if_index = ntohl (sw_if_index);
6628   mp->sub_id = ntohl (sub_id);
6629
6630 #define _(a) mp->a = a;
6631   foreach_create_subif_bit;
6632 #undef _
6633
6634   mp->outer_vlan_id = ntohs (outer_vlan_id);
6635   mp->inner_vlan_id = ntohs (inner_vlan_id);
6636
6637   S;
6638   W;
6639   /* NOTREACHED */
6640   return 0;
6641 }
6642
6643 static int
6644 api_oam_add_del (vat_main_t * vam)
6645 {
6646   unformat_input_t *i = vam->input;
6647   vl_api_oam_add_del_t *mp;
6648   f64 timeout;
6649   u32 vrf_id = 0;
6650   u8 is_add = 1;
6651   ip4_address_t src, dst;
6652   u8 src_set = 0;
6653   u8 dst_set = 0;
6654
6655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6656     {
6657       if (unformat (i, "vrf %d", &vrf_id))
6658         ;
6659       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6660         src_set = 1;
6661       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6662         dst_set = 1;
6663       else if (unformat (i, "del"))
6664         is_add = 0;
6665       else
6666         {
6667           clib_warning ("parse error '%U'", format_unformat_error, i);
6668           return -99;
6669         }
6670     }
6671
6672   if (src_set == 0)
6673     {
6674       errmsg ("missing src addr\n");
6675       return -99;
6676     }
6677
6678   if (dst_set == 0)
6679     {
6680       errmsg ("missing dst addr\n");
6681       return -99;
6682     }
6683
6684   M (OAM_ADD_DEL, oam_add_del);
6685
6686   mp->vrf_id = ntohl (vrf_id);
6687   mp->is_add = is_add;
6688   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6689   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6690
6691   S;
6692   W;
6693   /* NOTREACHED */
6694   return 0;
6695 }
6696
6697 static int
6698 api_reset_fib (vat_main_t * vam)
6699 {
6700   unformat_input_t *i = vam->input;
6701   vl_api_reset_fib_t *mp;
6702   f64 timeout;
6703   u32 vrf_id = 0;
6704   u8 is_ipv6 = 0;
6705   u8 vrf_id_set = 0;
6706
6707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6708     {
6709       if (unformat (i, "vrf %d", &vrf_id))
6710         vrf_id_set = 1;
6711       else if (unformat (i, "ipv6"))
6712         is_ipv6 = 1;
6713       else
6714         {
6715           clib_warning ("parse error '%U'", format_unformat_error, i);
6716           return -99;
6717         }
6718     }
6719
6720   if (vrf_id_set == 0)
6721     {
6722       errmsg ("missing vrf id\n");
6723       return -99;
6724     }
6725
6726   M (RESET_FIB, reset_fib);
6727
6728   mp->vrf_id = ntohl (vrf_id);
6729   mp->is_ipv6 = is_ipv6;
6730
6731   S;
6732   W;
6733   /* NOTREACHED */
6734   return 0;
6735 }
6736
6737 static int
6738 api_dhcp_proxy_config (vat_main_t * vam)
6739 {
6740   unformat_input_t *i = vam->input;
6741   vl_api_dhcp_proxy_config_t *mp;
6742   f64 timeout;
6743   u32 vrf_id = 0;
6744   u8 is_add = 1;
6745   u8 insert_cid = 1;
6746   u8 v4_address_set = 0;
6747   u8 v6_address_set = 0;
6748   ip4_address_t v4address;
6749   ip6_address_t v6address;
6750   u8 v4_src_address_set = 0;
6751   u8 v6_src_address_set = 0;
6752   ip4_address_t v4srcaddress;
6753   ip6_address_t v6srcaddress;
6754
6755   /* Parse args required to build the message */
6756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6757     {
6758       if (unformat (i, "del"))
6759         is_add = 0;
6760       else if (unformat (i, "vrf %d", &vrf_id))
6761         ;
6762       else if (unformat (i, "insert-cid %d", &insert_cid))
6763         ;
6764       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6765         v4_address_set = 1;
6766       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6767         v6_address_set = 1;
6768       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6769         v4_src_address_set = 1;
6770       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6771         v6_src_address_set = 1;
6772       else
6773         break;
6774     }
6775
6776   if (v4_address_set && v6_address_set)
6777     {
6778       errmsg ("both v4 and v6 server addresses set\n");
6779       return -99;
6780     }
6781   if (!v4_address_set && !v6_address_set)
6782     {
6783       errmsg ("no server addresses set\n");
6784       return -99;
6785     }
6786
6787   if (v4_src_address_set && v6_src_address_set)
6788     {
6789       errmsg ("both v4 and v6  src addresses set\n");
6790       return -99;
6791     }
6792   if (!v4_src_address_set && !v6_src_address_set)
6793     {
6794       errmsg ("no src addresses set\n");
6795       return -99;
6796     }
6797
6798   if (!(v4_src_address_set && v4_address_set) &&
6799       !(v6_src_address_set && v6_address_set))
6800     {
6801       errmsg ("no matching server and src addresses set\n");
6802       return -99;
6803     }
6804
6805   /* Construct the API message */
6806   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6807
6808   mp->insert_circuit_id = insert_cid;
6809   mp->is_add = is_add;
6810   mp->vrf_id = ntohl (vrf_id);
6811   if (v6_address_set)
6812     {
6813       mp->is_ipv6 = 1;
6814       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6815       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6816     }
6817   else
6818     {
6819       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6820       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6821     }
6822
6823   /* send it... */
6824   S;
6825
6826   /* Wait for a reply, return good/bad news  */
6827   W;
6828   /* NOTREACHED */
6829   return 0;
6830 }
6831
6832 static int
6833 api_dhcp_proxy_config_2 (vat_main_t * vam)
6834 {
6835   unformat_input_t *i = vam->input;
6836   vl_api_dhcp_proxy_config_2_t *mp;
6837   f64 timeout;
6838   u32 rx_vrf_id = 0;
6839   u32 server_vrf_id = 0;
6840   u8 is_add = 1;
6841   u8 insert_cid = 1;
6842   u8 v4_address_set = 0;
6843   u8 v6_address_set = 0;
6844   ip4_address_t v4address;
6845   ip6_address_t v6address;
6846   u8 v4_src_address_set = 0;
6847   u8 v6_src_address_set = 0;
6848   ip4_address_t v4srcaddress;
6849   ip6_address_t v6srcaddress;
6850
6851   /* Parse args required to build the message */
6852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6853     {
6854       if (unformat (i, "del"))
6855         is_add = 0;
6856       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6857         ;
6858       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6859         ;
6860       else if (unformat (i, "insert-cid %d", &insert_cid))
6861         ;
6862       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6863         v4_address_set = 1;
6864       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6865         v6_address_set = 1;
6866       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6867         v4_src_address_set = 1;
6868       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6869         v6_src_address_set = 1;
6870       else
6871         break;
6872     }
6873
6874   if (v4_address_set && v6_address_set)
6875     {
6876       errmsg ("both v4 and v6 server addresses set\n");
6877       return -99;
6878     }
6879   if (!v4_address_set && !v6_address_set)
6880     {
6881       errmsg ("no server addresses set\n");
6882       return -99;
6883     }
6884
6885   if (v4_src_address_set && v6_src_address_set)
6886     {
6887       errmsg ("both v4 and v6  src addresses set\n");
6888       return -99;
6889     }
6890   if (!v4_src_address_set && !v6_src_address_set)
6891     {
6892       errmsg ("no src addresses set\n");
6893       return -99;
6894     }
6895
6896   if (!(v4_src_address_set && v4_address_set) &&
6897       !(v6_src_address_set && v6_address_set))
6898     {
6899       errmsg ("no matching server and src addresses set\n");
6900       return -99;
6901     }
6902
6903   /* Construct the API message */
6904   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6905
6906   mp->insert_circuit_id = insert_cid;
6907   mp->is_add = is_add;
6908   mp->rx_vrf_id = ntohl (rx_vrf_id);
6909   mp->server_vrf_id = ntohl (server_vrf_id);
6910   if (v6_address_set)
6911     {
6912       mp->is_ipv6 = 1;
6913       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6914       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6915     }
6916   else
6917     {
6918       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6919       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6920     }
6921
6922   /* send it... */
6923   S;
6924
6925   /* Wait for a reply, return good/bad news  */
6926   W;
6927   /* NOTREACHED */
6928   return 0;
6929 }
6930
6931 static int
6932 api_dhcp_proxy_set_vss (vat_main_t * vam)
6933 {
6934   unformat_input_t *i = vam->input;
6935   vl_api_dhcp_proxy_set_vss_t *mp;
6936   f64 timeout;
6937   u8 is_ipv6 = 0;
6938   u8 is_add = 1;
6939   u32 tbl_id;
6940   u8 tbl_id_set = 0;
6941   u32 oui;
6942   u8 oui_set = 0;
6943   u32 fib_id;
6944   u8 fib_id_set = 0;
6945
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "tbl_id %d", &tbl_id))
6949         tbl_id_set = 1;
6950       if (unformat (i, "fib_id %d", &fib_id))
6951         fib_id_set = 1;
6952       if (unformat (i, "oui %d", &oui))
6953         oui_set = 1;
6954       else if (unformat (i, "ipv6"))
6955         is_ipv6 = 1;
6956       else if (unformat (i, "del"))
6957         is_add = 0;
6958       else
6959         {
6960           clib_warning ("parse error '%U'", format_unformat_error, i);
6961           return -99;
6962         }
6963     }
6964
6965   if (tbl_id_set == 0)
6966     {
6967       errmsg ("missing tbl id\n");
6968       return -99;
6969     }
6970
6971   if (fib_id_set == 0)
6972     {
6973       errmsg ("missing fib id\n");
6974       return -99;
6975     }
6976   if (oui_set == 0)
6977     {
6978       errmsg ("missing oui\n");
6979       return -99;
6980     }
6981
6982   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6983   mp->tbl_id = ntohl (tbl_id);
6984   mp->fib_id = ntohl (fib_id);
6985   mp->oui = ntohl (oui);
6986   mp->is_ipv6 = is_ipv6;
6987   mp->is_add = is_add;
6988
6989   S;
6990   W;
6991   /* NOTREACHED */
6992   return 0;
6993 }
6994
6995 static int
6996 api_dhcp_client_config (vat_main_t * vam)
6997 {
6998   unformat_input_t *i = vam->input;
6999   vl_api_dhcp_client_config_t *mp;
7000   f64 timeout;
7001   u32 sw_if_index;
7002   u8 sw_if_index_set = 0;
7003   u8 is_add = 1;
7004   u8 *hostname = 0;
7005   u8 disable_event = 0;
7006
7007   /* Parse args required to build the message */
7008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7009     {
7010       if (unformat (i, "del"))
7011         is_add = 0;
7012       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7013         sw_if_index_set = 1;
7014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7015         sw_if_index_set = 1;
7016       else if (unformat (i, "hostname %s", &hostname))
7017         ;
7018       else if (unformat (i, "disable_event"))
7019         disable_event = 1;
7020       else
7021         break;
7022     }
7023
7024   if (sw_if_index_set == 0)
7025     {
7026       errmsg ("missing interface name or sw_if_index\n");
7027       return -99;
7028     }
7029
7030   if (vec_len (hostname) > 63)
7031     {
7032       errmsg ("hostname too long\n");
7033     }
7034   vec_add1 (hostname, 0);
7035
7036   /* Construct the API message */
7037   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7038
7039   mp->sw_if_index = ntohl (sw_if_index);
7040   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7041   vec_free (hostname);
7042   mp->is_add = is_add;
7043   mp->want_dhcp_event = disable_event ? 0 : 1;
7044   mp->pid = getpid ();
7045
7046   /* send it... */
7047   S;
7048
7049   /* Wait for a reply, return good/bad news  */
7050   W;
7051   /* NOTREACHED */
7052   return 0;
7053 }
7054
7055 static int
7056 api_set_ip_flow_hash (vat_main_t * vam)
7057 {
7058   unformat_input_t *i = vam->input;
7059   vl_api_set_ip_flow_hash_t *mp;
7060   f64 timeout;
7061   u32 vrf_id = 0;
7062   u8 is_ipv6 = 0;
7063   u8 vrf_id_set = 0;
7064   u8 src = 0;
7065   u8 dst = 0;
7066   u8 sport = 0;
7067   u8 dport = 0;
7068   u8 proto = 0;
7069   u8 reverse = 0;
7070
7071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7072     {
7073       if (unformat (i, "vrf %d", &vrf_id))
7074         vrf_id_set = 1;
7075       else if (unformat (i, "ipv6"))
7076         is_ipv6 = 1;
7077       else if (unformat (i, "src"))
7078         src = 1;
7079       else if (unformat (i, "dst"))
7080         dst = 1;
7081       else if (unformat (i, "sport"))
7082         sport = 1;
7083       else if (unformat (i, "dport"))
7084         dport = 1;
7085       else if (unformat (i, "proto"))
7086         proto = 1;
7087       else if (unformat (i, "reverse"))
7088         reverse = 1;
7089
7090       else
7091         {
7092           clib_warning ("parse error '%U'", format_unformat_error, i);
7093           return -99;
7094         }
7095     }
7096
7097   if (vrf_id_set == 0)
7098     {
7099       errmsg ("missing vrf id\n");
7100       return -99;
7101     }
7102
7103   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7104   mp->src = src;
7105   mp->dst = dst;
7106   mp->sport = sport;
7107   mp->dport = dport;
7108   mp->proto = proto;
7109   mp->reverse = reverse;
7110   mp->vrf_id = ntohl (vrf_id);
7111   mp->is_ipv6 = is_ipv6;
7112
7113   S;
7114   W;
7115   /* NOTREACHED */
7116   return 0;
7117 }
7118
7119 static int
7120 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7121 {
7122   unformat_input_t *i = vam->input;
7123   vl_api_sw_interface_ip6_enable_disable_t *mp;
7124   f64 timeout;
7125   u32 sw_if_index;
7126   u8 sw_if_index_set = 0;
7127   u8 enable = 0;
7128
7129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7130     {
7131       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7132         sw_if_index_set = 1;
7133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7134         sw_if_index_set = 1;
7135       else if (unformat (i, "enable"))
7136         enable = 1;
7137       else if (unformat (i, "disable"))
7138         enable = 0;
7139       else
7140         {
7141           clib_warning ("parse error '%U'", format_unformat_error, i);
7142           return -99;
7143         }
7144     }
7145
7146   if (sw_if_index_set == 0)
7147     {
7148       errmsg ("missing interface name or sw_if_index\n");
7149       return -99;
7150     }
7151
7152   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7153
7154   mp->sw_if_index = ntohl (sw_if_index);
7155   mp->enable = enable;
7156
7157   S;
7158   W;
7159   /* NOTREACHED */
7160   return 0;
7161 }
7162
7163 static int
7164 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7165 {
7166   unformat_input_t *i = vam->input;
7167   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7168   f64 timeout;
7169   u32 sw_if_index;
7170   u8 sw_if_index_set = 0;
7171   u32 address_length = 0;
7172   u8 v6_address_set = 0;
7173   ip6_address_t v6address;
7174
7175   /* Parse args required to build the message */
7176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7177     {
7178       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7179         sw_if_index_set = 1;
7180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7181         sw_if_index_set = 1;
7182       else if (unformat (i, "%U/%d",
7183                          unformat_ip6_address, &v6address, &address_length))
7184         v6_address_set = 1;
7185       else
7186         break;
7187     }
7188
7189   if (sw_if_index_set == 0)
7190     {
7191       errmsg ("missing interface name or sw_if_index\n");
7192       return -99;
7193     }
7194   if (!v6_address_set)
7195     {
7196       errmsg ("no address set\n");
7197       return -99;
7198     }
7199
7200   /* Construct the API message */
7201   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7202      sw_interface_ip6_set_link_local_address);
7203
7204   mp->sw_if_index = ntohl (sw_if_index);
7205   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7206   mp->address_length = address_length;
7207
7208   /* send it... */
7209   S;
7210
7211   /* Wait for a reply, return good/bad news  */
7212   W;
7213
7214   /* NOTREACHED */
7215   return 0;
7216 }
7217
7218
7219 static int
7220 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7221 {
7222   unformat_input_t *i = vam->input;
7223   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7224   f64 timeout;
7225   u32 sw_if_index;
7226   u8 sw_if_index_set = 0;
7227   u32 address_length = 0;
7228   u8 v6_address_set = 0;
7229   ip6_address_t v6address;
7230   u8 use_default = 0;
7231   u8 no_advertise = 0;
7232   u8 off_link = 0;
7233   u8 no_autoconfig = 0;
7234   u8 no_onlink = 0;
7235   u8 is_no = 0;
7236   u32 val_lifetime = 0;
7237   u32 pref_lifetime = 0;
7238
7239   /* Parse args required to build the message */
7240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7241     {
7242       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7243         sw_if_index_set = 1;
7244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7245         sw_if_index_set = 1;
7246       else if (unformat (i, "%U/%d",
7247                          unformat_ip6_address, &v6address, &address_length))
7248         v6_address_set = 1;
7249       else if (unformat (i, "val_life %d", &val_lifetime))
7250         ;
7251       else if (unformat (i, "pref_life %d", &pref_lifetime))
7252         ;
7253       else if (unformat (i, "def"))
7254         use_default = 1;
7255       else if (unformat (i, "noadv"))
7256         no_advertise = 1;
7257       else if (unformat (i, "offl"))
7258         off_link = 1;
7259       else if (unformat (i, "noauto"))
7260         no_autoconfig = 1;
7261       else if (unformat (i, "nolink"))
7262         no_onlink = 1;
7263       else if (unformat (i, "isno"))
7264         is_no = 1;
7265       else
7266         {
7267           clib_warning ("parse error '%U'", format_unformat_error, i);
7268           return -99;
7269         }
7270     }
7271
7272   if (sw_if_index_set == 0)
7273     {
7274       errmsg ("missing interface name or sw_if_index\n");
7275       return -99;
7276     }
7277   if (!v6_address_set)
7278     {
7279       errmsg ("no address set\n");
7280       return -99;
7281     }
7282
7283   /* Construct the API message */
7284   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7285
7286   mp->sw_if_index = ntohl (sw_if_index);
7287   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7288   mp->address_length = address_length;
7289   mp->use_default = use_default;
7290   mp->no_advertise = no_advertise;
7291   mp->off_link = off_link;
7292   mp->no_autoconfig = no_autoconfig;
7293   mp->no_onlink = no_onlink;
7294   mp->is_no = is_no;
7295   mp->val_lifetime = ntohl (val_lifetime);
7296   mp->pref_lifetime = ntohl (pref_lifetime);
7297
7298   /* send it... */
7299   S;
7300
7301   /* Wait for a reply, return good/bad news  */
7302   W;
7303
7304   /* NOTREACHED */
7305   return 0;
7306 }
7307
7308 static int
7309 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7310 {
7311   unformat_input_t *i = vam->input;
7312   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7313   f64 timeout;
7314   u32 sw_if_index;
7315   u8 sw_if_index_set = 0;
7316   u8 suppress = 0;
7317   u8 managed = 0;
7318   u8 other = 0;
7319   u8 ll_option = 0;
7320   u8 send_unicast = 0;
7321   u8 cease = 0;
7322   u8 is_no = 0;
7323   u8 default_router = 0;
7324   u32 max_interval = 0;
7325   u32 min_interval = 0;
7326   u32 lifetime = 0;
7327   u32 initial_count = 0;
7328   u32 initial_interval = 0;
7329
7330
7331   /* Parse args required to build the message */
7332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7333     {
7334       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7335         sw_if_index_set = 1;
7336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7337         sw_if_index_set = 1;
7338       else if (unformat (i, "maxint %d", &max_interval))
7339         ;
7340       else if (unformat (i, "minint %d", &min_interval))
7341         ;
7342       else if (unformat (i, "life %d", &lifetime))
7343         ;
7344       else if (unformat (i, "count %d", &initial_count))
7345         ;
7346       else if (unformat (i, "interval %d", &initial_interval))
7347         ;
7348       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7349         suppress = 1;
7350       else if (unformat (i, "managed"))
7351         managed = 1;
7352       else if (unformat (i, "other"))
7353         other = 1;
7354       else if (unformat (i, "ll"))
7355         ll_option = 1;
7356       else if (unformat (i, "send"))
7357         send_unicast = 1;
7358       else if (unformat (i, "cease"))
7359         cease = 1;
7360       else if (unformat (i, "isno"))
7361         is_no = 1;
7362       else if (unformat (i, "def"))
7363         default_router = 1;
7364       else
7365         {
7366           clib_warning ("parse error '%U'", format_unformat_error, i);
7367           return -99;
7368         }
7369     }
7370
7371   if (sw_if_index_set == 0)
7372     {
7373       errmsg ("missing interface name or sw_if_index\n");
7374       return -99;
7375     }
7376
7377   /* Construct the API message */
7378   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7379
7380   mp->sw_if_index = ntohl (sw_if_index);
7381   mp->max_interval = ntohl (max_interval);
7382   mp->min_interval = ntohl (min_interval);
7383   mp->lifetime = ntohl (lifetime);
7384   mp->initial_count = ntohl (initial_count);
7385   mp->initial_interval = ntohl (initial_interval);
7386   mp->suppress = suppress;
7387   mp->managed = managed;
7388   mp->other = other;
7389   mp->ll_option = ll_option;
7390   mp->send_unicast = send_unicast;
7391   mp->cease = cease;
7392   mp->is_no = is_no;
7393   mp->default_router = default_router;
7394
7395   /* send it... */
7396   S;
7397
7398   /* Wait for a reply, return good/bad news  */
7399   W;
7400
7401   /* NOTREACHED */
7402   return 0;
7403 }
7404
7405 static int
7406 api_set_arp_neighbor_limit (vat_main_t * vam)
7407 {
7408   unformat_input_t *i = vam->input;
7409   vl_api_set_arp_neighbor_limit_t *mp;
7410   f64 timeout;
7411   u32 arp_nbr_limit;
7412   u8 limit_set = 0;
7413   u8 is_ipv6 = 0;
7414
7415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7416     {
7417       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7418         limit_set = 1;
7419       else if (unformat (i, "ipv6"))
7420         is_ipv6 = 1;
7421       else
7422         {
7423           clib_warning ("parse error '%U'", format_unformat_error, i);
7424           return -99;
7425         }
7426     }
7427
7428   if (limit_set == 0)
7429     {
7430       errmsg ("missing limit value\n");
7431       return -99;
7432     }
7433
7434   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7435
7436   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7437   mp->is_ipv6 = is_ipv6;
7438
7439   S;
7440   W;
7441   /* NOTREACHED */
7442   return 0;
7443 }
7444
7445 static int
7446 api_l2_patch_add_del (vat_main_t * vam)
7447 {
7448   unformat_input_t *i = vam->input;
7449   vl_api_l2_patch_add_del_t *mp;
7450   f64 timeout;
7451   u32 rx_sw_if_index;
7452   u8 rx_sw_if_index_set = 0;
7453   u32 tx_sw_if_index;
7454   u8 tx_sw_if_index_set = 0;
7455   u8 is_add = 1;
7456
7457   /* Parse args required to build the message */
7458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7459     {
7460       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7461         rx_sw_if_index_set = 1;
7462       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7463         tx_sw_if_index_set = 1;
7464       else if (unformat (i, "rx"))
7465         {
7466           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7467             {
7468               if (unformat (i, "%U", unformat_sw_if_index, vam,
7469                             &rx_sw_if_index))
7470                 rx_sw_if_index_set = 1;
7471             }
7472           else
7473             break;
7474         }
7475       else if (unformat (i, "tx"))
7476         {
7477           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7478             {
7479               if (unformat (i, "%U", unformat_sw_if_index, vam,
7480                             &tx_sw_if_index))
7481                 tx_sw_if_index_set = 1;
7482             }
7483           else
7484             break;
7485         }
7486       else if (unformat (i, "del"))
7487         is_add = 0;
7488       else
7489         break;
7490     }
7491
7492   if (rx_sw_if_index_set == 0)
7493     {
7494       errmsg ("missing rx interface name or rx_sw_if_index\n");
7495       return -99;
7496     }
7497
7498   if (tx_sw_if_index_set == 0)
7499     {
7500       errmsg ("missing tx interface name or tx_sw_if_index\n");
7501       return -99;
7502     }
7503
7504   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7505
7506   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7507   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7508   mp->is_add = is_add;
7509
7510   S;
7511   W;
7512   /* NOTREACHED */
7513   return 0;
7514 }
7515
7516 static int
7517 api_ioam_enable (vat_main_t * vam)
7518 {
7519   unformat_input_t *input = vam->input;
7520   vl_api_ioam_enable_t *mp;
7521   f64 timeout;
7522   u32 id = 0;
7523   int has_trace_option = 0;
7524   int has_pow_option = 0;
7525   int has_ppc_option = 0;
7526
7527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7528     {
7529       if (unformat (input, "trace"))
7530         has_trace_option = 1;
7531       else if (unformat (input, "pow"))
7532         has_pow_option = 1;
7533       else if (unformat (input, "ppc encap"))
7534         has_ppc_option = PPC_ENCAP;
7535       else if (unformat (input, "ppc decap"))
7536         has_ppc_option = PPC_DECAP;
7537       else if (unformat (input, "ppc none"))
7538         has_ppc_option = PPC_NONE;
7539       else
7540         break;
7541     }
7542   M (IOAM_ENABLE, ioam_enable);
7543   mp->id = htons (id);
7544   mp->trace_ppc = has_ppc_option;
7545   mp->pow_enable = has_pow_option;
7546   mp->trace_enable = has_trace_option;
7547
7548   S;
7549   W;
7550
7551   return (0);
7552
7553 }
7554
7555
7556 static int
7557 api_ioam_disable (vat_main_t * vam)
7558 {
7559   vl_api_ioam_disable_t *mp;
7560   f64 timeout;
7561
7562   M (IOAM_DISABLE, ioam_disable);
7563   S;
7564   W;
7565   return 0;
7566 }
7567
7568 static int
7569 api_sr_tunnel_add_del (vat_main_t * vam)
7570 {
7571   unformat_input_t *i = vam->input;
7572   vl_api_sr_tunnel_add_del_t *mp;
7573   f64 timeout;
7574   int is_del = 0;
7575   int pl_index;
7576   ip6_address_t src_address;
7577   int src_address_set = 0;
7578   ip6_address_t dst_address;
7579   u32 dst_mask_width;
7580   int dst_address_set = 0;
7581   u16 flags = 0;
7582   u32 rx_table_id = 0;
7583   u32 tx_table_id = 0;
7584   ip6_address_t *segments = 0;
7585   ip6_address_t *this_seg;
7586   ip6_address_t *tags = 0;
7587   ip6_address_t *this_tag;
7588   ip6_address_t next_address, tag;
7589   u8 *name = 0;
7590   u8 *policy_name = 0;
7591
7592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7593     {
7594       if (unformat (i, "del"))
7595         is_del = 1;
7596       else if (unformat (i, "name %s", &name))
7597         ;
7598       else if (unformat (i, "policy %s", &policy_name))
7599         ;
7600       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7601         ;
7602       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7603         ;
7604       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7605         src_address_set = 1;
7606       else if (unformat (i, "dst %U/%d",
7607                          unformat_ip6_address, &dst_address, &dst_mask_width))
7608         dst_address_set = 1;
7609       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7610         {
7611           vec_add2 (segments, this_seg, 1);
7612           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7613                        sizeof (*this_seg));
7614         }
7615       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7616         {
7617           vec_add2 (tags, this_tag, 1);
7618           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7619         }
7620       else if (unformat (i, "clean"))
7621         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7622       else if (unformat (i, "protected"))
7623         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7624       else if (unformat (i, "InPE %d", &pl_index))
7625         {
7626           if (pl_index <= 0 || pl_index > 4)
7627             {
7628             pl_index_range_error:
7629               errmsg ("pl index %d out of range\n", pl_index);
7630               return -99;
7631             }
7632           flags |=
7633             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7634         }
7635       else if (unformat (i, "EgPE %d", &pl_index))
7636         {
7637           if (pl_index <= 0 || pl_index > 4)
7638             goto pl_index_range_error;
7639           flags |=
7640             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7641         }
7642       else if (unformat (i, "OrgSrc %d", &pl_index))
7643         {
7644           if (pl_index <= 0 || pl_index > 4)
7645             goto pl_index_range_error;
7646           flags |=
7647             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7648         }
7649       else
7650         break;
7651     }
7652
7653   if (!src_address_set)
7654     {
7655       errmsg ("src address required\n");
7656       return -99;
7657     }
7658
7659   if (!dst_address_set)
7660     {
7661       errmsg ("dst address required\n");
7662       return -99;
7663     }
7664
7665   if (!segments)
7666     {
7667       errmsg ("at least one sr segment required\n");
7668       return -99;
7669     }
7670
7671   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7672       vec_len (segments) * sizeof (ip6_address_t)
7673       + vec_len (tags) * sizeof (ip6_address_t));
7674
7675   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7676   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7677   mp->dst_mask_width = dst_mask_width;
7678   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7679   mp->n_segments = vec_len (segments);
7680   mp->n_tags = vec_len (tags);
7681   mp->is_add = is_del == 0;
7682   clib_memcpy (mp->segs_and_tags, segments,
7683                vec_len (segments) * sizeof (ip6_address_t));
7684   clib_memcpy (mp->segs_and_tags +
7685                vec_len (segments) * sizeof (ip6_address_t), tags,
7686                vec_len (tags) * sizeof (ip6_address_t));
7687
7688   mp->outer_vrf_id = ntohl (rx_table_id);
7689   mp->inner_vrf_id = ntohl (tx_table_id);
7690   memcpy (mp->name, name, vec_len (name));
7691   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7692
7693   vec_free (segments);
7694   vec_free (tags);
7695
7696   S;
7697   W;
7698   /* NOTREACHED */
7699 }
7700
7701 static int
7702 api_sr_policy_add_del (vat_main_t * vam)
7703 {
7704   unformat_input_t *input = vam->input;
7705   vl_api_sr_policy_add_del_t *mp;
7706   f64 timeout;
7707   int is_del = 0;
7708   u8 *name = 0;
7709   u8 *tunnel_name = 0;
7710   u8 **tunnel_names = 0;
7711
7712   int name_set = 0;
7713   int tunnel_set = 0;
7714   int j = 0;
7715   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7716   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7717
7718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7719     {
7720       if (unformat (input, "del"))
7721         is_del = 1;
7722       else if (unformat (input, "name %s", &name))
7723         name_set = 1;
7724       else if (unformat (input, "tunnel %s", &tunnel_name))
7725         {
7726           if (tunnel_name)
7727             {
7728               vec_add1 (tunnel_names, tunnel_name);
7729               /* For serializer:
7730                  - length = #bytes to store in serial vector
7731                  - +1 = byte to store that length
7732                */
7733               tunnel_names_length += (vec_len (tunnel_name) + 1);
7734               tunnel_set = 1;
7735               tunnel_name = 0;
7736             }
7737         }
7738       else
7739         break;
7740     }
7741
7742   if (!name_set)
7743     {
7744       errmsg ("policy name required\n");
7745       return -99;
7746     }
7747
7748   if ((!tunnel_set) && (!is_del))
7749     {
7750       errmsg ("tunnel name required\n");
7751       return -99;
7752     }
7753
7754   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7755
7756
7757
7758   mp->is_add = !is_del;
7759
7760   memcpy (mp->name, name, vec_len (name));
7761   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7762   u8 *serial_orig = 0;
7763   vec_validate (serial_orig, tunnel_names_length);
7764   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7765   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7766
7767   for (j = 0; j < vec_len (tunnel_names); j++)
7768     {
7769       tun_name_len = vec_len (tunnel_names[j]);
7770       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7771       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7772       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7773       serial_orig += tun_name_len;      // Advance past the copy
7774     }
7775   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7776
7777   vec_free (tunnel_names);
7778   vec_free (tunnel_name);
7779
7780   S;
7781   W;
7782   /* NOTREACHED */
7783 }
7784
7785 static int
7786 api_sr_multicast_map_add_del (vat_main_t * vam)
7787 {
7788   unformat_input_t *input = vam->input;
7789   vl_api_sr_multicast_map_add_del_t *mp;
7790   f64 timeout;
7791   int is_del = 0;
7792   ip6_address_t multicast_address;
7793   u8 *policy_name = 0;
7794   int multicast_address_set = 0;
7795
7796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7797     {
7798       if (unformat (input, "del"))
7799         is_del = 1;
7800       else
7801         if (unformat
7802             (input, "address %U", unformat_ip6_address, &multicast_address))
7803         multicast_address_set = 1;
7804       else if (unformat (input, "sr-policy %s", &policy_name))
7805         ;
7806       else
7807         break;
7808     }
7809
7810   if (!is_del && !policy_name)
7811     {
7812       errmsg ("sr-policy name required\n");
7813       return -99;
7814     }
7815
7816
7817   if (!multicast_address_set)
7818     {
7819       errmsg ("address required\n");
7820       return -99;
7821     }
7822
7823   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7824
7825   mp->is_add = !is_del;
7826   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7827   clib_memcpy (mp->multicast_address, &multicast_address,
7828                sizeof (mp->multicast_address));
7829
7830
7831   vec_free (policy_name);
7832
7833   S;
7834   W;
7835   /* NOTREACHED */
7836 }
7837
7838
7839 #define foreach_tcp_proto_field                 \
7840 _(src_port)                                     \
7841 _(dst_port)
7842
7843 #define foreach_udp_proto_field                 \
7844 _(src_port)                                     \
7845 _(dst_port)
7846
7847 #define foreach_ip4_proto_field                 \
7848 _(src_address)                                  \
7849 _(dst_address)                                  \
7850 _(tos)                                          \
7851 _(length)                                       \
7852 _(fragment_id)                                  \
7853 _(ttl)                                          \
7854 _(protocol)                                     \
7855 _(checksum)
7856
7857 uword
7858 unformat_tcp_mask (unformat_input_t * input, va_list * args)
7859 {
7860   u8 **maskp = va_arg (*args, u8 **);
7861   u8 *mask = 0;
7862   u8 found_something = 0;
7863   tcp_header_t *tcp;
7864
7865 #define _(a) u8 a=0;
7866   foreach_tcp_proto_field;
7867 #undef _
7868
7869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7870     {
7871       if (0);
7872 #define _(a) else if (unformat (input, #a)) a=1;
7873       foreach_tcp_proto_field
7874 #undef _
7875         else
7876         break;
7877     }
7878
7879 #define _(a) found_something += a;
7880   foreach_tcp_proto_field;
7881 #undef _
7882
7883   if (found_something == 0)
7884     return 0;
7885
7886   vec_validate (mask, sizeof (*tcp) - 1);
7887
7888   tcp = (tcp_header_t *) mask;
7889
7890 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
7891   foreach_tcp_proto_field;
7892 #undef _
7893
7894   *maskp = mask;
7895   return 1;
7896 }
7897
7898 uword
7899 unformat_udp_mask (unformat_input_t * input, va_list * args)
7900 {
7901   u8 **maskp = va_arg (*args, u8 **);
7902   u8 *mask = 0;
7903   u8 found_something = 0;
7904   udp_header_t *udp;
7905
7906 #define _(a) u8 a=0;
7907   foreach_udp_proto_field;
7908 #undef _
7909
7910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7911     {
7912       if (0);
7913 #define _(a) else if (unformat (input, #a)) a=1;
7914       foreach_udp_proto_field
7915 #undef _
7916         else
7917         break;
7918     }
7919
7920 #define _(a) found_something += a;
7921   foreach_udp_proto_field;
7922 #undef _
7923
7924   if (found_something == 0)
7925     return 0;
7926
7927   vec_validate (mask, sizeof (*udp) - 1);
7928
7929   udp = (udp_header_t *) mask;
7930
7931 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
7932   foreach_udp_proto_field;
7933 #undef _
7934
7935   *maskp = mask;
7936   return 1;
7937 }
7938
7939 typedef struct
7940 {
7941   u16 src_port, dst_port;
7942 } tcpudp_header_t;
7943
7944 uword
7945 unformat_l4_mask (unformat_input_t * input, va_list * args)
7946 {
7947   u8 **maskp = va_arg (*args, u8 **);
7948   u16 src_port = 0, dst_port = 0;
7949   tcpudp_header_t *tcpudp;
7950
7951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7952     {
7953       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7954         return 1;
7955       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7956         return 1;
7957       else if (unformat (input, "src_port"))
7958         src_port = 0xFFFF;
7959       else if (unformat (input, "dst_port"))
7960         dst_port = 0xFFFF;
7961       else
7962         return 0;
7963     }
7964
7965   if (!src_port && !dst_port)
7966     return 0;
7967
7968   u8 *mask = 0;
7969   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7970
7971   tcpudp = (tcpudp_header_t *) mask;
7972   tcpudp->src_port = src_port;
7973   tcpudp->dst_port = dst_port;
7974
7975   *maskp = mask;
7976
7977   return 1;
7978 }
7979
7980 uword
7981 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7982 {
7983   u8 **maskp = va_arg (*args, u8 **);
7984   u8 *mask = 0;
7985   u8 found_something = 0;
7986   ip4_header_t *ip;
7987
7988 #define _(a) u8 a=0;
7989   foreach_ip4_proto_field;
7990 #undef _
7991   u8 version = 0;
7992   u8 hdr_length = 0;
7993
7994
7995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7996     {
7997       if (unformat (input, "version"))
7998         version = 1;
7999       else if (unformat (input, "hdr_length"))
8000         hdr_length = 1;
8001       else if (unformat (input, "src"))
8002         src_address = 1;
8003       else if (unformat (input, "dst"))
8004         dst_address = 1;
8005       else if (unformat (input, "proto"))
8006         protocol = 1;
8007
8008 #define _(a) else if (unformat (input, #a)) a=1;
8009       foreach_ip4_proto_field
8010 #undef _
8011         else
8012         break;
8013     }
8014
8015 #define _(a) found_something += a;
8016   foreach_ip4_proto_field;
8017 #undef _
8018
8019   if (found_something == 0)
8020     return 0;
8021
8022   vec_validate (mask, sizeof (*ip) - 1);
8023
8024   ip = (ip4_header_t *) mask;
8025
8026 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8027   foreach_ip4_proto_field;
8028 #undef _
8029
8030   ip->ip_version_and_header_length = 0;
8031
8032   if (version)
8033     ip->ip_version_and_header_length |= 0xF0;
8034
8035   if (hdr_length)
8036     ip->ip_version_and_header_length |= 0x0F;
8037
8038   *maskp = mask;
8039   return 1;
8040 }
8041
8042 #define foreach_ip6_proto_field                 \
8043 _(src_address)                                  \
8044 _(dst_address)                                  \
8045 _(payload_length)                               \
8046 _(hop_limit)                                    \
8047 _(protocol)
8048
8049 uword
8050 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8051 {
8052   u8 **maskp = va_arg (*args, u8 **);
8053   u8 *mask = 0;
8054   u8 found_something = 0;
8055   ip6_header_t *ip;
8056   u32 ip_version_traffic_class_and_flow_label;
8057
8058 #define _(a) u8 a=0;
8059   foreach_ip6_proto_field;
8060 #undef _
8061   u8 version = 0;
8062   u8 traffic_class = 0;
8063   u8 flow_label = 0;
8064
8065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8066     {
8067       if (unformat (input, "version"))
8068         version = 1;
8069       else if (unformat (input, "traffic-class"))
8070         traffic_class = 1;
8071       else if (unformat (input, "flow-label"))
8072         flow_label = 1;
8073       else if (unformat (input, "src"))
8074         src_address = 1;
8075       else if (unformat (input, "dst"))
8076         dst_address = 1;
8077       else if (unformat (input, "proto"))
8078         protocol = 1;
8079
8080 #define _(a) else if (unformat (input, #a)) a=1;
8081       foreach_ip6_proto_field
8082 #undef _
8083         else
8084         break;
8085     }
8086
8087 #define _(a) found_something += a;
8088   foreach_ip6_proto_field;
8089 #undef _
8090
8091   if (found_something == 0)
8092     return 0;
8093
8094   vec_validate (mask, sizeof (*ip) - 1);
8095
8096   ip = (ip6_header_t *) mask;
8097
8098 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8099   foreach_ip6_proto_field;
8100 #undef _
8101
8102   ip_version_traffic_class_and_flow_label = 0;
8103
8104   if (version)
8105     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8106
8107   if (traffic_class)
8108     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8109
8110   if (flow_label)
8111     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8112
8113   ip->ip_version_traffic_class_and_flow_label =
8114     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8115
8116   *maskp = mask;
8117   return 1;
8118 }
8119
8120 uword
8121 unformat_l3_mask (unformat_input_t * input, va_list * args)
8122 {
8123   u8 **maskp = va_arg (*args, u8 **);
8124
8125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8126     {
8127       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8128         return 1;
8129       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8130         return 1;
8131       else
8132         break;
8133     }
8134   return 0;
8135 }
8136
8137 uword
8138 unformat_l2_mask (unformat_input_t * input, va_list * args)
8139 {
8140   u8 **maskp = va_arg (*args, u8 **);
8141   u8 *mask = 0;
8142   u8 src = 0;
8143   u8 dst = 0;
8144   u8 proto = 0;
8145   u8 tag1 = 0;
8146   u8 tag2 = 0;
8147   u8 ignore_tag1 = 0;
8148   u8 ignore_tag2 = 0;
8149   u8 cos1 = 0;
8150   u8 cos2 = 0;
8151   u8 dot1q = 0;
8152   u8 dot1ad = 0;
8153   int len = 14;
8154
8155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8156     {
8157       if (unformat (input, "src"))
8158         src = 1;
8159       else if (unformat (input, "dst"))
8160         dst = 1;
8161       else if (unformat (input, "proto"))
8162         proto = 1;
8163       else if (unformat (input, "tag1"))
8164         tag1 = 1;
8165       else if (unformat (input, "tag2"))
8166         tag2 = 1;
8167       else if (unformat (input, "ignore-tag1"))
8168         ignore_tag1 = 1;
8169       else if (unformat (input, "ignore-tag2"))
8170         ignore_tag2 = 1;
8171       else if (unformat (input, "cos1"))
8172         cos1 = 1;
8173       else if (unformat (input, "cos2"))
8174         cos2 = 1;
8175       else if (unformat (input, "dot1q"))
8176         dot1q = 1;
8177       else if (unformat (input, "dot1ad"))
8178         dot1ad = 1;
8179       else
8180         break;
8181     }
8182   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8183        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8184     return 0;
8185
8186   if (tag1 || ignore_tag1 || cos1 || dot1q)
8187     len = 18;
8188   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8189     len = 22;
8190
8191   vec_validate (mask, len - 1);
8192
8193   if (dst)
8194     memset (mask, 0xff, 6);
8195
8196   if (src)
8197     memset (mask + 6, 0xff, 6);
8198
8199   if (tag2 || dot1ad)
8200     {
8201       /* inner vlan tag */
8202       if (tag2)
8203         {
8204           mask[19] = 0xff;
8205           mask[18] = 0x0f;
8206         }
8207       if (cos2)
8208         mask[18] |= 0xe0;
8209       if (proto)
8210         mask[21] = mask[20] = 0xff;
8211       if (tag1)
8212         {
8213           mask[15] = 0xff;
8214           mask[14] = 0x0f;
8215         }
8216       if (cos1)
8217         mask[14] |= 0xe0;
8218       *maskp = mask;
8219       return 1;
8220     }
8221   if (tag1 | dot1q)
8222     {
8223       if (tag1)
8224         {
8225           mask[15] = 0xff;
8226           mask[14] = 0x0f;
8227         }
8228       if (cos1)
8229         mask[14] |= 0xe0;
8230       if (proto)
8231         mask[16] = mask[17] = 0xff;
8232
8233       *maskp = mask;
8234       return 1;
8235     }
8236   if (cos2)
8237     mask[18] |= 0xe0;
8238   if (cos1)
8239     mask[14] |= 0xe0;
8240   if (proto)
8241     mask[12] = mask[13] = 0xff;
8242
8243   *maskp = mask;
8244   return 1;
8245 }
8246
8247 uword
8248 unformat_classify_mask (unformat_input_t * input, va_list * args)
8249 {
8250   u8 **maskp = va_arg (*args, u8 **);
8251   u32 *skipp = va_arg (*args, u32 *);
8252   u32 *matchp = va_arg (*args, u32 *);
8253   u32 match;
8254   u8 *mask = 0;
8255   u8 *l2 = 0;
8256   u8 *l3 = 0;
8257   u8 *l4 = 0;
8258   int i;
8259
8260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8261     {
8262       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8263         ;
8264       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8265         ;
8266       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8267         ;
8268       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8269         ;
8270       else
8271         break;
8272     }
8273
8274   if (l4 && !l3)
8275     {
8276       vec_free (mask);
8277       vec_free (l2);
8278       vec_free (l4);
8279       return 0;
8280     }
8281
8282   if (mask || l2 || l3 || l4)
8283     {
8284       if (l2 || l3 || l4)
8285         {
8286           /* "With a free Ethernet header in every package" */
8287           if (l2 == 0)
8288             vec_validate (l2, 13);
8289           mask = l2;
8290           if (vec_len (l3))
8291             {
8292               vec_append (mask, l3);
8293               vec_free (l3);
8294             }
8295           if (vec_len (l4))
8296             {
8297               vec_append (mask, l4);
8298               vec_free (l4);
8299             }
8300         }
8301
8302       /* Scan forward looking for the first significant mask octet */
8303       for (i = 0; i < vec_len (mask); i++)
8304         if (mask[i])
8305           break;
8306
8307       /* compute (skip, match) params */
8308       *skipp = i / sizeof (u32x4);
8309       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8310
8311       /* Pad mask to an even multiple of the vector size */
8312       while (vec_len (mask) % sizeof (u32x4))
8313         vec_add1 (mask, 0);
8314
8315       match = vec_len (mask) / sizeof (u32x4);
8316
8317       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8318         {
8319           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8320           if (*tmp || *(tmp + 1))
8321             break;
8322           match--;
8323         }
8324       if (match == 0)
8325         clib_warning ("BUG: match 0");
8326
8327       _vec_len (mask) = match * sizeof (u32x4);
8328
8329       *matchp = match;
8330       *maskp = mask;
8331
8332       return 1;
8333     }
8334
8335   return 0;
8336 }
8337
8338 #define foreach_l2_next                         \
8339 _(drop, DROP)                                   \
8340 _(ethernet, ETHERNET_INPUT)                     \
8341 _(ip4, IP4_INPUT)                               \
8342 _(ip6, IP6_INPUT)
8343
8344 uword
8345 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8346 {
8347   u32 *miss_next_indexp = va_arg (*args, u32 *);
8348   u32 next_index = 0;
8349   u32 tmp;
8350
8351 #define _(n,N) \
8352   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8353   foreach_l2_next;
8354 #undef _
8355
8356   if (unformat (input, "%d", &tmp))
8357     {
8358       next_index = tmp;
8359       goto out;
8360     }
8361
8362   return 0;
8363
8364 out:
8365   *miss_next_indexp = next_index;
8366   return 1;
8367 }
8368
8369 #define foreach_ip_next                         \
8370 _(drop, DROP)                                   \
8371 _(local, LOCAL)                                 \
8372 _(rewrite, REWRITE)
8373
8374 uword
8375 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8376 {
8377   u32 *miss_next_indexp = va_arg (*args, u32 *);
8378   u32 next_index = 0;
8379   u32 tmp;
8380
8381 #define _(n,N) \
8382   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8383   foreach_ip_next;
8384 #undef _
8385
8386   if (unformat (input, "%d", &tmp))
8387     {
8388       next_index = tmp;
8389       goto out;
8390     }
8391
8392   return 0;
8393
8394 out:
8395   *miss_next_indexp = next_index;
8396   return 1;
8397 }
8398
8399 #define foreach_acl_next                        \
8400 _(deny, DENY)
8401
8402 uword
8403 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8404 {
8405   u32 *miss_next_indexp = va_arg (*args, u32 *);
8406   u32 next_index = 0;
8407   u32 tmp;
8408
8409 #define _(n,N) \
8410   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8411   foreach_acl_next;
8412 #undef _
8413
8414   if (unformat (input, "permit"))
8415     {
8416       next_index = ~0;
8417       goto out;
8418     }
8419   else if (unformat (input, "%d", &tmp))
8420     {
8421       next_index = tmp;
8422       goto out;
8423     }
8424
8425   return 0;
8426
8427 out:
8428   *miss_next_indexp = next_index;
8429   return 1;
8430 }
8431
8432 uword
8433 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8434 {
8435   u32 *r = va_arg (*args, u32 *);
8436
8437   if (unformat (input, "conform-color"))
8438     *r = POLICE_CONFORM;
8439   else if (unformat (input, "exceed-color"))
8440     *r = POLICE_EXCEED;
8441   else
8442     return 0;
8443
8444   return 1;
8445 }
8446
8447 static int
8448 api_classify_add_del_table (vat_main_t * vam)
8449 {
8450   unformat_input_t *i = vam->input;
8451   vl_api_classify_add_del_table_t *mp;
8452
8453   u32 nbuckets = 2;
8454   u32 skip = ~0;
8455   u32 match = ~0;
8456   int is_add = 1;
8457   u32 table_index = ~0;
8458   u32 next_table_index = ~0;
8459   u32 miss_next_index = ~0;
8460   u32 memory_size = 32 << 20;
8461   u8 *mask = 0;
8462   f64 timeout;
8463
8464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8465     {
8466       if (unformat (i, "del"))
8467         is_add = 0;
8468       else if (unformat (i, "buckets %d", &nbuckets))
8469         ;
8470       else if (unformat (i, "memory_size %d", &memory_size))
8471         ;
8472       else if (unformat (i, "skip %d", &skip))
8473         ;
8474       else if (unformat (i, "match %d", &match))
8475         ;
8476       else if (unformat (i, "table %d", &table_index))
8477         ;
8478       else if (unformat (i, "mask %U", unformat_classify_mask,
8479                          &mask, &skip, &match))
8480         ;
8481       else if (unformat (i, "next-table %d", &next_table_index))
8482         ;
8483       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8484                          &miss_next_index))
8485         ;
8486       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8487                          &miss_next_index))
8488         ;
8489       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8490                          &miss_next_index))
8491         ;
8492       else
8493         break;
8494     }
8495
8496   if (is_add && mask == 0)
8497     {
8498       errmsg ("Mask required\n");
8499       return -99;
8500     }
8501
8502   if (is_add && skip == ~0)
8503     {
8504       errmsg ("skip count required\n");
8505       return -99;
8506     }
8507
8508   if (is_add && match == ~0)
8509     {
8510       errmsg ("match count required\n");
8511       return -99;
8512     }
8513
8514   if (!is_add && table_index == ~0)
8515     {
8516       errmsg ("table index required for delete\n");
8517       return -99;
8518     }
8519
8520   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8521
8522   mp->is_add = is_add;
8523   mp->table_index = ntohl (table_index);
8524   mp->nbuckets = ntohl (nbuckets);
8525   mp->memory_size = ntohl (memory_size);
8526   mp->skip_n_vectors = ntohl (skip);
8527   mp->match_n_vectors = ntohl (match);
8528   mp->next_table_index = ntohl (next_table_index);
8529   mp->miss_next_index = ntohl (miss_next_index);
8530   clib_memcpy (mp->mask, mask, vec_len (mask));
8531
8532   vec_free (mask);
8533
8534   S;
8535   W;
8536   /* NOTREACHED */
8537 }
8538
8539 uword
8540 unformat_l4_match (unformat_input_t * input, va_list * args)
8541 {
8542   u8 **matchp = va_arg (*args, u8 **);
8543
8544   u8 *proto_header = 0;
8545   int src_port = 0;
8546   int dst_port = 0;
8547
8548   tcpudp_header_t h;
8549
8550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8551     {
8552       if (unformat (input, "src_port %d", &src_port))
8553         ;
8554       else if (unformat (input, "dst_port %d", &dst_port))
8555         ;
8556       else
8557         return 0;
8558     }
8559
8560   h.src_port = clib_host_to_net_u16 (src_port);
8561   h.dst_port = clib_host_to_net_u16 (dst_port);
8562   vec_validate (proto_header, sizeof (h) - 1);
8563   memcpy (proto_header, &h, sizeof (h));
8564
8565   *matchp = proto_header;
8566
8567   return 1;
8568 }
8569
8570 uword
8571 unformat_ip4_match (unformat_input_t * input, va_list * args)
8572 {
8573   u8 **matchp = va_arg (*args, u8 **);
8574   u8 *match = 0;
8575   ip4_header_t *ip;
8576   int version = 0;
8577   u32 version_val;
8578   int hdr_length = 0;
8579   u32 hdr_length_val;
8580   int src = 0, dst = 0;
8581   ip4_address_t src_val, dst_val;
8582   int proto = 0;
8583   u32 proto_val;
8584   int tos = 0;
8585   u32 tos_val;
8586   int length = 0;
8587   u32 length_val;
8588   int fragment_id = 0;
8589   u32 fragment_id_val;
8590   int ttl = 0;
8591   int ttl_val;
8592   int checksum = 0;
8593   u32 checksum_val;
8594
8595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8596     {
8597       if (unformat (input, "version %d", &version_val))
8598         version = 1;
8599       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8600         hdr_length = 1;
8601       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8602         src = 1;
8603       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8604         dst = 1;
8605       else if (unformat (input, "proto %d", &proto_val))
8606         proto = 1;
8607       else if (unformat (input, "tos %d", &tos_val))
8608         tos = 1;
8609       else if (unformat (input, "length %d", &length_val))
8610         length = 1;
8611       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8612         fragment_id = 1;
8613       else if (unformat (input, "ttl %d", &ttl_val))
8614         ttl = 1;
8615       else if (unformat (input, "checksum %d", &checksum_val))
8616         checksum = 1;
8617       else
8618         break;
8619     }
8620
8621   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8622       + ttl + checksum == 0)
8623     return 0;
8624
8625   /*
8626    * Aligned because we use the real comparison functions
8627    */
8628   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8629
8630   ip = (ip4_header_t *) match;
8631
8632   /* These are realistically matched in practice */
8633   if (src)
8634     ip->src_address.as_u32 = src_val.as_u32;
8635
8636   if (dst)
8637     ip->dst_address.as_u32 = dst_val.as_u32;
8638
8639   if (proto)
8640     ip->protocol = proto_val;
8641
8642
8643   /* These are not, but they're included for completeness */
8644   if (version)
8645     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8646
8647   if (hdr_length)
8648     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8649
8650   if (tos)
8651     ip->tos = tos_val;
8652
8653   if (length)
8654     ip->length = clib_host_to_net_u16 (length_val);
8655
8656   if (ttl)
8657     ip->ttl = ttl_val;
8658
8659   if (checksum)
8660     ip->checksum = clib_host_to_net_u16 (checksum_val);
8661
8662   *matchp = match;
8663   return 1;
8664 }
8665
8666 uword
8667 unformat_ip6_match (unformat_input_t * input, va_list * args)
8668 {
8669   u8 **matchp = va_arg (*args, u8 **);
8670   u8 *match = 0;
8671   ip6_header_t *ip;
8672   int version = 0;
8673   u32 version_val;
8674   u8 traffic_class = 0;
8675   u32 traffic_class_val = 0;
8676   u8 flow_label = 0;
8677   u8 flow_label_val;
8678   int src = 0, dst = 0;
8679   ip6_address_t src_val, dst_val;
8680   int proto = 0;
8681   u32 proto_val;
8682   int payload_length = 0;
8683   u32 payload_length_val;
8684   int hop_limit = 0;
8685   int hop_limit_val;
8686   u32 ip_version_traffic_class_and_flow_label;
8687
8688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8689     {
8690       if (unformat (input, "version %d", &version_val))
8691         version = 1;
8692       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8693         traffic_class = 1;
8694       else if (unformat (input, "flow_label %d", &flow_label_val))
8695         flow_label = 1;
8696       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8697         src = 1;
8698       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8699         dst = 1;
8700       else if (unformat (input, "proto %d", &proto_val))
8701         proto = 1;
8702       else if (unformat (input, "payload_length %d", &payload_length_val))
8703         payload_length = 1;
8704       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8705         hop_limit = 1;
8706       else
8707         break;
8708     }
8709
8710   if (version + traffic_class + flow_label + src + dst + proto +
8711       payload_length + hop_limit == 0)
8712     return 0;
8713
8714   /*
8715    * Aligned because we use the real comparison functions
8716    */
8717   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8718
8719   ip = (ip6_header_t *) match;
8720
8721   if (src)
8722     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8723
8724   if (dst)
8725     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8726
8727   if (proto)
8728     ip->protocol = proto_val;
8729
8730   ip_version_traffic_class_and_flow_label = 0;
8731
8732   if (version)
8733     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8734
8735   if (traffic_class)
8736     ip_version_traffic_class_and_flow_label |=
8737       (traffic_class_val & 0xFF) << 20;
8738
8739   if (flow_label)
8740     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8741
8742   ip->ip_version_traffic_class_and_flow_label =
8743     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8744
8745   if (payload_length)
8746     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8747
8748   if (hop_limit)
8749     ip->hop_limit = hop_limit_val;
8750
8751   *matchp = match;
8752   return 1;
8753 }
8754
8755 uword
8756 unformat_l3_match (unformat_input_t * input, va_list * args)
8757 {
8758   u8 **matchp = va_arg (*args, u8 **);
8759
8760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8761     {
8762       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8763         return 1;
8764       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8765         return 1;
8766       else
8767         break;
8768     }
8769   return 0;
8770 }
8771
8772 uword
8773 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8774 {
8775   u8 *tagp = va_arg (*args, u8 *);
8776   u32 tag;
8777
8778   if (unformat (input, "%d", &tag))
8779     {
8780       tagp[0] = (tag >> 8) & 0x0F;
8781       tagp[1] = tag & 0xFF;
8782       return 1;
8783     }
8784
8785   return 0;
8786 }
8787
8788 uword
8789 unformat_l2_match (unformat_input_t * input, va_list * args)
8790 {
8791   u8 **matchp = va_arg (*args, u8 **);
8792   u8 *match = 0;
8793   u8 src = 0;
8794   u8 src_val[6];
8795   u8 dst = 0;
8796   u8 dst_val[6];
8797   u8 proto = 0;
8798   u16 proto_val;
8799   u8 tag1 = 0;
8800   u8 tag1_val[2];
8801   u8 tag2 = 0;
8802   u8 tag2_val[2];
8803   int len = 14;
8804   u8 ignore_tag1 = 0;
8805   u8 ignore_tag2 = 0;
8806   u8 cos1 = 0;
8807   u8 cos2 = 0;
8808   u32 cos1_val = 0;
8809   u32 cos2_val = 0;
8810
8811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8812     {
8813       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8814         src = 1;
8815       else
8816         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8817         dst = 1;
8818       else if (unformat (input, "proto %U",
8819                          unformat_ethernet_type_host_byte_order, &proto_val))
8820         proto = 1;
8821       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8822         tag1 = 1;
8823       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8824         tag2 = 1;
8825       else if (unformat (input, "ignore-tag1"))
8826         ignore_tag1 = 1;
8827       else if (unformat (input, "ignore-tag2"))
8828         ignore_tag2 = 1;
8829       else if (unformat (input, "cos1 %d", &cos1_val))
8830         cos1 = 1;
8831       else if (unformat (input, "cos2 %d", &cos2_val))
8832         cos2 = 1;
8833       else
8834         break;
8835     }
8836   if ((src + dst + proto + tag1 + tag2 +
8837        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8838     return 0;
8839
8840   if (tag1 || ignore_tag1 || cos1)
8841     len = 18;
8842   if (tag2 || ignore_tag2 || cos2)
8843     len = 22;
8844
8845   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8846
8847   if (dst)
8848     clib_memcpy (match, dst_val, 6);
8849
8850   if (src)
8851     clib_memcpy (match + 6, src_val, 6);
8852
8853   if (tag2)
8854     {
8855       /* inner vlan tag */
8856       match[19] = tag2_val[1];
8857       match[18] = tag2_val[0];
8858       if (cos2)
8859         match[18] |= (cos2_val & 0x7) << 5;
8860       if (proto)
8861         {
8862           match[21] = proto_val & 0xff;
8863           match[20] = proto_val >> 8;
8864         }
8865       if (tag1)
8866         {
8867           match[15] = tag1_val[1];
8868           match[14] = tag1_val[0];
8869         }
8870       if (cos1)
8871         match[14] |= (cos1_val & 0x7) << 5;
8872       *matchp = match;
8873       return 1;
8874     }
8875   if (tag1)
8876     {
8877       match[15] = tag1_val[1];
8878       match[14] = tag1_val[0];
8879       if (proto)
8880         {
8881           match[17] = proto_val & 0xff;
8882           match[16] = proto_val >> 8;
8883         }
8884       if (cos1)
8885         match[14] |= (cos1_val & 0x7) << 5;
8886
8887       *matchp = match;
8888       return 1;
8889     }
8890   if (cos2)
8891     match[18] |= (cos2_val & 0x7) << 5;
8892   if (cos1)
8893     match[14] |= (cos1_val & 0x7) << 5;
8894   if (proto)
8895     {
8896       match[13] = proto_val & 0xff;
8897       match[12] = proto_val >> 8;
8898     }
8899
8900   *matchp = match;
8901   return 1;
8902 }
8903
8904
8905 uword
8906 unformat_classify_match (unformat_input_t * input, va_list * args)
8907 {
8908   u8 **matchp = va_arg (*args, u8 **);
8909   u32 skip_n_vectors = va_arg (*args, u32);
8910   u32 match_n_vectors = va_arg (*args, u32);
8911
8912   u8 *match = 0;
8913   u8 *l2 = 0;
8914   u8 *l3 = 0;
8915   u8 *l4 = 0;
8916
8917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8918     {
8919       if (unformat (input, "hex %U", unformat_hex_string, &match))
8920         ;
8921       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8922         ;
8923       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8924         ;
8925       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8926         ;
8927       else
8928         break;
8929     }
8930
8931   if (l4 && !l3)
8932     {
8933       vec_free (match);
8934       vec_free (l2);
8935       vec_free (l4);
8936       return 0;
8937     }
8938
8939   if (match || l2 || l3 || l4)
8940     {
8941       if (l2 || l3 || l4)
8942         {
8943           /* "Win a free Ethernet header in every packet" */
8944           if (l2 == 0)
8945             vec_validate_aligned (l2, 13, sizeof (u32x4));
8946           match = l2;
8947           if (vec_len (l3))
8948             {
8949               vec_append_aligned (match, l3, sizeof (u32x4));
8950               vec_free (l3);
8951             }
8952           if (vec_len (l4))
8953             {
8954               vec_append_aligned (match, l4, sizeof (u32x4));
8955               vec_free (l4);
8956             }
8957         }
8958
8959       /* Make sure the vector is big enough even if key is all 0's */
8960       vec_validate_aligned
8961         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8962          sizeof (u32x4));
8963
8964       /* Set size, include skipped vectors */
8965       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8966
8967       *matchp = match;
8968
8969       return 1;
8970     }
8971
8972   return 0;
8973 }
8974
8975 static int
8976 api_classify_add_del_session (vat_main_t * vam)
8977 {
8978   unformat_input_t *i = vam->input;
8979   vl_api_classify_add_del_session_t *mp;
8980   int is_add = 1;
8981   u32 table_index = ~0;
8982   u32 hit_next_index = ~0;
8983   u32 opaque_index = ~0;
8984   u8 *match = 0;
8985   i32 advance = 0;
8986   f64 timeout;
8987   u32 skip_n_vectors = 0;
8988   u32 match_n_vectors = 0;
8989
8990   /*
8991    * Warning: you have to supply skip_n and match_n
8992    * because the API client cant simply look at the classify
8993    * table object.
8994    */
8995
8996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8997     {
8998       if (unformat (i, "del"))
8999         is_add = 0;
9000       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9001                          &hit_next_index))
9002         ;
9003       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9004                          &hit_next_index))
9005         ;
9006       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9007                          &hit_next_index))
9008         ;
9009       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9010         ;
9011       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9012         ;
9013       else if (unformat (i, "opaque-index %d", &opaque_index))
9014         ;
9015       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9016         ;
9017       else if (unformat (i, "match_n %d", &match_n_vectors))
9018         ;
9019       else if (unformat (i, "match %U", unformat_classify_match,
9020                          &match, skip_n_vectors, match_n_vectors))
9021         ;
9022       else if (unformat (i, "advance %d", &advance))
9023         ;
9024       else if (unformat (i, "table-index %d", &table_index))
9025         ;
9026       else
9027         break;
9028     }
9029
9030   if (table_index == ~0)
9031     {
9032       errmsg ("Table index required\n");
9033       return -99;
9034     }
9035
9036   if (is_add && match == 0)
9037     {
9038       errmsg ("Match value required\n");
9039       return -99;
9040     }
9041
9042   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9043
9044   mp->is_add = is_add;
9045   mp->table_index = ntohl (table_index);
9046   mp->hit_next_index = ntohl (hit_next_index);
9047   mp->opaque_index = ntohl (opaque_index);
9048   mp->advance = ntohl (advance);
9049   clib_memcpy (mp->match, match, vec_len (match));
9050   vec_free (match);
9051
9052   S;
9053   W;
9054   /* NOTREACHED */
9055 }
9056
9057 static int
9058 api_classify_set_interface_ip_table (vat_main_t * vam)
9059 {
9060   unformat_input_t *i = vam->input;
9061   vl_api_classify_set_interface_ip_table_t *mp;
9062   f64 timeout;
9063   u32 sw_if_index;
9064   int sw_if_index_set;
9065   u32 table_index = ~0;
9066   u8 is_ipv6 = 0;
9067
9068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9069     {
9070       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9071         sw_if_index_set = 1;
9072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9073         sw_if_index_set = 1;
9074       else if (unformat (i, "table %d", &table_index))
9075         ;
9076       else
9077         {
9078           clib_warning ("parse error '%U'", format_unformat_error, i);
9079           return -99;
9080         }
9081     }
9082
9083   if (sw_if_index_set == 0)
9084     {
9085       errmsg ("missing interface name or sw_if_index\n");
9086       return -99;
9087     }
9088
9089
9090   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9091
9092   mp->sw_if_index = ntohl (sw_if_index);
9093   mp->table_index = ntohl (table_index);
9094   mp->is_ipv6 = is_ipv6;
9095
9096   S;
9097   W;
9098   /* NOTREACHED */
9099   return 0;
9100 }
9101
9102 static int
9103 api_classify_set_interface_l2_tables (vat_main_t * vam)
9104 {
9105   unformat_input_t *i = vam->input;
9106   vl_api_classify_set_interface_l2_tables_t *mp;
9107   f64 timeout;
9108   u32 sw_if_index;
9109   int sw_if_index_set;
9110   u32 ip4_table_index = ~0;
9111   u32 ip6_table_index = ~0;
9112   u32 other_table_index = ~0;
9113   u32 is_input = 1;
9114
9115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9116     {
9117       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9118         sw_if_index_set = 1;
9119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9120         sw_if_index_set = 1;
9121       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9122         ;
9123       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9124         ;
9125       else if (unformat (i, "other-table %d", &other_table_index))
9126         ;
9127       else if (unformat (i, "is-input %d", &is_input))
9128         ;
9129       else
9130         {
9131           clib_warning ("parse error '%U'", format_unformat_error, i);
9132           return -99;
9133         }
9134     }
9135
9136   if (sw_if_index_set == 0)
9137     {
9138       errmsg ("missing interface name or sw_if_index\n");
9139       return -99;
9140     }
9141
9142
9143   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9144
9145   mp->sw_if_index = ntohl (sw_if_index);
9146   mp->ip4_table_index = ntohl (ip4_table_index);
9147   mp->ip6_table_index = ntohl (ip6_table_index);
9148   mp->other_table_index = ntohl (other_table_index);
9149   mp->is_input = (u8) is_input;
9150
9151   S;
9152   W;
9153   /* NOTREACHED */
9154   return 0;
9155 }
9156
9157 static int
9158 api_set_ipfix_exporter (vat_main_t * vam)
9159 {
9160   unformat_input_t *i = vam->input;
9161   vl_api_set_ipfix_exporter_t *mp;
9162   ip4_address_t collector_address;
9163   u8 collector_address_set = 0;
9164   u32 collector_port = ~0;
9165   ip4_address_t src_address;
9166   u8 src_address_set = 0;
9167   u32 vrf_id = ~0;
9168   u32 path_mtu = ~0;
9169   u32 template_interval = ~0;
9170   u8 udp_checksum = 0;
9171   f64 timeout;
9172
9173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9174     {
9175       if (unformat (i, "collector_address %U", unformat_ip4_address,
9176                     &collector_address))
9177         collector_address_set = 1;
9178       else if (unformat (i, "collector_port %d", &collector_port))
9179         ;
9180       else if (unformat (i, "src_address %U", unformat_ip4_address,
9181                          &src_address))
9182         src_address_set = 1;
9183       else if (unformat (i, "vrf_id %d", &vrf_id))
9184         ;
9185       else if (unformat (i, "path_mtu %d", &path_mtu))
9186         ;
9187       else if (unformat (i, "template_interval %d", &template_interval))
9188         ;
9189       else if (unformat (i, "udp_checksum"))
9190         udp_checksum = 1;
9191       else
9192         break;
9193     }
9194
9195   if (collector_address_set == 0)
9196     {
9197       errmsg ("collector_address required\n");
9198       return -99;
9199     }
9200
9201   if (src_address_set == 0)
9202     {
9203       errmsg ("src_address required\n");
9204       return -99;
9205     }
9206
9207   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9208
9209   memcpy (mp->collector_address, collector_address.data,
9210           sizeof (collector_address.data));
9211   mp->collector_port = htons ((u16) collector_port);
9212   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9213   mp->vrf_id = htonl (vrf_id);
9214   mp->path_mtu = htonl (path_mtu);
9215   mp->template_interval = htonl (template_interval);
9216   mp->udp_checksum = udp_checksum;
9217
9218   S;
9219   W;
9220   /* NOTREACHED */
9221 }
9222
9223 static int
9224 api_set_ipfix_classify_stream (vat_main_t * vam)
9225 {
9226   unformat_input_t *i = vam->input;
9227   vl_api_set_ipfix_classify_stream_t *mp;
9228   u32 domain_id = 0;
9229   u32 src_port = UDP_DST_PORT_ipfix;
9230   f64 timeout;
9231
9232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9233     {
9234       if (unformat (i, "domain %d", &domain_id))
9235         ;
9236       else if (unformat (i, "src_port %d", &src_port))
9237         ;
9238       else
9239         {
9240           errmsg ("unknown input `%U'", format_unformat_error, i);
9241           return -99;
9242         }
9243     }
9244
9245   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9246
9247   mp->domain_id = htonl (domain_id);
9248   mp->src_port = htons ((u16) src_port);
9249
9250   S;
9251   W;
9252   /* NOTREACHED */
9253 }
9254
9255 static int
9256 api_ipfix_classify_table_add_del (vat_main_t * vam)
9257 {
9258   unformat_input_t *i = vam->input;
9259   vl_api_ipfix_classify_table_add_del_t *mp;
9260   int is_add = -1;
9261   u32 classify_table_index = ~0;
9262   u8 ip_version = 0;
9263   u8 transport_protocol = 255;
9264   f64 timeout;
9265
9266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9267     {
9268       if (unformat (i, "add"))
9269         is_add = 1;
9270       else if (unformat (i, "del"))
9271         is_add = 0;
9272       else if (unformat (i, "table %d", &classify_table_index))
9273         ;
9274       else if (unformat (i, "ip4"))
9275         ip_version = 4;
9276       else if (unformat (i, "ip6"))
9277         ip_version = 6;
9278       else if (unformat (i, "tcp"))
9279         transport_protocol = 6;
9280       else if (unformat (i, "udp"))
9281         transport_protocol = 17;
9282       else
9283         {
9284           errmsg ("unknown input `%U'", format_unformat_error, i);
9285           return -99;
9286         }
9287     }
9288
9289   if (is_add == -1)
9290     {
9291       errmsg ("expecting: add|del");
9292       return -99;
9293     }
9294   if (classify_table_index == ~0)
9295     {
9296       errmsg ("classifier table not specified");
9297       return -99;
9298     }
9299   if (ip_version == 0)
9300     {
9301       errmsg ("IP version not specified");
9302       return -99;
9303     }
9304
9305   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9306
9307   mp->is_add = is_add;
9308   mp->table_id = htonl (classify_table_index);
9309   mp->ip_version = ip_version;
9310   mp->transport_protocol = transport_protocol;
9311
9312   S;
9313   W;
9314   /* NOTREACHED */
9315 }
9316
9317 static int
9318 api_get_node_index (vat_main_t * vam)
9319 {
9320   unformat_input_t *i = vam->input;
9321   vl_api_get_node_index_t *mp;
9322   f64 timeout;
9323   u8 *name = 0;
9324
9325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9326     {
9327       if (unformat (i, "node %s", &name))
9328         ;
9329       else
9330         break;
9331     }
9332   if (name == 0)
9333     {
9334       errmsg ("node name required\n");
9335       return -99;
9336     }
9337   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9338     {
9339       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9340       return -99;
9341     }
9342
9343   M (GET_NODE_INDEX, get_node_index);
9344   clib_memcpy (mp->node_name, name, vec_len (name));
9345   vec_free (name);
9346
9347   S;
9348   W;
9349   /* NOTREACHED */
9350   return 0;
9351 }
9352
9353 static int
9354 api_get_next_index (vat_main_t * vam)
9355 {
9356   unformat_input_t *i = vam->input;
9357   vl_api_get_next_index_t *mp;
9358   f64 timeout;
9359   u8 *node_name = 0, *next_node_name = 0;
9360
9361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9362     {
9363       if (unformat (i, "node-name %s", &node_name))
9364         ;
9365       else if (unformat (i, "next-node-name %s", &next_node_name))
9366         break;
9367     }
9368
9369   if (node_name == 0)
9370     {
9371       errmsg ("node name required\n");
9372       return -99;
9373     }
9374   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9375     {
9376       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9377       return -99;
9378     }
9379
9380   if (next_node_name == 0)
9381     {
9382       errmsg ("next node name required\n");
9383       return -99;
9384     }
9385   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9386     {
9387       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9388       return -99;
9389     }
9390
9391   M (GET_NEXT_INDEX, get_next_index);
9392   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9393   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9394   vec_free (node_name);
9395   vec_free (next_node_name);
9396
9397   S;
9398   W;
9399   /* NOTREACHED */
9400   return 0;
9401 }
9402
9403 static int
9404 api_add_node_next (vat_main_t * vam)
9405 {
9406   unformat_input_t *i = vam->input;
9407   vl_api_add_node_next_t *mp;
9408   f64 timeout;
9409   u8 *name = 0;
9410   u8 *next = 0;
9411
9412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9413     {
9414       if (unformat (i, "node %s", &name))
9415         ;
9416       else if (unformat (i, "next %s", &next))
9417         ;
9418       else
9419         break;
9420     }
9421   if (name == 0)
9422     {
9423       errmsg ("node name required\n");
9424       return -99;
9425     }
9426   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9427     {
9428       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9429       return -99;
9430     }
9431   if (next == 0)
9432     {
9433       errmsg ("next node required\n");
9434       return -99;
9435     }
9436   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9437     {
9438       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9439       return -99;
9440     }
9441
9442   M (ADD_NODE_NEXT, add_node_next);
9443   clib_memcpy (mp->node_name, name, vec_len (name));
9444   clib_memcpy (mp->next_name, next, vec_len (next));
9445   vec_free (name);
9446   vec_free (next);
9447
9448   S;
9449   W;
9450   /* NOTREACHED */
9451   return 0;
9452 }
9453
9454 static int
9455 api_l2tpv3_create_tunnel (vat_main_t * vam)
9456 {
9457   unformat_input_t *i = vam->input;
9458   ip6_address_t client_address, our_address;
9459   int client_address_set = 0;
9460   int our_address_set = 0;
9461   u32 local_session_id = 0;
9462   u32 remote_session_id = 0;
9463   u64 local_cookie = 0;
9464   u64 remote_cookie = 0;
9465   u8 l2_sublayer_present = 0;
9466   vl_api_l2tpv3_create_tunnel_t *mp;
9467   f64 timeout;
9468
9469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9470     {
9471       if (unformat (i, "client_address %U", unformat_ip6_address,
9472                     &client_address))
9473         client_address_set = 1;
9474       else if (unformat (i, "our_address %U", unformat_ip6_address,
9475                          &our_address))
9476         our_address_set = 1;
9477       else if (unformat (i, "local_session_id %d", &local_session_id))
9478         ;
9479       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9480         ;
9481       else if (unformat (i, "local_cookie %lld", &local_cookie))
9482         ;
9483       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9484         ;
9485       else if (unformat (i, "l2-sublayer-present"))
9486         l2_sublayer_present = 1;
9487       else
9488         break;
9489     }
9490
9491   if (client_address_set == 0)
9492     {
9493       errmsg ("client_address required\n");
9494       return -99;
9495     }
9496
9497   if (our_address_set == 0)
9498     {
9499       errmsg ("our_address required\n");
9500       return -99;
9501     }
9502
9503   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9504
9505   clib_memcpy (mp->client_address, client_address.as_u8,
9506                sizeof (mp->client_address));
9507
9508   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9509
9510   mp->local_session_id = ntohl (local_session_id);
9511   mp->remote_session_id = ntohl (remote_session_id);
9512   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9513   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9514   mp->l2_sublayer_present = l2_sublayer_present;
9515   mp->is_ipv6 = 1;
9516
9517   S;
9518   W;
9519   /* NOTREACHED */
9520   return 0;
9521 }
9522
9523 static int
9524 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9525 {
9526   unformat_input_t *i = vam->input;
9527   u32 sw_if_index;
9528   u8 sw_if_index_set = 0;
9529   u64 new_local_cookie = 0;
9530   u64 new_remote_cookie = 0;
9531   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9532   f64 timeout;
9533
9534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9535     {
9536       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9537         sw_if_index_set = 1;
9538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9539         sw_if_index_set = 1;
9540       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9541         ;
9542       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9543         ;
9544       else
9545         break;
9546     }
9547
9548   if (sw_if_index_set == 0)
9549     {
9550       errmsg ("missing interface name or sw_if_index\n");
9551       return -99;
9552     }
9553
9554   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9555
9556   mp->sw_if_index = ntohl (sw_if_index);
9557   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9558   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9559
9560   S;
9561   W;
9562   /* NOTREACHED */
9563   return 0;
9564 }
9565
9566 static int
9567 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9568 {
9569   unformat_input_t *i = vam->input;
9570   vl_api_l2tpv3_interface_enable_disable_t *mp;
9571   f64 timeout;
9572   u32 sw_if_index;
9573   u8 sw_if_index_set = 0;
9574   u8 enable_disable = 1;
9575
9576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9577     {
9578       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9579         sw_if_index_set = 1;
9580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9581         sw_if_index_set = 1;
9582       else if (unformat (i, "enable"))
9583         enable_disable = 1;
9584       else if (unformat (i, "disable"))
9585         enable_disable = 0;
9586       else
9587         break;
9588     }
9589
9590   if (sw_if_index_set == 0)
9591     {
9592       errmsg ("missing interface name or sw_if_index\n");
9593       return -99;
9594     }
9595
9596   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9597
9598   mp->sw_if_index = ntohl (sw_if_index);
9599   mp->enable_disable = enable_disable;
9600
9601   S;
9602   W;
9603   /* NOTREACHED */
9604   return 0;
9605 }
9606
9607 static int
9608 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9609 {
9610   unformat_input_t *i = vam->input;
9611   vl_api_l2tpv3_set_lookup_key_t *mp;
9612   f64 timeout;
9613   u8 key = ~0;
9614
9615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9616     {
9617       if (unformat (i, "lookup_v6_src"))
9618         key = L2T_LOOKUP_SRC_ADDRESS;
9619       else if (unformat (i, "lookup_v6_dst"))
9620         key = L2T_LOOKUP_DST_ADDRESS;
9621       else if (unformat (i, "lookup_session_id"))
9622         key = L2T_LOOKUP_SESSION_ID;
9623       else
9624         break;
9625     }
9626
9627   if (key == (u8) ~ 0)
9628     {
9629       errmsg ("l2tp session lookup key unset\n");
9630       return -99;
9631     }
9632
9633   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9634
9635   mp->key = key;
9636
9637   S;
9638   W;
9639   /* NOTREACHED */
9640   return 0;
9641 }
9642
9643 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9644   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9645 {
9646   vat_main_t *vam = &vat_main;
9647
9648   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9649            format_ip6_address, mp->our_address,
9650            format_ip6_address, mp->client_address,
9651            clib_net_to_host_u32 (mp->sw_if_index));
9652
9653   fformat (vam->ofp,
9654            "   local cookies %016llx %016llx remote cookie %016llx\n",
9655            clib_net_to_host_u64 (mp->local_cookie[0]),
9656            clib_net_to_host_u64 (mp->local_cookie[1]),
9657            clib_net_to_host_u64 (mp->remote_cookie));
9658
9659   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9660            clib_net_to_host_u32 (mp->local_session_id),
9661            clib_net_to_host_u32 (mp->remote_session_id));
9662
9663   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9664            mp->l2_sublayer_present ? "preset" : "absent");
9665
9666 }
9667
9668 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9669   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9670 {
9671   vat_main_t *vam = &vat_main;
9672   vat_json_node_t *node = NULL;
9673   struct in6_addr addr;
9674
9675   if (VAT_JSON_ARRAY != vam->json_tree.type)
9676     {
9677       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9678       vat_json_init_array (&vam->json_tree);
9679     }
9680   node = vat_json_array_add (&vam->json_tree);
9681
9682   vat_json_init_object (node);
9683
9684   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9685   vat_json_object_add_ip6 (node, "our_address", addr);
9686   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9687   vat_json_object_add_ip6 (node, "client_address", addr);
9688
9689   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9690   vat_json_init_array (lc);
9691   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9692   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9693   vat_json_object_add_uint (node, "remote_cookie",
9694                             clib_net_to_host_u64 (mp->remote_cookie));
9695
9696   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9697   vat_json_object_add_uint (node, "local_session_id",
9698                             clib_net_to_host_u32 (mp->local_session_id));
9699   vat_json_object_add_uint (node, "remote_session_id",
9700                             clib_net_to_host_u32 (mp->remote_session_id));
9701   vat_json_object_add_string_copy (node, "l2_sublayer",
9702                                    mp->l2_sublayer_present ? (u8 *) "present"
9703                                    : (u8 *) "absent");
9704 }
9705
9706 static int
9707 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9708 {
9709   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9710   f64 timeout;
9711
9712   /* Get list of l2tpv3-tunnel interfaces */
9713   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9714   S;
9715
9716   /* Use a control ping for synchronization */
9717   {
9718     vl_api_control_ping_t *mp;
9719     M (CONTROL_PING, control_ping);
9720     S;
9721   }
9722   W;
9723 }
9724
9725
9726 static void vl_api_sw_interface_tap_details_t_handler
9727   (vl_api_sw_interface_tap_details_t * mp)
9728 {
9729   vat_main_t *vam = &vat_main;
9730
9731   fformat (vam->ofp, "%-16s %d\n",
9732            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9733 }
9734
9735 static void vl_api_sw_interface_tap_details_t_handler_json
9736   (vl_api_sw_interface_tap_details_t * mp)
9737 {
9738   vat_main_t *vam = &vat_main;
9739   vat_json_node_t *node = NULL;
9740
9741   if (VAT_JSON_ARRAY != vam->json_tree.type)
9742     {
9743       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9744       vat_json_init_array (&vam->json_tree);
9745     }
9746   node = vat_json_array_add (&vam->json_tree);
9747
9748   vat_json_init_object (node);
9749   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9750   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9751 }
9752
9753 static int
9754 api_sw_interface_tap_dump (vat_main_t * vam)
9755 {
9756   vl_api_sw_interface_tap_dump_t *mp;
9757   f64 timeout;
9758
9759   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9760   /* Get list of tap interfaces */
9761   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9762   S;
9763
9764   /* Use a control ping for synchronization */
9765   {
9766     vl_api_control_ping_t *mp;
9767     M (CONTROL_PING, control_ping);
9768     S;
9769   }
9770   W;
9771 }
9772
9773 static uword unformat_vxlan_decap_next
9774   (unformat_input_t * input, va_list * args)
9775 {
9776   u32 *result = va_arg (*args, u32 *);
9777   u32 tmp;
9778
9779   if (unformat (input, "drop"))
9780     *result = VXLAN_INPUT_NEXT_DROP;
9781   else if (unformat (input, "ip4"))
9782     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9783   else if (unformat (input, "ip6"))
9784     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9785   else if (unformat (input, "l2"))
9786     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9787   else if (unformat (input, "%d", &tmp))
9788     *result = tmp;
9789   else
9790     return 0;
9791   return 1;
9792 }
9793
9794 static int
9795 api_vxlan_add_del_tunnel (vat_main_t * vam)
9796 {
9797   unformat_input_t *line_input = vam->input;
9798   vl_api_vxlan_add_del_tunnel_t *mp;
9799   f64 timeout;
9800   ip4_address_t src4, dst4;
9801   ip6_address_t src6, dst6;
9802   u8 is_add = 1;
9803   u8 ipv4_set = 0, ipv6_set = 0;
9804   u8 src_set = 0;
9805   u8 dst_set = 0;
9806   u32 encap_vrf_id = 0;
9807   u32 decap_next_index = ~0;
9808   u32 vni = 0;
9809
9810   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (line_input, "del"))
9813         is_add = 0;
9814       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9815         {
9816           ipv4_set = 1;
9817           src_set = 1;
9818         }
9819       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9820         {
9821           ipv4_set = 1;
9822           dst_set = 1;
9823         }
9824       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9825         {
9826           ipv6_set = 1;
9827           src_set = 1;
9828         }
9829       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9830         {
9831           ipv6_set = 1;
9832           dst_set = 1;
9833         }
9834       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9835         ;
9836       else if (unformat (line_input, "decap-next %U",
9837                          unformat_vxlan_decap_next, &decap_next_index))
9838         ;
9839       else if (unformat (line_input, "vni %d", &vni))
9840         ;
9841       else
9842         {
9843           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9844           return -99;
9845         }
9846     }
9847
9848   if (src_set == 0)
9849     {
9850       errmsg ("tunnel src address not specified\n");
9851       return -99;
9852     }
9853   if (dst_set == 0)
9854     {
9855       errmsg ("tunnel dst address not specified\n");
9856       return -99;
9857     }
9858
9859   if (ipv4_set && ipv6_set)
9860     {
9861       errmsg ("both IPv4 and IPv6 addresses specified");
9862       return -99;
9863     }
9864
9865   if ((vni == 0) || (vni >> 24))
9866     {
9867       errmsg ("vni not specified or out of range\n");
9868       return -99;
9869     }
9870
9871   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9872
9873   if (ipv6_set)
9874     {
9875       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9876       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9877     }
9878   else
9879     {
9880       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9881       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9882     }
9883   mp->encap_vrf_id = ntohl (encap_vrf_id);
9884   mp->decap_next_index = ntohl (decap_next_index);
9885   mp->vni = ntohl (vni);
9886   mp->is_add = is_add;
9887   mp->is_ipv6 = ipv6_set;
9888
9889   S;
9890   W;
9891   /* NOTREACHED */
9892   return 0;
9893 }
9894
9895 static void vl_api_vxlan_tunnel_details_t_handler
9896   (vl_api_vxlan_tunnel_details_t * mp)
9897 {
9898   vat_main_t *vam = &vat_main;
9899
9900   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9901            ntohl (mp->sw_if_index),
9902            format_ip46_address, &(mp->src_address[0]),
9903            IP46_TYPE_ANY,
9904            format_ip46_address, &(mp->dst_address[0]),
9905            IP46_TYPE_ANY,
9906            ntohl (mp->encap_vrf_id),
9907            ntohl (mp->decap_next_index), ntohl (mp->vni));
9908 }
9909
9910 static void vl_api_vxlan_tunnel_details_t_handler_json
9911   (vl_api_vxlan_tunnel_details_t * mp)
9912 {
9913   vat_main_t *vam = &vat_main;
9914   vat_json_node_t *node = NULL;
9915   struct in_addr ip4;
9916   struct in6_addr ip6;
9917
9918   if (VAT_JSON_ARRAY != vam->json_tree.type)
9919     {
9920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9921       vat_json_init_array (&vam->json_tree);
9922     }
9923   node = vat_json_array_add (&vam->json_tree);
9924
9925   vat_json_init_object (node);
9926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9927   if (mp->is_ipv6)
9928     {
9929       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9930       vat_json_object_add_ip6 (node, "src_address", ip6);
9931       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9932       vat_json_object_add_ip6 (node, "dst_address", ip6);
9933     }
9934   else
9935     {
9936       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9937       vat_json_object_add_ip4 (node, "src_address", ip4);
9938       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9939       vat_json_object_add_ip4 (node, "dst_address", ip4);
9940     }
9941   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9942   vat_json_object_add_uint (node, "decap_next_index",
9943                             ntohl (mp->decap_next_index));
9944   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9945   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9946 }
9947
9948 static int
9949 api_vxlan_tunnel_dump (vat_main_t * vam)
9950 {
9951   unformat_input_t *i = vam->input;
9952   vl_api_vxlan_tunnel_dump_t *mp;
9953   f64 timeout;
9954   u32 sw_if_index;
9955   u8 sw_if_index_set = 0;
9956
9957   /* Parse args required to build the message */
9958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9959     {
9960       if (unformat (i, "sw_if_index %d", &sw_if_index))
9961         sw_if_index_set = 1;
9962       else
9963         break;
9964     }
9965
9966   if (sw_if_index_set == 0)
9967     {
9968       sw_if_index = ~0;
9969     }
9970
9971   if (!vam->json_output)
9972     {
9973       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9974                "sw_if_index", "src_address", "dst_address",
9975                "encap_vrf_id", "decap_next_index", "vni");
9976     }
9977
9978   /* Get list of vxlan-tunnel interfaces */
9979   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9980
9981   mp->sw_if_index = htonl (sw_if_index);
9982
9983   S;
9984
9985   /* Use a control ping for synchronization */
9986   {
9987     vl_api_control_ping_t *mp;
9988     M (CONTROL_PING, control_ping);
9989     S;
9990   }
9991   W;
9992 }
9993
9994 static int
9995 api_gre_add_del_tunnel (vat_main_t * vam)
9996 {
9997   unformat_input_t *line_input = vam->input;
9998   vl_api_gre_add_del_tunnel_t *mp;
9999   f64 timeout;
10000   ip4_address_t src4, dst4;
10001   u8 is_add = 1;
10002   u8 teb = 0;
10003   u8 src_set = 0;
10004   u8 dst_set = 0;
10005   u32 outer_fib_id = 0;
10006
10007   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10008     {
10009       if (unformat (line_input, "del"))
10010         is_add = 0;
10011       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10012         src_set = 1;
10013       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10014         dst_set = 1;
10015       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10016         ;
10017       else if (unformat (line_input, "teb"))
10018         teb = 1;
10019       else
10020         {
10021           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10022           return -99;
10023         }
10024     }
10025
10026   if (src_set == 0)
10027     {
10028       errmsg ("tunnel src address not specified\n");
10029       return -99;
10030     }
10031   if (dst_set == 0)
10032     {
10033       errmsg ("tunnel dst address not specified\n");
10034       return -99;
10035     }
10036
10037
10038   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10039
10040   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10041   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10042   mp->outer_fib_id = ntohl (outer_fib_id);
10043   mp->is_add = is_add;
10044   mp->teb = teb;
10045
10046   S;
10047   W;
10048   /* NOTREACHED */
10049   return 0;
10050 }
10051
10052 static void vl_api_gre_tunnel_details_t_handler
10053   (vl_api_gre_tunnel_details_t * mp)
10054 {
10055   vat_main_t *vam = &vat_main;
10056
10057   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10058            ntohl (mp->sw_if_index),
10059            format_ip4_address, &mp->src_address,
10060            format_ip4_address, &mp->dst_address,
10061            mp->teb, ntohl (mp->outer_fib_id));
10062 }
10063
10064 static void vl_api_gre_tunnel_details_t_handler_json
10065   (vl_api_gre_tunnel_details_t * mp)
10066 {
10067   vat_main_t *vam = &vat_main;
10068   vat_json_node_t *node = NULL;
10069   struct in_addr ip4;
10070
10071   if (VAT_JSON_ARRAY != vam->json_tree.type)
10072     {
10073       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10074       vat_json_init_array (&vam->json_tree);
10075     }
10076   node = vat_json_array_add (&vam->json_tree);
10077
10078   vat_json_init_object (node);
10079   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10080   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10081   vat_json_object_add_ip4 (node, "src_address", ip4);
10082   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10083   vat_json_object_add_ip4 (node, "dst_address", ip4);
10084   vat_json_object_add_uint (node, "teb", mp->teb);
10085   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10086 }
10087
10088 static int
10089 api_gre_tunnel_dump (vat_main_t * vam)
10090 {
10091   unformat_input_t *i = vam->input;
10092   vl_api_gre_tunnel_dump_t *mp;
10093   f64 timeout;
10094   u32 sw_if_index;
10095   u8 sw_if_index_set = 0;
10096
10097   /* Parse args required to build the message */
10098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10099     {
10100       if (unformat (i, "sw_if_index %d", &sw_if_index))
10101         sw_if_index_set = 1;
10102       else
10103         break;
10104     }
10105
10106   if (sw_if_index_set == 0)
10107     {
10108       sw_if_index = ~0;
10109     }
10110
10111   if (!vam->json_output)
10112     {
10113       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10114                "sw_if_index", "src_address", "dst_address", "teb",
10115                "outer_fib_id");
10116     }
10117
10118   /* Get list of gre-tunnel interfaces */
10119   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10120
10121   mp->sw_if_index = htonl (sw_if_index);
10122
10123   S;
10124
10125   /* Use a control ping for synchronization */
10126   {
10127     vl_api_control_ping_t *mp;
10128     M (CONTROL_PING, control_ping);
10129     S;
10130   }
10131   W;
10132 }
10133
10134 static int
10135 api_l2_fib_clear_table (vat_main_t * vam)
10136 {
10137 //  unformat_input_t * i = vam->input;
10138   vl_api_l2_fib_clear_table_t *mp;
10139   f64 timeout;
10140
10141   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10142
10143   S;
10144   W;
10145   /* NOTREACHED */
10146   return 0;
10147 }
10148
10149 static int
10150 api_l2_interface_efp_filter (vat_main_t * vam)
10151 {
10152   unformat_input_t *i = vam->input;
10153   vl_api_l2_interface_efp_filter_t *mp;
10154   f64 timeout;
10155   u32 sw_if_index;
10156   u8 enable = 1;
10157   u8 sw_if_index_set = 0;
10158
10159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10160     {
10161       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10162         sw_if_index_set = 1;
10163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10164         sw_if_index_set = 1;
10165       else if (unformat (i, "enable"))
10166         enable = 1;
10167       else if (unformat (i, "disable"))
10168         enable = 0;
10169       else
10170         {
10171           clib_warning ("parse error '%U'", format_unformat_error, i);
10172           return -99;
10173         }
10174     }
10175
10176   if (sw_if_index_set == 0)
10177     {
10178       errmsg ("missing sw_if_index\n");
10179       return -99;
10180     }
10181
10182   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10183
10184   mp->sw_if_index = ntohl (sw_if_index);
10185   mp->enable_disable = enable;
10186
10187   S;
10188   W;
10189   /* NOTREACHED */
10190   return 0;
10191 }
10192
10193 #define foreach_vtr_op                          \
10194 _("disable",  L2_VTR_DISABLED)                  \
10195 _("push-1",  L2_VTR_PUSH_1)                     \
10196 _("push-2",  L2_VTR_PUSH_2)                     \
10197 _("pop-1",  L2_VTR_POP_1)                       \
10198 _("pop-2",  L2_VTR_POP_2)                       \
10199 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10200 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10201 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10202 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10203
10204 static int
10205 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10206 {
10207   unformat_input_t *i = vam->input;
10208   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10209   f64 timeout;
10210   u32 sw_if_index;
10211   u8 sw_if_index_set = 0;
10212   u8 vtr_op_set = 0;
10213   u32 vtr_op = 0;
10214   u32 push_dot1q = 1;
10215   u32 tag1 = ~0;
10216   u32 tag2 = ~0;
10217
10218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10219     {
10220       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10221         sw_if_index_set = 1;
10222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10223         sw_if_index_set = 1;
10224       else if (unformat (i, "vtr_op %d", &vtr_op))
10225         vtr_op_set = 1;
10226 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10227       foreach_vtr_op
10228 #undef _
10229         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10230         ;
10231       else if (unformat (i, "tag1 %d", &tag1))
10232         ;
10233       else if (unformat (i, "tag2 %d", &tag2))
10234         ;
10235       else
10236         {
10237           clib_warning ("parse error '%U'", format_unformat_error, i);
10238           return -99;
10239         }
10240     }
10241
10242   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10243     {
10244       errmsg ("missing vtr operation or sw_if_index\n");
10245       return -99;
10246     }
10247
10248   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10249     mp->sw_if_index = ntohl (sw_if_index);
10250   mp->vtr_op = ntohl (vtr_op);
10251   mp->push_dot1q = ntohl (push_dot1q);
10252   mp->tag1 = ntohl (tag1);
10253   mp->tag2 = ntohl (tag2);
10254
10255   S;
10256   W;
10257   /* NOTREACHED */
10258   return 0;
10259 }
10260
10261 static int
10262 api_create_vhost_user_if (vat_main_t * vam)
10263 {
10264   unformat_input_t *i = vam->input;
10265   vl_api_create_vhost_user_if_t *mp;
10266   f64 timeout;
10267   u8 *file_name;
10268   u8 is_server = 0;
10269   u8 file_name_set = 0;
10270   u32 custom_dev_instance = ~0;
10271   u8 hwaddr[6];
10272   u8 use_custom_mac = 0;
10273
10274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10275     {
10276       if (unformat (i, "socket %s", &file_name))
10277         {
10278           file_name_set = 1;
10279         }
10280       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10281         ;
10282       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10283         use_custom_mac = 1;
10284       else if (unformat (i, "server"))
10285         is_server = 1;
10286       else
10287         break;
10288     }
10289
10290   if (file_name_set == 0)
10291     {
10292       errmsg ("missing socket file name\n");
10293       return -99;
10294     }
10295
10296   if (vec_len (file_name) > 255)
10297     {
10298       errmsg ("socket file name too long\n");
10299       return -99;
10300     }
10301   vec_add1 (file_name, 0);
10302
10303   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10304
10305   mp->is_server = is_server;
10306   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10307   vec_free (file_name);
10308   if (custom_dev_instance != ~0)
10309     {
10310       mp->renumber = 1;
10311       mp->custom_dev_instance = ntohl (custom_dev_instance);
10312     }
10313   mp->use_custom_mac = use_custom_mac;
10314   clib_memcpy (mp->mac_address, hwaddr, 6);
10315
10316   S;
10317   W;
10318   /* NOTREACHED */
10319   return 0;
10320 }
10321
10322 static int
10323 api_modify_vhost_user_if (vat_main_t * vam)
10324 {
10325   unformat_input_t *i = vam->input;
10326   vl_api_modify_vhost_user_if_t *mp;
10327   f64 timeout;
10328   u8 *file_name;
10329   u8 is_server = 0;
10330   u8 file_name_set = 0;
10331   u32 custom_dev_instance = ~0;
10332   u8 sw_if_index_set = 0;
10333   u32 sw_if_index = (u32) ~ 0;
10334
10335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10336     {
10337       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10338         sw_if_index_set = 1;
10339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10340         sw_if_index_set = 1;
10341       else if (unformat (i, "socket %s", &file_name))
10342         {
10343           file_name_set = 1;
10344         }
10345       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10346         ;
10347       else if (unformat (i, "server"))
10348         is_server = 1;
10349       else
10350         break;
10351     }
10352
10353   if (sw_if_index_set == 0)
10354     {
10355       errmsg ("missing sw_if_index or interface name\n");
10356       return -99;
10357     }
10358
10359   if (file_name_set == 0)
10360     {
10361       errmsg ("missing socket file name\n");
10362       return -99;
10363     }
10364
10365   if (vec_len (file_name) > 255)
10366     {
10367       errmsg ("socket file name too long\n");
10368       return -99;
10369     }
10370   vec_add1 (file_name, 0);
10371
10372   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10373
10374   mp->sw_if_index = ntohl (sw_if_index);
10375   mp->is_server = is_server;
10376   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10377   vec_free (file_name);
10378   if (custom_dev_instance != ~0)
10379     {
10380       mp->renumber = 1;
10381       mp->custom_dev_instance = ntohl (custom_dev_instance);
10382     }
10383
10384   S;
10385   W;
10386   /* NOTREACHED */
10387   return 0;
10388 }
10389
10390 static int
10391 api_delete_vhost_user_if (vat_main_t * vam)
10392 {
10393   unformat_input_t *i = vam->input;
10394   vl_api_delete_vhost_user_if_t *mp;
10395   f64 timeout;
10396   u32 sw_if_index = ~0;
10397   u8 sw_if_index_set = 0;
10398
10399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10400     {
10401       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10402         sw_if_index_set = 1;
10403       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10404         sw_if_index_set = 1;
10405       else
10406         break;
10407     }
10408
10409   if (sw_if_index_set == 0)
10410     {
10411       errmsg ("missing sw_if_index or interface name\n");
10412       return -99;
10413     }
10414
10415
10416   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10417
10418   mp->sw_if_index = ntohl (sw_if_index);
10419
10420   S;
10421   W;
10422   /* NOTREACHED */
10423   return 0;
10424 }
10425
10426 static void vl_api_sw_interface_vhost_user_details_t_handler
10427   (vl_api_sw_interface_vhost_user_details_t * mp)
10428 {
10429   vat_main_t *vam = &vat_main;
10430
10431   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10432            (char *) mp->interface_name,
10433            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10434            clib_net_to_host_u64 (mp->features), mp->is_server,
10435            ntohl (mp->num_regions), (char *) mp->sock_filename);
10436   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10437 }
10438
10439 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10440   (vl_api_sw_interface_vhost_user_details_t * mp)
10441 {
10442   vat_main_t *vam = &vat_main;
10443   vat_json_node_t *node = NULL;
10444
10445   if (VAT_JSON_ARRAY != vam->json_tree.type)
10446     {
10447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10448       vat_json_init_array (&vam->json_tree);
10449     }
10450   node = vat_json_array_add (&vam->json_tree);
10451
10452   vat_json_init_object (node);
10453   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10454   vat_json_object_add_string_copy (node, "interface_name",
10455                                    mp->interface_name);
10456   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10457                             ntohl (mp->virtio_net_hdr_sz));
10458   vat_json_object_add_uint (node, "features",
10459                             clib_net_to_host_u64 (mp->features));
10460   vat_json_object_add_uint (node, "is_server", mp->is_server);
10461   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10462   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10463   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10464 }
10465
10466 static int
10467 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10468 {
10469   vl_api_sw_interface_vhost_user_dump_t *mp;
10470   f64 timeout;
10471   fformat (vam->ofp,
10472            "Interface name           idx hdr_sz features server regions filename\n");
10473
10474   /* Get list of vhost-user interfaces */
10475   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10476   S;
10477
10478   /* Use a control ping for synchronization */
10479   {
10480     vl_api_control_ping_t *mp;
10481     M (CONTROL_PING, control_ping);
10482     S;
10483   }
10484   W;
10485 }
10486
10487 static int
10488 api_show_version (vat_main_t * vam)
10489 {
10490   vl_api_show_version_t *mp;
10491   f64 timeout;
10492
10493   M (SHOW_VERSION, show_version);
10494
10495   S;
10496   W;
10497   /* NOTREACHED */
10498   return 0;
10499 }
10500
10501
10502 static int
10503 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10504 {
10505   unformat_input_t *line_input = vam->input;
10506   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10507   f64 timeout;
10508   ip4_address_t local4, remote4;
10509   ip6_address_t local6, remote6;
10510   u8 is_add = 1;
10511   u8 ipv4_set = 0, ipv6_set = 0;
10512   u8 local_set = 0;
10513   u8 remote_set = 0;
10514   u32 encap_vrf_id = 0;
10515   u32 decap_vrf_id = 0;
10516   u8 protocol = ~0;
10517   u32 vni;
10518   u8 vni_set = 0;
10519
10520   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10521     {
10522       if (unformat (line_input, "del"))
10523         is_add = 0;
10524       else if (unformat (line_input, "local %U",
10525                          unformat_ip4_address, &local4))
10526         {
10527           local_set = 1;
10528           ipv4_set = 1;
10529         }
10530       else if (unformat (line_input, "remote %U",
10531                          unformat_ip4_address, &remote4))
10532         {
10533           remote_set = 1;
10534           ipv4_set = 1;
10535         }
10536       else if (unformat (line_input, "local %U",
10537                          unformat_ip6_address, &local6))
10538         {
10539           local_set = 1;
10540           ipv6_set = 1;
10541         }
10542       else if (unformat (line_input, "remote %U",
10543                          unformat_ip6_address, &remote6))
10544         {
10545           remote_set = 1;
10546           ipv6_set = 1;
10547         }
10548       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10549         ;
10550       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10551         ;
10552       else if (unformat (line_input, "vni %d", &vni))
10553         vni_set = 1;
10554       else if (unformat (line_input, "next-ip4"))
10555         protocol = 1;
10556       else if (unformat (line_input, "next-ip6"))
10557         protocol = 2;
10558       else if (unformat (line_input, "next-ethernet"))
10559         protocol = 3;
10560       else if (unformat (line_input, "next-nsh"))
10561         protocol = 4;
10562       else
10563         {
10564           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10565           return -99;
10566         }
10567     }
10568
10569   if (local_set == 0)
10570     {
10571       errmsg ("tunnel local address not specified\n");
10572       return -99;
10573     }
10574   if (remote_set == 0)
10575     {
10576       errmsg ("tunnel remote address not specified\n");
10577       return -99;
10578     }
10579   if (ipv4_set && ipv6_set)
10580     {
10581       errmsg ("both IPv4 and IPv6 addresses specified");
10582       return -99;
10583     }
10584
10585   if (vni_set == 0)
10586     {
10587       errmsg ("vni not specified\n");
10588       return -99;
10589     }
10590
10591   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10592
10593
10594   if (ipv6_set)
10595     {
10596       clib_memcpy (&mp->local, &local6, sizeof (local6));
10597       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10598     }
10599   else
10600     {
10601       clib_memcpy (&mp->local, &local4, sizeof (local4));
10602       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10603     }
10604
10605   mp->encap_vrf_id = ntohl (encap_vrf_id);
10606   mp->decap_vrf_id = ntohl (decap_vrf_id);
10607   mp->protocol = ntohl (protocol);
10608   mp->vni = ntohl (vni);
10609   mp->is_add = is_add;
10610   mp->is_ipv6 = ipv6_set;
10611
10612   S;
10613   W;
10614   /* NOTREACHED */
10615   return 0;
10616 }
10617
10618 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10619   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10620 {
10621   vat_main_t *vam = &vat_main;
10622
10623   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10624            ntohl (mp->sw_if_index),
10625            format_ip46_address, &(mp->local[0]),
10626            format_ip46_address, &(mp->remote[0]),
10627            ntohl (mp->vni),
10628            ntohl (mp->protocol),
10629            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10630 }
10631
10632 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10633   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10634 {
10635   vat_main_t *vam = &vat_main;
10636   vat_json_node_t *node = NULL;
10637   struct in_addr ip4;
10638   struct in6_addr ip6;
10639
10640   if (VAT_JSON_ARRAY != vam->json_tree.type)
10641     {
10642       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10643       vat_json_init_array (&vam->json_tree);
10644     }
10645   node = vat_json_array_add (&vam->json_tree);
10646
10647   vat_json_init_object (node);
10648   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10649   if (mp->is_ipv6)
10650     {
10651       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10652       vat_json_object_add_ip6 (node, "local", ip6);
10653       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10654       vat_json_object_add_ip6 (node, "remote", ip6);
10655     }
10656   else
10657     {
10658       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10659       vat_json_object_add_ip4 (node, "local", ip4);
10660       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10661       vat_json_object_add_ip4 (node, "remote", ip4);
10662     }
10663   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10664   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10665   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10666   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10667   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10668 }
10669
10670 static int
10671 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10672 {
10673   unformat_input_t *i = vam->input;
10674   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10675   f64 timeout;
10676   u32 sw_if_index;
10677   u8 sw_if_index_set = 0;
10678
10679   /* Parse args required to build the message */
10680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10681     {
10682       if (unformat (i, "sw_if_index %d", &sw_if_index))
10683         sw_if_index_set = 1;
10684       else
10685         break;
10686     }
10687
10688   if (sw_if_index_set == 0)
10689     {
10690       sw_if_index = ~0;
10691     }
10692
10693   if (!vam->json_output)
10694     {
10695       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10696                "sw_if_index", "local", "remote", "vni",
10697                "protocol", "encap_vrf_id", "decap_vrf_id");
10698     }
10699
10700   /* Get list of vxlan-tunnel interfaces */
10701   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10702
10703   mp->sw_if_index = htonl (sw_if_index);
10704
10705   S;
10706
10707   /* Use a control ping for synchronization */
10708   {
10709     vl_api_control_ping_t *mp;
10710     M (CONTROL_PING, control_ping);
10711     S;
10712   }
10713   W;
10714 }
10715
10716 u8 *
10717 format_l2_fib_mac_address (u8 * s, va_list * args)
10718 {
10719   u8 *a = va_arg (*args, u8 *);
10720
10721   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10722                  a[2], a[3], a[4], a[5], a[6], a[7]);
10723 }
10724
10725 static void vl_api_l2_fib_table_entry_t_handler
10726   (vl_api_l2_fib_table_entry_t * mp)
10727 {
10728   vat_main_t *vam = &vat_main;
10729
10730   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10731            "       %d       %d     %d\n",
10732            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10733            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10734            mp->bvi_mac);
10735 }
10736
10737 static void vl_api_l2_fib_table_entry_t_handler_json
10738   (vl_api_l2_fib_table_entry_t * mp)
10739 {
10740   vat_main_t *vam = &vat_main;
10741   vat_json_node_t *node = NULL;
10742
10743   if (VAT_JSON_ARRAY != vam->json_tree.type)
10744     {
10745       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10746       vat_json_init_array (&vam->json_tree);
10747     }
10748   node = vat_json_array_add (&vam->json_tree);
10749
10750   vat_json_init_object (node);
10751   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10752   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10753   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10754   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10755   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10756   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10757 }
10758
10759 static int
10760 api_l2_fib_table_dump (vat_main_t * vam)
10761 {
10762   unformat_input_t *i = vam->input;
10763   vl_api_l2_fib_table_dump_t *mp;
10764   f64 timeout;
10765   u32 bd_id;
10766   u8 bd_id_set = 0;
10767
10768   /* Parse args required to build the message */
10769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (i, "bd_id %d", &bd_id))
10772         bd_id_set = 1;
10773       else
10774         break;
10775     }
10776
10777   if (bd_id_set == 0)
10778     {
10779       errmsg ("missing bridge domain\n");
10780       return -99;
10781     }
10782
10783   fformat (vam->ofp,
10784            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10785
10786   /* Get list of l2 fib entries */
10787   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10788
10789   mp->bd_id = ntohl (bd_id);
10790   S;
10791
10792   /* Use a control ping for synchronization */
10793   {
10794     vl_api_control_ping_t *mp;
10795     M (CONTROL_PING, control_ping);
10796     S;
10797   }
10798   W;
10799 }
10800
10801
10802 static int
10803 api_interface_name_renumber (vat_main_t * vam)
10804 {
10805   unformat_input_t *line_input = vam->input;
10806   vl_api_interface_name_renumber_t *mp;
10807   u32 sw_if_index = ~0;
10808   f64 timeout;
10809   u32 new_show_dev_instance = ~0;
10810
10811   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10812     {
10813       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10814                     &sw_if_index))
10815         ;
10816       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10817         ;
10818       else if (unformat (line_input, "new_show_dev_instance %d",
10819                          &new_show_dev_instance))
10820         ;
10821       else
10822         break;
10823     }
10824
10825   if (sw_if_index == ~0)
10826     {
10827       errmsg ("missing interface name or sw_if_index\n");
10828       return -99;
10829     }
10830
10831   if (new_show_dev_instance == ~0)
10832     {
10833       errmsg ("missing new_show_dev_instance\n");
10834       return -99;
10835     }
10836
10837   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10838
10839   mp->sw_if_index = ntohl (sw_if_index);
10840   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10841
10842   S;
10843   W;
10844 }
10845
10846 static int
10847 api_want_ip4_arp_events (vat_main_t * vam)
10848 {
10849   unformat_input_t *line_input = vam->input;
10850   vl_api_want_ip4_arp_events_t *mp;
10851   f64 timeout;
10852   ip4_address_t address;
10853   int address_set = 0;
10854   u32 enable_disable = 1;
10855
10856   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10857     {
10858       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10859         address_set = 1;
10860       else if (unformat (line_input, "del"))
10861         enable_disable = 0;
10862       else
10863         break;
10864     }
10865
10866   if (address_set == 0)
10867     {
10868       errmsg ("missing addresses\n");
10869       return -99;
10870     }
10871
10872   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10873   mp->enable_disable = enable_disable;
10874   mp->pid = getpid ();
10875   mp->address = address.as_u32;
10876
10877   S;
10878   W;
10879 }
10880
10881 static int
10882 api_want_ip6_nd_events (vat_main_t * vam)
10883 {
10884   unformat_input_t *line_input = vam->input;
10885   vl_api_want_ip6_nd_events_t *mp;
10886   f64 timeout;
10887   ip6_address_t address;
10888   int address_set = 0;
10889   u32 enable_disable = 1;
10890
10891   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10892     {
10893       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10894         address_set = 1;
10895       else if (unformat (line_input, "del"))
10896         enable_disable = 0;
10897       else
10898         break;
10899     }
10900
10901   if (address_set == 0)
10902     {
10903       errmsg ("missing addresses\n");
10904       return -99;
10905     }
10906
10907   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10908   mp->enable_disable = enable_disable;
10909   mp->pid = getpid ();
10910   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10911
10912   S;
10913   W;
10914 }
10915
10916 static int
10917 api_input_acl_set_interface (vat_main_t * vam)
10918 {
10919   unformat_input_t *i = vam->input;
10920   vl_api_input_acl_set_interface_t *mp;
10921   f64 timeout;
10922   u32 sw_if_index;
10923   int sw_if_index_set;
10924   u32 ip4_table_index = ~0;
10925   u32 ip6_table_index = ~0;
10926   u32 l2_table_index = ~0;
10927   u8 is_add = 1;
10928
10929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10930     {
10931       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10932         sw_if_index_set = 1;
10933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10934         sw_if_index_set = 1;
10935       else if (unformat (i, "del"))
10936         is_add = 0;
10937       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10938         ;
10939       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10940         ;
10941       else if (unformat (i, "l2-table %d", &l2_table_index))
10942         ;
10943       else
10944         {
10945           clib_warning ("parse error '%U'", format_unformat_error, i);
10946           return -99;
10947         }
10948     }
10949
10950   if (sw_if_index_set == 0)
10951     {
10952       errmsg ("missing interface name or sw_if_index\n");
10953       return -99;
10954     }
10955
10956   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10957
10958   mp->sw_if_index = ntohl (sw_if_index);
10959   mp->ip4_table_index = ntohl (ip4_table_index);
10960   mp->ip6_table_index = ntohl (ip6_table_index);
10961   mp->l2_table_index = ntohl (l2_table_index);
10962   mp->is_add = is_add;
10963
10964   S;
10965   W;
10966   /* NOTREACHED */
10967   return 0;
10968 }
10969
10970 static int
10971 api_ip_address_dump (vat_main_t * vam)
10972 {
10973   unformat_input_t *i = vam->input;
10974   vl_api_ip_address_dump_t *mp;
10975   u32 sw_if_index = ~0;
10976   u8 sw_if_index_set = 0;
10977   u8 ipv4_set = 0;
10978   u8 ipv6_set = 0;
10979   f64 timeout;
10980
10981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10982     {
10983       if (unformat (i, "sw_if_index %d", &sw_if_index))
10984         sw_if_index_set = 1;
10985       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10986         sw_if_index_set = 1;
10987       else if (unformat (i, "ipv4"))
10988         ipv4_set = 1;
10989       else if (unformat (i, "ipv6"))
10990         ipv6_set = 1;
10991       else
10992         break;
10993     }
10994
10995   if (ipv4_set && ipv6_set)
10996     {
10997       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10998       return -99;
10999     }
11000
11001   if ((!ipv4_set) && (!ipv6_set))
11002     {
11003       errmsg ("no ipv4 nor ipv6 flag set\n");
11004       return -99;
11005     }
11006
11007   if (sw_if_index_set == 0)
11008     {
11009       errmsg ("missing interface name or sw_if_index\n");
11010       return -99;
11011     }
11012
11013   vam->current_sw_if_index = sw_if_index;
11014   vam->is_ipv6 = ipv6_set;
11015
11016   M (IP_ADDRESS_DUMP, ip_address_dump);
11017   mp->sw_if_index = ntohl (sw_if_index);
11018   mp->is_ipv6 = ipv6_set;
11019   S;
11020
11021   /* Use a control ping for synchronization */
11022   {
11023     vl_api_control_ping_t *mp;
11024     M (CONTROL_PING, control_ping);
11025     S;
11026   }
11027   W;
11028 }
11029
11030 static int
11031 api_ip_dump (vat_main_t * vam)
11032 {
11033   vl_api_ip_dump_t *mp;
11034   unformat_input_t *in = vam->input;
11035   int ipv4_set = 0;
11036   int ipv6_set = 0;
11037   int is_ipv6;
11038   f64 timeout;
11039   int i;
11040
11041   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11042     {
11043       if (unformat (in, "ipv4"))
11044         ipv4_set = 1;
11045       else if (unformat (in, "ipv6"))
11046         ipv6_set = 1;
11047       else
11048         break;
11049     }
11050
11051   if (ipv4_set && ipv6_set)
11052     {
11053       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11054       return -99;
11055     }
11056
11057   if ((!ipv4_set) && (!ipv6_set))
11058     {
11059       errmsg ("no ipv4 nor ipv6 flag set\n");
11060       return -99;
11061     }
11062
11063   is_ipv6 = ipv6_set;
11064   vam->is_ipv6 = is_ipv6;
11065
11066   /* free old data */
11067   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11068     {
11069       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11070     }
11071   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11072
11073   M (IP_DUMP, ip_dump);
11074   mp->is_ipv6 = ipv6_set;
11075   S;
11076
11077   /* Use a control ping for synchronization */
11078   {
11079     vl_api_control_ping_t *mp;
11080     M (CONTROL_PING, control_ping);
11081     S;
11082   }
11083   W;
11084 }
11085
11086 static int
11087 api_ipsec_spd_add_del (vat_main_t * vam)
11088 {
11089 #if DPDK > 0
11090   unformat_input_t *i = vam->input;
11091   vl_api_ipsec_spd_add_del_t *mp;
11092   f64 timeout;
11093   u32 spd_id = ~0;
11094   u8 is_add = 1;
11095
11096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11097     {
11098       if (unformat (i, "spd_id %d", &spd_id))
11099         ;
11100       else if (unformat (i, "del"))
11101         is_add = 0;
11102       else
11103         {
11104           clib_warning ("parse error '%U'", format_unformat_error, i);
11105           return -99;
11106         }
11107     }
11108   if (spd_id == ~0)
11109     {
11110       errmsg ("spd_id must be set\n");
11111       return -99;
11112     }
11113
11114   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11115
11116   mp->spd_id = ntohl (spd_id);
11117   mp->is_add = is_add;
11118
11119   S;
11120   W;
11121   /* NOTREACHED */
11122   return 0;
11123 #else
11124   clib_warning ("unsupported (no dpdk)");
11125   return -99;
11126 #endif
11127 }
11128
11129 static int
11130 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11131 {
11132 #if DPDK > 0
11133   unformat_input_t *i = vam->input;
11134   vl_api_ipsec_interface_add_del_spd_t *mp;
11135   f64 timeout;
11136   u32 sw_if_index;
11137   u8 sw_if_index_set = 0;
11138   u32 spd_id = (u32) ~ 0;
11139   u8 is_add = 1;
11140
11141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11142     {
11143       if (unformat (i, "del"))
11144         is_add = 0;
11145       else if (unformat (i, "spd_id %d", &spd_id))
11146         ;
11147       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11148         sw_if_index_set = 1;
11149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11150         sw_if_index_set = 1;
11151       else
11152         {
11153           clib_warning ("parse error '%U'", format_unformat_error, i);
11154           return -99;
11155         }
11156
11157     }
11158
11159   if (spd_id == (u32) ~ 0)
11160     {
11161       errmsg ("spd_id must be set\n");
11162       return -99;
11163     }
11164
11165   if (sw_if_index_set == 0)
11166     {
11167       errmsg ("missing interface name or sw_if_index\n");
11168       return -99;
11169     }
11170
11171   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11172
11173   mp->spd_id = ntohl (spd_id);
11174   mp->sw_if_index = ntohl (sw_if_index);
11175   mp->is_add = is_add;
11176
11177   S;
11178   W;
11179   /* NOTREACHED */
11180   return 0;
11181 #else
11182   clib_warning ("unsupported (no dpdk)");
11183   return -99;
11184 #endif
11185 }
11186
11187 static int
11188 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11189 {
11190 #if DPDK > 0
11191   unformat_input_t *i = vam->input;
11192   vl_api_ipsec_spd_add_del_entry_t *mp;
11193   f64 timeout;
11194   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11195   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11196   i32 priority = 0;
11197   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11198   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11199   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11200   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11201
11202   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11203   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11204   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11205   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11206   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11207   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11208
11209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11210     {
11211       if (unformat (i, "del"))
11212         is_add = 0;
11213       if (unformat (i, "outbound"))
11214         is_outbound = 1;
11215       if (unformat (i, "inbound"))
11216         is_outbound = 0;
11217       else if (unformat (i, "spd_id %d", &spd_id))
11218         ;
11219       else if (unformat (i, "sa_id %d", &sa_id))
11220         ;
11221       else if (unformat (i, "priority %d", &priority))
11222         ;
11223       else if (unformat (i, "protocol %d", &protocol))
11224         ;
11225       else if (unformat (i, "lport_start %d", &lport_start))
11226         ;
11227       else if (unformat (i, "lport_stop %d", &lport_stop))
11228         ;
11229       else if (unformat (i, "rport_start %d", &rport_start))
11230         ;
11231       else if (unformat (i, "rport_stop %d", &rport_stop))
11232         ;
11233       else
11234         if (unformat
11235             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11236         {
11237           is_ipv6 = 0;
11238           is_ip_any = 0;
11239         }
11240       else
11241         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11242         {
11243           is_ipv6 = 0;
11244           is_ip_any = 0;
11245         }
11246       else
11247         if (unformat
11248             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11249         {
11250           is_ipv6 = 0;
11251           is_ip_any = 0;
11252         }
11253       else
11254         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11255         {
11256           is_ipv6 = 0;
11257           is_ip_any = 0;
11258         }
11259       else
11260         if (unformat
11261             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11262         {
11263           is_ipv6 = 1;
11264           is_ip_any = 0;
11265         }
11266       else
11267         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11268         {
11269           is_ipv6 = 1;
11270           is_ip_any = 0;
11271         }
11272       else
11273         if (unformat
11274             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11275         {
11276           is_ipv6 = 1;
11277           is_ip_any = 0;
11278         }
11279       else
11280         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11281         {
11282           is_ipv6 = 1;
11283           is_ip_any = 0;
11284         }
11285       else
11286         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11287         {
11288           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11289             {
11290               clib_warning ("unsupported action: 'resolve'");
11291               return -99;
11292             }
11293         }
11294       else
11295         {
11296           clib_warning ("parse error '%U'", format_unformat_error, i);
11297           return -99;
11298         }
11299
11300     }
11301
11302   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11303
11304   mp->spd_id = ntohl (spd_id);
11305   mp->priority = ntohl (priority);
11306   mp->is_outbound = is_outbound;
11307
11308   mp->is_ipv6 = is_ipv6;
11309   if (is_ipv6 || is_ip_any)
11310     {
11311       clib_memcpy (mp->remote_address_start, &raddr6_start,
11312                    sizeof (ip6_address_t));
11313       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11314                    sizeof (ip6_address_t));
11315       clib_memcpy (mp->local_address_start, &laddr6_start,
11316                    sizeof (ip6_address_t));
11317       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11318                    sizeof (ip6_address_t));
11319     }
11320   else
11321     {
11322       clib_memcpy (mp->remote_address_start, &raddr4_start,
11323                    sizeof (ip4_address_t));
11324       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11325                    sizeof (ip4_address_t));
11326       clib_memcpy (mp->local_address_start, &laddr4_start,
11327                    sizeof (ip4_address_t));
11328       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11329                    sizeof (ip4_address_t));
11330     }
11331   mp->protocol = (u8) protocol;
11332   mp->local_port_start = ntohs ((u16) lport_start);
11333   mp->local_port_stop = ntohs ((u16) lport_stop);
11334   mp->remote_port_start = ntohs ((u16) rport_start);
11335   mp->remote_port_stop = ntohs ((u16) rport_stop);
11336   mp->policy = (u8) policy;
11337   mp->sa_id = ntohl (sa_id);
11338   mp->is_add = is_add;
11339   mp->is_ip_any = is_ip_any;
11340   S;
11341   W;
11342   /* NOTREACHED */
11343   return 0;
11344 #else
11345   clib_warning ("unsupported (no dpdk)");
11346   return -99;
11347 #endif
11348 }
11349
11350 static int
11351 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11352 {
11353 #if DPDK > 0
11354   unformat_input_t *i = vam->input;
11355   vl_api_ipsec_sad_add_del_entry_t *mp;
11356   f64 timeout;
11357   u32 sad_id = 0, spi = 0;
11358   u8 *ck = 0, *ik = 0;
11359   u8 is_add = 1;
11360
11361   u8 protocol = IPSEC_PROTOCOL_AH;
11362   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11363   u32 crypto_alg = 0, integ_alg = 0;
11364   ip4_address_t tun_src4;
11365   ip4_address_t tun_dst4;
11366   ip6_address_t tun_src6;
11367   ip6_address_t tun_dst6;
11368
11369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11370     {
11371       if (unformat (i, "del"))
11372         is_add = 0;
11373       else if (unformat (i, "sad_id %d", &sad_id))
11374         ;
11375       else if (unformat (i, "spi %d", &spi))
11376         ;
11377       else if (unformat (i, "esp"))
11378         protocol = IPSEC_PROTOCOL_ESP;
11379       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11380         {
11381           is_tunnel = 1;
11382           is_tunnel_ipv6 = 0;
11383         }
11384       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11385         {
11386           is_tunnel = 1;
11387           is_tunnel_ipv6 = 0;
11388         }
11389       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11390         {
11391           is_tunnel = 1;
11392           is_tunnel_ipv6 = 1;
11393         }
11394       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11395         {
11396           is_tunnel = 1;
11397           is_tunnel_ipv6 = 1;
11398         }
11399       else
11400         if (unformat
11401             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11402         {
11403           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11404               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11405             {
11406               clib_warning ("unsupported crypto-alg: '%U'",
11407                             format_ipsec_crypto_alg, crypto_alg);
11408               return -99;
11409             }
11410         }
11411       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11412         ;
11413       else
11414         if (unformat
11415             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11416         {
11417           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11418               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11419             {
11420               clib_warning ("unsupported integ-alg: '%U'",
11421                             format_ipsec_integ_alg, integ_alg);
11422               return -99;
11423             }
11424         }
11425       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11426         ;
11427       else
11428         {
11429           clib_warning ("parse error '%U'", format_unformat_error, i);
11430           return -99;
11431         }
11432
11433     }
11434
11435   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11436
11437   mp->sad_id = ntohl (sad_id);
11438   mp->is_add = is_add;
11439   mp->protocol = protocol;
11440   mp->spi = ntohl (spi);
11441   mp->is_tunnel = is_tunnel;
11442   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11443   mp->crypto_algorithm = crypto_alg;
11444   mp->integrity_algorithm = integ_alg;
11445   mp->crypto_key_length = vec_len (ck);
11446   mp->integrity_key_length = vec_len (ik);
11447
11448   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11449     mp->crypto_key_length = sizeof (mp->crypto_key);
11450
11451   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11452     mp->integrity_key_length = sizeof (mp->integrity_key);
11453
11454   if (ck)
11455     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11456   if (ik)
11457     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11458
11459   if (is_tunnel)
11460     {
11461       if (is_tunnel_ipv6)
11462         {
11463           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11464                        sizeof (ip6_address_t));
11465           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11466                        sizeof (ip6_address_t));
11467         }
11468       else
11469         {
11470           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11471                        sizeof (ip4_address_t));
11472           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11473                        sizeof (ip4_address_t));
11474         }
11475     }
11476
11477   S;
11478   W;
11479   /* NOTREACHED */
11480   return 0;
11481 #else
11482   clib_warning ("unsupported (no dpdk)");
11483   return -99;
11484 #endif
11485 }
11486
11487 static int
11488 api_ipsec_sa_set_key (vat_main_t * vam)
11489 {
11490 #if DPDK > 0
11491   unformat_input_t *i = vam->input;
11492   vl_api_ipsec_sa_set_key_t *mp;
11493   f64 timeout;
11494   u32 sa_id;
11495   u8 *ck = 0, *ik = 0;
11496
11497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11498     {
11499       if (unformat (i, "sa_id %d", &sa_id))
11500         ;
11501       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11502         ;
11503       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11504         ;
11505       else
11506         {
11507           clib_warning ("parse error '%U'", format_unformat_error, i);
11508           return -99;
11509         }
11510     }
11511
11512   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11513
11514   mp->sa_id = ntohl (sa_id);
11515   mp->crypto_key_length = vec_len (ck);
11516   mp->integrity_key_length = vec_len (ik);
11517
11518   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11519     mp->crypto_key_length = sizeof (mp->crypto_key);
11520
11521   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11522     mp->integrity_key_length = sizeof (mp->integrity_key);
11523
11524   if (ck)
11525     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11526   if (ik)
11527     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11528
11529   S;
11530   W;
11531   /* NOTREACHED */
11532   return 0;
11533 #else
11534   clib_warning ("unsupported (no dpdk)");
11535   return -99;
11536 #endif
11537 }
11538
11539 static int
11540 api_ikev2_profile_add_del (vat_main_t * vam)
11541 {
11542 #if DPDK > 0
11543   unformat_input_t *i = vam->input;
11544   vl_api_ikev2_profile_add_del_t *mp;
11545   f64 timeout;
11546   u8 is_add = 1;
11547   u8 *name = 0;
11548
11549   const char *valid_chars = "a-zA-Z0-9_";
11550
11551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11552     {
11553       if (unformat (i, "del"))
11554         is_add = 0;
11555       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11556         vec_add1 (name, 0);
11557       else
11558         {
11559           errmsg ("parse error '%U'", format_unformat_error, i);
11560           return -99;
11561         }
11562     }
11563
11564   if (!vec_len (name))
11565     {
11566       errmsg ("profile name must be specified");
11567       return -99;
11568     }
11569
11570   if (vec_len (name) > 64)
11571     {
11572       errmsg ("profile name too long");
11573       return -99;
11574     }
11575
11576   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11577
11578   clib_memcpy (mp->name, name, vec_len (name));
11579   mp->is_add = is_add;
11580   vec_free (name);
11581
11582   S;
11583   W;
11584   /* NOTREACHED */
11585   return 0;
11586 #else
11587   clib_warning ("unsupported (no dpdk)");
11588   return -99;
11589 #endif
11590 }
11591
11592 static int
11593 api_ikev2_profile_set_auth (vat_main_t * vam)
11594 {
11595 #if DPDK > 0
11596   unformat_input_t *i = vam->input;
11597   vl_api_ikev2_profile_set_auth_t *mp;
11598   f64 timeout;
11599   u8 *name = 0;
11600   u8 *data = 0;
11601   u32 auth_method = 0;
11602   u8 is_hex = 0;
11603
11604   const char *valid_chars = "a-zA-Z0-9_";
11605
11606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11607     {
11608       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11609         vec_add1 (name, 0);
11610       else if (unformat (i, "auth_method %U",
11611                          unformat_ikev2_auth_method, &auth_method))
11612         ;
11613       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11614         is_hex = 1;
11615       else if (unformat (i, "auth_data %v", &data))
11616         ;
11617       else
11618         {
11619           errmsg ("parse error '%U'", format_unformat_error, i);
11620           return -99;
11621         }
11622     }
11623
11624   if (!vec_len (name))
11625     {
11626       errmsg ("profile name must be specified");
11627       return -99;
11628     }
11629
11630   if (vec_len (name) > 64)
11631     {
11632       errmsg ("profile name too long");
11633       return -99;
11634     }
11635
11636   if (!vec_len (data))
11637     {
11638       errmsg ("auth_data must be specified");
11639       return -99;
11640     }
11641
11642   if (!auth_method)
11643     {
11644       errmsg ("auth_method must be specified");
11645       return -99;
11646     }
11647
11648   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11649
11650   mp->is_hex = is_hex;
11651   mp->auth_method = (u8) auth_method;
11652   mp->data_len = vec_len (data);
11653   clib_memcpy (mp->name, name, vec_len (name));
11654   clib_memcpy (mp->data, data, vec_len (data));
11655   vec_free (name);
11656   vec_free (data);
11657
11658   S;
11659   W;
11660   /* NOTREACHED */
11661   return 0;
11662 #else
11663   clib_warning ("unsupported (no dpdk)");
11664   return -99;
11665 #endif
11666 }
11667
11668 static int
11669 api_ikev2_profile_set_id (vat_main_t * vam)
11670 {
11671 #if DPDK > 0
11672   unformat_input_t *i = vam->input;
11673   vl_api_ikev2_profile_set_id_t *mp;
11674   f64 timeout;
11675   u8 *name = 0;
11676   u8 *data = 0;
11677   u8 is_local = 0;
11678   u32 id_type = 0;
11679   ip4_address_t ip4;
11680
11681   const char *valid_chars = "a-zA-Z0-9_";
11682
11683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11684     {
11685       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11686         vec_add1 (name, 0);
11687       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11688         ;
11689       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11690         {
11691           data = vec_new (u8, 4);
11692           clib_memcpy (data, ip4.as_u8, 4);
11693         }
11694       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11695         ;
11696       else if (unformat (i, "id_data %v", &data))
11697         ;
11698       else if (unformat (i, "local"))
11699         is_local = 1;
11700       else if (unformat (i, "remote"))
11701         is_local = 0;
11702       else
11703         {
11704           errmsg ("parse error '%U'", format_unformat_error, i);
11705           return -99;
11706         }
11707     }
11708
11709   if (!vec_len (name))
11710     {
11711       errmsg ("profile name must be specified");
11712       return -99;
11713     }
11714
11715   if (vec_len (name) > 64)
11716     {
11717       errmsg ("profile name too long");
11718       return -99;
11719     }
11720
11721   if (!vec_len (data))
11722     {
11723       errmsg ("id_data must be specified");
11724       return -99;
11725     }
11726
11727   if (!id_type)
11728     {
11729       errmsg ("id_type must be specified");
11730       return -99;
11731     }
11732
11733   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11734
11735   mp->is_local = is_local;
11736   mp->id_type = (u8) id_type;
11737   mp->data_len = vec_len (data);
11738   clib_memcpy (mp->name, name, vec_len (name));
11739   clib_memcpy (mp->data, data, vec_len (data));
11740   vec_free (name);
11741   vec_free (data);
11742
11743   S;
11744   W;
11745   /* NOTREACHED */
11746   return 0;
11747 #else
11748   clib_warning ("unsupported (no dpdk)");
11749   return -99;
11750 #endif
11751 }
11752
11753 static int
11754 api_ikev2_profile_set_ts (vat_main_t * vam)
11755 {
11756 #if DPDK > 0
11757   unformat_input_t *i = vam->input;
11758   vl_api_ikev2_profile_set_ts_t *mp;
11759   f64 timeout;
11760   u8 *name = 0;
11761   u8 is_local = 0;
11762   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11763   ip4_address_t start_addr, end_addr;
11764
11765   const char *valid_chars = "a-zA-Z0-9_";
11766
11767   start_addr.as_u32 = 0;
11768   end_addr.as_u32 = (u32) ~ 0;
11769
11770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11771     {
11772       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11773         vec_add1 (name, 0);
11774       else if (unformat (i, "protocol %d", &proto))
11775         ;
11776       else if (unformat (i, "start_port %d", &start_port))
11777         ;
11778       else if (unformat (i, "end_port %d", &end_port))
11779         ;
11780       else
11781         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11782         ;
11783       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11784         ;
11785       else if (unformat (i, "local"))
11786         is_local = 1;
11787       else if (unformat (i, "remote"))
11788         is_local = 0;
11789       else
11790         {
11791           errmsg ("parse error '%U'", format_unformat_error, i);
11792           return -99;
11793         }
11794     }
11795
11796   if (!vec_len (name))
11797     {
11798       errmsg ("profile name must be specified");
11799       return -99;
11800     }
11801
11802   if (vec_len (name) > 64)
11803     {
11804       errmsg ("profile name too long");
11805       return -99;
11806     }
11807
11808   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11809
11810   mp->is_local = is_local;
11811   mp->proto = (u8) proto;
11812   mp->start_port = (u16) start_port;
11813   mp->end_port = (u16) end_port;
11814   mp->start_addr = start_addr.as_u32;
11815   mp->end_addr = end_addr.as_u32;
11816   clib_memcpy (mp->name, name, vec_len (name));
11817   vec_free (name);
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_set_local_key (vat_main_t * vam)
11831 {
11832 #if DPDK > 0
11833   unformat_input_t *i = vam->input;
11834   vl_api_ikev2_set_local_key_t *mp;
11835   f64 timeout;
11836   u8 *file = 0;
11837
11838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11839     {
11840       if (unformat (i, "file %v", &file))
11841         vec_add1 (file, 0);
11842       else
11843         {
11844           errmsg ("parse error '%U'", format_unformat_error, i);
11845           return -99;
11846         }
11847     }
11848
11849   if (!vec_len (file))
11850     {
11851       errmsg ("RSA key file must be specified");
11852       return -99;
11853     }
11854
11855   if (vec_len (file) > 256)
11856     {
11857       errmsg ("file name too long");
11858       return -99;
11859     }
11860
11861   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11862
11863   clib_memcpy (mp->key_file, file, vec_len (file));
11864   vec_free (file);
11865
11866   S;
11867   W;
11868   /* NOTREACHED */
11869   return 0;
11870 #else
11871   clib_warning ("unsupported (no dpdk)");
11872   return -99;
11873 #endif
11874 }
11875
11876 /*
11877  * MAP
11878  */
11879 static int
11880 api_map_add_domain (vat_main_t * vam)
11881 {
11882   unformat_input_t *i = vam->input;
11883   vl_api_map_add_domain_t *mp;
11884   f64 timeout;
11885
11886   ip4_address_t ip4_prefix;
11887   ip6_address_t ip6_prefix;
11888   ip6_address_t ip6_src;
11889   u32 num_m_args = 0;
11890   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11891     0, psid_length = 0;
11892   u8 is_translation = 0;
11893   u32 mtu = 0;
11894   u32 ip6_src_len = 128;
11895
11896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11897     {
11898       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11899                     &ip4_prefix, &ip4_prefix_len))
11900         num_m_args++;
11901       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11902                          &ip6_prefix, &ip6_prefix_len))
11903         num_m_args++;
11904       else
11905         if (unformat
11906             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11907              &ip6_src_len))
11908         num_m_args++;
11909       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11910         num_m_args++;
11911       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11912         num_m_args++;
11913       else if (unformat (i, "psid-offset %d", &psid_offset))
11914         num_m_args++;
11915       else if (unformat (i, "psid-len %d", &psid_length))
11916         num_m_args++;
11917       else if (unformat (i, "mtu %d", &mtu))
11918         num_m_args++;
11919       else if (unformat (i, "map-t"))
11920         is_translation = 1;
11921       else
11922         {
11923           clib_warning ("parse error '%U'", format_unformat_error, i);
11924           return -99;
11925         }
11926     }
11927
11928   if (num_m_args < 3)
11929     {
11930       errmsg ("mandatory argument(s) missing\n");
11931       return -99;
11932     }
11933
11934   /* Construct the API message */
11935   M (MAP_ADD_DOMAIN, map_add_domain);
11936
11937   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11938   mp->ip4_prefix_len = ip4_prefix_len;
11939
11940   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11941   mp->ip6_prefix_len = ip6_prefix_len;
11942
11943   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11944   mp->ip6_src_prefix_len = ip6_src_len;
11945
11946   mp->ea_bits_len = ea_bits_len;
11947   mp->psid_offset = psid_offset;
11948   mp->psid_length = psid_length;
11949   mp->is_translation = is_translation;
11950   mp->mtu = htons (mtu);
11951
11952   /* send it... */
11953   S;
11954
11955   /* Wait for a reply, return good/bad news  */
11956   W;
11957 }
11958
11959 static int
11960 api_map_del_domain (vat_main_t * vam)
11961 {
11962   unformat_input_t *i = vam->input;
11963   vl_api_map_del_domain_t *mp;
11964   f64 timeout;
11965
11966   u32 num_m_args = 0;
11967   u32 index;
11968
11969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11970     {
11971       if (unformat (i, "index %d", &index))
11972         num_m_args++;
11973       else
11974         {
11975           clib_warning ("parse error '%U'", format_unformat_error, i);
11976           return -99;
11977         }
11978     }
11979
11980   if (num_m_args != 1)
11981     {
11982       errmsg ("mandatory argument(s) missing\n");
11983       return -99;
11984     }
11985
11986   /* Construct the API message */
11987   M (MAP_DEL_DOMAIN, map_del_domain);
11988
11989   mp->index = ntohl (index);
11990
11991   /* send it... */
11992   S;
11993
11994   /* Wait for a reply, return good/bad news  */
11995   W;
11996 }
11997
11998 static int
11999 api_map_add_del_rule (vat_main_t * vam)
12000 {
12001   unformat_input_t *i = vam->input;
12002   vl_api_map_add_del_rule_t *mp;
12003   f64 timeout;
12004   u8 is_add = 1;
12005   ip6_address_t ip6_dst;
12006   u32 num_m_args = 0, index, psid = 0;
12007
12008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12009     {
12010       if (unformat (i, "index %d", &index))
12011         num_m_args++;
12012       else if (unformat (i, "psid %d", &psid))
12013         num_m_args++;
12014       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12015         num_m_args++;
12016       else if (unformat (i, "del"))
12017         {
12018           is_add = 0;
12019         }
12020       else
12021         {
12022           clib_warning ("parse error '%U'", format_unformat_error, i);
12023           return -99;
12024         }
12025     }
12026
12027   /* Construct the API message */
12028   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12029
12030   mp->index = ntohl (index);
12031   mp->is_add = is_add;
12032   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12033   mp->psid = ntohs (psid);
12034
12035   /* send it... */
12036   S;
12037
12038   /* Wait for a reply, return good/bad news  */
12039   W;
12040 }
12041
12042 static int
12043 api_map_domain_dump (vat_main_t * vam)
12044 {
12045   vl_api_map_domain_dump_t *mp;
12046   f64 timeout;
12047
12048   /* Construct the API message */
12049   M (MAP_DOMAIN_DUMP, map_domain_dump);
12050
12051   /* send it... */
12052   S;
12053
12054   /* Use a control ping for synchronization */
12055   {
12056     vl_api_control_ping_t *mp;
12057     M (CONTROL_PING, control_ping);
12058     S;
12059   }
12060   W;
12061 }
12062
12063 static int
12064 api_map_rule_dump (vat_main_t * vam)
12065 {
12066   unformat_input_t *i = vam->input;
12067   vl_api_map_rule_dump_t *mp;
12068   f64 timeout;
12069   u32 domain_index = ~0;
12070
12071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12072     {
12073       if (unformat (i, "index %u", &domain_index))
12074         ;
12075       else
12076         break;
12077     }
12078
12079   if (domain_index == ~0)
12080     {
12081       clib_warning ("parse error: domain index expected");
12082       return -99;
12083     }
12084
12085   /* Construct the API message */
12086   M (MAP_RULE_DUMP, map_rule_dump);
12087
12088   mp->domain_index = htonl (domain_index);
12089
12090   /* send it... */
12091   S;
12092
12093   /* Use a control ping for synchronization */
12094   {
12095     vl_api_control_ping_t *mp;
12096     M (CONTROL_PING, control_ping);
12097     S;
12098   }
12099   W;
12100 }
12101
12102 static void vl_api_map_add_domain_reply_t_handler
12103   (vl_api_map_add_domain_reply_t * mp)
12104 {
12105   vat_main_t *vam = &vat_main;
12106   i32 retval = ntohl (mp->retval);
12107
12108   if (vam->async_mode)
12109     {
12110       vam->async_errors += (retval < 0);
12111     }
12112   else
12113     {
12114       vam->retval = retval;
12115       vam->result_ready = 1;
12116     }
12117 }
12118
12119 static void vl_api_map_add_domain_reply_t_handler_json
12120   (vl_api_map_add_domain_reply_t * mp)
12121 {
12122   vat_main_t *vam = &vat_main;
12123   vat_json_node_t node;
12124
12125   vat_json_init_object (&node);
12126   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12127   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12128
12129   vat_json_print (vam->ofp, &node);
12130   vat_json_free (&node);
12131
12132   vam->retval = ntohl (mp->retval);
12133   vam->result_ready = 1;
12134 }
12135
12136 static int
12137 api_get_first_msg_id (vat_main_t * vam)
12138 {
12139   vl_api_get_first_msg_id_t *mp;
12140   f64 timeout;
12141   unformat_input_t *i = vam->input;
12142   u8 *name;
12143   u8 name_set = 0;
12144
12145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12146     {
12147       if (unformat (i, "client %s", &name))
12148         name_set = 1;
12149       else
12150         break;
12151     }
12152
12153   if (name_set == 0)
12154     {
12155       errmsg ("missing client name\n");
12156       return -99;
12157     }
12158   vec_add1 (name, 0);
12159
12160   if (vec_len (name) > 63)
12161     {
12162       errmsg ("client name too long\n");
12163       return -99;
12164     }
12165
12166   M (GET_FIRST_MSG_ID, get_first_msg_id);
12167   clib_memcpy (mp->name, name, vec_len (name));
12168   S;
12169   W;
12170   /* NOTREACHED */
12171   return 0;
12172 }
12173
12174 static int
12175 api_cop_interface_enable_disable (vat_main_t * vam)
12176 {
12177   unformat_input_t *line_input = vam->input;
12178   vl_api_cop_interface_enable_disable_t *mp;
12179   f64 timeout;
12180   u32 sw_if_index = ~0;
12181   u8 enable_disable = 1;
12182
12183   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12184     {
12185       if (unformat (line_input, "disable"))
12186         enable_disable = 0;
12187       if (unformat (line_input, "enable"))
12188         enable_disable = 1;
12189       else if (unformat (line_input, "%U", unformat_sw_if_index,
12190                          vam, &sw_if_index))
12191         ;
12192       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12193         ;
12194       else
12195         break;
12196     }
12197
12198   if (sw_if_index == ~0)
12199     {
12200       errmsg ("missing interface name or sw_if_index\n");
12201       return -99;
12202     }
12203
12204   /* Construct the API message */
12205   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12206   mp->sw_if_index = ntohl (sw_if_index);
12207   mp->enable_disable = enable_disable;
12208
12209   /* send it... */
12210   S;
12211   /* Wait for the reply */
12212   W;
12213 }
12214
12215 static int
12216 api_cop_whitelist_enable_disable (vat_main_t * vam)
12217 {
12218   unformat_input_t *line_input = vam->input;
12219   vl_api_cop_whitelist_enable_disable_t *mp;
12220   f64 timeout;
12221   u32 sw_if_index = ~0;
12222   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12223   u32 fib_id = 0;
12224
12225   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12226     {
12227       if (unformat (line_input, "ip4"))
12228         ip4 = 1;
12229       else if (unformat (line_input, "ip6"))
12230         ip6 = 1;
12231       else if (unformat (line_input, "default"))
12232         default_cop = 1;
12233       else if (unformat (line_input, "%U", unformat_sw_if_index,
12234                          vam, &sw_if_index))
12235         ;
12236       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12237         ;
12238       else if (unformat (line_input, "fib-id %d", &fib_id))
12239         ;
12240       else
12241         break;
12242     }
12243
12244   if (sw_if_index == ~0)
12245     {
12246       errmsg ("missing interface name or sw_if_index\n");
12247       return -99;
12248     }
12249
12250   /* Construct the API message */
12251   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12252   mp->sw_if_index = ntohl (sw_if_index);
12253   mp->fib_id = ntohl (fib_id);
12254   mp->ip4 = ip4;
12255   mp->ip6 = ip6;
12256   mp->default_cop = default_cop;
12257
12258   /* send it... */
12259   S;
12260   /* Wait for the reply */
12261   W;
12262 }
12263
12264 static int
12265 api_get_node_graph (vat_main_t * vam)
12266 {
12267   vl_api_get_node_graph_t *mp;
12268   f64 timeout;
12269
12270   M (GET_NODE_GRAPH, get_node_graph);
12271
12272   /* send it... */
12273   S;
12274   /* Wait for the reply */
12275   W;
12276 }
12277
12278 /* *INDENT-OFF* */
12279 /** Used for parsing LISP eids */
12280 typedef CLIB_PACKED(struct{
12281   u8 addr[16];   /**< eid address */
12282   u32 len;       /**< prefix length if IP */
12283   u8 type;      /**< type of eid */
12284 }) lisp_eid_vat_t;
12285 /* *INDENT-ON* */
12286
12287 static uword
12288 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12289 {
12290   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12291
12292   memset (a, 0, sizeof (a[0]));
12293
12294   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12295     {
12296       a->type = 0;              /* ipv4 type */
12297     }
12298   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12299     {
12300       a->type = 1;              /* ipv6 type */
12301     }
12302   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12303     {
12304       a->type = 2;              /* mac type */
12305     }
12306   else
12307     {
12308       return 0;
12309     }
12310
12311   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12312     {
12313       return 0;
12314     }
12315
12316   return 1;
12317 }
12318
12319 static int
12320 lisp_eid_size_vat (u8 type)
12321 {
12322   switch (type)
12323     {
12324     case 0:
12325       return 4;
12326     case 1:
12327       return 16;
12328     case 2:
12329       return 6;
12330     }
12331   return 0;
12332 }
12333
12334 static void
12335 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12336 {
12337   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12338 }
12339
12340 /* *INDENT-OFF* */
12341 /** Used for transferring locators via VPP API */
12342 typedef CLIB_PACKED(struct
12343 {
12344   u32 sw_if_index; /**< locator sw_if_index */
12345   u8 priority; /**< locator priority */
12346   u8 weight;   /**< locator weight */
12347 }) ls_locator_t;
12348 /* *INDENT-ON* */
12349
12350 static int
12351 api_lisp_add_del_locator_set (vat_main_t * vam)
12352 {
12353   unformat_input_t *input = vam->input;
12354   vl_api_lisp_add_del_locator_set_t *mp;
12355   f64 timeout = ~0;
12356   u8 is_add = 1;
12357   u8 *locator_set_name = NULL;
12358   u8 locator_set_name_set = 0;
12359   ls_locator_t locator, *locators = 0;
12360   u32 sw_if_index, priority, weight;
12361   u32 data_len = 0;
12362
12363   /* Parse args required to build the message */
12364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12365     {
12366       if (unformat (input, "del"))
12367         {
12368           is_add = 0;
12369         }
12370       else if (unformat (input, "locator-set %s", &locator_set_name))
12371         {
12372           locator_set_name_set = 1;
12373         }
12374       else if (unformat (input, "sw_if_index %u p %u w %u",
12375                          &sw_if_index, &priority, &weight))
12376         {
12377           locator.sw_if_index = htonl (sw_if_index);
12378           locator.priority = priority;
12379           locator.weight = weight;
12380           vec_add1 (locators, locator);
12381         }
12382       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12383                          vam, &sw_if_index, &priority, &weight))
12384         {
12385           locator.sw_if_index = htonl (sw_if_index);
12386           locator.priority = priority;
12387           locator.weight = weight;
12388           vec_add1 (locators, locator);
12389         }
12390       else
12391         break;
12392     }
12393
12394   if (locator_set_name_set == 0)
12395     {
12396       errmsg ("missing locator-set name");
12397       vec_free (locators);
12398       return -99;
12399     }
12400
12401   if (vec_len (locator_set_name) > 64)
12402     {
12403       errmsg ("locator-set name too long\n");
12404       vec_free (locator_set_name);
12405       vec_free (locators);
12406       return -99;
12407     }
12408   vec_add1 (locator_set_name, 0);
12409
12410   data_len = sizeof (ls_locator_t) * vec_len (locators);
12411
12412   /* Construct the API message */
12413   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12414
12415   mp->is_add = is_add;
12416   clib_memcpy (mp->locator_set_name, locator_set_name,
12417                vec_len (locator_set_name));
12418   vec_free (locator_set_name);
12419
12420   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12421   if (locators)
12422     clib_memcpy (mp->locators, locators, data_len);
12423   vec_free (locators);
12424
12425   /* send it... */
12426   S;
12427
12428   /* Wait for a reply... */
12429   W;
12430
12431   /* NOTREACHED */
12432   return 0;
12433 }
12434
12435 static int
12436 api_lisp_add_del_locator (vat_main_t * vam)
12437 {
12438   unformat_input_t *input = vam->input;
12439   vl_api_lisp_add_del_locator_t *mp;
12440   f64 timeout = ~0;
12441   u32 tmp_if_index = ~0;
12442   u32 sw_if_index = ~0;
12443   u8 sw_if_index_set = 0;
12444   u8 sw_if_index_if_name_set = 0;
12445   u32 priority = ~0;
12446   u8 priority_set = 0;
12447   u32 weight = ~0;
12448   u8 weight_set = 0;
12449   u8 is_add = 1;
12450   u8 *locator_set_name = NULL;
12451   u8 locator_set_name_set = 0;
12452
12453   /* Parse args required to build the message */
12454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12455     {
12456       if (unformat (input, "del"))
12457         {
12458           is_add = 0;
12459         }
12460       else if (unformat (input, "locator-set %s", &locator_set_name))
12461         {
12462           locator_set_name_set = 1;
12463         }
12464       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12465                          &tmp_if_index))
12466         {
12467           sw_if_index_if_name_set = 1;
12468           sw_if_index = tmp_if_index;
12469         }
12470       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12471         {
12472           sw_if_index_set = 1;
12473           sw_if_index = tmp_if_index;
12474         }
12475       else if (unformat (input, "p %d", &priority))
12476         {
12477           priority_set = 1;
12478         }
12479       else if (unformat (input, "w %d", &weight))
12480         {
12481           weight_set = 1;
12482         }
12483       else
12484         break;
12485     }
12486
12487   if (locator_set_name_set == 0)
12488     {
12489       errmsg ("missing locator-set name");
12490       return -99;
12491     }
12492
12493   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12494     {
12495       errmsg ("missing sw_if_index");
12496       vec_free (locator_set_name);
12497       return -99;
12498     }
12499
12500   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12501     {
12502       errmsg ("cannot use both params interface name and sw_if_index");
12503       vec_free (locator_set_name);
12504       return -99;
12505     }
12506
12507   if (priority_set == 0)
12508     {
12509       errmsg ("missing locator-set priority\n");
12510       vec_free (locator_set_name);
12511       return -99;
12512     }
12513
12514   if (weight_set == 0)
12515     {
12516       errmsg ("missing locator-set weight\n");
12517       vec_free (locator_set_name);
12518       return -99;
12519     }
12520
12521   if (vec_len (locator_set_name) > 64)
12522     {
12523       errmsg ("locator-set name too long\n");
12524       vec_free (locator_set_name);
12525       return -99;
12526     }
12527   vec_add1 (locator_set_name, 0);
12528
12529   /* Construct the API message */
12530   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12531
12532   mp->is_add = is_add;
12533   mp->sw_if_index = ntohl (sw_if_index);
12534   mp->priority = priority;
12535   mp->weight = weight;
12536   clib_memcpy (mp->locator_set_name, locator_set_name,
12537                vec_len (locator_set_name));
12538   vec_free (locator_set_name);
12539
12540   /* send it... */
12541   S;
12542
12543   /* Wait for a reply... */
12544   W;
12545
12546   /* NOTREACHED */
12547   return 0;
12548 }
12549
12550 static int
12551 api_lisp_add_del_local_eid (vat_main_t * vam)
12552 {
12553   unformat_input_t *input = vam->input;
12554   vl_api_lisp_add_del_local_eid_t *mp;
12555   f64 timeout = ~0;
12556   u8 is_add = 1;
12557   u8 eid_set = 0;
12558   lisp_eid_vat_t _eid, *eid = &_eid;
12559   u8 *locator_set_name = 0;
12560   u8 locator_set_name_set = 0;
12561   u32 vni = 0;
12562
12563   /* Parse args required to build the message */
12564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12565     {
12566       if (unformat (input, "del"))
12567         {
12568           is_add = 0;
12569         }
12570       else if (unformat (input, "vni %d", &vni))
12571         {
12572           ;
12573         }
12574       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12575         {
12576           eid_set = 1;
12577         }
12578       else if (unformat (input, "locator-set %s", &locator_set_name))
12579         {
12580           locator_set_name_set = 1;
12581         }
12582       else
12583         break;
12584     }
12585
12586   if (locator_set_name_set == 0)
12587     {
12588       errmsg ("missing locator-set name\n");
12589       return -99;
12590     }
12591
12592   if (0 == eid_set)
12593     {
12594       errmsg ("EID address not set!");
12595       vec_free (locator_set_name);
12596       return -99;
12597     }
12598
12599   if (vec_len (locator_set_name) > 64)
12600     {
12601       errmsg ("locator-set name too long\n");
12602       vec_free (locator_set_name);
12603       return -99;
12604     }
12605   vec_add1 (locator_set_name, 0);
12606
12607   /* Construct the API message */
12608   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12609
12610   mp->is_add = is_add;
12611   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12612   mp->eid_type = eid->type;
12613   mp->prefix_len = eid->len;
12614   mp->vni = clib_host_to_net_u32 (vni);
12615   clib_memcpy (mp->locator_set_name, locator_set_name,
12616                vec_len (locator_set_name));
12617
12618   vec_free (locator_set_name);
12619
12620   /* send it... */
12621   S;
12622
12623   /* Wait for a reply... */
12624   W;
12625
12626   /* NOTREACHED */
12627   return 0;
12628 }
12629
12630 /* *INDENT-OFF* */
12631 /** Used for transferring locators via VPP API */
12632 typedef CLIB_PACKED(struct
12633 {
12634   u8 is_ip4; /**< is locator an IPv4 address? */
12635   u8 priority; /**< locator priority */
12636   u8 weight;   /**< locator weight */
12637   u8 addr[16]; /**< IPv4/IPv6 address */
12638 }) rloc_t;
12639 /* *INDENT-ON* */
12640
12641 static int
12642 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12643 {
12644   unformat_input_t *input = vam->input;
12645   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12646   f64 timeout = ~0;
12647   u8 is_add = 1;
12648   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12649   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12650   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12651   u32 action = ~0, p, w;
12652   ip4_address_t rmt_rloc4, lcl_rloc4;
12653   ip6_address_t rmt_rloc6, lcl_rloc6;
12654   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12655
12656   memset (&rloc, 0, sizeof (rloc));
12657
12658   /* Parse args required to build the message */
12659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12660     {
12661       if (unformat (input, "del"))
12662         {
12663           is_add = 0;
12664         }
12665       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12666         {
12667           rmt_eid_set = 1;
12668         }
12669       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12670         {
12671           lcl_eid_set = 1;
12672         }
12673       else if (unformat (input, "p %d w %d", &p, &w))
12674         {
12675           if (!curr_rloc)
12676             {
12677               errmsg ("No RLOC configured for setting priority/weight!");
12678               return -99;
12679             }
12680           curr_rloc->priority = p;
12681           curr_rloc->weight = w;
12682         }
12683       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12684                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12685         {
12686           rloc.is_ip4 = 1;
12687
12688           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12689           rloc.priority = rloc.weight = 0;
12690           vec_add1 (lcl_locs, rloc);
12691
12692           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12693           vec_add1 (rmt_locs, rloc);
12694           /* priority and weight saved in rmt loc */
12695           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12696         }
12697       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12698                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12699         {
12700           rloc.is_ip4 = 0;
12701           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12702           rloc.priority = rloc.weight = 0;
12703           vec_add1 (lcl_locs, rloc);
12704
12705           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12706           vec_add1 (rmt_locs, rloc);
12707           /* priority and weight saved in rmt loc */
12708           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12709         }
12710       else if (unformat (input, "action %d", &action))
12711         {
12712           ;
12713         }
12714       else
12715         {
12716           clib_warning ("parse error '%U'", format_unformat_error, input);
12717           return -99;
12718         }
12719     }
12720
12721   if (!rmt_eid_set)
12722     {
12723       errmsg ("remote eid addresses not set\n");
12724       return -99;
12725     }
12726
12727   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12728     {
12729       errmsg ("eid types don't match\n");
12730       return -99;
12731     }
12732
12733   if (0 == rmt_locs && (u32) ~ 0 == action)
12734     {
12735       errmsg ("action not set for negative mapping\n");
12736       return -99;
12737     }
12738
12739   /* Construct the API message */
12740   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12741
12742   mp->is_add = is_add;
12743   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12744   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12745   mp->eid_type = rmt_eid->type;
12746   mp->rmt_len = rmt_eid->len;
12747   mp->lcl_len = lcl_eid->len;
12748   mp->action = action;
12749
12750   if (0 != rmt_locs && 0 != lcl_locs)
12751     {
12752       mp->loc_num = vec_len (rmt_locs);
12753       clib_memcpy (mp->lcl_locs, lcl_locs,
12754                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12755       clib_memcpy (mp->rmt_locs, rmt_locs,
12756                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12757     }
12758   vec_free (lcl_locs);
12759   vec_free (rmt_locs);
12760
12761   /* send it... */
12762   S;
12763
12764   /* Wait for a reply... */
12765   W;
12766
12767   /* NOTREACHED */
12768   return 0;
12769 }
12770
12771 static int
12772 api_lisp_add_del_map_resolver (vat_main_t * vam)
12773 {
12774   unformat_input_t *input = vam->input;
12775   vl_api_lisp_add_del_map_resolver_t *mp;
12776   f64 timeout = ~0;
12777   u8 is_add = 1;
12778   u8 ipv4_set = 0;
12779   u8 ipv6_set = 0;
12780   ip4_address_t ipv4;
12781   ip6_address_t ipv6;
12782
12783   /* Parse args required to build the message */
12784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12785     {
12786       if (unformat (input, "del"))
12787         {
12788           is_add = 0;
12789         }
12790       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12791         {
12792           ipv4_set = 1;
12793         }
12794       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12795         {
12796           ipv6_set = 1;
12797         }
12798       else
12799         break;
12800     }
12801
12802   if (ipv4_set && ipv6_set)
12803     {
12804       errmsg ("both eid v4 and v6 addresses set\n");
12805       return -99;
12806     }
12807
12808   if (!ipv4_set && !ipv6_set)
12809     {
12810       errmsg ("eid addresses not set\n");
12811       return -99;
12812     }
12813
12814   /* Construct the API message */
12815   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12816
12817   mp->is_add = is_add;
12818   if (ipv6_set)
12819     {
12820       mp->is_ipv6 = 1;
12821       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12822     }
12823   else
12824     {
12825       mp->is_ipv6 = 0;
12826       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12827     }
12828
12829   /* send it... */
12830   S;
12831
12832   /* Wait for a reply... */
12833   W;
12834
12835   /* NOTREACHED */
12836   return 0;
12837 }
12838
12839 static int
12840 api_lisp_gpe_enable_disable (vat_main_t * vam)
12841 {
12842   unformat_input_t *input = vam->input;
12843   vl_api_lisp_gpe_enable_disable_t *mp;
12844   f64 timeout = ~0;
12845   u8 is_set = 0;
12846   u8 is_en = 1;
12847
12848   /* Parse args required to build the message */
12849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12850     {
12851       if (unformat (input, "enable"))
12852         {
12853           is_set = 1;
12854           is_en = 1;
12855         }
12856       else if (unformat (input, "disable"))
12857         {
12858           is_set = 1;
12859           is_en = 0;
12860         }
12861       else
12862         break;
12863     }
12864
12865   if (is_set == 0)
12866     {
12867       errmsg ("Value not set\n");
12868       return -99;
12869     }
12870
12871   /* Construct the API message */
12872   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12873
12874   mp->is_en = is_en;
12875
12876   /* send it... */
12877   S;
12878
12879   /* Wait for a reply... */
12880   W;
12881
12882   /* NOTREACHED */
12883   return 0;
12884 }
12885
12886 static int
12887 api_lisp_enable_disable (vat_main_t * vam)
12888 {
12889   unformat_input_t *input = vam->input;
12890   vl_api_lisp_enable_disable_t *mp;
12891   f64 timeout = ~0;
12892   u8 is_set = 0;
12893   u8 is_en = 0;
12894
12895   /* Parse args required to build the message */
12896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12897     {
12898       if (unformat (input, "enable"))
12899         {
12900           is_set = 1;
12901           is_en = 1;
12902         }
12903       else if (unformat (input, "disable"))
12904         {
12905           is_set = 1;
12906         }
12907       else
12908         break;
12909     }
12910
12911   if (!is_set)
12912     {
12913       errmsg ("Value not set\n");
12914       return -99;
12915     }
12916
12917   /* Construct the API message */
12918   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12919
12920   mp->is_en = is_en;
12921
12922   /* send it... */
12923   S;
12924
12925   /* Wait for a reply... */
12926   W;
12927
12928   /* NOTREACHED */
12929   return 0;
12930 }
12931
12932 static int
12933 api_show_lisp_map_request_mode (vat_main_t * vam)
12934 {
12935   f64 timeout = ~0;
12936   vl_api_show_lisp_map_request_mode_t *mp;
12937
12938   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
12939
12940   /* send */
12941   S;
12942
12943   /* wait for reply */
12944   W;
12945
12946   return 0;
12947 }
12948
12949 static int
12950 api_lisp_map_request_mode (vat_main_t * vam)
12951 {
12952   f64 timeout = ~0;
12953   unformat_input_t *input = vam->input;
12954   vl_api_lisp_map_request_mode_t *mp;
12955   u8 mode = 0;
12956
12957   /* Parse args required to build the message */
12958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12959     {
12960       if (unformat (input, "dst-only"))
12961         mode = 0;
12962       else if (unformat (input, "src-dst"))
12963         mode = 1;
12964       else
12965         {
12966           errmsg ("parse error '%U'", format_unformat_error, input);
12967           return -99;
12968         }
12969     }
12970
12971   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
12972
12973   mp->mode = mode;
12974
12975   /* send */
12976   S;
12977
12978   /* wait for reply */
12979   W;
12980
12981   /* notreached */
12982   return 0;
12983 }
12984
12985 /**
12986  * Enable/disable LISP proxy ITR.
12987  *
12988  * @param vam vpp API test context
12989  * @return return code
12990  */
12991 static int
12992 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12993 {
12994   f64 timeout = ~0;
12995   u8 ls_name_set = 0;
12996   unformat_input_t *input = vam->input;
12997   vl_api_lisp_pitr_set_locator_set_t *mp;
12998   u8 is_add = 1;
12999   u8 *ls_name = 0;
13000
13001   /* Parse args required to build the message */
13002   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13003     {
13004       if (unformat (input, "del"))
13005         is_add = 0;
13006       else if (unformat (input, "locator-set %s", &ls_name))
13007         ls_name_set = 1;
13008       else
13009         {
13010           errmsg ("parse error '%U'", format_unformat_error, input);
13011           return -99;
13012         }
13013     }
13014
13015   if (!ls_name_set)
13016     {
13017       errmsg ("locator-set name not set!");
13018       return -99;
13019     }
13020
13021   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13022
13023   mp->is_add = is_add;
13024   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13025   vec_free (ls_name);
13026
13027   /* send */
13028   S;
13029
13030   /* wait for reply */
13031   W;
13032
13033   /* notreached */
13034   return 0;
13035 }
13036
13037 static int
13038 api_show_lisp_pitr (vat_main_t * vam)
13039 {
13040   vl_api_show_lisp_pitr_t *mp;
13041   f64 timeout = ~0;
13042
13043   if (!vam->json_output)
13044     {
13045       fformat (vam->ofp, "%=20s\n", "lisp status:");
13046     }
13047
13048   M (SHOW_LISP_PITR, show_lisp_pitr);
13049   /* send it... */
13050   S;
13051
13052   /* Wait for a reply... */
13053   W;
13054
13055   /* NOTREACHED */
13056   return 0;
13057 }
13058
13059 /**
13060  * Add/delete mapping between vni and vrf
13061  */
13062 static int
13063 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13064 {
13065   f64 timeout = ~0;
13066   unformat_input_t *input = vam->input;
13067   vl_api_lisp_eid_table_add_del_map_t *mp;
13068   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13069   u32 vni, vrf, bd_index;
13070
13071   /* Parse args required to build the message */
13072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13073     {
13074       if (unformat (input, "del"))
13075         is_add = 0;
13076       else if (unformat (input, "vrf %d", &vrf))
13077         vrf_set = 1;
13078       else if (unformat (input, "bd_index %d", &bd_index))
13079         bd_index_set = 1;
13080       else if (unformat (input, "vni %d", &vni))
13081         vni_set = 1;
13082       else
13083         break;
13084     }
13085
13086   if (!vni_set || (!vrf_set && !bd_index_set))
13087     {
13088       errmsg ("missing arguments!");
13089       return -99;
13090     }
13091
13092   if (vrf_set && bd_index_set)
13093     {
13094       errmsg ("error: both vrf and bd entered!");
13095       return -99;
13096     }
13097
13098   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13099
13100   mp->is_add = is_add;
13101   mp->vni = htonl (vni);
13102   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13103   mp->is_l2 = bd_index_set;
13104
13105   /* send */
13106   S;
13107
13108   /* wait for reply */
13109   W;
13110
13111   /* notreached */
13112   return 0;
13113 }
13114
13115 uword
13116 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13117 {
13118   u32 *action = va_arg (*args, u32 *);
13119   u8 *s = 0;
13120
13121   if (unformat (input, "%s", &s))
13122     {
13123       if (!strcmp ((char *) s, "no-action"))
13124         action[0] = 0;
13125       else if (!strcmp ((char *) s, "natively-forward"))
13126         action[0] = 1;
13127       else if (!strcmp ((char *) s, "send-map-request"))
13128         action[0] = 2;
13129       else if (!strcmp ((char *) s, "drop"))
13130         action[0] = 3;
13131       else
13132         {
13133           clib_warning ("invalid action: '%s'", s);
13134           action[0] = 3;
13135         }
13136     }
13137   else
13138     return 0;
13139
13140   vec_free (s);
13141   return 1;
13142 }
13143
13144 /**
13145  * Add/del remote mapping to/from LISP control plane
13146  *
13147  * @param vam vpp API test context
13148  * @return return code
13149  */
13150 static int
13151 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13152 {
13153   unformat_input_t *input = vam->input;
13154   vl_api_lisp_add_del_remote_mapping_t *mp;
13155   f64 timeout = ~0;
13156   u32 vni = 0;
13157   lisp_eid_vat_t _eid, *eid = &_eid;
13158   lisp_eid_vat_t _seid, *seid = &_seid;
13159   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13160   u32 action = ~0, p, w, data_len;
13161   ip4_address_t rloc4;
13162   ip6_address_t rloc6;
13163   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13164
13165   memset (&rloc, 0, sizeof (rloc));
13166
13167   /* Parse args required to build the message */
13168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13169     {
13170       if (unformat (input, "del-all"))
13171         {
13172           del_all = 1;
13173         }
13174       else if (unformat (input, "del"))
13175         {
13176           is_add = 0;
13177         }
13178       else if (unformat (input, "add"))
13179         {
13180           is_add = 1;
13181         }
13182       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13183         {
13184           eid_set = 1;
13185         }
13186       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13187         {
13188           seid_set = 1;
13189         }
13190       else if (unformat (input, "vni %d", &vni))
13191         {
13192           ;
13193         }
13194       else if (unformat (input, "p %d w %d", &p, &w))
13195         {
13196           if (!curr_rloc)
13197             {
13198               errmsg ("No RLOC configured for setting priority/weight!");
13199               return -99;
13200             }
13201           curr_rloc->priority = p;
13202           curr_rloc->weight = w;
13203         }
13204       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13205         {
13206           rloc.is_ip4 = 1;
13207           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13208           vec_add1 (rlocs, rloc);
13209           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13210         }
13211       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13212         {
13213           rloc.is_ip4 = 0;
13214           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13215           vec_add1 (rlocs, rloc);
13216           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13217         }
13218       else if (unformat (input, "action %U",
13219                          unformat_negative_mapping_action, &action))
13220         {
13221           ;
13222         }
13223       else
13224         {
13225           clib_warning ("parse error '%U'", format_unformat_error, input);
13226           return -99;
13227         }
13228     }
13229
13230   if (0 == eid_set)
13231     {
13232       errmsg ("missing params!");
13233       return -99;
13234     }
13235
13236   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13237     {
13238       errmsg ("no action set for negative map-reply!");
13239       return -99;
13240     }
13241
13242   data_len = vec_len (rlocs) * sizeof (rloc_t);
13243
13244   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13245   mp->is_add = is_add;
13246   mp->vni = htonl (vni);
13247   mp->action = (u8) action;
13248   mp->is_src_dst = seid_set;
13249   mp->eid_len = eid->len;
13250   mp->seid_len = seid->len;
13251   mp->del_all = del_all;
13252   mp->eid_type = eid->type;
13253   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13254   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13255
13256   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13257   clib_memcpy (mp->rlocs, rlocs, data_len);
13258   vec_free (rlocs);
13259
13260   /* send it... */
13261   S;
13262
13263   /* Wait for a reply... */
13264   W;
13265
13266   /* NOTREACHED */
13267   return 0;
13268 }
13269
13270 /**
13271  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13272  * forwarding entries in data-plane accordingly.
13273  *
13274  * @param vam vpp API test context
13275  * @return return code
13276  */
13277 static int
13278 api_lisp_add_del_adjacency (vat_main_t * vam)
13279 {
13280   unformat_input_t *input = vam->input;
13281   vl_api_lisp_add_del_adjacency_t *mp;
13282   f64 timeout = ~0;
13283   u32 vni = 0;
13284   ip4_address_t leid4, reid4;
13285   ip6_address_t leid6, reid6;
13286   u8 reid_mac[6] = { 0 };
13287   u8 leid_mac[6] = { 0 };
13288   u8 reid_type, leid_type;
13289   u32 leid_len = 0, reid_len = 0, len;
13290   u8 is_add = 1;
13291
13292   leid_type = reid_type = (u8) ~ 0;
13293
13294   /* Parse args required to build the message */
13295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13296     {
13297       if (unformat (input, "del"))
13298         {
13299           is_add = 0;
13300         }
13301       else if (unformat (input, "add"))
13302         {
13303           is_add = 1;
13304         }
13305       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13306                          &reid4, &len))
13307         {
13308           reid_type = 0;        /* ipv4 */
13309           reid_len = len;
13310         }
13311       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13312                          &reid6, &len))
13313         {
13314           reid_type = 1;        /* ipv6 */
13315           reid_len = len;
13316         }
13317       else if (unformat (input, "reid %U", unformat_ethernet_address,
13318                          reid_mac))
13319         {
13320           reid_type = 2;        /* mac */
13321         }
13322       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13323                          &leid4, &len))
13324         {
13325           leid_type = 0;        /* ipv4 */
13326           leid_len = len;
13327         }
13328       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13329                          &leid6, &len))
13330         {
13331           leid_type = 1;        /* ipv6 */
13332           leid_len = len;
13333         }
13334       else if (unformat (input, "leid %U", unformat_ethernet_address,
13335                          leid_mac))
13336         {
13337           leid_type = 2;        /* mac */
13338         }
13339       else if (unformat (input, "vni %d", &vni))
13340         {
13341           ;
13342         }
13343       else
13344         {
13345           errmsg ("parse error '%U'", format_unformat_error, input);
13346           return -99;
13347         }
13348     }
13349
13350   if ((u8) ~ 0 == reid_type)
13351     {
13352       errmsg ("missing params!");
13353       return -99;
13354     }
13355
13356   if (leid_type != reid_type)
13357     {
13358       errmsg ("remote and local EIDs are of different types!");
13359       return -99;
13360     }
13361
13362   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13363   mp->is_add = is_add;
13364   mp->vni = htonl (vni);
13365   mp->leid_len = leid_len;
13366   mp->reid_len = reid_len;
13367   mp->eid_type = reid_type;
13368
13369   switch (mp->eid_type)
13370     {
13371     case 0:
13372       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13373       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13374       break;
13375     case 1:
13376       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13377       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13378       break;
13379     case 2:
13380       clib_memcpy (mp->leid, leid_mac, 6);
13381       clib_memcpy (mp->reid, reid_mac, 6);
13382       break;
13383     default:
13384       errmsg ("unknown EID type %d!", mp->eid_type);
13385       return 0;
13386     }
13387
13388   /* send it... */
13389   S;
13390
13391   /* Wait for a reply... */
13392   W;
13393
13394   /* NOTREACHED */
13395   return 0;
13396 }
13397
13398 static int
13399 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13400 {
13401   unformat_input_t *input = vam->input;
13402   vl_api_lisp_gpe_add_del_iface_t *mp;
13403   f64 timeout = ~0;
13404   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13405   u32 dp_table = 0, vni = 0;
13406
13407   /* Parse args required to build the message */
13408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13409     {
13410       if (unformat (input, "up"))
13411         {
13412           action_set = 1;
13413           is_add = 1;
13414         }
13415       else if (unformat (input, "down"))
13416         {
13417           action_set = 1;
13418           is_add = 0;
13419         }
13420       else if (unformat (input, "table_id %d", &dp_table))
13421         {
13422           dp_table_set = 1;
13423         }
13424       else if (unformat (input, "bd_id %d", &dp_table))
13425         {
13426           dp_table_set = 1;
13427           is_l2 = 1;
13428         }
13429       else if (unformat (input, "vni %d", &vni))
13430         {
13431           vni_set = 1;
13432         }
13433       else
13434         break;
13435     }
13436
13437   if (action_set == 0)
13438     {
13439       errmsg ("Action not set\n");
13440       return -99;
13441     }
13442   if (dp_table_set == 0 || vni_set == 0)
13443     {
13444       errmsg ("vni and dp_table must be set\n");
13445       return -99;
13446     }
13447
13448   /* Construct the API message */
13449   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13450
13451   mp->is_add = is_add;
13452   mp->dp_table = dp_table;
13453   mp->is_l2 = is_l2;
13454   mp->vni = vni;
13455
13456   /* send it... */
13457   S;
13458
13459   /* Wait for a reply... */
13460   W;
13461
13462   /* NOTREACHED */
13463   return 0;
13464 }
13465
13466 /**
13467  * Add/del map request itr rlocs from LISP control plane and updates
13468  *
13469  * @param vam vpp API test context
13470  * @return return code
13471  */
13472 static int
13473 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13474 {
13475   unformat_input_t *input = vam->input;
13476   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13477   f64 timeout = ~0;
13478   u8 *locator_set_name = 0;
13479   u8 locator_set_name_set = 0;
13480   u8 is_add = 1;
13481
13482   /* Parse args required to build the message */
13483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13484     {
13485       if (unformat (input, "del"))
13486         {
13487           is_add = 0;
13488         }
13489       else if (unformat (input, "%_%v%_", &locator_set_name))
13490         {
13491           locator_set_name_set = 1;
13492         }
13493       else
13494         {
13495           clib_warning ("parse error '%U'", format_unformat_error, input);
13496           return -99;
13497         }
13498     }
13499
13500   if (is_add && !locator_set_name_set)
13501     {
13502       errmsg ("itr-rloc is not set!");
13503       return -99;
13504     }
13505
13506   if (is_add && vec_len (locator_set_name) > 64)
13507     {
13508       errmsg ("itr-rloc locator-set name too long\n");
13509       vec_free (locator_set_name);
13510       return -99;
13511     }
13512
13513   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13514   mp->is_add = is_add;
13515   if (is_add)
13516     {
13517       clib_memcpy (mp->locator_set_name, locator_set_name,
13518                    vec_len (locator_set_name));
13519     }
13520   else
13521     {
13522       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13523     }
13524   vec_free (locator_set_name);
13525
13526   /* send it... */
13527   S;
13528
13529   /* Wait for a reply... */
13530   W;
13531
13532   /* NOTREACHED */
13533   return 0;
13534 }
13535
13536 static int
13537 api_lisp_locator_dump (vat_main_t * vam)
13538 {
13539   unformat_input_t *input = vam->input;
13540   vl_api_lisp_locator_dump_t *mp;
13541   f64 timeout = ~0;
13542   u8 is_index_set = 0, is_name_set = 0;
13543   u8 *ls_name = 0;
13544   u32 ls_index = ~0;
13545
13546   /* Parse args required to build the message */
13547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13548     {
13549       if (unformat (input, "ls_name %_%v%_", &ls_name))
13550         {
13551           is_name_set = 1;
13552         }
13553       else if (unformat (input, "ls_index %d", &ls_index))
13554         {
13555           is_index_set = 1;
13556         }
13557       else
13558         {
13559           errmsg ("parse error '%U'", format_unformat_error, input);
13560           return -99;
13561         }
13562     }
13563
13564   if (!is_index_set && !is_name_set)
13565     {
13566       errmsg ("error: expected one of index or name!\n");
13567       return -99;
13568     }
13569
13570   if (is_index_set && is_name_set)
13571     {
13572       errmsg ("error: only one param expected!\n");
13573       return -99;
13574     }
13575
13576   if (vec_len (ls_name) > 62)
13577     {
13578       errmsg ("error: locator set name too long!");
13579       return -99;
13580     }
13581
13582   if (!vam->json_output)
13583     {
13584       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13585                "weight");
13586     }
13587
13588   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13589   mp->is_index_set = is_index_set;
13590
13591   if (is_index_set)
13592     mp->ls_index = clib_host_to_net_u32 (ls_index);
13593   else
13594     {
13595       vec_add1 (ls_name, 0);
13596       strncpy ((char *) mp->ls_name, (char *) ls_name,
13597                sizeof (mp->ls_name) - 1);
13598     }
13599
13600   /* send it... */
13601   S;
13602
13603   /* Use a control ping for synchronization */
13604   {
13605     vl_api_control_ping_t *mp;
13606     M (CONTROL_PING, control_ping);
13607     S;
13608   }
13609   /* Wait for a reply... */
13610   W;
13611
13612   /* NOTREACHED */
13613   return 0;
13614 }
13615
13616 static int
13617 api_lisp_locator_set_dump (vat_main_t * vam)
13618 {
13619   vl_api_lisp_locator_set_dump_t *mp;
13620   unformat_input_t *input = vam->input;
13621   f64 timeout = ~0;
13622   u8 filter = 0;
13623
13624   /* Parse args required to build the message */
13625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13626     {
13627       if (unformat (input, "local"))
13628         {
13629           filter = 1;
13630         }
13631       else if (unformat (input, "remote"))
13632         {
13633           filter = 2;
13634         }
13635       else
13636         {
13637           errmsg ("parse error '%U'", format_unformat_error, input);
13638           return -99;
13639         }
13640     }
13641
13642   if (!vam->json_output)
13643     {
13644       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13645     }
13646
13647   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13648
13649   mp->filter = filter;
13650
13651   /* send it... */
13652   S;
13653
13654   /* Use a control ping for synchronization */
13655   {
13656     vl_api_control_ping_t *mp;
13657     M (CONTROL_PING, control_ping);
13658     S;
13659   }
13660   /* Wait for a reply... */
13661   W;
13662
13663   /* NOTREACHED */
13664   return 0;
13665 }
13666
13667 static int
13668 api_lisp_eid_table_map_dump (vat_main_t * vam)
13669 {
13670   u8 is_l2 = 0;
13671   u8 mode_set = 0;
13672   unformat_input_t *input = vam->input;
13673   vl_api_lisp_eid_table_map_dump_t *mp;
13674   f64 timeout = ~0;
13675
13676   /* Parse args required to build the message */
13677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13678     {
13679       if (unformat (input, "l2"))
13680         {
13681           is_l2 = 1;
13682           mode_set = 1;
13683         }
13684       else if (unformat (input, "l3"))
13685         {
13686           is_l2 = 0;
13687           mode_set = 1;
13688         }
13689       else
13690         {
13691           errmsg ("parse error '%U'", format_unformat_error, input);
13692           return -99;
13693         }
13694     }
13695
13696   if (!mode_set)
13697     {
13698       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13699       return -99;
13700     }
13701
13702   if (!vam->json_output)
13703     {
13704       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13705     }
13706
13707   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13708   mp->is_l2 = is_l2;
13709
13710   /* send it... */
13711   S;
13712
13713   /* Use a control ping for synchronization */
13714   {
13715     vl_api_control_ping_t *mp;
13716     M (CONTROL_PING, control_ping);
13717     S;
13718   }
13719   /* Wait for a reply... */
13720   W;
13721
13722   /* NOTREACHED */
13723   return 0;
13724 }
13725
13726 static int
13727 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13728 {
13729   vl_api_lisp_eid_table_vni_dump_t *mp;
13730   f64 timeout = ~0;
13731
13732   if (!vam->json_output)
13733     {
13734       fformat (vam->ofp, "VNI\n");
13735     }
13736
13737   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13738
13739   /* send it... */
13740   S;
13741
13742   /* Use a control ping for synchronization */
13743   {
13744     vl_api_control_ping_t *mp;
13745     M (CONTROL_PING, control_ping);
13746     S;
13747   }
13748   /* Wait for a reply... */
13749   W;
13750
13751   /* NOTREACHED */
13752   return 0;
13753 }
13754
13755 static int
13756 api_lisp_eid_table_dump (vat_main_t * vam)
13757 {
13758   unformat_input_t *i = vam->input;
13759   vl_api_lisp_eid_table_dump_t *mp;
13760   f64 timeout = ~0;
13761   struct in_addr ip4;
13762   struct in6_addr ip6;
13763   u8 mac[6];
13764   u8 eid_type = ~0, eid_set = 0;
13765   u32 prefix_length = ~0, t, vni = 0;
13766   u8 filter = 0;
13767
13768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13769     {
13770       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13771         {
13772           eid_set = 1;
13773           eid_type = 0;
13774           prefix_length = t;
13775         }
13776       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13777         {
13778           eid_set = 1;
13779           eid_type = 1;
13780           prefix_length = t;
13781         }
13782       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13783         {
13784           eid_set = 1;
13785           eid_type = 2;
13786         }
13787       else if (unformat (i, "vni %d", &t))
13788         {
13789           vni = t;
13790         }
13791       else if (unformat (i, "local"))
13792         {
13793           filter = 1;
13794         }
13795       else if (unformat (i, "remote"))
13796         {
13797           filter = 2;
13798         }
13799       else
13800         {
13801           errmsg ("parse error '%U'", format_unformat_error, i);
13802           return -99;
13803         }
13804     }
13805
13806   if (!vam->json_output)
13807     {
13808       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13809                "ls_index", "ttl", "authoritative");
13810     }
13811
13812   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13813
13814   mp->filter = filter;
13815   if (eid_set)
13816     {
13817       mp->eid_set = 1;
13818       mp->vni = htonl (vni);
13819       mp->eid_type = eid_type;
13820       switch (eid_type)
13821         {
13822         case 0:
13823           mp->prefix_length = prefix_length;
13824           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13825           break;
13826         case 1:
13827           mp->prefix_length = prefix_length;
13828           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13829           break;
13830         case 2:
13831           clib_memcpy (mp->eid, mac, sizeof (mac));
13832           break;
13833         default:
13834           errmsg ("unknown EID type %d!", eid_type);
13835           return -99;
13836         }
13837     }
13838
13839   /* send it... */
13840   S;
13841
13842   /* Use a control ping for synchronization */
13843   {
13844     vl_api_control_ping_t *mp;
13845     M (CONTROL_PING, control_ping);
13846     S;
13847   }
13848
13849   /* Wait for a reply... */
13850   W;
13851
13852   /* NOTREACHED */
13853   return 0;
13854 }
13855
13856 static int
13857 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13858 {
13859   vl_api_lisp_gpe_tunnel_dump_t *mp;
13860   f64 timeout = ~0;
13861
13862   if (!vam->json_output)
13863     {
13864       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13865                "%=16s%=16s%=16s%=16s%=16s\n",
13866                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13867                "Decap next", "Lisp version", "Flags", "Next protocol",
13868                "ver_res", "res", "iid");
13869     }
13870
13871   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13872   /* send it... */
13873   S;
13874
13875   /* Use a control ping for synchronization */
13876   {
13877     vl_api_control_ping_t *mp;
13878     M (CONTROL_PING, control_ping);
13879     S;
13880   }
13881   /* Wait for a reply... */
13882   W;
13883
13884   /* NOTREACHED */
13885   return 0;
13886 }
13887
13888 static int
13889 api_lisp_map_resolver_dump (vat_main_t * vam)
13890 {
13891   vl_api_lisp_map_resolver_dump_t *mp;
13892   f64 timeout = ~0;
13893
13894   if (!vam->json_output)
13895     {
13896       fformat (vam->ofp, "%=20s\n", "Map resolver");
13897     }
13898
13899   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13900   /* send it... */
13901   S;
13902
13903   /* Use a control ping for synchronization */
13904   {
13905     vl_api_control_ping_t *mp;
13906     M (CONTROL_PING, control_ping);
13907     S;
13908   }
13909   /* Wait for a reply... */
13910   W;
13911
13912   /* NOTREACHED */
13913   return 0;
13914 }
13915
13916 static int
13917 api_show_lisp_status (vat_main_t * vam)
13918 {
13919   vl_api_show_lisp_status_t *mp;
13920   f64 timeout = ~0;
13921
13922   if (!vam->json_output)
13923     {
13924       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13925     }
13926
13927   M (SHOW_LISP_STATUS, show_lisp_status);
13928   /* send it... */
13929   S;
13930   /* Wait for a reply... */
13931   W;
13932
13933   /* NOTREACHED */
13934   return 0;
13935 }
13936
13937 static int
13938 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13939 {
13940   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13941   f64 timeout = ~0;
13942
13943   if (!vam->json_output)
13944     {
13945       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13946     }
13947
13948   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13949   /* send it... */
13950   S;
13951   /* Wait for a reply... */
13952   W;
13953
13954   /* NOTREACHED */
13955   return 0;
13956 }
13957
13958 static int
13959 api_af_packet_create (vat_main_t * vam)
13960 {
13961   unformat_input_t *i = vam->input;
13962   vl_api_af_packet_create_t *mp;
13963   f64 timeout;
13964   u8 *host_if_name = 0;
13965   u8 hw_addr[6];
13966   u8 random_hw_addr = 1;
13967
13968   memset (hw_addr, 0, sizeof (hw_addr));
13969
13970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13971     {
13972       if (unformat (i, "name %s", &host_if_name))
13973         vec_add1 (host_if_name, 0);
13974       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13975         random_hw_addr = 0;
13976       else
13977         break;
13978     }
13979
13980   if (!vec_len (host_if_name))
13981     {
13982       errmsg ("host-interface name must be specified");
13983       return -99;
13984     }
13985
13986   if (vec_len (host_if_name) > 64)
13987     {
13988       errmsg ("host-interface name too long");
13989       return -99;
13990     }
13991
13992   M (AF_PACKET_CREATE, af_packet_create);
13993
13994   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13995   clib_memcpy (mp->hw_addr, hw_addr, 6);
13996   mp->use_random_hw_addr = random_hw_addr;
13997   vec_free (host_if_name);
13998
13999   S;
14000   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14001   /* NOTREACHED */
14002   return 0;
14003 }
14004
14005 static int
14006 api_af_packet_delete (vat_main_t * vam)
14007 {
14008   unformat_input_t *i = vam->input;
14009   vl_api_af_packet_delete_t *mp;
14010   f64 timeout;
14011   u8 *host_if_name = 0;
14012
14013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14014     {
14015       if (unformat (i, "name %s", &host_if_name))
14016         vec_add1 (host_if_name, 0);
14017       else
14018         break;
14019     }
14020
14021   if (!vec_len (host_if_name))
14022     {
14023       errmsg ("host-interface name must be specified");
14024       return -99;
14025     }
14026
14027   if (vec_len (host_if_name) > 64)
14028     {
14029       errmsg ("host-interface name too long");
14030       return -99;
14031     }
14032
14033   M (AF_PACKET_DELETE, af_packet_delete);
14034
14035   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14036   vec_free (host_if_name);
14037
14038   S;
14039   W;
14040   /* NOTREACHED */
14041   return 0;
14042 }
14043
14044 static int
14045 api_policer_add_del (vat_main_t * vam)
14046 {
14047   unformat_input_t *i = vam->input;
14048   vl_api_policer_add_del_t *mp;
14049   f64 timeout;
14050   u8 is_add = 1;
14051   u8 *name = 0;
14052   u32 cir = 0;
14053   u32 eir = 0;
14054   u64 cb = 0;
14055   u64 eb = 0;
14056   u8 rate_type = 0;
14057   u8 round_type = 0;
14058   u8 type = 0;
14059   u8 color_aware = 0;
14060   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14061
14062   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14063   conform_action.dscp = 0;
14064   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14065   exceed_action.dscp = 0;
14066   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14067   violate_action.dscp = 0;
14068
14069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14070     {
14071       if (unformat (i, "del"))
14072         is_add = 0;
14073       else if (unformat (i, "name %s", &name))
14074         vec_add1 (name, 0);
14075       else if (unformat (i, "cir %u", &cir))
14076         ;
14077       else if (unformat (i, "eir %u", &eir))
14078         ;
14079       else if (unformat (i, "cb %u", &cb))
14080         ;
14081       else if (unformat (i, "eb %u", &eb))
14082         ;
14083       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14084                          &rate_type))
14085         ;
14086       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14087                          &round_type))
14088         ;
14089       else if (unformat (i, "type %U", unformat_policer_type, &type))
14090         ;
14091       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14092                          &conform_action))
14093         ;
14094       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14095                          &exceed_action))
14096         ;
14097       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14098                          &violate_action))
14099         ;
14100       else if (unformat (i, "color-aware"))
14101         color_aware = 1;
14102       else
14103         break;
14104     }
14105
14106   if (!vec_len (name))
14107     {
14108       errmsg ("policer name must be specified");
14109       return -99;
14110     }
14111
14112   if (vec_len (name) > 64)
14113     {
14114       errmsg ("policer name too long");
14115       return -99;
14116     }
14117
14118   M (POLICER_ADD_DEL, policer_add_del);
14119
14120   clib_memcpy (mp->name, name, vec_len (name));
14121   vec_free (name);
14122   mp->is_add = is_add;
14123   mp->cir = cir;
14124   mp->eir = eir;
14125   mp->cb = cb;
14126   mp->eb = eb;
14127   mp->rate_type = rate_type;
14128   mp->round_type = round_type;
14129   mp->type = type;
14130   mp->conform_action_type = conform_action.action_type;
14131   mp->conform_dscp = conform_action.dscp;
14132   mp->exceed_action_type = exceed_action.action_type;
14133   mp->exceed_dscp = exceed_action.dscp;
14134   mp->violate_action_type = violate_action.action_type;
14135   mp->violate_dscp = violate_action.dscp;
14136   mp->color_aware = color_aware;
14137
14138   S;
14139   W;
14140   /* NOTREACHED */
14141   return 0;
14142 }
14143
14144 static int
14145 api_policer_dump (vat_main_t * vam)
14146 {
14147   unformat_input_t *i = vam->input;
14148   vl_api_policer_dump_t *mp;
14149   f64 timeout = ~0;
14150   u8 *match_name = 0;
14151   u8 match_name_valid = 0;
14152
14153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14154     {
14155       if (unformat (i, "name %s", &match_name))
14156         {
14157           vec_add1 (match_name, 0);
14158           match_name_valid = 1;
14159         }
14160       else
14161         break;
14162     }
14163
14164   M (POLICER_DUMP, policer_dump);
14165   mp->match_name_valid = match_name_valid;
14166   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14167   vec_free (match_name);
14168   /* send it... */
14169   S;
14170
14171   /* Use a control ping for synchronization */
14172   {
14173     vl_api_control_ping_t *mp;
14174     M (CONTROL_PING, control_ping);
14175     S;
14176   }
14177   /* Wait for a reply... */
14178   W;
14179
14180   /* NOTREACHED */
14181   return 0;
14182 }
14183
14184 static int
14185 api_policer_classify_set_interface (vat_main_t * vam)
14186 {
14187   unformat_input_t *i = vam->input;
14188   vl_api_policer_classify_set_interface_t *mp;
14189   f64 timeout;
14190   u32 sw_if_index;
14191   int sw_if_index_set;
14192   u32 ip4_table_index = ~0;
14193   u32 ip6_table_index = ~0;
14194   u32 l2_table_index = ~0;
14195   u8 is_add = 1;
14196
14197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14198     {
14199       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14200         sw_if_index_set = 1;
14201       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14202         sw_if_index_set = 1;
14203       else if (unformat (i, "del"))
14204         is_add = 0;
14205       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14206         ;
14207       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14208         ;
14209       else if (unformat (i, "l2-table %d", &l2_table_index))
14210         ;
14211       else
14212         {
14213           clib_warning ("parse error '%U'", format_unformat_error, i);
14214           return -99;
14215         }
14216     }
14217
14218   if (sw_if_index_set == 0)
14219     {
14220       errmsg ("missing interface name or sw_if_index\n");
14221       return -99;
14222     }
14223
14224   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14225
14226   mp->sw_if_index = ntohl (sw_if_index);
14227   mp->ip4_table_index = ntohl (ip4_table_index);
14228   mp->ip6_table_index = ntohl (ip6_table_index);
14229   mp->l2_table_index = ntohl (l2_table_index);
14230   mp->is_add = is_add;
14231
14232   S;
14233   W;
14234   /* NOTREACHED */
14235   return 0;
14236 }
14237
14238 static int
14239 api_policer_classify_dump (vat_main_t * vam)
14240 {
14241   unformat_input_t *i = vam->input;
14242   vl_api_policer_classify_dump_t *mp;
14243   f64 timeout = ~0;
14244   u8 type = POLICER_CLASSIFY_N_TABLES;
14245
14246   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14247     ;
14248   else
14249     {
14250       errmsg ("classify table type must be specified\n");
14251       return -99;
14252     }
14253
14254   if (!vam->json_output)
14255     {
14256       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14257     }
14258
14259   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14260   mp->type = type;
14261   /* send it... */
14262   S;
14263
14264   /* Use a control ping for synchronization */
14265   {
14266     vl_api_control_ping_t *mp;
14267     M (CONTROL_PING, control_ping);
14268     S;
14269   }
14270   /* Wait for a reply... */
14271   W;
14272
14273   /* NOTREACHED */
14274   return 0;
14275 }
14276
14277 static int
14278 api_netmap_create (vat_main_t * vam)
14279 {
14280   unformat_input_t *i = vam->input;
14281   vl_api_netmap_create_t *mp;
14282   f64 timeout;
14283   u8 *if_name = 0;
14284   u8 hw_addr[6];
14285   u8 random_hw_addr = 1;
14286   u8 is_pipe = 0;
14287   u8 is_master = 0;
14288
14289   memset (hw_addr, 0, sizeof (hw_addr));
14290
14291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14292     {
14293       if (unformat (i, "name %s", &if_name))
14294         vec_add1 (if_name, 0);
14295       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14296         random_hw_addr = 0;
14297       else if (unformat (i, "pipe"))
14298         is_pipe = 1;
14299       else if (unformat (i, "master"))
14300         is_master = 1;
14301       else if (unformat (i, "slave"))
14302         is_master = 0;
14303       else
14304         break;
14305     }
14306
14307   if (!vec_len (if_name))
14308     {
14309       errmsg ("interface name must be specified");
14310       return -99;
14311     }
14312
14313   if (vec_len (if_name) > 64)
14314     {
14315       errmsg ("interface name too long");
14316       return -99;
14317     }
14318
14319   M (NETMAP_CREATE, netmap_create);
14320
14321   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14322   clib_memcpy (mp->hw_addr, hw_addr, 6);
14323   mp->use_random_hw_addr = random_hw_addr;
14324   mp->is_pipe = is_pipe;
14325   mp->is_master = is_master;
14326   vec_free (if_name);
14327
14328   S;
14329   W;
14330   /* NOTREACHED */
14331   return 0;
14332 }
14333
14334 static int
14335 api_netmap_delete (vat_main_t * vam)
14336 {
14337   unformat_input_t *i = vam->input;
14338   vl_api_netmap_delete_t *mp;
14339   f64 timeout;
14340   u8 *if_name = 0;
14341
14342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14343     {
14344       if (unformat (i, "name %s", &if_name))
14345         vec_add1 (if_name, 0);
14346       else
14347         break;
14348     }
14349
14350   if (!vec_len (if_name))
14351     {
14352       errmsg ("interface name must be specified");
14353       return -99;
14354     }
14355
14356   if (vec_len (if_name) > 64)
14357     {
14358       errmsg ("interface name too long");
14359       return -99;
14360     }
14361
14362   M (NETMAP_DELETE, netmap_delete);
14363
14364   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14365   vec_free (if_name);
14366
14367   S;
14368   W;
14369   /* NOTREACHED */
14370   return 0;
14371 }
14372
14373 static void vl_api_mpls_gre_tunnel_details_t_handler
14374   (vl_api_mpls_gre_tunnel_details_t * mp)
14375 {
14376   vat_main_t *vam = &vat_main;
14377   i32 i;
14378   i32 len = ntohl (mp->nlabels);
14379
14380   if (mp->l2_only == 0)
14381     {
14382       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14383                ntohl (mp->tunnel_index),
14384                format_ip4_address, &mp->tunnel_src,
14385                format_ip4_address, &mp->tunnel_dst,
14386                format_ip4_address, &mp->intfc_address,
14387                ntohl (mp->mask_width));
14388       for (i = 0; i < len; i++)
14389         {
14390           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14391         }
14392       fformat (vam->ofp, "\n");
14393       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14394                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14395     }
14396   else
14397     {
14398       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14399                ntohl (mp->tunnel_index),
14400                format_ip4_address, &mp->tunnel_src,
14401                format_ip4_address, &mp->tunnel_dst,
14402                format_ip4_address, &mp->intfc_address);
14403       for (i = 0; i < len; i++)
14404         {
14405           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14406         }
14407       fformat (vam->ofp, "\n");
14408       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14409                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14410     }
14411 }
14412
14413 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14414   (vl_api_mpls_gre_tunnel_details_t * mp)
14415 {
14416   vat_main_t *vam = &vat_main;
14417   vat_json_node_t *node = NULL;
14418   struct in_addr ip4;
14419   i32 i;
14420   i32 len = ntohl (mp->nlabels);
14421
14422   if (VAT_JSON_ARRAY != vam->json_tree.type)
14423     {
14424       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14425       vat_json_init_array (&vam->json_tree);
14426     }
14427   node = vat_json_array_add (&vam->json_tree);
14428
14429   vat_json_init_object (node);
14430   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14431   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14432   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14433   vat_json_object_add_uint (node, "inner_fib_index",
14434                             ntohl (mp->inner_fib_index));
14435   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14436   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14437   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14438   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14439   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14440   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14441   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14442   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14443   vat_json_object_add_uint (node, "outer_fib_index",
14444                             ntohl (mp->outer_fib_index));
14445   vat_json_object_add_uint (node, "label_count", len);
14446   for (i = 0; i < len; i++)
14447     {
14448       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14449     }
14450 }
14451
14452 static int
14453 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14454 {
14455   vl_api_mpls_gre_tunnel_dump_t *mp;
14456   f64 timeout;
14457   i32 index = -1;
14458
14459   /* Parse args required to build the message */
14460   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14461     {
14462       if (!unformat (vam->input, "tunnel_index %d", &index))
14463         {
14464           index = -1;
14465           break;
14466         }
14467     }
14468
14469   fformat (vam->ofp, "  tunnel_index %d\n", index);
14470
14471   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14472   mp->tunnel_index = htonl (index);
14473   S;
14474
14475   /* Use a control ping for synchronization */
14476   {
14477     vl_api_control_ping_t *mp;
14478     M (CONTROL_PING, control_ping);
14479     S;
14480   }
14481   W;
14482 }
14483
14484 static void vl_api_mpls_eth_tunnel_details_t_handler
14485   (vl_api_mpls_eth_tunnel_details_t * mp)
14486 {
14487   vat_main_t *vam = &vat_main;
14488   i32 i;
14489   i32 len = ntohl (mp->nlabels);
14490
14491   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14492            ntohl (mp->tunnel_index),
14493            format_ethernet_address, &mp->tunnel_dst_mac,
14494            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14495   for (i = 0; i < len; i++)
14496     {
14497       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14498     }
14499   fformat (vam->ofp, "\n");
14500   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14501            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14502 }
14503
14504 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14505   (vl_api_mpls_eth_tunnel_details_t * mp)
14506 {
14507   vat_main_t *vam = &vat_main;
14508   vat_json_node_t *node = NULL;
14509   struct in_addr ip4;
14510   i32 i;
14511   i32 len = ntohl (mp->nlabels);
14512
14513   if (VAT_JSON_ARRAY != vam->json_tree.type)
14514     {
14515       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14516       vat_json_init_array (&vam->json_tree);
14517     }
14518   node = vat_json_array_add (&vam->json_tree);
14519
14520   vat_json_init_object (node);
14521   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14522   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14523   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14524   vat_json_object_add_uint (node, "inner_fib_index",
14525                             ntohl (mp->inner_fib_index));
14526   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14527   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14528   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14529   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14530   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14531                                    format (0, "%U", format_ethernet_address,
14532                                            &mp->tunnel_dst_mac));
14533   vat_json_object_add_uint (node, "tx_sw_if_index",
14534                             ntohl (mp->tx_sw_if_index));
14535   vat_json_object_add_uint (node, "label_count", len);
14536   for (i = 0; i < len; i++)
14537     {
14538       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14539     }
14540 }
14541
14542 static int
14543 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14544 {
14545   vl_api_mpls_eth_tunnel_dump_t *mp;
14546   f64 timeout;
14547   i32 index = -1;
14548
14549   /* Parse args required to build the message */
14550   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14551     {
14552       if (!unformat (vam->input, "tunnel_index %d", &index))
14553         {
14554           index = -1;
14555           break;
14556         }
14557     }
14558
14559   fformat (vam->ofp, "  tunnel_index %d\n", index);
14560
14561   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14562   mp->tunnel_index = htonl (index);
14563   S;
14564
14565   /* Use a control ping for synchronization */
14566   {
14567     vl_api_control_ping_t *mp;
14568     M (CONTROL_PING, control_ping);
14569     S;
14570   }
14571   W;
14572 }
14573
14574 static void vl_api_mpls_fib_encap_details_t_handler
14575   (vl_api_mpls_fib_encap_details_t * mp)
14576 {
14577   vat_main_t *vam = &vat_main;
14578   i32 i;
14579   i32 len = ntohl (mp->nlabels);
14580
14581   fformat (vam->ofp, "table %d, dest %U, label ",
14582            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14583   for (i = 0; i < len; i++)
14584     {
14585       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14586     }
14587   fformat (vam->ofp, "\n");
14588 }
14589
14590 static void vl_api_mpls_fib_encap_details_t_handler_json
14591   (vl_api_mpls_fib_encap_details_t * mp)
14592 {
14593   vat_main_t *vam = &vat_main;
14594   vat_json_node_t *node = NULL;
14595   i32 i;
14596   i32 len = ntohl (mp->nlabels);
14597   struct in_addr ip4;
14598
14599   if (VAT_JSON_ARRAY != vam->json_tree.type)
14600     {
14601       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14602       vat_json_init_array (&vam->json_tree);
14603     }
14604   node = vat_json_array_add (&vam->json_tree);
14605
14606   vat_json_init_object (node);
14607   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14608   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14609   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14610   vat_json_object_add_ip4 (node, "dest", ip4);
14611   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14612   vat_json_object_add_uint (node, "label_count", len);
14613   for (i = 0; i < len; i++)
14614     {
14615       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14616     }
14617 }
14618
14619 static int
14620 api_mpls_fib_encap_dump (vat_main_t * vam)
14621 {
14622   vl_api_mpls_fib_encap_dump_t *mp;
14623   f64 timeout;
14624
14625   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14626   S;
14627
14628   /* Use a control ping for synchronization */
14629   {
14630     vl_api_control_ping_t *mp;
14631     M (CONTROL_PING, control_ping);
14632     S;
14633   }
14634   W;
14635 }
14636
14637 static void vl_api_mpls_fib_decap_details_t_handler
14638   (vl_api_mpls_fib_decap_details_t * mp)
14639 {
14640   vat_main_t *vam = &vat_main;
14641
14642   fformat (vam->ofp,
14643            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14644            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14645            ntohl (mp->label), ntohl (mp->s_bit));
14646 }
14647
14648 static void vl_api_mpls_fib_decap_details_t_handler_json
14649   (vl_api_mpls_fib_decap_details_t * mp)
14650 {
14651   vat_main_t *vam = &vat_main;
14652   vat_json_node_t *node = NULL;
14653   struct in_addr ip4;
14654
14655   if (VAT_JSON_ARRAY != vam->json_tree.type)
14656     {
14657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14658       vat_json_init_array (&vam->json_tree);
14659     }
14660   node = vat_json_array_add (&vam->json_tree);
14661
14662   vat_json_init_object (node);
14663   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14664   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14665   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14666   vat_json_object_add_ip4 (node, "dest", ip4);
14667   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14668   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14669   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14670   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14671   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14672 }
14673
14674 static int
14675 api_mpls_fib_decap_dump (vat_main_t * vam)
14676 {
14677   vl_api_mpls_fib_decap_dump_t *mp;
14678   f64 timeout;
14679
14680   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14681   S;
14682
14683   /* Use a control ping for synchronization */
14684   {
14685     vl_api_control_ping_t *mp;
14686     M (CONTROL_PING, control_ping);
14687     S;
14688   }
14689   W;
14690 }
14691
14692 int
14693 api_classify_table_ids (vat_main_t * vam)
14694 {
14695   vl_api_classify_table_ids_t *mp;
14696   f64 timeout;
14697
14698   /* Construct the API message */
14699   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14700   mp->context = 0;
14701
14702   S;
14703   W;
14704   /* NOTREACHED */
14705   return 0;
14706 }
14707
14708 int
14709 api_classify_table_by_interface (vat_main_t * vam)
14710 {
14711   unformat_input_t *input = vam->input;
14712   vl_api_classify_table_by_interface_t *mp;
14713   f64 timeout;
14714
14715   u32 sw_if_index = ~0;
14716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14717     {
14718       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14719         ;
14720       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14721         ;
14722       else
14723         break;
14724     }
14725   if (sw_if_index == ~0)
14726     {
14727       errmsg ("missing interface name or sw_if_index\n");
14728       return -99;
14729     }
14730
14731   /* Construct the API message */
14732   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14733   mp->context = 0;
14734   mp->sw_if_index = ntohl (sw_if_index);
14735
14736   S;
14737   W;
14738   /* NOTREACHED */
14739   return 0;
14740 }
14741
14742 int
14743 api_classify_table_info (vat_main_t * vam)
14744 {
14745   unformat_input_t *input = vam->input;
14746   vl_api_classify_table_info_t *mp;
14747   f64 timeout;
14748
14749   u32 table_id = ~0;
14750   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14751     {
14752       if (unformat (input, "table_id %d", &table_id))
14753         ;
14754       else
14755         break;
14756     }
14757   if (table_id == ~0)
14758     {
14759       errmsg ("missing table id\n");
14760       return -99;
14761     }
14762
14763   /* Construct the API message */
14764   M (CLASSIFY_TABLE_INFO, classify_table_info);
14765   mp->context = 0;
14766   mp->table_id = ntohl (table_id);
14767
14768   S;
14769   W;
14770   /* NOTREACHED */
14771   return 0;
14772 }
14773
14774 int
14775 api_classify_session_dump (vat_main_t * vam)
14776 {
14777   unformat_input_t *input = vam->input;
14778   vl_api_classify_session_dump_t *mp;
14779   f64 timeout;
14780
14781   u32 table_id = ~0;
14782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14783     {
14784       if (unformat (input, "table_id %d", &table_id))
14785         ;
14786       else
14787         break;
14788     }
14789   if (table_id == ~0)
14790     {
14791       errmsg ("missing table id\n");
14792       return -99;
14793     }
14794
14795   /* Construct the API message */
14796   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14797   mp->context = 0;
14798   mp->table_id = ntohl (table_id);
14799   S;
14800
14801   /* Use a control ping for synchronization */
14802   {
14803     vl_api_control_ping_t *mp;
14804     M (CONTROL_PING, control_ping);
14805     S;
14806   }
14807   W;
14808   /* NOTREACHED */
14809   return 0;
14810 }
14811
14812 static void
14813 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14814 {
14815   vat_main_t *vam = &vat_main;
14816
14817   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14818            "src_address %U, vrf_id %d, path_mtu %u, "
14819            "template_interval %u, udp_checksum %d\n",
14820            format_ip4_address, mp->collector_address,
14821            ntohs (mp->collector_port),
14822            format_ip4_address, mp->src_address,
14823            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14824            ntohl (mp->template_interval), mp->udp_checksum);
14825
14826   vam->retval = 0;
14827   vam->result_ready = 1;
14828 }
14829
14830 static void
14831   vl_api_ipfix_exporter_details_t_handler_json
14832   (vl_api_ipfix_exporter_details_t * mp)
14833 {
14834   vat_main_t *vam = &vat_main;
14835   vat_json_node_t node;
14836   struct in_addr collector_address;
14837   struct in_addr src_address;
14838
14839   vat_json_init_object (&node);
14840   clib_memcpy (&collector_address, &mp->collector_address,
14841                sizeof (collector_address));
14842   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14843   vat_json_object_add_uint (&node, "collector_port",
14844                             ntohs (mp->collector_port));
14845   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14846   vat_json_object_add_ip4 (&node, "src_address", src_address);
14847   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14848   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14849   vat_json_object_add_uint (&node, "template_interval",
14850                             ntohl (mp->template_interval));
14851   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14852
14853   vat_json_print (vam->ofp, &node);
14854   vat_json_free (&node);
14855   vam->retval = 0;
14856   vam->result_ready = 1;
14857 }
14858
14859 int
14860 api_ipfix_exporter_dump (vat_main_t * vam)
14861 {
14862   vl_api_ipfix_exporter_dump_t *mp;
14863   f64 timeout;
14864
14865   /* Construct the API message */
14866   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14867   mp->context = 0;
14868
14869   S;
14870   W;
14871   /* NOTREACHED */
14872   return 0;
14873 }
14874
14875 static int
14876 api_ipfix_classify_stream_dump (vat_main_t * vam)
14877 {
14878   vl_api_ipfix_classify_stream_dump_t *mp;
14879   f64 timeout;
14880
14881   /* Construct the API message */
14882   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14883   mp->context = 0;
14884
14885   S;
14886   W;
14887   /* NOTREACHED */
14888   return 0;
14889 }
14890
14891 static void
14892   vl_api_ipfix_classify_stream_details_t_handler
14893   (vl_api_ipfix_classify_stream_details_t * mp)
14894 {
14895   vat_main_t *vam = &vat_main;
14896   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14897            ntohl (mp->domain_id), ntohs (mp->src_port));
14898   vam->retval = 0;
14899   vam->result_ready = 1;
14900 }
14901
14902 static void
14903   vl_api_ipfix_classify_stream_details_t_handler_json
14904   (vl_api_ipfix_classify_stream_details_t * mp)
14905 {
14906   vat_main_t *vam = &vat_main;
14907   vat_json_node_t node;
14908
14909   vat_json_init_object (&node);
14910   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14911   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14912
14913   vat_json_print (vam->ofp, &node);
14914   vat_json_free (&node);
14915   vam->retval = 0;
14916   vam->result_ready = 1;
14917 }
14918
14919 static int
14920 api_ipfix_classify_table_dump (vat_main_t * vam)
14921 {
14922   vl_api_ipfix_classify_table_dump_t *mp;
14923   f64 timeout;
14924
14925   if (!vam->json_output)
14926     {
14927       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14928                "transport_protocol");
14929     }
14930
14931   /* Construct the API message */
14932   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14933
14934   /* send it... */
14935   S;
14936
14937   /* Use a control ping for synchronization */
14938   {
14939     vl_api_control_ping_t *mp;
14940     M (CONTROL_PING, control_ping);
14941     S;
14942   }
14943   W;
14944 }
14945
14946 static void
14947   vl_api_ipfix_classify_table_details_t_handler
14948   (vl_api_ipfix_classify_table_details_t * mp)
14949 {
14950   vat_main_t *vam = &vat_main;
14951   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14952            mp->transport_protocol);
14953 }
14954
14955 static void
14956   vl_api_ipfix_classify_table_details_t_handler_json
14957   (vl_api_ipfix_classify_table_details_t * mp)
14958 {
14959   vat_json_node_t *node = NULL;
14960   vat_main_t *vam = &vat_main;
14961
14962   if (VAT_JSON_ARRAY != vam->json_tree.type)
14963     {
14964       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14965       vat_json_init_array (&vam->json_tree);
14966     }
14967
14968   node = vat_json_array_add (&vam->json_tree);
14969   vat_json_init_object (node);
14970
14971   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
14972   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
14973   vat_json_object_add_uint (node, "transport_protocol",
14974                             mp->transport_protocol);
14975 }
14976
14977 int
14978 api_pg_create_interface (vat_main_t * vam)
14979 {
14980   unformat_input_t *input = vam->input;
14981   vl_api_pg_create_interface_t *mp;
14982   f64 timeout;
14983
14984   u32 if_id = ~0;
14985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14986     {
14987       if (unformat (input, "if_id %d", &if_id))
14988         ;
14989       else
14990         break;
14991     }
14992   if (if_id == ~0)
14993     {
14994       errmsg ("missing pg interface index\n");
14995       return -99;
14996     }
14997
14998   /* Construct the API message */
14999   M (PG_CREATE_INTERFACE, pg_create_interface);
15000   mp->context = 0;
15001   mp->interface_id = ntohl (if_id);
15002
15003   S;
15004   W;
15005   /* NOTREACHED */
15006   return 0;
15007 }
15008
15009 int
15010 api_pg_capture (vat_main_t * vam)
15011 {
15012   unformat_input_t *input = vam->input;
15013   vl_api_pg_capture_t *mp;
15014   f64 timeout;
15015
15016   u32 if_id = ~0;
15017   u8 enable = 1;
15018   u32 count = 1;
15019   u8 pcap_file_set = 0;
15020   u8 *pcap_file = 0;
15021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (input, "if_id %d", &if_id))
15024         ;
15025       else if (unformat (input, "pcap %s", &pcap_file))
15026         pcap_file_set = 1;
15027       else if (unformat (input, "count %d", &count))
15028         ;
15029       else if (unformat (input, "disable"))
15030         enable = 0;
15031       else
15032         break;
15033     }
15034   if (if_id == ~0)
15035     {
15036       errmsg ("missing pg interface index\n");
15037       return -99;
15038     }
15039   if (pcap_file_set > 0)
15040     {
15041       if (vec_len (pcap_file) > 255)
15042         {
15043           errmsg ("pcap file name is too long\n");
15044           return -99;
15045         }
15046     }
15047
15048   u32 name_len = vec_len (pcap_file);
15049   /* Construct the API message */
15050   M (PG_CAPTURE, pg_capture);
15051   mp->context = 0;
15052   mp->interface_id = ntohl (if_id);
15053   mp->is_enabled = enable;
15054   mp->count = ntohl (count);
15055   mp->pcap_name_length = ntohl (name_len);
15056   if (pcap_file_set != 0)
15057     {
15058       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15059     }
15060   vec_free (pcap_file);
15061
15062   S;
15063   W;
15064   /* NOTREACHED */
15065   return 0;
15066 }
15067
15068 int
15069 api_pg_enable_disable (vat_main_t * vam)
15070 {
15071   unformat_input_t *input = vam->input;
15072   vl_api_pg_enable_disable_t *mp;
15073   f64 timeout;
15074
15075   u8 enable = 1;
15076   u8 stream_name_set = 0;
15077   u8 *stream_name = 0;
15078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15079     {
15080       if (unformat (input, "stream %s", &stream_name))
15081         stream_name_set = 1;
15082       else if (unformat (input, "disable"))
15083         enable = 0;
15084       else
15085         break;
15086     }
15087
15088   if (stream_name_set > 0)
15089     {
15090       if (vec_len (stream_name) > 255)
15091         {
15092           errmsg ("stream name too long\n");
15093           return -99;
15094         }
15095     }
15096
15097   u32 name_len = vec_len (stream_name);
15098   /* Construct the API message */
15099   M (PG_ENABLE_DISABLE, pg_enable_disable);
15100   mp->context = 0;
15101   mp->is_enabled = enable;
15102   if (stream_name_set != 0)
15103     {
15104       mp->stream_name_length = ntohl (name_len);
15105       clib_memcpy (mp->stream_name, stream_name, name_len);
15106     }
15107   vec_free (stream_name);
15108
15109   S;
15110   W;
15111   /* NOTREACHED */
15112   return 0;
15113 }
15114
15115 int
15116 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15117 {
15118   unformat_input_t *input = vam->input;
15119   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15120   f64 timeout;
15121
15122   u16 *low_ports = 0;
15123   u16 *high_ports = 0;
15124   u16 this_low;
15125   u16 this_hi;
15126   ip4_address_t ip4_addr;
15127   ip6_address_t ip6_addr;
15128   u32 length;
15129   u32 tmp, tmp2;
15130   u8 prefix_set = 0;
15131   u32 vrf_id = ~0;
15132   u8 is_add = 1;
15133   u8 is_ipv6 = 0;
15134
15135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15136     {
15137       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15138         {
15139           prefix_set = 1;
15140         }
15141       else
15142         if (unformat
15143             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15144         {
15145           prefix_set = 1;
15146           is_ipv6 = 1;
15147         }
15148       else if (unformat (input, "vrf %d", &vrf_id))
15149         ;
15150       else if (unformat (input, "del"))
15151         is_add = 0;
15152       else if (unformat (input, "port %d", &tmp))
15153         {
15154           if (tmp == 0 || tmp > 65535)
15155             {
15156               errmsg ("port %d out of range", tmp);
15157               return -99;
15158             }
15159           this_low = tmp;
15160           this_hi = this_low + 1;
15161           vec_add1 (low_ports, this_low);
15162           vec_add1 (high_ports, this_hi);
15163         }
15164       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15165         {
15166           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15167             {
15168               errmsg ("incorrect range parameters\n");
15169               return -99;
15170             }
15171           this_low = tmp;
15172           /* Note: in debug CLI +1 is added to high before
15173              passing to real fn that does "the work"
15174              (ip_source_and_port_range_check_add_del).
15175              This fn is a wrapper around the binary API fn a
15176              control plane will call, which expects this increment
15177              to have occurred. Hence letting the binary API control
15178              plane fn do the increment for consistency between VAT
15179              and other control planes.
15180            */
15181           this_hi = tmp2;
15182           vec_add1 (low_ports, this_low);
15183           vec_add1 (high_ports, this_hi);
15184         }
15185       else
15186         break;
15187     }
15188
15189   if (prefix_set == 0)
15190     {
15191       errmsg ("<address>/<mask> not specified\n");
15192       return -99;
15193     }
15194
15195   if (vrf_id == ~0)
15196     {
15197       errmsg ("VRF ID required, not specified\n");
15198       return -99;
15199     }
15200
15201   if (vrf_id == 0)
15202     {
15203       errmsg
15204         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15205       return -99;
15206     }
15207
15208   if (vec_len (low_ports) == 0)
15209     {
15210       errmsg ("At least one port or port range required\n");
15211       return -99;
15212     }
15213
15214   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15215      ip_source_and_port_range_check_add_del);
15216
15217   mp->is_add = is_add;
15218
15219   if (is_ipv6)
15220     {
15221       mp->is_ipv6 = 1;
15222       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15223     }
15224   else
15225     {
15226       mp->is_ipv6 = 0;
15227       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15228     }
15229
15230   mp->mask_length = length;
15231   mp->number_of_ranges = vec_len (low_ports);
15232
15233   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15234   vec_free (low_ports);
15235
15236   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15237   vec_free (high_ports);
15238
15239   mp->vrf_id = ntohl (vrf_id);
15240
15241   S;
15242   W;
15243   /* NOTREACHED */
15244   return 0;
15245 }
15246
15247 int
15248 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15249 {
15250   unformat_input_t *input = vam->input;
15251   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15252   f64 timeout;
15253   u32 sw_if_index = ~0;
15254   int vrf_set = 0;
15255   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15256   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15257   u8 is_add = 1;
15258
15259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15260     {
15261       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15262         ;
15263       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15264         ;
15265       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15266         vrf_set = 1;
15267       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15268         vrf_set = 1;
15269       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15270         vrf_set = 1;
15271       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15272         vrf_set = 1;
15273       else if (unformat (input, "del"))
15274         is_add = 0;
15275       else
15276         break;
15277     }
15278
15279   if (sw_if_index == ~0)
15280     {
15281       errmsg ("Interface required but not specified\n");
15282       return -99;
15283     }
15284
15285   if (vrf_set == 0)
15286     {
15287       errmsg ("VRF ID required but not specified\n");
15288       return -99;
15289     }
15290
15291   if (tcp_out_vrf_id == 0
15292       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15293     {
15294       errmsg
15295         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15296       return -99;
15297     }
15298
15299   /* Construct the API message */
15300   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15301      ip_source_and_port_range_check_interface_add_del);
15302
15303   mp->sw_if_index = ntohl (sw_if_index);
15304   mp->is_add = is_add;
15305   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15306   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15307   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15308   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15309
15310   /* send it... */
15311   S;
15312
15313   /* Wait for a reply... */
15314   W;
15315 }
15316
15317 static int
15318 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15319 {
15320   unformat_input_t *i = vam->input;
15321   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15322   f64 timeout;
15323   u32 local_sa_id = 0;
15324   u32 remote_sa_id = 0;
15325   ip4_address_t src_address;
15326   ip4_address_t dst_address;
15327   u8 is_add = 1;
15328
15329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15330     {
15331       if (unformat (i, "local_sa %d", &local_sa_id))
15332         ;
15333       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15334         ;
15335       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15336         ;
15337       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15338         ;
15339       else if (unformat (i, "del"))
15340         is_add = 0;
15341       else
15342         {
15343           clib_warning ("parse error '%U'", format_unformat_error, i);
15344           return -99;
15345         }
15346     }
15347
15348   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15349
15350   mp->local_sa_id = ntohl (local_sa_id);
15351   mp->remote_sa_id = ntohl (remote_sa_id);
15352   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15353   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15354   mp->is_add = is_add;
15355
15356   S;
15357   W;
15358   /* NOTREACHED */
15359   return 0;
15360 }
15361
15362 static int
15363 api_punt (vat_main_t * vam)
15364 {
15365   unformat_input_t *i = vam->input;
15366   vl_api_punt_t *mp;
15367   f64 timeout;
15368   u32 ipv = ~0;
15369   u32 protocol = ~0;
15370   u32 port = ~0;
15371   int is_add = 1;
15372
15373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15374     {
15375       if (unformat (i, "ip %d", &ipv))
15376         ;
15377       else if (unformat (i, "protocol %d", &protocol))
15378         ;
15379       else if (unformat (i, "port %d", &port))
15380         ;
15381       else if (unformat (i, "del"))
15382         is_add = 0;
15383       else
15384         {
15385           clib_warning ("parse error '%U'", format_unformat_error, i);
15386           return -99;
15387         }
15388     }
15389
15390   M (PUNT, punt);
15391
15392   mp->is_add = (u8) is_add;
15393   mp->ipv = (u8) ipv;
15394   mp->l4_protocol = (u8) protocol;
15395   mp->l4_port = htons ((u16) port);
15396
15397   S;
15398   W;
15399   /* NOTREACHED */
15400   return 0;
15401 }
15402
15403 static void vl_api_ipsec_gre_tunnel_details_t_handler
15404   (vl_api_ipsec_gre_tunnel_details_t * mp)
15405 {
15406   vat_main_t *vam = &vat_main;
15407
15408   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15409            ntohl (mp->sw_if_index),
15410            format_ip4_address, &mp->src_address,
15411            format_ip4_address, &mp->dst_address,
15412            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15413 }
15414
15415 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15416   (vl_api_ipsec_gre_tunnel_details_t * mp)
15417 {
15418   vat_main_t *vam = &vat_main;
15419   vat_json_node_t *node = NULL;
15420   struct in_addr ip4;
15421
15422   if (VAT_JSON_ARRAY != vam->json_tree.type)
15423     {
15424       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15425       vat_json_init_array (&vam->json_tree);
15426     }
15427   node = vat_json_array_add (&vam->json_tree);
15428
15429   vat_json_init_object (node);
15430   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15431   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15432   vat_json_object_add_ip4 (node, "src_address", ip4);
15433   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15434   vat_json_object_add_ip4 (node, "dst_address", ip4);
15435   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15436   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15437 }
15438
15439 static int
15440 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15441 {
15442   unformat_input_t *i = vam->input;
15443   vl_api_ipsec_gre_tunnel_dump_t *mp;
15444   f64 timeout;
15445   u32 sw_if_index;
15446   u8 sw_if_index_set = 0;
15447
15448   /* Parse args required to build the message */
15449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15450     {
15451       if (unformat (i, "sw_if_index %d", &sw_if_index))
15452         sw_if_index_set = 1;
15453       else
15454         break;
15455     }
15456
15457   if (sw_if_index_set == 0)
15458     {
15459       sw_if_index = ~0;
15460     }
15461
15462   if (!vam->json_output)
15463     {
15464       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15465                "sw_if_index", "src_address", "dst_address",
15466                "local_sa_id", "remote_sa_id");
15467     }
15468
15469   /* Get list of gre-tunnel interfaces */
15470   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15471
15472   mp->sw_if_index = htonl (sw_if_index);
15473
15474   S;
15475
15476   /* Use a control ping for synchronization */
15477   {
15478     vl_api_control_ping_t *mp;
15479     M (CONTROL_PING, control_ping);
15480     S;
15481   }
15482   W;
15483 }
15484
15485 static int
15486 api_delete_subif (vat_main_t * vam)
15487 {
15488   unformat_input_t *i = vam->input;
15489   vl_api_delete_subif_t *mp;
15490   f64 timeout;
15491   u32 sw_if_index = ~0;
15492
15493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15494     {
15495       if (unformat (i, "sw_if_index %d", &sw_if_index))
15496         ;
15497       else
15498         break;
15499     }
15500
15501   if (sw_if_index == ~0)
15502     {
15503       errmsg ("missing sw_if_index\n");
15504       return -99;
15505     }
15506
15507   /* Construct the API message */
15508   M (DELETE_SUBIF, delete_subif);
15509   mp->sw_if_index = ntohl (sw_if_index);
15510
15511   S;
15512   W;
15513 }
15514
15515 #define foreach_pbb_vtr_op      \
15516 _("disable",  L2_VTR_DISABLED)  \
15517 _("pop",  L2_VTR_POP_2)         \
15518 _("push",  L2_VTR_PUSH_2)
15519
15520 static int
15521 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15522 {
15523   unformat_input_t *i = vam->input;
15524   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15525   f64 timeout;
15526   u32 sw_if_index = ~0, vtr_op = ~0;
15527   u16 outer_tag = ~0;
15528   u8 dmac[6], smac[6];
15529   u8 dmac_set = 0, smac_set = 0;
15530   u16 vlanid = 0;
15531   u32 sid = ~0;
15532   u32 tmp;
15533
15534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15535     {
15536       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15537         ;
15538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15539         ;
15540       else if (unformat (i, "vtr_op %d", &vtr_op))
15541         ;
15542 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15543       foreach_pbb_vtr_op
15544 #undef _
15545         else if (unformat (i, "translate_pbb_stag"))
15546         {
15547           if (unformat (i, "%d", &tmp))
15548             {
15549               vtr_op = L2_VTR_TRANSLATE_2_1;
15550               outer_tag = tmp;
15551             }
15552           else
15553             {
15554               errmsg
15555                 ("translate_pbb_stag operation requires outer tag definition\n");
15556               return -99;
15557             }
15558         }
15559       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15560         dmac_set++;
15561       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15562         smac_set++;
15563       else if (unformat (i, "sid %d", &sid))
15564         ;
15565       else if (unformat (i, "vlanid %d", &tmp))
15566         vlanid = tmp;
15567       else
15568         {
15569           clib_warning ("parse error '%U'", format_unformat_error, i);
15570           return -99;
15571         }
15572     }
15573
15574   if ((sw_if_index == ~0) || (vtr_op == ~0))
15575     {
15576       errmsg ("missing sw_if_index or vtr operation\n");
15577       return -99;
15578     }
15579   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15580       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15581     {
15582       errmsg
15583         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15584       return -99;
15585     }
15586
15587   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15588   mp->sw_if_index = ntohl (sw_if_index);
15589   mp->vtr_op = ntohl (vtr_op);
15590   mp->outer_tag = ntohs (outer_tag);
15591   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15592   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15593   mp->b_vlanid = ntohs (vlanid);
15594   mp->i_sid = ntohl (sid);
15595
15596   S;
15597   W;
15598   /* NOTREACHED */
15599   return 0;
15600 }
15601
15602 static int
15603 api_flow_classify_set_interface (vat_main_t * vam)
15604 {
15605   unformat_input_t *i = vam->input;
15606   vl_api_flow_classify_set_interface_t *mp;
15607   f64 timeout;
15608   u32 sw_if_index;
15609   int sw_if_index_set;
15610   u32 ip4_table_index = ~0;
15611   u32 ip6_table_index = ~0;
15612   u8 is_add = 1;
15613
15614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15615     {
15616       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15617         sw_if_index_set = 1;
15618       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15619         sw_if_index_set = 1;
15620       else if (unformat (i, "del"))
15621         is_add = 0;
15622       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15623         ;
15624       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15625         ;
15626       else
15627         {
15628           clib_warning ("parse error '%U'", format_unformat_error, i);
15629           return -99;
15630         }
15631     }
15632
15633   if (sw_if_index_set == 0)
15634     {
15635       errmsg ("missing interface name or sw_if_index\n");
15636       return -99;
15637     }
15638
15639   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
15640
15641   mp->sw_if_index = ntohl (sw_if_index);
15642   mp->ip4_table_index = ntohl (ip4_table_index);
15643   mp->ip6_table_index = ntohl (ip6_table_index);
15644   mp->is_add = is_add;
15645
15646   S;
15647   W;
15648   /* NOTREACHED */
15649   return 0;
15650 }
15651
15652 static int
15653 api_flow_classify_dump (vat_main_t * vam)
15654 {
15655   unformat_input_t *i = vam->input;
15656   vl_api_flow_classify_dump_t *mp;
15657   f64 timeout = ~0;
15658   u8 type = FLOW_CLASSIFY_N_TABLES;
15659
15660   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
15661     ;
15662   else
15663     {
15664       errmsg ("classify table type must be specified\n");
15665       return -99;
15666     }
15667
15668   if (!vam->json_output)
15669     {
15670       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15671     }
15672
15673   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
15674   mp->type = type;
15675   /* send it... */
15676   S;
15677
15678   /* Use a control ping for synchronization */
15679   {
15680     vl_api_control_ping_t *mp;
15681     M (CONTROL_PING, control_ping);
15682     S;
15683   }
15684   /* Wait for a reply... */
15685   W;
15686
15687   /* NOTREACHED */
15688   return 0;
15689 }
15690
15691 static int
15692 q_or_quit (vat_main_t * vam)
15693 {
15694   longjmp (vam->jump_buf, 1);
15695   return 0;                     /* not so much */
15696 }
15697
15698 static int
15699 q (vat_main_t * vam)
15700 {
15701   return q_or_quit (vam);
15702 }
15703
15704 static int
15705 quit (vat_main_t * vam)
15706 {
15707   return q_or_quit (vam);
15708 }
15709
15710 static int
15711 comment (vat_main_t * vam)
15712 {
15713   return 0;
15714 }
15715
15716 static int
15717 cmd_cmp (void *a1, void *a2)
15718 {
15719   u8 **c1 = a1;
15720   u8 **c2 = a2;
15721
15722   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15723 }
15724
15725 static int
15726 help (vat_main_t * vam)
15727 {
15728   u8 **cmds = 0;
15729   u8 *name = 0;
15730   hash_pair_t *p;
15731   unformat_input_t *i = vam->input;
15732   int j;
15733
15734   if (unformat (i, "%s", &name))
15735     {
15736       uword *hs;
15737
15738       vec_add1 (name, 0);
15739
15740       hs = hash_get_mem (vam->help_by_name, name);
15741       if (hs)
15742         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15743       else
15744         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15745       vec_free (name);
15746       return 0;
15747     }
15748
15749   fformat (vam->ofp, "Help is available for the following:\n");
15750
15751     /* *INDENT-OFF* */
15752     hash_foreach_pair (p, vam->function_by_name,
15753     ({
15754       vec_add1 (cmds, (u8 *)(p->key));
15755     }));
15756     /* *INDENT-ON* */
15757
15758   vec_sort_with_function (cmds, cmd_cmp);
15759
15760   for (j = 0; j < vec_len (cmds); j++)
15761     fformat (vam->ofp, "%s\n", cmds[j]);
15762
15763   vec_free (cmds);
15764   return 0;
15765 }
15766
15767 static int
15768 set (vat_main_t * vam)
15769 {
15770   u8 *name = 0, *value = 0;
15771   unformat_input_t *i = vam->input;
15772
15773   if (unformat (i, "%s", &name))
15774     {
15775       /* The input buffer is a vector, not a string. */
15776       value = vec_dup (i->buffer);
15777       vec_delete (value, i->index, 0);
15778       /* Almost certainly has a trailing newline */
15779       if (value[vec_len (value) - 1] == '\n')
15780         value[vec_len (value) - 1] = 0;
15781       /* Make sure it's a proper string, one way or the other */
15782       vec_add1 (value, 0);
15783       (void) clib_macro_set_value (&vam->macro_main,
15784                                    (char *) name, (char *) value);
15785     }
15786   else
15787     errmsg ("usage: set <name> <value>\n");
15788
15789   vec_free (name);
15790   vec_free (value);
15791   return 0;
15792 }
15793
15794 static int
15795 unset (vat_main_t * vam)
15796 {
15797   u8 *name = 0;
15798
15799   if (unformat (vam->input, "%s", &name))
15800     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15801       errmsg ("unset: %s wasn't set\n", name);
15802   vec_free (name);
15803   return 0;
15804 }
15805
15806 typedef struct
15807 {
15808   u8 *name;
15809   u8 *value;
15810 } macro_sort_t;
15811
15812
15813 static int
15814 macro_sort_cmp (void *a1, void *a2)
15815 {
15816   macro_sort_t *s1 = a1;
15817   macro_sort_t *s2 = a2;
15818
15819   return strcmp ((char *) (s1->name), (char *) (s2->name));
15820 }
15821
15822 static int
15823 dump_macro_table (vat_main_t * vam)
15824 {
15825   macro_sort_t *sort_me = 0, *sm;
15826   int i;
15827   hash_pair_t *p;
15828
15829     /* *INDENT-OFF* */
15830     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15831     ({
15832       vec_add2 (sort_me, sm, 1);
15833       sm->name = (u8 *)(p->key);
15834       sm->value = (u8 *) (p->value[0]);
15835     }));
15836     /* *INDENT-ON* */
15837
15838   vec_sort_with_function (sort_me, macro_sort_cmp);
15839
15840   if (vec_len (sort_me))
15841     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15842   else
15843     fformat (vam->ofp, "The macro table is empty...\n");
15844
15845   for (i = 0; i < vec_len (sort_me); i++)
15846     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15847   return 0;
15848 }
15849
15850 static int
15851 dump_node_table (vat_main_t * vam)
15852 {
15853   int i, j;
15854   vlib_node_t *node, *next_node;
15855
15856   if (vec_len (vam->graph_nodes) == 0)
15857     {
15858       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15859       return 0;
15860     }
15861
15862   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15863     {
15864       node = vam->graph_nodes[i];
15865       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15866       for (j = 0; j < vec_len (node->next_nodes); j++)
15867         {
15868           if (node->next_nodes[j] != ~0)
15869             {
15870               next_node = vam->graph_nodes[node->next_nodes[j]];
15871               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15872             }
15873         }
15874     }
15875   return 0;
15876 }
15877
15878 static int
15879 search_node_table (vat_main_t * vam)
15880 {
15881   unformat_input_t *line_input = vam->input;
15882   u8 *node_to_find;
15883   int j;
15884   vlib_node_t *node, *next_node;
15885   uword *p;
15886
15887   if (vam->graph_node_index_by_name == 0)
15888     {
15889       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15890       return 0;
15891     }
15892
15893   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15894     {
15895       if (unformat (line_input, "%s", &node_to_find))
15896         {
15897           vec_add1 (node_to_find, 0);
15898           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15899           if (p == 0)
15900             {
15901               fformat (vam->ofp, "%s not found...\n", node_to_find);
15902               goto out;
15903             }
15904           node = vam->graph_nodes[p[0]];
15905           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15906           for (j = 0; j < vec_len (node->next_nodes); j++)
15907             {
15908               if (node->next_nodes[j] != ~0)
15909                 {
15910                   next_node = vam->graph_nodes[node->next_nodes[j]];
15911                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15912                 }
15913             }
15914         }
15915
15916       else
15917         {
15918           clib_warning ("parse error '%U'", format_unformat_error,
15919                         line_input);
15920           return -99;
15921         }
15922
15923     out:
15924       vec_free (node_to_find);
15925
15926     }
15927
15928   return 0;
15929 }
15930
15931
15932 static int
15933 script (vat_main_t * vam)
15934 {
15935   u8 *s = 0;
15936   char *save_current_file;
15937   unformat_input_t save_input;
15938   jmp_buf save_jump_buf;
15939   u32 save_line_number;
15940
15941   FILE *new_fp, *save_ifp;
15942
15943   if (unformat (vam->input, "%s", &s))
15944     {
15945       new_fp = fopen ((char *) s, "r");
15946       if (new_fp == 0)
15947         {
15948           errmsg ("Couldn't open script file %s\n", s);
15949           vec_free (s);
15950           return -99;
15951         }
15952     }
15953   else
15954     {
15955       errmsg ("Missing script name\n");
15956       return -99;
15957     }
15958
15959   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15960   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15961   save_ifp = vam->ifp;
15962   save_line_number = vam->input_line_number;
15963   save_current_file = (char *) vam->current_file;
15964
15965   vam->input_line_number = 0;
15966   vam->ifp = new_fp;
15967   vam->current_file = s;
15968   do_one_file (vam);
15969
15970   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15971   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15972   vam->ifp = save_ifp;
15973   vam->input_line_number = save_line_number;
15974   vam->current_file = (u8 *) save_current_file;
15975   vec_free (s);
15976
15977   return 0;
15978 }
15979
15980 static int
15981 echo (vat_main_t * vam)
15982 {
15983   fformat (vam->ofp, "%v", vam->input->buffer);
15984   return 0;
15985 }
15986
15987 /* List of API message constructors, CLI names map to api_xxx */
15988 #define foreach_vpe_api_msg                                             \
15989 _(create_loopback,"[mac <mac-addr>]")                                   \
15990 _(sw_interface_dump,"")                                                 \
15991 _(sw_interface_set_flags,                                               \
15992   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15993 _(sw_interface_add_del_address,                                         \
15994   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15995 _(sw_interface_set_table,                                               \
15996   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15997 _(sw_interface_set_vpath,                                               \
15998   "<intfc> | sw_if_index <id> enable | disable")                        \
15999 _(sw_interface_set_l2_xconnect,                                         \
16000   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16001   "enable | disable")                                                   \
16002 _(sw_interface_set_l2_bridge,                                           \
16003   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16004   "[shg <split-horizon-group>] [bvi]\n"                                 \
16005   "enable | disable")                                                   \
16006 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16007   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16008   "profile <profile-id>\n")                                             \
16009 _(sw_interface_set_dpdk_hqos_subport,                                   \
16010   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16011   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16012 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16013   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16014 _(bridge_domain_add_del,                                                \
16015   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16016 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16017 _(l2fib_add_del,                                                        \
16018   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16019 _(l2_flags,                                                             \
16020   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16021 _(bridge_flags,                                                         \
16022   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16023 _(tap_connect,                                                          \
16024   "tapname <name> mac <mac-addr> | random-mac")                         \
16025 _(tap_modify,                                                           \
16026   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16027 _(tap_delete,                                                           \
16028   "<vpp-if-name> | sw_if_index <id>")                                   \
16029 _(sw_interface_tap_dump, "")                                            \
16030 _(ip_add_del_route,                                                     \
16031   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
16032   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16033   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16034   "[multipath] [count <n>]")                                            \
16035 _(proxy_arp_add_del,                                                    \
16036   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16037 _(proxy_arp_intfc_enable_disable,                                       \
16038   "<intfc> | sw_if_index <id> enable | disable")                        \
16039 _(mpls_add_del_encap,                                                   \
16040   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16041 _(mpls_add_del_decap,                                                   \
16042   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
16043 _(mpls_gre_add_del_tunnel,                                              \
16044   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
16045   "adj <ip4-address>/<mask-width> [del]")                               \
16046 _(sw_interface_set_unnumbered,                                          \
16047   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16048 _(ip_neighbor_add_del,                                                  \
16049   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16050   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16051 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16052 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16053 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16054   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16055   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16056   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16057 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16058 _(reset_fib, "vrf <n> [ipv6]")                                          \
16059 _(dhcp_proxy_config,                                                    \
16060   "svr <v46-address> src <v46-address>\n"                               \
16061    "insert-cid <n> [del]")                                              \
16062 _(dhcp_proxy_config_2,                                                  \
16063   "svr <v46-address> src <v46-address>\n"                               \
16064    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16065 _(dhcp_proxy_set_vss,                                                   \
16066   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16067 _(dhcp_client_config,                                                   \
16068   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16069 _(set_ip_flow_hash,                                                     \
16070   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16071 _(sw_interface_ip6_enable_disable,                                      \
16072   "<intfc> | sw_if_index <id> enable | disable")                        \
16073 _(sw_interface_ip6_set_link_local_address,                              \
16074   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16075 _(sw_interface_ip6nd_ra_prefix,                                         \
16076   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16077   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16078   "[nolink] [isno]")                                                    \
16079 _(sw_interface_ip6nd_ra_config,                                         \
16080   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16081   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16082   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16083 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16084 _(l2_patch_add_del,                                                     \
16085   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16086   "enable | disable")                                                   \
16087 _(mpls_ethernet_add_del_tunnel,                                         \
16088   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16089   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16090 _(mpls_ethernet_add_del_tunnel_2,                                       \
16091   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16092   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16093 _(sr_tunnel_add_del,                                                    \
16094   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16095   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16096   "[policy <policy_name>]")                                             \
16097 _(sr_policy_add_del,                                                    \
16098   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16099 _(sr_multicast_map_add_del,                                             \
16100   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16101 _(classify_add_del_table,                                               \
16102   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16103   "[del] mask <mask-value>\n"                                           \
16104   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
16105 _(classify_add_del_session,                                             \
16106   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16107   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16108   "  [l3 [ip4|ip6]]")                                                   \
16109 _(classify_set_interface_ip_table,                                      \
16110   "<intfc> | sw_if_index <nn> table <nn>")                              \
16111 _(classify_set_interface_l2_tables,                                     \
16112   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16113   "  [other-table <nn>]")                                               \
16114 _(get_node_index, "node <node-name")                                    \
16115 _(add_node_next, "node <node-name> next <next-node-name>")              \
16116 _(l2tpv3_create_tunnel,                                                 \
16117   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16118   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16119   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16120 _(l2tpv3_set_tunnel_cookies,                                            \
16121   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16122   "[new_remote_cookie <nn>]\n")                                         \
16123 _(l2tpv3_interface_enable_disable,                                      \
16124   "<intfc> | sw_if_index <nn> enable | disable")                        \
16125 _(l2tpv3_set_lookup_key,                                                \
16126   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16127 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16128 _(vxlan_add_del_tunnel,                                                 \
16129   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16130   " [decap-next l2|ip4|ip6] [del]")                                     \
16131 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16132 _(gre_add_del_tunnel,                                                   \
16133   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16134 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16135 _(l2_fib_clear_table, "")                                               \
16136 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16137 _(l2_interface_vlan_tag_rewrite,                                        \
16138   "<intfc> | sw_if_index <nn> \n"                                       \
16139   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16140   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16141 _(create_vhost_user_if,                                                 \
16142         "socket <filename> [server] [renumber <dev_instance>] "         \
16143         "[mac <mac_address>]")                                          \
16144 _(modify_vhost_user_if,                                                 \
16145         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16146         "[server] [renumber <dev_instance>]")                           \
16147 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16148 _(sw_interface_vhost_user_dump, "")                                     \
16149 _(show_version, "")                                                     \
16150 _(vxlan_gpe_add_del_tunnel,                                             \
16151   "local <addr> remote <addr> vni <nn>\n"                               \
16152     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16153   "[next-ethernet] [next-nsh]\n")                                       \
16154 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16155 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16156 _(interface_name_renumber,                                              \
16157   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16158 _(input_acl_set_interface,                                              \
16159   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16160   "  [l2-table <nn>] [del]")                                            \
16161 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16162 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16163 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16164 _(ip_dump, "ipv4 | ipv6")                                               \
16165 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16166 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16167   "  spid_id <n> ")                                                     \
16168 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16169   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16170   "  integ_alg <alg> integ_key <hex>")                                  \
16171 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16172   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16173   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16174   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16175 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16176 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16177 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16178   "(auth_data 0x<data> | auth_data <data>)")                            \
16179 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16180   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16181 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16182   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16183   "(local|remote)")                                                     \
16184 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16185 _(delete_loopback,"sw_if_index <nn>")                                   \
16186 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16187 _(map_add_domain,                                                       \
16188   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16189   "ip6-src <ip6addr> "                                                  \
16190   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16191 _(map_del_domain, "index <n>")                                          \
16192 _(map_add_del_rule,                                                     \
16193   "index <n> psid <n> dst <ip6addr> [del]")                             \
16194 _(map_domain_dump, "")                                                  \
16195 _(map_rule_dump, "index <map-domain>")                                  \
16196 _(want_interface_events,  "enable|disable")                             \
16197 _(want_stats,"enable|disable")                                          \
16198 _(get_first_msg_id, "client <name>")                                    \
16199 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16200 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16201   "fib-id <nn> [ip4][ip6][default]")                                    \
16202 _(get_node_graph, " ")                                                  \
16203 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16204 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16205 _(ioam_disable, "")                                                \
16206 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16207                             " sw_if_index <sw_if_index> p <priority> "  \
16208                             "w <weight>] [del]")                        \
16209 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16210                         "iface <intf> | sw_if_index <sw_if_index> "     \
16211                         "p <priority> w <weight> [del]")                \
16212 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16213                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16214                           "locator-set <locator_name> [del]")           \
16215 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16216   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16217 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16218 _(lisp_gpe_enable_disable, "enable|disable")                            \
16219 _(lisp_enable_disable, "enable|disable")                                \
16220 _(lisp_gpe_add_del_iface, "up|down")                                    \
16221 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16222                                "[seid <seid>] "                         \
16223                                "rloc <locator> p <prio> "               \
16224                                "w <weight> [rloc <loc> ... ] "          \
16225                                "action <action> [del-all]")             \
16226 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16227                           "<local-eid>")                                \
16228 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16229 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16230 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16231 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16232 _(lisp_locator_set_dump, "[local | remote]")                            \
16233 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16234 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16235                        "[local] | [remote]")                            \
16236 _(lisp_eid_table_vni_dump, "")                                          \
16237 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16238 _(lisp_gpe_tunnel_dump, "")                                             \
16239 _(lisp_map_resolver_dump, "")                                           \
16240 _(show_lisp_status, "")                                                 \
16241 _(lisp_get_map_request_itr_rlocs, "")                                   \
16242 _(show_lisp_pitr, "")                                                   \
16243 _(show_lisp_map_request_mode, "")                                       \
16244 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16245 _(af_packet_delete, "name <host interface name>")                       \
16246 _(policer_add_del, "name <policer name> <params> [del]")                \
16247 _(policer_dump, "[name <policer name>]")                                \
16248 _(policer_classify_set_interface,                                       \
16249   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16250   "  [l2-table <nn>] [del]")                                            \
16251 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16252 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16253     "[master|slave]")                                                   \
16254 _(netmap_delete, "name <interface name>")                               \
16255 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16256 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16257 _(mpls_fib_encap_dump, "")                                              \
16258 _(mpls_fib_decap_dump, "")                                              \
16259 _(classify_table_ids, "")                                               \
16260 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16261 _(classify_table_info, "table_id <nn>")                                 \
16262 _(classify_session_dump, "table_id <nn>")                               \
16263 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16264     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16265     "[template_interval <nn>] [udp_checksum]")                          \
16266 _(ipfix_exporter_dump, "")                                              \
16267 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16268 _(ipfix_classify_stream_dump, "")                                       \
16269 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16270 _(ipfix_classify_table_dump, "")                                        \
16271 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16272 _(pg_create_interface, "if_id <nn>")                                    \
16273 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16274 _(pg_enable_disable, "[stream <id>] disable")                           \
16275 _(ip_source_and_port_range_check_add_del,                               \
16276   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16277 _(ip_source_and_port_range_check_interface_add_del,                     \
16278   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16279   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16280 _(ipsec_gre_add_del_tunnel,                                             \
16281   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16282 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16283 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
16284 _(l2_interface_pbb_tag_rewrite,                                         \
16285   "<intfc> | sw_if_index <nn> \n"                                       \
16286   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16287   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16288 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16289 _(flow_classify_set_interface,                                          \
16290   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16291 _(flow_classify_dump, "type [ip4|ip6]")
16292
16293 /* List of command functions, CLI names map directly to functions */
16294 #define foreach_cli_function                                    \
16295 _(comment, "usage: comment <ignore-rest-of-line>")              \
16296 _(dump_interface_table, "usage: dump_interface_table")          \
16297 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16298 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16299 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16300 _(dump_stats_table, "usage: dump_stats_table")                  \
16301 _(dump_macro_table, "usage: dump_macro_table ")                 \
16302 _(dump_node_table, "usage: dump_node_table")                    \
16303 _(echo, "usage: echo <message>")                                \
16304 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16305 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16306 _(help, "usage: help")                                          \
16307 _(q, "usage: quit")                                             \
16308 _(quit, "usage: quit")                                          \
16309 _(search_node_table, "usage: search_node_table <name>...")      \
16310 _(set, "usage: set <variable-name> <value>")                    \
16311 _(script, "usage: script <file-name>")                          \
16312 _(unset, "usage: unset <variable-name>")
16313
16314 #define _(N,n)                                  \
16315     static void vl_api_##n##_t_handler_uni      \
16316     (vl_api_##n##_t * mp)                       \
16317     {                                           \
16318         vat_main_t * vam = &vat_main;           \
16319         if (vam->json_output) {                 \
16320             vl_api_##n##_t_handler_json(mp);    \
16321         } else {                                \
16322             vl_api_##n##_t_handler(mp);         \
16323         }                                       \
16324     }
16325 foreach_vpe_api_reply_msg;
16326 #undef _
16327
16328 void
16329 vat_api_hookup (vat_main_t * vam)
16330 {
16331 #define _(N,n)                                                  \
16332     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16333                            vl_api_##n##_t_handler_uni,          \
16334                            vl_noop_handler,                     \
16335                            vl_api_##n##_t_endian,               \
16336                            vl_api_##n##_t_print,                \
16337                            sizeof(vl_api_##n##_t), 1);
16338   foreach_vpe_api_reply_msg;
16339 #undef _
16340
16341   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16342
16343   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16344
16345   vam->function_by_name = hash_create_string (0, sizeof (uword));
16346
16347   vam->help_by_name = hash_create_string (0, sizeof (uword));
16348
16349   /* API messages we can send */
16350 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16351   foreach_vpe_api_msg;
16352 #undef _
16353
16354   /* Help strings */
16355 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16356   foreach_vpe_api_msg;
16357 #undef _
16358
16359   /* CLI functions */
16360 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16361   foreach_cli_function;
16362 #undef _
16363
16364   /* Help strings */
16365 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16366   foreach_cli_function;
16367 #undef _
16368 }
16369
16370 #undef vl_api_version
16371 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16372 #include <vpp-api/vpe.api.h>
16373 #undef vl_api_version
16374
16375 void
16376 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16377 {
16378   /*
16379    * Send the main API signature in slot 0. This bit of code must
16380    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16381    */
16382   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16383 }
16384
16385 /*
16386  * fd.io coding-style-patch-verification: ON
16387  *
16388  * Local Variables:
16389  * eval: (c-set-style "gnu")
16390  * End:
16391  */