Deprecate MPLSoGRE tunnels (VPP-502)
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53
54 #include "vat/json_format.h"
55
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp-api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp-api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp-api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 uword
75 unformat_sw_if_index (unformat_input_t * input, va_list * args)
76 {
77   vat_main_t *vam = va_arg (*args, vat_main_t *);
78   u32 *result = va_arg (*args, u32 *);
79   u8 *if_name;
80   uword *p;
81
82   if (!unformat (input, "%s", &if_name))
83     return 0;
84
85   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
86   if (p == 0)
87     return 0;
88   *result = p[0];
89   return 1;
90 }
91
92 /* Parse an IP4 address %d.%d.%d.%d. */
93 uword
94 unformat_ip4_address (unformat_input_t * input, va_list * args)
95 {
96   u8 *result = va_arg (*args, u8 *);
97   unsigned a[4];
98
99   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
100     return 0;
101
102   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
103     return 0;
104
105   result[0] = a[0];
106   result[1] = a[1];
107   result[2] = a[2];
108   result[3] = a[3];
109
110   return 1;
111 }
112
113
114 uword
115 unformat_ethernet_address (unformat_input_t * input, va_list * args)
116 {
117   u8 *result = va_arg (*args, u8 *);
118   u32 i, a[6];
119
120   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
121                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
122     return 0;
123
124   /* Check range. */
125   for (i = 0; i < 6; i++)
126     if (a[i] >= (1 << 8))
127       return 0;
128
129   for (i = 0; i < 6; i++)
130     result[i] = a[i];
131
132   return 1;
133 }
134
135 /* Returns ethernet type as an int in host byte order. */
136 uword
137 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
138                                         va_list * args)
139 {
140   u16 *result = va_arg (*args, u16 *);
141   int type;
142
143   /* Numeric type. */
144   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
145     {
146       if (type >= (1 << 16))
147         return 0;
148       *result = type;
149       return 1;
150     }
151   return 0;
152 }
153
154 /* Parse an IP6 address. */
155 uword
156 unformat_ip6_address (unformat_input_t * input, va_list * args)
157 {
158   ip6_address_t *result = va_arg (*args, ip6_address_t *);
159   u16 hex_quads[8];
160   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
161   uword c, n_colon, double_colon_index;
162
163   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
164   double_colon_index = ARRAY_LEN (hex_quads);
165   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
166     {
167       hex_digit = 16;
168       if (c >= '0' && c <= '9')
169         hex_digit = c - '0';
170       else if (c >= 'a' && c <= 'f')
171         hex_digit = c + 10 - 'a';
172       else if (c >= 'A' && c <= 'F')
173         hex_digit = c + 10 - 'A';
174       else if (c == ':' && n_colon < 2)
175         n_colon++;
176       else
177         {
178           unformat_put_input (input);
179           break;
180         }
181
182       /* Too many hex quads. */
183       if (n_hex_quads >= ARRAY_LEN (hex_quads))
184         return 0;
185
186       if (hex_digit < 16)
187         {
188           hex_quad = (hex_quad << 4) | hex_digit;
189
190           /* Hex quad must fit in 16 bits. */
191           if (n_hex_digits >= 4)
192             return 0;
193
194           n_colon = 0;
195           n_hex_digits++;
196         }
197
198       /* Save position of :: */
199       if (n_colon == 2)
200         {
201           /* More than one :: ? */
202           if (double_colon_index < ARRAY_LEN (hex_quads))
203             return 0;
204           double_colon_index = n_hex_quads;
205         }
206
207       if (n_colon > 0 && n_hex_digits > 0)
208         {
209           hex_quads[n_hex_quads++] = hex_quad;
210           hex_quad = 0;
211           n_hex_digits = 0;
212         }
213     }
214
215   if (n_hex_digits > 0)
216     hex_quads[n_hex_quads++] = hex_quad;
217
218   {
219     word i;
220
221     /* Expand :: to appropriate number of zero hex quads. */
222     if (double_colon_index < ARRAY_LEN (hex_quads))
223       {
224         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
225
226         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
227           hex_quads[n_zero + i] = hex_quads[i];
228
229         for (i = 0; i < n_zero; i++)
230           hex_quads[double_colon_index + i] = 0;
231
232         n_hex_quads = ARRAY_LEN (hex_quads);
233       }
234
235     /* Too few hex quads given. */
236     if (n_hex_quads < ARRAY_LEN (hex_quads))
237       return 0;
238
239     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
240       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
241
242     return 1;
243   }
244 }
245
246 uword
247 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
248 {
249 #if DPDK > 0
250   u32 *r = va_arg (*args, u32 *);
251
252   if (0);
253 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254   foreach_ipsec_policy_action
255 #undef _
256     else
257     return 0;
258   return 1;
259 #else
260   return 0;
261 #endif
262 }
263
264 uword
265 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
266 {
267 #if DPDK > 0
268   u32 *r = va_arg (*args, u32 *);
269
270   if (0);
271 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
272   foreach_ipsec_crypto_alg
273 #undef _
274     else
275     return 0;
276   return 1;
277 #else
278   return 0;
279 #endif
280 }
281
282 u8 *
283 format_ipsec_crypto_alg (u8 * s, va_list * args)
284 {
285 #if DPDK > 0
286   u32 i = va_arg (*args, u32);
287   u8 *t = 0;
288
289   switch (i)
290     {
291 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
292       foreach_ipsec_crypto_alg
293 #undef _
294     default:
295       return format (s, "unknown");
296     }
297   return format (s, "%s", t);
298 #else
299   return format (s, "Unimplemented");
300 #endif
301 }
302
303 uword
304 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
305 {
306 #if DPDK > 0
307   u32 *r = va_arg (*args, u32 *);
308
309   if (0);
310 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
311   foreach_ipsec_integ_alg
312 #undef _
313     else
314     return 0;
315   return 1;
316 #else
317   return 0;
318 #endif
319 }
320
321 u8 *
322 format_ipsec_integ_alg (u8 * s, va_list * args)
323 {
324 #if DPDK > 0
325   u32 i = va_arg (*args, u32);
326   u8 *t = 0;
327
328   switch (i)
329     {
330 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
331       foreach_ipsec_integ_alg
332 #undef _
333     default:
334       return format (s, "unknown");
335     }
336   return format (s, "%s", t);
337 #else
338   return format (s, "Unsupported");
339 #endif
340 }
341
342 uword
343 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
344 {
345 #if DPDK > 0
346   u32 *r = va_arg (*args, u32 *);
347
348   if (0);
349 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
350   foreach_ikev2_auth_method
351 #undef _
352     else
353     return 0;
354   return 1;
355 #else
356   return 0;
357 #endif
358 }
359
360 uword
361 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
362 {
363 #if DPDK > 0
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
368   foreach_ikev2_id_type
369 #undef _
370     else
371     return 0;
372   return 1;
373 #else
374   return 0;
375 #endif
376 }
377
378 uword
379 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
380 {
381   u8 *r = va_arg (*args, u8 *);
382
383   if (unformat (input, "kbps"))
384     *r = SSE2_QOS_RATE_KBPS;
385   else if (unformat (input, "pps"))
386     *r = SSE2_QOS_RATE_PPS;
387   else
388     return 0;
389   return 1;
390 }
391
392 uword
393 unformat_policer_round_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "closest"))
398     *r = SSE2_QOS_ROUND_TO_CLOSEST;
399   else if (unformat (input, "up"))
400     *r = SSE2_QOS_ROUND_TO_UP;
401   else if (unformat (input, "down"))
402     *r = SSE2_QOS_ROUND_TO_DOWN;
403   else
404     return 0;
405   return 1;
406 }
407
408 uword
409 unformat_policer_type (unformat_input_t * input, va_list * args)
410 {
411   u8 *r = va_arg (*args, u8 *);
412
413   if (unformat (input, "1r2c"))
414     *r = SSE2_QOS_POLICER_TYPE_1R2C;
415   else if (unformat (input, "1r3c"))
416     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
417   else if (unformat (input, "2r3c-2698"))
418     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
419   else if (unformat (input, "2r3c-4115"))
420     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
421   else if (unformat (input, "2r3c-mef5cf1"))
422     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
423   else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_dscp (unformat_input_t * input, va_list * va)
430 {
431   u8 *r = va_arg (*va, u8 *);
432
433   if (0);
434 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
435   foreach_vnet_dscp
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_policer_action_type (unformat_input_t * input, va_list * va)
444 {
445   sse2_qos_pol_action_params_st *a
446     = va_arg (*va, sse2_qos_pol_action_params_st *);
447
448   if (unformat (input, "drop"))
449     a->action_type = SSE2_QOS_ACTION_DROP;
450   else if (unformat (input, "transmit"))
451     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
452   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
453     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
454   else
455     return 0;
456   return 1;
457 }
458
459 uword
460 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
461 {
462   u32 *r = va_arg (*va, u32 *);
463   u32 tid;
464
465   if (unformat (input, "ip4"))
466     tid = POLICER_CLASSIFY_TABLE_IP4;
467   else if (unformat (input, "ip6"))
468     tid = POLICER_CLASSIFY_TABLE_IP6;
469   else if (unformat (input, "l2"))
470     tid = POLICER_CLASSIFY_TABLE_L2;
471   else
472     return 0;
473
474   *r = tid;
475   return 1;
476 }
477
478 uword
479 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
480 {
481   u32 *r = va_arg (*va, u32 *);
482   u32 tid;
483
484   if (unformat (input, "ip4"))
485     tid = FLOW_CLASSIFY_TABLE_IP4;
486   else if (unformat (input, "ip6"))
487     tid = FLOW_CLASSIFY_TABLE_IP6;
488   else
489     return 0;
490
491   *r = tid;
492   return 1;
493 }
494
495 u8 *
496 format_ip4_address (u8 * s, va_list * args)
497 {
498   u8 *a = va_arg (*args, u8 *);
499   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
500 }
501
502 u8 *
503 format_ip6_address (u8 * s, va_list * args)
504 {
505   ip6_address_t *a = va_arg (*args, ip6_address_t *);
506   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
507
508   i_max_n_zero = ARRAY_LEN (a->as_u16);
509   max_n_zeros = 0;
510   i_first_zero = i_max_n_zero;
511   n_zeros = 0;
512   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
513     {
514       u32 is_zero = a->as_u16[i] == 0;
515       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
516         {
517           i_first_zero = i;
518           n_zeros = 0;
519         }
520       n_zeros += is_zero;
521       if ((!is_zero && n_zeros > max_n_zeros)
522           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
523         {
524           i_max_n_zero = i_first_zero;
525           max_n_zeros = n_zeros;
526           i_first_zero = ARRAY_LEN (a->as_u16);
527           n_zeros = 0;
528         }
529     }
530
531   last_double_colon = 0;
532   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
533     {
534       if (i == i_max_n_zero && max_n_zeros > 1)
535         {
536           s = format (s, "::");
537           i += max_n_zeros - 1;
538           last_double_colon = 1;
539         }
540       else
541         {
542           s = format (s, "%s%x",
543                       (last_double_colon || i == 0) ? "" : ":",
544                       clib_net_to_host_u16 (a->as_u16[i]));
545           last_double_colon = 0;
546         }
547     }
548
549   return s;
550 }
551
552 /* Format an IP46 address. */
553 u8 *
554 format_ip46_address (u8 * s, va_list * args)
555 {
556   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
557   ip46_type_t type = va_arg (*args, ip46_type_t);
558   int is_ip4 = 1;
559
560   switch (type)
561     {
562     case IP46_TYPE_ANY:
563       is_ip4 = ip46_address_is_ip4 (ip46);
564       break;
565     case IP46_TYPE_IP4:
566       is_ip4 = 1;
567       break;
568     case IP46_TYPE_IP6:
569       is_ip4 = 0;
570       break;
571     }
572
573   return is_ip4 ?
574     format (s, "%U", format_ip4_address, &ip46->ip4) :
575     format (s, "%U", format_ip6_address, &ip46->ip6);
576 }
577
578 u8 *
579 format_ethernet_address (u8 * s, va_list * args)
580 {
581   u8 *a = va_arg (*args, u8 *);
582
583   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
584                  a[0], a[1], a[2], a[3], a[4], a[5]);
585 }
586
587 void
588 increment_v4_address (ip4_address_t * a)
589 {
590   u32 v;
591
592   v = ntohl (a->as_u32) + 1;
593   a->as_u32 = ntohl (v);
594 }
595
596 void
597 increment_v6_address (ip6_address_t * a)
598 {
599   u64 v0, v1;
600
601   v0 = clib_net_to_host_u64 (a->as_u64[0]);
602   v1 = clib_net_to_host_u64 (a->as_u64[1]);
603
604   v1 += 1;
605   if (v1 == 0)
606     v0 += 1;
607   a->as_u64[0] = clib_net_to_host_u64 (v0);
608   a->as_u64[1] = clib_net_to_host_u64 (v1);
609 }
610
611 void
612 increment_mac_address (u64 * mac)
613 {
614   u64 tmp = *mac;
615
616   tmp = clib_net_to_host_u64 (tmp);
617   tmp += 1 << 16;               /* skip unused (least significant) octets */
618   tmp = clib_host_to_net_u64 (tmp);
619   *mac = tmp;
620 }
621
622 static void vl_api_create_loopback_reply_t_handler
623   (vl_api_create_loopback_reply_t * mp)
624 {
625   vat_main_t *vam = &vat_main;
626   i32 retval = ntohl (mp->retval);
627
628   vam->retval = retval;
629   vam->regenerate_interface_table = 1;
630   vam->sw_if_index = ntohl (mp->sw_if_index);
631   vam->result_ready = 1;
632 }
633
634 static void vl_api_create_loopback_reply_t_handler_json
635   (vl_api_create_loopback_reply_t * mp)
636 {
637   vat_main_t *vam = &vat_main;
638   vat_json_node_t node;
639
640   vat_json_init_object (&node);
641   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
642   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
643
644   vat_json_print (vam->ofp, &node);
645   vat_json_free (&node);
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_af_packet_create_reply_t_handler
651   (vl_api_af_packet_create_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_af_packet_create_reply_t_handler_json
663   (vl_api_af_packet_create_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_vlan_subif_reply_t_handler
680   (vl_api_create_vlan_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_vlan_subif_reply_t_handler_json
692   (vl_api_create_vlan_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_create_subif_reply_t_handler
709   (vl_api_create_subif_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->sw_if_index = ntohl (mp->sw_if_index);
717   vam->result_ready = 1;
718 }
719
720 static void vl_api_create_subif_reply_t_handler_json
721   (vl_api_create_subif_reply_t * mp)
722 {
723   vat_main_t *vam = &vat_main;
724   vat_json_node_t node;
725
726   vat_json_init_object (&node);
727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
729
730   vat_json_print (vam->ofp, &node);
731   vat_json_free (&node);
732
733   vam->retval = ntohl (mp->retval);
734   vam->result_ready = 1;
735 }
736
737 static void vl_api_interface_name_renumber_reply_t_handler
738   (vl_api_interface_name_renumber_reply_t * mp)
739 {
740   vat_main_t *vam = &vat_main;
741   i32 retval = ntohl (mp->retval);
742
743   vam->retval = retval;
744   vam->regenerate_interface_table = 1;
745   vam->result_ready = 1;
746 }
747
748 static void vl_api_interface_name_renumber_reply_t_handler_json
749   (vl_api_interface_name_renumber_reply_t * mp)
750 {
751   vat_main_t *vam = &vat_main;
752   vat_json_node_t node;
753
754   vat_json_init_object (&node);
755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
756
757   vat_json_print (vam->ofp, &node);
758   vat_json_free (&node);
759
760   vam->retval = ntohl (mp->retval);
761   vam->result_ready = 1;
762 }
763
764 /*
765  * Special-case: build the interface table, maintain
766  * the next loopback sw_if_index vbl.
767  */
768 static void vl_api_sw_interface_details_t_handler
769   (vl_api_sw_interface_details_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   u8 *s = format (0, "%s%c", mp->interface_name, 0);
773
774   hash_set_mem (vam->sw_if_index_by_interface_name, s,
775                 ntohl (mp->sw_if_index));
776
777   /* In sub interface case, fill the sub interface table entry */
778   if (mp->sw_if_index != mp->sup_sw_if_index)
779     {
780       sw_interface_subif_t *sub = NULL;
781
782       vec_add2 (vam->sw_if_subif_table, sub, 1);
783
784       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
785       strncpy ((char *) sub->interface_name, (char *) s,
786                vec_len (sub->interface_name));
787       sub->sw_if_index = ntohl (mp->sw_if_index);
788       sub->sub_id = ntohl (mp->sub_id);
789
790       sub->sub_dot1ad = mp->sub_dot1ad;
791       sub->sub_number_of_tags = mp->sub_number_of_tags;
792       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
793       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
794       sub->sub_exact_match = mp->sub_exact_match;
795       sub->sub_default = mp->sub_default;
796       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
797       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
798
799       /* vlan tag rewrite */
800       sub->vtr_op = ntohl (mp->vtr_op);
801       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
802       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
803       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
804     }
805 }
806
807 static void vl_api_sw_interface_details_t_handler_json
808   (vl_api_sw_interface_details_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t *node = NULL;
812
813   if (VAT_JSON_ARRAY != vam->json_tree.type)
814     {
815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
816       vat_json_init_array (&vam->json_tree);
817     }
818   node = vat_json_array_add (&vam->json_tree);
819
820   vat_json_init_object (node);
821   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
822   vat_json_object_add_uint (node, "sup_sw_if_index",
823                             ntohl (mp->sup_sw_if_index));
824   vat_json_object_add_uint (node, "l2_address_length",
825                             ntohl (mp->l2_address_length));
826   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
827                              sizeof (mp->l2_address));
828   vat_json_object_add_string_copy (node, "interface_name",
829                                    mp->interface_name);
830   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
831   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
832   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
833   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
834   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
835   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
836   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
837   vat_json_object_add_uint (node, "sub_number_of_tags",
838                             mp->sub_number_of_tags);
839   vat_json_object_add_uint (node, "sub_outer_vlan_id",
840                             ntohs (mp->sub_outer_vlan_id));
841   vat_json_object_add_uint (node, "sub_inner_vlan_id",
842                             ntohs (mp->sub_inner_vlan_id));
843   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
844   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
845   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
846                             mp->sub_outer_vlan_id_any);
847   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
848                             mp->sub_inner_vlan_id_any);
849   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
850   vat_json_object_add_uint (node, "vtr_push_dot1q",
851                             ntohl (mp->vtr_push_dot1q));
852   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
853   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
854 }
855
856 static void vl_api_sw_interface_set_flags_t_handler
857   (vl_api_sw_interface_set_flags_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   if (vam->interface_event_display)
861     errmsg ("interface flags: sw_if_index %d %s %s\n",
862             ntohl (mp->sw_if_index),
863             mp->admin_up_down ? "admin-up" : "admin-down",
864             mp->link_up_down ? "link-up" : "link-down");
865 }
866
867 static void vl_api_sw_interface_set_flags_t_handler_json
868   (vl_api_sw_interface_set_flags_t * mp)
869 {
870   /* JSON output not supported */
871 }
872
873 static void
874 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   i32 retval = ntohl (mp->retval);
878
879   vam->retval = retval;
880   vam->shmem_result = (u8 *) mp->reply_in_shmem;
881   vam->result_ready = 1;
882 }
883
884 static void
885 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   vat_json_node_t node;
889   api_main_t *am = &api_main;
890   void *oldheap;
891   u8 *reply;
892
893   vat_json_init_object (&node);
894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
895   vat_json_object_add_uint (&node, "reply_in_shmem",
896                             ntohl (mp->reply_in_shmem));
897   /* Toss the shared-memory original... */
898   pthread_mutex_lock (&am->vlib_rp->mutex);
899   oldheap = svm_push_data_heap (am->vlib_rp);
900
901   reply = (u8 *) (mp->reply_in_shmem);
902   vec_free (reply);
903
904   svm_pop_heap (oldheap);
905   pthread_mutex_unlock (&am->vlib_rp->mutex);
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 static void
915 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   i32 retval = ntohl (mp->retval);
919
920   vam->retval = retval;
921   vam->cmd_reply = mp->reply;
922   vam->result_ready = 1;
923 }
924
925 static void
926 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_string_copy (&node, "reply", mp->reply);
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_classify_add_del_table_reply_t_handler
943   (vl_api_classify_add_del_table_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947   if (vam->async_mode)
948     {
949       vam->async_errors += (retval < 0);
950     }
951   else
952     {
953       vam->retval = retval;
954       if (retval == 0 &&
955           ((mp->new_table_index != 0xFFFFFFFF) ||
956            (mp->skip_n_vectors != 0xFFFFFFFF) ||
957            (mp->match_n_vectors != 0xFFFFFFFF)))
958         /*
959          * Note: this is just barely thread-safe, depends on
960          * the main thread spinning waiting for an answer...
961          */
962         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
963                 ntohl (mp->new_table_index),
964                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
965       vam->result_ready = 1;
966     }
967 }
968
969 static void vl_api_classify_add_del_table_reply_t_handler_json
970   (vl_api_classify_add_del_table_reply_t * mp)
971 {
972   vat_main_t *vam = &vat_main;
973   vat_json_node_t node;
974
975   vat_json_init_object (&node);
976   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
977   vat_json_object_add_uint (&node, "new_table_index",
978                             ntohl (mp->new_table_index));
979   vat_json_object_add_uint (&node, "skip_n_vectors",
980                             ntohl (mp->skip_n_vectors));
981   vat_json_object_add_uint (&node, "match_n_vectors",
982                             ntohl (mp->match_n_vectors));
983
984   vat_json_print (vam->ofp, &node);
985   vat_json_free (&node);
986
987   vam->retval = ntohl (mp->retval);
988   vam->result_ready = 1;
989 }
990
991 static void vl_api_get_node_index_reply_t_handler
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   i32 retval = ntohl (mp->retval);
996   if (vam->async_mode)
997     {
998       vam->async_errors += (retval < 0);
999     }
1000   else
1001     {
1002       vam->retval = retval;
1003       if (retval == 0)
1004         errmsg ("node index %d\n", ntohl (mp->node_index));
1005       vam->result_ready = 1;
1006     }
1007 }
1008
1009 static void vl_api_get_node_index_reply_t_handler_json
1010   (vl_api_get_node_index_reply_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t node;
1014
1015   vat_json_init_object (&node);
1016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1017   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1018
1019   vat_json_print (vam->ofp, &node);
1020   vat_json_free (&node);
1021
1022   vam->retval = ntohl (mp->retval);
1023   vam->result_ready = 1;
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031   if (vam->async_mode)
1032     {
1033       vam->async_errors += (retval < 0);
1034     }
1035   else
1036     {
1037       vam->retval = retval;
1038       if (retval == 0)
1039         errmsg ("next node index %d\n", ntohl (mp->next_index));
1040       vam->result_ready = 1;
1041     }
1042 }
1043
1044 static void vl_api_get_next_index_reply_t_handler_json
1045   (vl_api_get_next_index_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049
1050   vat_json_init_object (&node);
1051   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1052   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1053
1054   vat_json_print (vam->ofp, &node);
1055   vat_json_free (&node);
1056
1057   vam->retval = ntohl (mp->retval);
1058   vam->result_ready = 1;
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   i32 retval = ntohl (mp->retval);
1066   if (vam->async_mode)
1067     {
1068       vam->async_errors += (retval < 0);
1069     }
1070   else
1071     {
1072       vam->retval = retval;
1073       if (retval == 0)
1074         errmsg ("next index %d\n", ntohl (mp->next_index));
1075       vam->result_ready = 1;
1076     }
1077 }
1078
1079 static void vl_api_add_node_next_reply_t_handler_json
1080   (vl_api_add_node_next_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   vat_json_node_t node;
1084
1085   vat_json_init_object (&node);
1086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1087   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1088
1089   vat_json_print (vam->ofp, &node);
1090   vat_json_free (&node);
1091
1092   vam->retval = ntohl (mp->retval);
1093   vam->result_ready = 1;
1094 }
1095
1096 static void vl_api_show_version_reply_t_handler
1097   (vl_api_show_version_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   i32 retval = ntohl (mp->retval);
1101
1102   if (retval >= 0)
1103     {
1104       errmsg ("        program: %s\n", mp->program);
1105       errmsg ("        version: %s\n", mp->version);
1106       errmsg ("     build date: %s\n", mp->build_date);
1107       errmsg ("build directory: %s\n", mp->build_directory);
1108     }
1109   vam->retval = retval;
1110   vam->result_ready = 1;
1111 }
1112
1113 static void vl_api_show_version_reply_t_handler_json
1114   (vl_api_show_version_reply_t * mp)
1115 {
1116   vat_main_t *vam = &vat_main;
1117   vat_json_node_t node;
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "program", mp->program);
1122   vat_json_object_add_string_copy (&node, "version", mp->version);
1123   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1124   vat_json_object_add_string_copy (&node, "build_directory",
1125                                    mp->build_directory);
1126
1127   vat_json_print (vam->ofp, &node);
1128   vat_json_free (&node);
1129
1130   vam->retval = ntohl (mp->retval);
1131   vam->result_ready = 1;
1132 }
1133
1134 static void
1135 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1136 {
1137   vat_main_t *vam = &vat_main;
1138   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1139           mp->mac_ip ? "mac/ip binding" : "address resolution",
1140           format_ip4_address, &mp->address,
1141           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1142 }
1143
1144 static void
1145 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1146 {
1147   /* JSON output not supported */
1148 }
1149
1150 static void
1151 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip6_address, mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 /*
1167  * Special-case: build the bridge domain table, maintain
1168  * the next bd id vbl.
1169  */
1170 static void vl_api_bridge_domain_details_t_handler
1171   (vl_api_bridge_domain_details_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1175
1176   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1177            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1178
1179   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1180            ntohl (mp->bd_id), mp->learn, mp->forward,
1181            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1182
1183   if (n_sw_ifs)
1184     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1185              "Interface Name");
1186 }
1187
1188 static void vl_api_bridge_domain_details_t_handler_json
1189   (vl_api_bridge_domain_details_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   vat_json_node_t *node, *array = NULL;
1193
1194   if (VAT_JSON_ARRAY != vam->json_tree.type)
1195     {
1196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1197       vat_json_init_array (&vam->json_tree);
1198     }
1199   node = vat_json_array_add (&vam->json_tree);
1200
1201   vat_json_init_object (node);
1202   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1203   vat_json_object_add_uint (node, "flood", mp->flood);
1204   vat_json_object_add_uint (node, "forward", mp->forward);
1205   vat_json_object_add_uint (node, "learn", mp->learn);
1206   vat_json_object_add_uint (node, "bvi_sw_if_index",
1207                             ntohl (mp->bvi_sw_if_index));
1208   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1209   array = vat_json_object_add (node, "sw_if");
1210   vat_json_init_array (array);
1211 }
1212
1213 /*
1214  * Special-case: build the bridge domain sw if table.
1215  */
1216 static void vl_api_bridge_domain_sw_if_details_t_handler
1217   (vl_api_bridge_domain_sw_if_details_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   hash_pair_t *p;
1221   u8 *sw_if_name = 0;
1222   u32 sw_if_index;
1223
1224   sw_if_index = ntohl (mp->sw_if_index);
1225   /* *INDENT-OFF* */
1226   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1227   ({
1228     if ((u32) p->value[0] == sw_if_index)
1229       {
1230         sw_if_name = (u8 *)(p->key);
1231         break;
1232       }
1233   }));
1234   /* *INDENT-ON* */
1235
1236   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1237            mp->shg, sw_if_name ? (char *) sw_if_name :
1238            "sw_if_index not found!");
1239 }
1240
1241 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1242   (vl_api_bridge_domain_sw_if_details_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t *node = NULL;
1246   uword last_index = 0;
1247
1248   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1249   ASSERT (vec_len (vam->json_tree.array) >= 1);
1250   last_index = vec_len (vam->json_tree.array) - 1;
1251   node = &vam->json_tree.array[last_index];
1252   node = vat_json_object_get_element (node, "sw_if");
1253   ASSERT (NULL != node);
1254   node = vat_json_array_add (node);
1255
1256   vat_json_init_object (node);
1257   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1258   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1259   vat_json_object_add_uint (node, "shg", mp->shg);
1260 }
1261
1262 static void vl_api_control_ping_reply_t_handler
1263   (vl_api_control_ping_reply_t * mp)
1264 {
1265   vat_main_t *vam = &vat_main;
1266   i32 retval = ntohl (mp->retval);
1267   if (vam->async_mode)
1268     {
1269       vam->async_errors += (retval < 0);
1270     }
1271   else
1272     {
1273       vam->retval = retval;
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler_json
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283
1284   if (VAT_JSON_NONE != vam->json_tree.type)
1285     {
1286       vat_json_print (vam->ofp, &vam->json_tree);
1287       vat_json_free (&vam->json_tree);
1288       vam->json_tree.type = VAT_JSON_NONE;
1289     }
1290   else
1291     {
1292       /* just print [] */
1293       vat_json_init_array (&vam->json_tree);
1294       vat_json_print (vam->ofp, &vam->json_tree);
1295       vam->json_tree.type = VAT_JSON_NONE;
1296     }
1297
1298   vam->retval = retval;
1299   vam->result_ready = 1;
1300 }
1301
1302 static void
1303 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   i32 retval = ntohl (mp->retval);
1307   if (vam->async_mode)
1308     {
1309       vam->async_errors += (retval < 0);
1310     }
1311   else
1312     {
1313       vam->retval = retval;
1314       vam->result_ready = 1;
1315     }
1316 }
1317
1318 static void vl_api_l2_flags_reply_t_handler_json
1319   (vl_api_l2_flags_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   vat_json_node_t node;
1323
1324   vat_json_init_object (&node);
1325   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1326   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1327                             ntohl (mp->resulting_feature_bitmap));
1328
1329   vat_json_print (vam->ofp, &node);
1330   vat_json_free (&node);
1331
1332   vam->retval = ntohl (mp->retval);
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_bridge_flags_reply_t_handler
1337   (vl_api_bridge_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   i32 retval = ntohl (mp->retval);
1341   if (vam->async_mode)
1342     {
1343       vam->async_errors += (retval < 0);
1344     }
1345   else
1346     {
1347       vam->retval = retval;
1348       vam->result_ready = 1;
1349     }
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler_json
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   vat_json_node_t node;
1357
1358   vat_json_init_object (&node);
1359   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1360   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1361                             ntohl (mp->resulting_feature_bitmap));
1362
1363   vat_json_print (vam->ofp, &node);
1364   vat_json_free (&node);
1365
1366   vam->retval = ntohl (mp->retval);
1367   vam->result_ready = 1;
1368 }
1369
1370 static void vl_api_tap_connect_reply_t_handler
1371   (vl_api_tap_connect_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   i32 retval = ntohl (mp->retval);
1375   if (vam->async_mode)
1376     {
1377       vam->async_errors += (retval < 0);
1378     }
1379   else
1380     {
1381       vam->retval = retval;
1382       vam->sw_if_index = ntohl (mp->sw_if_index);
1383       vam->result_ready = 1;
1384     }
1385
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler_json
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   vat_json_node_t node;
1393
1394   vat_json_init_object (&node);
1395   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1396   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1397
1398   vat_json_print (vam->ofp, &node);
1399   vat_json_free (&node);
1400
1401   vam->retval = ntohl (mp->retval);
1402   vam->result_ready = 1;
1403
1404 }
1405
1406 static void
1407 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   i32 retval = ntohl (mp->retval);
1411   if (vam->async_mode)
1412     {
1413       vam->async_errors += (retval < 0);
1414     }
1415   else
1416     {
1417       vam->retval = retval;
1418       vam->sw_if_index = ntohl (mp->sw_if_index);
1419       vam->result_ready = 1;
1420     }
1421 }
1422
1423 static void vl_api_tap_modify_reply_t_handler_json
1424   (vl_api_tap_modify_reply_t * mp)
1425 {
1426   vat_main_t *vam = &vat_main;
1427   vat_json_node_t node;
1428
1429   vat_json_init_object (&node);
1430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1431   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1432
1433   vat_json_print (vam->ofp, &node);
1434   vat_json_free (&node);
1435
1436   vam->retval = ntohl (mp->retval);
1437   vam->result_ready = 1;
1438 }
1439
1440 static void
1441 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   i32 retval = ntohl (mp->retval);
1445   if (vam->async_mode)
1446     {
1447       vam->async_errors += (retval < 0);
1448     }
1449   else
1450     {
1451       vam->retval = retval;
1452       vam->result_ready = 1;
1453     }
1454 }
1455
1456 static void vl_api_tap_delete_reply_t_handler_json
1457   (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   vat_json_node_t node;
1461
1462   vat_json_init_object (&node);
1463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1464
1465   vat_json_print (vam->ofp, &node);
1466   vat_json_free (&node);
1467
1468   vam->retval = ntohl (mp->retval);
1469   vam->result_ready = 1;
1470 }
1471
1472 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1473   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   i32 retval = ntohl (mp->retval);
1477   if (vam->async_mode)
1478     {
1479       vam->async_errors += (retval < 0);
1480     }
1481   else
1482     {
1483       vam->retval = retval;
1484       vam->result_ready = 1;
1485     }
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   vat_json_node_t node;
1493
1494   vat_json_init_object (&node);
1495   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1496   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1497                             ntohl (mp->tunnel_sw_if_index));
1498
1499   vat_json_print (vam->ofp, &node);
1500   vat_json_free (&node);
1501
1502   vam->retval = ntohl (mp->retval);
1503   vam->result_ready = 1;
1504 }
1505
1506 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1507   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   i32 retval = ntohl (mp->retval);
1511   if (vam->async_mode)
1512     {
1513       vam->async_errors += (retval < 0);
1514     }
1515   else
1516     {
1517       vam->retval = retval;
1518       vam->sw_if_index = ntohl (mp->sw_if_index);
1519       vam->result_ready = 1;
1520     }
1521 }
1522
1523 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1524   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1525 {
1526   vat_main_t *vam = &vat_main;
1527   vat_json_node_t node;
1528
1529   vat_json_init_object (&node);
1530   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1531   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540
1541 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1542   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   i32 retval = ntohl (mp->retval);
1546   if (vam->async_mode)
1547     {
1548       vam->async_errors += (retval < 0);
1549     }
1550   else
1551     {
1552       vam->retval = retval;
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   vat_json_node_t node;
1562
1563   vat_json_init_object (&node);
1564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1565   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1575   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->sw_if_index = ntohl (mp->sw_if_index);
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1592   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   vat_json_node_t node;
1596
1597   vat_json_init_object (&node);
1598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1599   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_gre_add_del_tunnel_reply_t_handler
1609   (vl_api_gre_add_del_tunnel_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623 }
1624
1625 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1626   (vl_api_gre_add_del_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   vat_json_node_t node;
1630
1631   vat_json_init_object (&node);
1632   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1633   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1634
1635   vat_json_print (vam->ofp, &node);
1636   vat_json_free (&node);
1637
1638   vam->retval = ntohl (mp->retval);
1639   vam->result_ready = 1;
1640 }
1641
1642 static void vl_api_create_vhost_user_if_reply_t_handler
1643   (vl_api_create_vhost_user_if_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   i32 retval = ntohl (mp->retval);
1647   if (vam->async_mode)
1648     {
1649       vam->async_errors += (retval < 0);
1650     }
1651   else
1652     {
1653       vam->retval = retval;
1654       vam->sw_if_index = ntohl (mp->sw_if_index);
1655       vam->result_ready = 1;
1656     }
1657 }
1658
1659 static void vl_api_create_vhost_user_if_reply_t_handler_json
1660   (vl_api_create_vhost_user_if_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   vat_json_node_t node;
1664
1665   vat_json_init_object (&node);
1666   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1667   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1668
1669   vat_json_print (vam->ofp, &node);
1670   vat_json_free (&node);
1671
1672   vam->retval = ntohl (mp->retval);
1673   vam->result_ready = 1;
1674 }
1675
1676 static void vl_api_ip_address_details_t_handler
1677   (vl_api_ip_address_details_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   static ip_address_details_t empty_ip_address_details = { {0} };
1681   ip_address_details_t *address = NULL;
1682   ip_details_t *current_ip_details = NULL;
1683   ip_details_t *details = NULL;
1684
1685   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1686
1687   if (!details || vam->current_sw_if_index >= vec_len (details)
1688       || !details[vam->current_sw_if_index].present)
1689     {
1690       errmsg ("ip address details arrived but not stored\n");
1691       errmsg ("ip_dump should be called first\n");
1692       return;
1693     }
1694
1695   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1696
1697 #define addresses (current_ip_details->addr)
1698
1699   vec_validate_init_empty (addresses, vec_len (addresses),
1700                            empty_ip_address_details);
1701
1702   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1703
1704   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1705   address->prefix_length = mp->prefix_length;
1706 #undef addresses
1707 }
1708
1709 static void vl_api_ip_address_details_t_handler_json
1710   (vl_api_ip_address_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   vat_json_node_t *node = NULL;
1714   struct in6_addr ip6;
1715   struct in_addr ip4;
1716
1717   if (VAT_JSON_ARRAY != vam->json_tree.type)
1718     {
1719       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1720       vat_json_init_array (&vam->json_tree);
1721     }
1722   node = vat_json_array_add (&vam->json_tree);
1723
1724   vat_json_init_object (node);
1725   if (vam->is_ipv6)
1726     {
1727       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1728       vat_json_object_add_ip6 (node, "ip", ip6);
1729     }
1730   else
1731     {
1732       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1733       vat_json_object_add_ip4 (node, "ip", ip4);
1734     }
1735   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1736 }
1737
1738 static void
1739 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   static ip_details_t empty_ip_details = { 0 };
1743   ip_details_t *ip = NULL;
1744   u32 sw_if_index = ~0;
1745
1746   sw_if_index = ntohl (mp->sw_if_index);
1747
1748   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1749                            sw_if_index, empty_ip_details);
1750
1751   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1752                          sw_if_index);
1753
1754   ip->present = 1;
1755 }
1756
1757 static void
1758 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1759 {
1760   vat_main_t *vam = &vat_main;
1761
1762   if (VAT_JSON_ARRAY != vam->json_tree.type)
1763     {
1764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1765       vat_json_init_array (&vam->json_tree);
1766     }
1767   vat_json_array_add_uint (&vam->json_tree,
1768                            clib_net_to_host_u32 (mp->sw_if_index));
1769 }
1770
1771 static void vl_api_map_domain_details_t_handler_json
1772   (vl_api_map_domain_details_t * mp)
1773 {
1774   vat_json_node_t *node = NULL;
1775   vat_main_t *vam = &vat_main;
1776   struct in6_addr ip6;
1777   struct in_addr ip4;
1778
1779   if (VAT_JSON_ARRAY != vam->json_tree.type)
1780     {
1781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1782       vat_json_init_array (&vam->json_tree);
1783     }
1784
1785   node = vat_json_array_add (&vam->json_tree);
1786   vat_json_init_object (node);
1787
1788   vat_json_object_add_uint (node, "domain_index",
1789                             clib_net_to_host_u32 (mp->domain_index));
1790   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1791   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1792   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1793   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1794   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1795   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1796   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1797   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1798   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1799   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1800   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1801   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1802   vat_json_object_add_uint (node, "flags", mp->flags);
1803   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1804   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1805 }
1806
1807 static void vl_api_map_domain_details_t_handler
1808   (vl_api_map_domain_details_t * mp)
1809 {
1810   vat_main_t *vam = &vat_main;
1811
1812   if (mp->is_translation)
1813     {
1814       fformat (vam->ofp,
1815                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1816                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1817                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1818                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1819                clib_net_to_host_u32 (mp->domain_index));
1820     }
1821   else
1822     {
1823       fformat (vam->ofp,
1824                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1825                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1826                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1827                format_ip6_address, mp->ip6_src,
1828                clib_net_to_host_u32 (mp->domain_index));
1829     }
1830   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1831            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1832            mp->is_translation ? "map-t" : "");
1833 }
1834
1835 static void vl_api_map_rule_details_t_handler_json
1836   (vl_api_map_rule_details_t * mp)
1837 {
1838   struct in6_addr ip6;
1839   vat_json_node_t *node = NULL;
1840   vat_main_t *vam = &vat_main;
1841
1842   if (VAT_JSON_ARRAY != vam->json_tree.type)
1843     {
1844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1845       vat_json_init_array (&vam->json_tree);
1846     }
1847
1848   node = vat_json_array_add (&vam->json_tree);
1849   vat_json_init_object (node);
1850
1851   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1852   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1853   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1854 }
1855
1856 static void
1857 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1861            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1862 }
1863
1864 static void
1865 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1869           "router_addr %U host_mac %U\n",
1870           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1871           format_ip4_address, &mp->host_address,
1872           format_ip4_address, &mp->router_address,
1873           format_ethernet_address, mp->host_mac);
1874 }
1875
1876 static void vl_api_dhcp_compl_event_t_handler_json
1877   (vl_api_dhcp_compl_event_t * mp)
1878 {
1879   /* JSON output not supported */
1880 }
1881
1882 static void
1883 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1884                               u32 counter)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   static u64 default_counter = 0;
1888
1889   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1890                            NULL);
1891   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1892                            sw_if_index, default_counter);
1893   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1894 }
1895
1896 static void
1897 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1898                                 interface_counter_t counter)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   static interface_counter_t default_counter = { 0, };
1902
1903   vec_validate_init_empty (vam->combined_interface_counters,
1904                            vnet_counter_type, NULL);
1905   vec_validate_init_empty (vam->combined_interface_counters
1906                            [vnet_counter_type], sw_if_index, default_counter);
1907   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1908 }
1909
1910 static void vl_api_vnet_interface_counters_t_handler
1911   (vl_api_vnet_interface_counters_t * mp)
1912 {
1913   /* not supported */
1914 }
1915
1916 static void vl_api_vnet_interface_counters_t_handler_json
1917   (vl_api_vnet_interface_counters_t * mp)
1918 {
1919   interface_counter_t counter;
1920   vlib_counter_t *v;
1921   u64 *v_packets;
1922   u64 packets;
1923   u32 count;
1924   u32 first_sw_if_index;
1925   int i;
1926
1927   count = ntohl (mp->count);
1928   first_sw_if_index = ntohl (mp->first_sw_if_index);
1929
1930   if (!mp->is_combined)
1931     {
1932       v_packets = (u64 *) & mp->data;
1933       for (i = 0; i < count; i++)
1934         {
1935           packets =
1936             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1937           set_simple_interface_counter (mp->vnet_counter_type,
1938                                         first_sw_if_index + i, packets);
1939           v_packets++;
1940         }
1941     }
1942   else
1943     {
1944       v = (vlib_counter_t *) & mp->data;
1945       for (i = 0; i < count; i++)
1946         {
1947           counter.packets =
1948             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1949           counter.bytes =
1950             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1951           set_combined_interface_counter (mp->vnet_counter_type,
1952                                           first_sw_if_index + i, counter);
1953           v++;
1954         }
1955     }
1956 }
1957
1958 static u32
1959 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   u32 i;
1963
1964   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1965     {
1966       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1967         {
1968           return i;
1969         }
1970     }
1971   return ~0;
1972 }
1973
1974 static u32
1975 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static void vl_api_vnet_ip4_fib_counters_t_handler
1991   (vl_api_vnet_ip4_fib_counters_t * mp)
1992 {
1993   /* not supported */
1994 }
1995
1996 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1997   (vl_api_vnet_ip4_fib_counters_t * mp)
1998 {
1999   vat_main_t *vam = &vat_main;
2000   vl_api_ip4_fib_counter_t *v;
2001   ip4_fib_counter_t *counter;
2002   struct in_addr ip4;
2003   u32 vrf_id;
2004   u32 vrf_index;
2005   u32 count;
2006   int i;
2007
2008   vrf_id = ntohl (mp->vrf_id);
2009   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2010   if (~0 == vrf_index)
2011     {
2012       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2013       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2014       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2015       vec_validate (vam->ip4_fib_counters, vrf_index);
2016       vam->ip4_fib_counters[vrf_index] = NULL;
2017     }
2018
2019   vec_free (vam->ip4_fib_counters[vrf_index]);
2020   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2021   count = ntohl (mp->count);
2022   for (i = 0; i < count; i++)
2023     {
2024       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2025       counter = &vam->ip4_fib_counters[vrf_index][i];
2026       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2027       counter->address = ip4;
2028       counter->address_length = v->address_length;
2029       counter->packets = clib_net_to_host_u64 (v->packets);
2030       counter->bytes = clib_net_to_host_u64 (v->bytes);
2031       v++;
2032     }
2033 }
2034
2035 static void vl_api_vnet_ip6_fib_counters_t_handler
2036   (vl_api_vnet_ip6_fib_counters_t * mp)
2037 {
2038   /* not supported */
2039 }
2040
2041 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2042   (vl_api_vnet_ip6_fib_counters_t * mp)
2043 {
2044   vat_main_t *vam = &vat_main;
2045   vl_api_ip6_fib_counter_t *v;
2046   ip6_fib_counter_t *counter;
2047   struct in6_addr ip6;
2048   u32 vrf_id;
2049   u32 vrf_index;
2050   u32 count;
2051   int i;
2052
2053   vrf_id = ntohl (mp->vrf_id);
2054   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2055   if (~0 == vrf_index)
2056     {
2057       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2058       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2059       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2060       vec_validate (vam->ip6_fib_counters, vrf_index);
2061       vam->ip6_fib_counters[vrf_index] = NULL;
2062     }
2063
2064   vec_free (vam->ip6_fib_counters[vrf_index]);
2065   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2066   count = ntohl (mp->count);
2067   for (i = 0; i < count; i++)
2068     {
2069       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2070       counter = &vam->ip6_fib_counters[vrf_index][i];
2071       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2072       counter->address = ip6;
2073       counter->address_length = v->address_length;
2074       counter->packets = clib_net_to_host_u64 (v->packets);
2075       counter->bytes = clib_net_to_host_u64 (v->bytes);
2076       v++;
2077     }
2078 }
2079
2080 static void vl_api_get_first_msg_id_reply_t_handler
2081   (vl_api_get_first_msg_id_reply_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   i32 retval = ntohl (mp->retval);
2085
2086   if (vam->async_mode)
2087     {
2088       vam->async_errors += (retval < 0);
2089     }
2090   else
2091     {
2092       vam->retval = retval;
2093       vam->result_ready = 1;
2094     }
2095   if (retval >= 0)
2096     {
2097       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2098     }
2099 }
2100
2101 static void vl_api_get_first_msg_id_reply_t_handler_json
2102   (vl_api_get_first_msg_id_reply_t * mp)
2103 {
2104   vat_main_t *vam = &vat_main;
2105   vat_json_node_t node;
2106
2107   vat_json_init_object (&node);
2108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2109   vat_json_object_add_uint (&node, "first_msg_id",
2110                             (uint) ntohs (mp->first_msg_id));
2111
2112   vat_json_print (vam->ofp, &node);
2113   vat_json_free (&node);
2114
2115   vam->retval = ntohl (mp->retval);
2116   vam->result_ready = 1;
2117 }
2118
2119 static void vl_api_get_node_graph_reply_t_handler
2120   (vl_api_get_node_graph_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   api_main_t *am = &api_main;
2124   i32 retval = ntohl (mp->retval);
2125   u8 *pvt_copy, *reply;
2126   void *oldheap;
2127   vlib_node_t *node;
2128   int i;
2129
2130   if (vam->async_mode)
2131     {
2132       vam->async_errors += (retval < 0);
2133     }
2134   else
2135     {
2136       vam->retval = retval;
2137       vam->result_ready = 1;
2138     }
2139
2140   /* "Should never happen..." */
2141   if (retval != 0)
2142     return;
2143
2144   reply = (u8 *) (mp->reply_in_shmem);
2145   pvt_copy = vec_dup (reply);
2146
2147   /* Toss the shared-memory original... */
2148   pthread_mutex_lock (&am->vlib_rp->mutex);
2149   oldheap = svm_push_data_heap (am->vlib_rp);
2150
2151   vec_free (reply);
2152
2153   svm_pop_heap (oldheap);
2154   pthread_mutex_unlock (&am->vlib_rp->mutex);
2155
2156   if (vam->graph_nodes)
2157     {
2158       hash_free (vam->graph_node_index_by_name);
2159
2160       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2161         {
2162           node = vam->graph_nodes[i];
2163           vec_free (node->name);
2164           vec_free (node->next_nodes);
2165           vec_free (node);
2166         }
2167       vec_free (vam->graph_nodes);
2168     }
2169
2170   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2171   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2172   vec_free (pvt_copy);
2173
2174   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2175     {
2176       node = vam->graph_nodes[i];
2177       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2178     }
2179 }
2180
2181 static void vl_api_get_node_graph_reply_t_handler_json
2182   (vl_api_get_node_graph_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   api_main_t *am = &api_main;
2186   void *oldheap;
2187   vat_json_node_t node;
2188   u8 *reply;
2189
2190   /* $$$$ make this real? */
2191   vat_json_init_object (&node);
2192   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2193   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2194
2195   reply = (u8 *) (mp->reply_in_shmem);
2196
2197   /* Toss the shared-memory original... */
2198   pthread_mutex_lock (&am->vlib_rp->mutex);
2199   oldheap = svm_push_data_heap (am->vlib_rp);
2200
2201   vec_free (reply);
2202
2203   svm_pop_heap (oldheap);
2204   pthread_mutex_unlock (&am->vlib_rp->mutex);
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void
2214 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   u8 *s = 0;
2218
2219   if (mp->local)
2220     {
2221       s = format (s, "%=16d%=16d%=16d\n",
2222                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2223     }
2224   else
2225     {
2226       s = format (s, "%=16U%=16d%=16d\n",
2227                   mp->is_ipv6 ? format_ip6_address :
2228                   format_ip4_address,
2229                   mp->ip_address, mp->priority, mp->weight);
2230     }
2231
2232   fformat (vam->ofp, "%v", s);
2233   vec_free (s);
2234 }
2235
2236 static void
2237 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2238                                             mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   vat_json_node_t *node = NULL;
2242   struct in6_addr ip6;
2243   struct in_addr ip4;
2244
2245   if (VAT_JSON_ARRAY != vam->json_tree.type)
2246     {
2247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2248       vat_json_init_array (&vam->json_tree);
2249     }
2250   node = vat_json_array_add (&vam->json_tree);
2251   vat_json_init_object (node);
2252
2253   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2254   vat_json_object_add_uint (node, "priority", mp->priority);
2255   vat_json_object_add_uint (node, "weight", mp->weight);
2256
2257   if (mp->local)
2258     vat_json_object_add_uint (node, "sw_if_index",
2259                               clib_net_to_host_u32 (mp->sw_if_index));
2260   else
2261     {
2262       if (mp->is_ipv6)
2263         {
2264           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2265           vat_json_object_add_ip6 (node, "address", ip6);
2266         }
2267       else
2268         {
2269           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2270           vat_json_object_add_ip4 (node, "address", ip4);
2271         }
2272     }
2273 }
2274
2275 static void
2276 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2277                                            mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   u8 *ls_name = 0;
2281
2282   ls_name = format (0, "%s", mp->ls_name);
2283
2284   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2285            ls_name);
2286   vec_free (ls_name);
2287 }
2288
2289 static void
2290   vl_api_lisp_locator_set_details_t_handler_json
2291   (vl_api_lisp_locator_set_details_t * mp)
2292 {
2293   vat_main_t *vam = &vat_main;
2294   vat_json_node_t *node = 0;
2295   u8 *ls_name = 0;
2296
2297   ls_name = format (0, "%s", mp->ls_name);
2298   vec_add1 (ls_name, 0);
2299
2300   if (VAT_JSON_ARRAY != vam->json_tree.type)
2301     {
2302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2303       vat_json_init_array (&vam->json_tree);
2304     }
2305   node = vat_json_array_add (&vam->json_tree);
2306
2307   vat_json_init_object (node);
2308   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2309   vat_json_object_add_uint (node, "ls_index",
2310                             clib_net_to_host_u32 (mp->ls_index));
2311   vec_free (ls_name);
2312 }
2313
2314 static u8 *
2315 format_lisp_flat_eid (u8 * s, va_list * args)
2316 {
2317   u32 type = va_arg (*args, u32);
2318   u8 *eid = va_arg (*args, u8 *);
2319   u32 eid_len = va_arg (*args, u32);
2320
2321   switch (type)
2322     {
2323     case 0:
2324       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2325     case 1:
2326       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2327     case 2:
2328       return format (s, "%U", format_ethernet_address, eid);
2329     }
2330   return 0;
2331 }
2332
2333 static u8 *
2334 format_lisp_eid_vat (u8 * s, va_list * args)
2335 {
2336   u32 type = va_arg (*args, u32);
2337   u8 *eid = va_arg (*args, u8 *);
2338   u32 eid_len = va_arg (*args, u32);
2339   u8 *seid = va_arg (*args, u8 *);
2340   u32 seid_len = va_arg (*args, u32);
2341   u32 is_src_dst = va_arg (*args, u32);
2342
2343   if (is_src_dst)
2344     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2345
2346   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2347
2348   return s;
2349 }
2350
2351 static void
2352 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   u8 *s = 0, *eid = 0;
2356
2357   if (~0 == mp->locator_set_index)
2358     s = format (0, "action: %d", mp->action);
2359   else
2360     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2361
2362   eid = format (0, "%U", format_lisp_eid_vat,
2363                 mp->eid_type,
2364                 mp->eid,
2365                 mp->eid_prefix_len,
2366                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2367   vec_add1 (eid, 0);
2368
2369   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2370            clib_net_to_host_u32 (mp->vni),
2371            eid,
2372            mp->is_local ? "local" : "remote",
2373            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2374   vec_free (s);
2375   vec_free (eid);
2376 }
2377
2378 static void
2379 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2380                                               * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   vat_json_node_t *node = 0;
2384   u8 *eid = 0;
2385
2386   if (VAT_JSON_ARRAY != vam->json_tree.type)
2387     {
2388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2389       vat_json_init_array (&vam->json_tree);
2390     }
2391   node = vat_json_array_add (&vam->json_tree);
2392
2393   vat_json_init_object (node);
2394   if (~0 == mp->locator_set_index)
2395     vat_json_object_add_uint (node, "action", mp->action);
2396   else
2397     vat_json_object_add_uint (node, "locator_set_index",
2398                               clib_net_to_host_u32 (mp->locator_set_index));
2399
2400   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2401   eid = format (0, "%U", format_lisp_eid_vat,
2402                 mp->eid_type,
2403                 mp->eid,
2404                 mp->eid_prefix_len,
2405                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2406   vec_add1 (eid, 0);
2407   vat_json_object_add_string_copy (node, "eid", eid);
2408   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2409   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2410   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2411   vec_free (eid);
2412 }
2413
2414 static void
2415   vl_api_lisp_eid_table_map_details_t_handler
2416   (vl_api_lisp_eid_table_map_details_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419
2420   u8 *line = format (0, "%=10d%=10d",
2421                      clib_net_to_host_u32 (mp->vni),
2422                      clib_net_to_host_u32 (mp->dp_table));
2423   fformat (vam->ofp, "%v\n", line);
2424   vec_free (line);
2425 }
2426
2427 static void
2428   vl_api_lisp_eid_table_map_details_t_handler_json
2429   (vl_api_lisp_eid_table_map_details_t * mp)
2430 {
2431   vat_main_t *vam = &vat_main;
2432   vat_json_node_t *node = NULL;
2433
2434   if (VAT_JSON_ARRAY != vam->json_tree.type)
2435     {
2436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2437       vat_json_init_array (&vam->json_tree);
2438     }
2439   node = vat_json_array_add (&vam->json_tree);
2440   vat_json_init_object (node);
2441   vat_json_object_add_uint (node, "dp_table",
2442                             clib_net_to_host_u32 (mp->dp_table));
2443   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2444 }
2445
2446 static void
2447   vl_api_lisp_eid_table_vni_details_t_handler
2448   (vl_api_lisp_eid_table_vni_details_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451
2452   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2453   fformat (vam->ofp, "%v\n", line);
2454   vec_free (line);
2455 }
2456
2457 static void
2458   vl_api_lisp_eid_table_vni_details_t_handler_json
2459   (vl_api_lisp_eid_table_vni_details_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   vat_json_node_t *node = NULL;
2463
2464   if (VAT_JSON_ARRAY != vam->json_tree.type)
2465     {
2466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2467       vat_json_init_array (&vam->json_tree);
2468     }
2469   node = vat_json_array_add (&vam->json_tree);
2470   vat_json_init_object (node);
2471   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2472 }
2473
2474 static u8 *
2475 format_decap_next (u8 * s, va_list * args)
2476 {
2477   u32 next_index = va_arg (*args, u32);
2478
2479   switch (next_index)
2480     {
2481     case LISP_GPE_INPUT_NEXT_DROP:
2482       return format (s, "drop");
2483     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2484       return format (s, "ip4");
2485     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2486       return format (s, "ip6");
2487     default:
2488       return format (s, "unknown %d", next_index);
2489     }
2490   return s;
2491 }
2492
2493 static void
2494 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2495                                           mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   u8 *iid_str;
2499   u8 *flag_str = NULL;
2500
2501   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2502
2503 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2504   foreach_lisp_gpe_flag_bit;
2505 #undef _
2506
2507   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2508            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2509            mp->tunnels,
2510            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2511            mp->source_ip,
2512            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2513            mp->destination_ip,
2514            ntohl (mp->encap_fib_id),
2515            ntohl (mp->decap_fib_id),
2516            format_decap_next, ntohl (mp->dcap_next),
2517            mp->ver_res >> 6,
2518            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2519
2520   vec_free (iid_str);
2521 }
2522
2523 static void
2524   vl_api_lisp_gpe_tunnel_details_t_handler_json
2525   (vl_api_lisp_gpe_tunnel_details_t * mp)
2526 {
2527   vat_main_t *vam = &vat_main;
2528   vat_json_node_t *node = NULL;
2529   struct in6_addr ip6;
2530   struct in_addr ip4;
2531   u8 *next_decap_str;
2532
2533   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2534
2535   if (VAT_JSON_ARRAY != vam->json_tree.type)
2536     {
2537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2538       vat_json_init_array (&vam->json_tree);
2539     }
2540   node = vat_json_array_add (&vam->json_tree);
2541
2542   vat_json_init_object (node);
2543   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2544   if (mp->is_ipv6)
2545     {
2546       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2547       vat_json_object_add_ip6 (node, "source address", ip6);
2548       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2549       vat_json_object_add_ip6 (node, "destination address", ip6);
2550     }
2551   else
2552     {
2553       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2554       vat_json_object_add_ip4 (node, "source address", ip4);
2555       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2556       vat_json_object_add_ip4 (node, "destination address", ip4);
2557     }
2558   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2559   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2560   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2561   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2562   vat_json_object_add_uint (node, "flags", mp->flags);
2563   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2564   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2565   vat_json_object_add_uint (node, "res", mp->res);
2566   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2567
2568   vec_free (next_decap_str);
2569 }
2570
2571 static void
2572   vl_api_lisp_adjacencies_get_reply_t_handler
2573   (vl_api_lisp_adjacencies_get_reply_t * mp)
2574 {
2575   vat_main_t *vam = &vat_main;
2576   u32 i, n;
2577   int retval = clib_net_to_host_u32 (mp->retval);
2578   vl_api_lisp_adjacency_t *a;
2579
2580   if (retval)
2581     goto end;
2582
2583   n = clib_net_to_host_u32 (mp->count);
2584
2585   for (i = 0; i < n; i++)
2586     {
2587       a = &mp->adjacencies[i];
2588       fformat (vam->ofp, "%U %40U\n",
2589                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2590                format_lisp_flat_eid, a->eid_type, a->reid,
2591                a->reid_prefix_len);
2592     }
2593
2594 end:
2595   vam->retval = retval;
2596   vam->result_ready = 1;
2597 }
2598
2599 static void
2600   vl_api_lisp_adjacencies_get_reply_t_handler_json
2601   (vl_api_lisp_adjacencies_get_reply_t * mp)
2602 {
2603   u8 *s = 0;
2604   vat_main_t *vam = &vat_main;
2605   vat_json_node_t *e = 0, root;
2606   u32 i, n;
2607   int retval = clib_net_to_host_u32 (mp->retval);
2608   vl_api_lisp_adjacency_t *a;
2609
2610   if (retval)
2611     goto end;
2612
2613   n = clib_net_to_host_u32 (mp->count);
2614   vat_json_init_array (&root);
2615
2616   for (i = 0; i < n; i++)
2617     {
2618       e = vat_json_array_add (&root);
2619       a = &mp->adjacencies[i];
2620
2621       vat_json_init_object (e);
2622       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2623                   a->leid_prefix_len);
2624       vec_add1 (s, 0);
2625       vat_json_object_add_string_copy (e, "leid", s);
2626       vec_free (s);
2627
2628       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2629                   a->reid_prefix_len);
2630       vec_add1 (s, 0);
2631       vat_json_object_add_string_copy (e, "reid", s);
2632       vec_free (s);
2633     }
2634
2635   vat_json_print (vam->ofp, &root);
2636   vat_json_free (&root);
2637
2638 end:
2639   vam->retval = retval;
2640   vam->result_ready = 1;
2641 }
2642
2643 static void
2644 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2645                                             * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648
2649   fformat (vam->ofp, "%=20U\n",
2650            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2651            mp->ip_address);
2652 }
2653
2654 static void
2655   vl_api_lisp_map_resolver_details_t_handler_json
2656   (vl_api_lisp_map_resolver_details_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   vat_json_node_t *node = NULL;
2660   struct in6_addr ip6;
2661   struct in_addr ip4;
2662
2663   if (VAT_JSON_ARRAY != vam->json_tree.type)
2664     {
2665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2666       vat_json_init_array (&vam->json_tree);
2667     }
2668   node = vat_json_array_add (&vam->json_tree);
2669
2670   vat_json_init_object (node);
2671   if (mp->is_ipv6)
2672     {
2673       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2674       vat_json_object_add_ip6 (node, "map resolver", ip6);
2675     }
2676   else
2677     {
2678       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2679       vat_json_object_add_ip4 (node, "map resolver", ip4);
2680     }
2681 }
2682
2683 static void
2684   vl_api_show_lisp_status_reply_t_handler
2685   (vl_api_show_lisp_status_reply_t * mp)
2686 {
2687   vat_main_t *vam = &vat_main;
2688   i32 retval = ntohl (mp->retval);
2689
2690   if (0 <= retval)
2691     {
2692       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2693                mp->feature_status ? "enabled" : "disabled",
2694                mp->gpe_status ? "enabled" : "disabled");
2695     }
2696
2697   vam->retval = retval;
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_show_lisp_status_reply_t_handler_json
2703   (vl_api_show_lisp_status_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   vat_json_node_t node;
2707   u8 *gpe_status = NULL;
2708   u8 *feature_status = NULL;
2709
2710   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2711   feature_status = format (0, "%s",
2712                            mp->feature_status ? "enabled" : "disabled");
2713   vec_add1 (gpe_status, 0);
2714   vec_add1 (feature_status, 0);
2715
2716   vat_json_init_object (&node);
2717   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2718   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2719
2720   vec_free (gpe_status);
2721   vec_free (feature_status);
2722
2723   vat_json_print (vam->ofp, &node);
2724   vat_json_free (&node);
2725
2726   vam->retval = ntohl (mp->retval);
2727   vam->result_ready = 1;
2728 }
2729
2730 static void
2731   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2732   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2733 {
2734   vat_main_t *vam = &vat_main;
2735   i32 retval = ntohl (mp->retval);
2736
2737   if (retval >= 0)
2738     {
2739       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2740     }
2741
2742   vam->retval = retval;
2743   vam->result_ready = 1;
2744 }
2745
2746 static void
2747   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2748   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2749 {
2750   vat_main_t *vam = &vat_main;
2751   vat_json_node_t *node = NULL;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2762
2763   vat_json_print (vam->ofp, node);
2764   vat_json_free (node);
2765
2766   vam->retval = ntohl (mp->retval);
2767   vam->result_ready = 1;
2768 }
2769
2770 static u8 *
2771 format_lisp_map_request_mode (u8 * s, va_list * args)
2772 {
2773   u32 mode = va_arg (*args, u32);
2774
2775   switch (mode)
2776     {
2777     case 0:
2778       return format (0, "dst-only");
2779     case 1:
2780       return format (0, "src-dst");
2781     }
2782   return 0;
2783 }
2784
2785 static void
2786   vl_api_show_lisp_map_request_mode_reply_t_handler
2787   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   i32 retval = ntohl (mp->retval);
2791
2792   if (0 <= retval)
2793     {
2794       u32 mode = mp->mode;
2795       fformat (vam->ofp, "map_request_mode: %U\n",
2796                format_lisp_map_request_mode, mode);
2797     }
2798
2799   vam->retval = retval;
2800   vam->result_ready = 1;
2801 }
2802
2803 static void
2804   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2805   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   vat_json_node_t node;
2809   u8 *s = 0;
2810   u32 mode;
2811
2812   mode = mp->mode;
2813   s = format (0, "%U", format_lisp_map_request_mode, mode);
2814   vec_add1 (s, 0);
2815
2816   vat_json_init_object (&node);
2817   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2818   vat_json_print (vam->ofp, &node);
2819   vat_json_free (&node);
2820
2821   vec_free (s);
2822   vam->retval = ntohl (mp->retval);
2823   vam->result_ready = 1;
2824 }
2825
2826 static void
2827 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   i32 retval = ntohl (mp->retval);
2831
2832   if (0 <= retval)
2833     {
2834       fformat (vam->ofp, "%-20s%-16s\n",
2835                mp->status ? "enabled" : "disabled",
2836                mp->status ? (char *) mp->locator_set_name : "");
2837     }
2838
2839   vam->retval = retval;
2840   vam->result_ready = 1;
2841 }
2842
2843 static void
2844 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2845                                             mp)
2846 {
2847   vat_main_t *vam = &vat_main;
2848   vat_json_node_t node;
2849   u8 *status = 0;
2850
2851   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2852   vec_add1 (status, 0);
2853
2854   vat_json_init_object (&node);
2855   vat_json_object_add_string_copy (&node, "status", status);
2856   if (mp->status)
2857     {
2858       vat_json_object_add_string_copy (&node, "locator_set",
2859                                        mp->locator_set_name);
2860     }
2861
2862   vec_free (status);
2863
2864   vat_json_print (vam->ofp, &node);
2865   vat_json_free (&node);
2866
2867   vam->retval = ntohl (mp->retval);
2868   vam->result_ready = 1;
2869 }
2870
2871 static u8 *
2872 format_policer_type (u8 * s, va_list * va)
2873 {
2874   u32 i = va_arg (*va, u32);
2875
2876   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2877     s = format (s, "1r2c");
2878   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2879     s = format (s, "1r3c");
2880   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2881     s = format (s, "2r3c-2698");
2882   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2883     s = format (s, "2r3c-4115");
2884   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2885     s = format (s, "2r3c-mef5cf1");
2886   else
2887     s = format (s, "ILLEGAL");
2888   return s;
2889 }
2890
2891 static u8 *
2892 format_policer_rate_type (u8 * s, va_list * va)
2893 {
2894   u32 i = va_arg (*va, u32);
2895
2896   if (i == SSE2_QOS_RATE_KBPS)
2897     s = format (s, "kbps");
2898   else if (i == SSE2_QOS_RATE_PPS)
2899     s = format (s, "pps");
2900   else
2901     s = format (s, "ILLEGAL");
2902   return s;
2903 }
2904
2905 static u8 *
2906 format_policer_round_type (u8 * s, va_list * va)
2907 {
2908   u32 i = va_arg (*va, u32);
2909
2910   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2911     s = format (s, "closest");
2912   else if (i == SSE2_QOS_ROUND_TO_UP)
2913     s = format (s, "up");
2914   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2915     s = format (s, "down");
2916   else
2917     s = format (s, "ILLEGAL");
2918   return s;
2919 }
2920
2921 static u8 *
2922 format_policer_action_type (u8 * s, va_list * va)
2923 {
2924   u32 i = va_arg (*va, u32);
2925
2926   if (i == SSE2_QOS_ACTION_DROP)
2927     s = format (s, "drop");
2928   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2929     s = format (s, "transmit");
2930   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2931     s = format (s, "mark-and-transmit");
2932   else
2933     s = format (s, "ILLEGAL");
2934   return s;
2935 }
2936
2937 static u8 *
2938 format_dscp (u8 * s, va_list * va)
2939 {
2940   u32 i = va_arg (*va, u32);
2941   char *t = 0;
2942
2943   switch (i)
2944     {
2945 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2946       foreach_vnet_dscp
2947 #undef _
2948     default:
2949       return format (s, "ILLEGAL");
2950     }
2951   s = format (s, "%s", t);
2952   return s;
2953 }
2954
2955 static void
2956 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2957 {
2958   vat_main_t *vam = &vat_main;
2959   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2960
2961   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2962     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2963   else
2964     conform_dscp_str = format (0, "");
2965
2966   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2967     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2968   else
2969     exceed_dscp_str = format (0, "");
2970
2971   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2972     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2973   else
2974     violate_dscp_str = format (0, "");
2975
2976   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2977            "rate type %U, round type %U, %s rate, %s color-aware, "
2978            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2979            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2980            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2981            mp->name,
2982            format_policer_type, mp->type,
2983            ntohl (mp->cir),
2984            ntohl (mp->eir),
2985            clib_net_to_host_u64 (mp->cb),
2986            clib_net_to_host_u64 (mp->eb),
2987            format_policer_rate_type, mp->rate_type,
2988            format_policer_round_type, mp->round_type,
2989            mp->single_rate ? "single" : "dual",
2990            mp->color_aware ? "is" : "not",
2991            ntohl (mp->cir_tokens_per_period),
2992            ntohl (mp->pir_tokens_per_period),
2993            ntohl (mp->scale),
2994            ntohl (mp->current_limit),
2995            ntohl (mp->current_bucket),
2996            ntohl (mp->extended_limit),
2997            ntohl (mp->extended_bucket),
2998            clib_net_to_host_u64 (mp->last_update_time),
2999            format_policer_action_type, mp->conform_action_type,
3000            conform_dscp_str,
3001            format_policer_action_type, mp->exceed_action_type,
3002            exceed_dscp_str,
3003            format_policer_action_type, mp->violate_action_type,
3004            violate_dscp_str);
3005
3006   vec_free (conform_dscp_str);
3007   vec_free (exceed_dscp_str);
3008   vec_free (violate_dscp_str);
3009 }
3010
3011 static void vl_api_policer_details_t_handler_json
3012   (vl_api_policer_details_t * mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   vat_json_node_t *node;
3016   u8 *rate_type_str, *round_type_str, *type_str;
3017   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3018
3019   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3020   round_type_str =
3021     format (0, "%U", format_policer_round_type, mp->round_type);
3022   type_str = format (0, "%U", format_policer_type, mp->type);
3023   conform_action_str = format (0, "%U", format_policer_action_type,
3024                                mp->conform_action_type);
3025   exceed_action_str = format (0, "%U", format_policer_action_type,
3026                               mp->exceed_action_type);
3027   violate_action_str = format (0, "%U", format_policer_action_type,
3028                                mp->violate_action_type);
3029
3030   if (VAT_JSON_ARRAY != vam->json_tree.type)
3031     {
3032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3033       vat_json_init_array (&vam->json_tree);
3034     }
3035   node = vat_json_array_add (&vam->json_tree);
3036
3037   vat_json_init_object (node);
3038   vat_json_object_add_string_copy (node, "name", mp->name);
3039   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3040   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3041   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3042   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3043   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3044   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3045   vat_json_object_add_string_copy (node, "type", type_str);
3046   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3047   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3048   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3049   vat_json_object_add_uint (node, "cir_tokens_per_period",
3050                             ntohl (mp->cir_tokens_per_period));
3051   vat_json_object_add_uint (node, "eir_tokens_per_period",
3052                             ntohl (mp->pir_tokens_per_period));
3053   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3054   vat_json_object_add_uint (node, "current_bucket",
3055                             ntohl (mp->current_bucket));
3056   vat_json_object_add_uint (node, "extended_limit",
3057                             ntohl (mp->extended_limit));
3058   vat_json_object_add_uint (node, "extended_bucket",
3059                             ntohl (mp->extended_bucket));
3060   vat_json_object_add_uint (node, "last_update_time",
3061                             ntohl (mp->last_update_time));
3062   vat_json_object_add_string_copy (node, "conform_action",
3063                                    conform_action_str);
3064   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3065     {
3066       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3067       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3068       vec_free (dscp_str);
3069     }
3070   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3071   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3072     {
3073       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3074       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3075       vec_free (dscp_str);
3076     }
3077   vat_json_object_add_string_copy (node, "violate_action",
3078                                    violate_action_str);
3079   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3080     {
3081       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3082       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3083       vec_free (dscp_str);
3084     }
3085
3086   vec_free (rate_type_str);
3087   vec_free (round_type_str);
3088   vec_free (type_str);
3089   vec_free (conform_action_str);
3090   vec_free (exceed_action_str);
3091   vec_free (violate_action_str);
3092 }
3093
3094 static void
3095 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3096                                            mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   int i, count = ntohl (mp->count);
3100
3101   if (count > 0)
3102     fformat (vam->ofp, "classify table ids (%d) : ", count);
3103   for (i = 0; i < count; i++)
3104     {
3105       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3106       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3107     }
3108   vam->retval = ntohl (mp->retval);
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_classify_table_ids_reply_t_handler_json
3114   (vl_api_classify_table_ids_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   int i, count = ntohl (mp->count);
3118
3119   if (count > 0)
3120     {
3121       vat_json_node_t node;
3122
3123       vat_json_init_object (&node);
3124       for (i = 0; i < count; i++)
3125         {
3126           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3127         }
3128       vat_json_print (vam->ofp, &node);
3129       vat_json_free (&node);
3130     }
3131   vam->retval = ntohl (mp->retval);
3132   vam->result_ready = 1;
3133 }
3134
3135 static void
3136   vl_api_classify_table_by_interface_reply_t_handler
3137   (vl_api_classify_table_by_interface_reply_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   u32 table_id;
3141
3142   table_id = ntohl (mp->l2_table_id);
3143   if (table_id != ~0)
3144     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3145   else
3146     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3147   table_id = ntohl (mp->ip4_table_id);
3148   if (table_id != ~0)
3149     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3150   else
3151     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3152   table_id = ntohl (mp->ip6_table_id);
3153   if (table_id != ~0)
3154     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3155   else
3156     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3157   vam->retval = ntohl (mp->retval);
3158   vam->result_ready = 1;
3159 }
3160
3161 static void
3162   vl_api_classify_table_by_interface_reply_t_handler_json
3163   (vl_api_classify_table_by_interface_reply_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   vat_json_node_t node;
3167
3168   vat_json_init_object (&node);
3169
3170   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3171   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3172   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3173
3174   vat_json_print (vam->ofp, &node);
3175   vat_json_free (&node);
3176
3177   vam->retval = ntohl (mp->retval);
3178   vam->result_ready = 1;
3179 }
3180
3181 static void vl_api_policer_add_del_reply_t_handler
3182   (vl_api_policer_add_del_reply_t * mp)
3183 {
3184   vat_main_t *vam = &vat_main;
3185   i32 retval = ntohl (mp->retval);
3186   if (vam->async_mode)
3187     {
3188       vam->async_errors += (retval < 0);
3189     }
3190   else
3191     {
3192       vam->retval = retval;
3193       vam->result_ready = 1;
3194       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3195         /*
3196          * Note: this is just barely thread-safe, depends on
3197          * the main thread spinning waiting for an answer...
3198          */
3199         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3200     }
3201 }
3202
3203 static void vl_api_policer_add_del_reply_t_handler_json
3204   (vl_api_policer_add_del_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t node;
3208
3209   vat_json_init_object (&node);
3210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3211   vat_json_object_add_uint (&node, "policer_index",
3212                             ntohl (mp->policer_index));
3213
3214   vat_json_print (vam->ofp, &node);
3215   vat_json_free (&node);
3216
3217   vam->retval = ntohl (mp->retval);
3218   vam->result_ready = 1;
3219 }
3220
3221 /* Format hex dump. */
3222 u8 *
3223 format_hex_bytes (u8 * s, va_list * va)
3224 {
3225   u8 *bytes = va_arg (*va, u8 *);
3226   int n_bytes = va_arg (*va, int);
3227   uword i;
3228
3229   /* Print short or long form depending on byte count. */
3230   uword short_form = n_bytes <= 32;
3231   uword indent = format_get_indent (s);
3232
3233   if (n_bytes == 0)
3234     return s;
3235
3236   for (i = 0; i < n_bytes; i++)
3237     {
3238       if (!short_form && (i % 32) == 0)
3239         s = format (s, "%08x: ", i);
3240       s = format (s, "%02x", bytes[i]);
3241       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3242         s = format (s, "\n%U", format_white_space, indent);
3243     }
3244
3245   return s;
3246 }
3247
3248 static void
3249 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3250                                             * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   i32 retval = ntohl (mp->retval);
3254   if (retval == 0)
3255     {
3256       fformat (vam->ofp, "classify table info :\n");
3257       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3258                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3259                ntohl (mp->miss_next_index));
3260       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3261                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3262                ntohl (mp->match_n_vectors));
3263       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3264                ntohl (mp->mask_length));
3265     }
3266   vam->retval = retval;
3267   vam->result_ready = 1;
3268 }
3269
3270 static void
3271   vl_api_classify_table_info_reply_t_handler_json
3272   (vl_api_classify_table_info_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   vat_json_node_t node;
3276
3277   i32 retval = ntohl (mp->retval);
3278   if (retval == 0)
3279     {
3280       vat_json_init_object (&node);
3281
3282       vat_json_object_add_int (&node, "sessions",
3283                                ntohl (mp->active_sessions));
3284       vat_json_object_add_int (&node, "nexttbl",
3285                                ntohl (mp->next_table_index));
3286       vat_json_object_add_int (&node, "nextnode",
3287                                ntohl (mp->miss_next_index));
3288       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3289       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3290       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3291       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3292                       ntohl (mp->mask_length), 0);
3293       vat_json_object_add_string_copy (&node, "mask", s);
3294
3295       vat_json_print (vam->ofp, &node);
3296       vat_json_free (&node);
3297     }
3298   vam->retval = ntohl (mp->retval);
3299   vam->result_ready = 1;
3300 }
3301
3302 static void
3303 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3304                                            mp)
3305 {
3306   vat_main_t *vam = &vat_main;
3307
3308   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3309            ntohl (mp->hit_next_index), ntohl (mp->advance),
3310            ntohl (mp->opaque_index));
3311   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3312            ntohl (mp->match_length));
3313 }
3314
3315 static void
3316   vl_api_classify_session_details_t_handler_json
3317   (vl_api_classify_session_details_t * mp)
3318 {
3319   vat_main_t *vam = &vat_main;
3320   vat_json_node_t *node = NULL;
3321
3322   if (VAT_JSON_ARRAY != vam->json_tree.type)
3323     {
3324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3325       vat_json_init_array (&vam->json_tree);
3326     }
3327   node = vat_json_array_add (&vam->json_tree);
3328
3329   vat_json_init_object (node);
3330   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3331   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3332   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3333   u8 *s =
3334     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3335             0);
3336   vat_json_object_add_string_copy (node, "match", s);
3337 }
3338
3339 static void vl_api_pg_create_interface_reply_t_handler
3340   (vl_api_pg_create_interface_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   vam->retval = ntohl (mp->retval);
3345   vam->result_ready = 1;
3346 }
3347
3348 static void vl_api_pg_create_interface_reply_t_handler_json
3349   (vl_api_pg_create_interface_reply_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t node;
3353
3354   i32 retval = ntohl (mp->retval);
3355   if (retval == 0)
3356     {
3357       vat_json_init_object (&node);
3358
3359       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3360
3361       vat_json_print (vam->ofp, &node);
3362       vat_json_free (&node);
3363     }
3364   vam->retval = ntohl (mp->retval);
3365   vam->result_ready = 1;
3366 }
3367
3368 static void vl_api_policer_classify_details_t_handler
3369   (vl_api_policer_classify_details_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372
3373   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3374            ntohl (mp->table_index));
3375 }
3376
3377 static void vl_api_policer_classify_details_t_handler_json
3378   (vl_api_policer_classify_details_t * mp)
3379 {
3380   vat_main_t *vam = &vat_main;
3381   vat_json_node_t *node;
3382
3383   if (VAT_JSON_ARRAY != vam->json_tree.type)
3384     {
3385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3386       vat_json_init_array (&vam->json_tree);
3387     }
3388   node = vat_json_array_add (&vam->json_tree);
3389
3390   vat_json_init_object (node);
3391   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3392   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3393 }
3394
3395 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3396   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399   i32 retval = ntohl (mp->retval);
3400   if (vam->async_mode)
3401     {
3402       vam->async_errors += (retval < 0);
3403     }
3404   else
3405     {
3406       vam->retval = retval;
3407       vam->sw_if_index = ntohl (mp->sw_if_index);
3408       vam->result_ready = 1;
3409     }
3410 }
3411
3412 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3413   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3414 {
3415   vat_main_t *vam = &vat_main;
3416   vat_json_node_t node;
3417
3418   vat_json_init_object (&node);
3419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3420   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3421
3422   vat_json_print (vam->ofp, &node);
3423   vat_json_free (&node);
3424
3425   vam->retval = ntohl (mp->retval);
3426   vam->result_ready = 1;
3427 }
3428
3429 static void vl_api_flow_classify_details_t_handler
3430   (vl_api_flow_classify_details_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3435            ntohl (mp->table_index));
3436 }
3437
3438 static void vl_api_flow_classify_details_t_handler_json
3439   (vl_api_flow_classify_details_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t *node;
3443
3444   if (VAT_JSON_ARRAY != vam->json_tree.type)
3445     {
3446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3447       vat_json_init_array (&vam->json_tree);
3448     }
3449   node = vat_json_array_add (&vam->json_tree);
3450
3451   vat_json_init_object (node);
3452   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3453   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3454 }
3455
3456
3457
3458 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3459 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3460 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3461 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3462 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3463 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3464
3465 /*
3466  * Generate boilerplate reply handlers, which
3467  * dig the return value out of the xxx_reply_t API message,
3468  * stick it into vam->retval, and set vam->result_ready
3469  *
3470  * Could also do this by pointing N message decode slots at
3471  * a single function, but that could break in subtle ways.
3472  */
3473
3474 #define foreach_standard_reply_retval_handler           \
3475 _(sw_interface_set_flags_reply)                         \
3476 _(sw_interface_add_del_address_reply)                   \
3477 _(sw_interface_set_table_reply)                         \
3478 _(sw_interface_set_vpath_reply)                         \
3479 _(sw_interface_set_l2_bridge_reply)                     \
3480 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3481 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3482 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3483 _(bridge_domain_add_del_reply)                          \
3484 _(sw_interface_set_l2_xconnect_reply)                   \
3485 _(l2fib_add_del_reply)                                  \
3486 _(ip_add_del_route_reply)                               \
3487 _(mpls_route_add_del_reply)                             \
3488 _(mpls_ip_bind_unbind_reply)                            \
3489 _(proxy_arp_add_del_reply)                              \
3490 _(proxy_arp_intfc_enable_disable_reply)                 \
3491 _(mpls_add_del_encap_reply)                             \
3492 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3493 _(sw_interface_set_unnumbered_reply)                    \
3494 _(ip_neighbor_add_del_reply)                            \
3495 _(reset_vrf_reply)                                      \
3496 _(oam_add_del_reply)                                    \
3497 _(reset_fib_reply)                                      \
3498 _(dhcp_proxy_config_reply)                              \
3499 _(dhcp_proxy_config_2_reply)                            \
3500 _(dhcp_proxy_set_vss_reply)                             \
3501 _(dhcp_client_config_reply)                             \
3502 _(set_ip_flow_hash_reply)                               \
3503 _(sw_interface_ip6_enable_disable_reply)                \
3504 _(sw_interface_ip6_set_link_local_address_reply)        \
3505 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3506 _(sw_interface_ip6nd_ra_config_reply)                   \
3507 _(set_arp_neighbor_limit_reply)                         \
3508 _(l2_patch_add_del_reply)                               \
3509 _(sr_tunnel_add_del_reply)                              \
3510 _(sr_policy_add_del_reply)                              \
3511 _(sr_multicast_map_add_del_reply)                       \
3512 _(classify_add_del_session_reply)                       \
3513 _(classify_set_interface_ip_table_reply)                \
3514 _(classify_set_interface_l2_tables_reply)               \
3515 _(l2tpv3_set_tunnel_cookies_reply)                      \
3516 _(l2tpv3_interface_enable_disable_reply)                \
3517 _(l2tpv3_set_lookup_key_reply)                          \
3518 _(l2_fib_clear_table_reply)                             \
3519 _(l2_interface_efp_filter_reply)                        \
3520 _(l2_interface_vlan_tag_rewrite_reply)                  \
3521 _(modify_vhost_user_if_reply)                           \
3522 _(delete_vhost_user_if_reply)                           \
3523 _(want_ip4_arp_events_reply)                            \
3524 _(want_ip6_nd_events_reply)                             \
3525 _(input_acl_set_interface_reply)                        \
3526 _(ipsec_spd_add_del_reply)                              \
3527 _(ipsec_interface_add_del_spd_reply)                    \
3528 _(ipsec_spd_add_del_entry_reply)                        \
3529 _(ipsec_sad_add_del_entry_reply)                        \
3530 _(ipsec_sa_set_key_reply)                               \
3531 _(ikev2_profile_add_del_reply)                          \
3532 _(ikev2_profile_set_auth_reply)                         \
3533 _(ikev2_profile_set_id_reply)                           \
3534 _(ikev2_profile_set_ts_reply)                           \
3535 _(ikev2_set_local_key_reply)                            \
3536 _(delete_loopback_reply)                                \
3537 _(bd_ip_mac_add_del_reply)                              \
3538 _(map_del_domain_reply)                                 \
3539 _(map_add_del_rule_reply)                               \
3540 _(want_interface_events_reply)                          \
3541 _(want_stats_reply)                                     \
3542 _(cop_interface_enable_disable_reply)                   \
3543 _(cop_whitelist_enable_disable_reply)                   \
3544 _(sw_interface_clear_stats_reply)                       \
3545 _(ioam_enable_reply)                              \
3546 _(ioam_disable_reply)                              \
3547 _(lisp_add_del_locator_reply)                           \
3548 _(lisp_add_del_local_eid_reply)                         \
3549 _(lisp_add_del_remote_mapping_reply)                    \
3550 _(lisp_add_del_adjacency_reply)                         \
3551 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3552 _(lisp_add_del_map_resolver_reply)                      \
3553 _(lisp_gpe_enable_disable_reply)                        \
3554 _(lisp_gpe_add_del_iface_reply)                         \
3555 _(lisp_enable_disable_reply)                            \
3556 _(lisp_pitr_set_locator_set_reply)                      \
3557 _(lisp_map_request_mode_reply)                          \
3558 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3559 _(lisp_eid_table_add_del_map_reply)                     \
3560 _(vxlan_gpe_add_del_tunnel_reply)                       \
3561 _(af_packet_delete_reply)                               \
3562 _(policer_classify_set_interface_reply)                 \
3563 _(netmap_create_reply)                                  \
3564 _(netmap_delete_reply)                                  \
3565 _(set_ipfix_exporter_reply)                             \
3566 _(set_ipfix_classify_stream_reply)                      \
3567 _(ipfix_classify_table_add_del_reply)                   \
3568 _(flow_classify_set_interface_reply)                    \
3569 _(pg_capture_reply)                                     \
3570 _(pg_enable_disable_reply)                              \
3571 _(ip_source_and_port_range_check_add_del_reply)         \
3572 _(ip_source_and_port_range_check_interface_add_del_reply)\
3573 _(delete_subif_reply)                                   \
3574 _(l2_interface_pbb_tag_rewrite_reply)                   \
3575 _(punt_reply)
3576
3577 #define _(n)                                    \
3578     static void vl_api_##n##_t_handler          \
3579     (vl_api_##n##_t * mp)                       \
3580     {                                           \
3581         vat_main_t * vam = &vat_main;           \
3582         i32 retval = ntohl(mp->retval);         \
3583         if (vam->async_mode) {                  \
3584             vam->async_errors += (retval < 0);  \
3585         } else {                                \
3586             vam->retval = retval;               \
3587             vam->result_ready = 1;              \
3588         }                                       \
3589     }
3590 foreach_standard_reply_retval_handler;
3591 #undef _
3592
3593 #define _(n)                                    \
3594     static void vl_api_##n##_t_handler_json     \
3595     (vl_api_##n##_t * mp)                       \
3596     {                                           \
3597         vat_main_t * vam = &vat_main;           \
3598         vat_json_node_t node;                   \
3599         vat_json_init_object(&node);            \
3600         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3601         vat_json_print(vam->ofp, &node);        \
3602         vam->retval = ntohl(mp->retval);        \
3603         vam->result_ready = 1;                  \
3604     }
3605 foreach_standard_reply_retval_handler;
3606 #undef _
3607
3608 /*
3609  * Table of message reply handlers, must include boilerplate handlers
3610  * we just generated
3611  */
3612
3613 #define foreach_vpe_api_reply_msg                                       \
3614 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3615 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3616 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3617 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3618 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3619 _(CLI_REPLY, cli_reply)                                                 \
3620 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3621 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3622   sw_interface_add_del_address_reply)                                   \
3623 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3624 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3625 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3626   sw_interface_set_l2_xconnect_reply)                                   \
3627 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3628   sw_interface_set_l2_bridge_reply)                                     \
3629 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3630   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3631 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3632   sw_interface_set_dpdk_hqos_subport_reply)                             \
3633 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3634   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3635 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3636 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3637 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3638 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3639 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3640 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3641 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3642 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3643 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3644 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3645 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3646 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3647 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3648 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3649 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3650   proxy_arp_intfc_enable_disable_reply)                                 \
3651 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3652 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3653   mpls_ethernet_add_del_tunnel_reply)                                   \
3654 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3655   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3656 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3657   sw_interface_set_unnumbered_reply)                                    \
3658 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3659 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3660 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3661 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3662 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3663 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3664 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3665 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3666 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3667 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3668 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3669 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3670   sw_interface_ip6_enable_disable_reply)                                \
3671 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3672   sw_interface_ip6_set_link_local_address_reply)                        \
3673 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3674   sw_interface_ip6nd_ra_prefix_reply)                                   \
3675 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3676   sw_interface_ip6nd_ra_config_reply)                                   \
3677 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3678 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3679 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3680 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3681 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3682 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3683 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3684 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3685 classify_set_interface_ip_table_reply)                                  \
3686 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3687   classify_set_interface_l2_tables_reply)                               \
3688 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3689 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3690 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3691 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3692 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3693   l2tpv3_interface_enable_disable_reply)                                \
3694 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3695 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3696 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3697 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3698 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3699 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3700 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3701 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3702 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3703 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3704 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3705 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3706 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3707 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3708 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3709 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3710 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3711 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3712 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3713 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3714 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3715 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3716 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3717 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3718 _(IP_DETAILS, ip_details)                                               \
3719 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3720 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3721 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3722 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3723 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3724 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3725 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3726 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3727 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3728 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3729 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3730 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3731 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3732 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3733 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3734 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3735 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3736 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3737 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3738 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3739 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3740 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3741 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3742 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3743 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3744 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3745 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3746 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3747 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3748 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3749 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3750 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3751 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3752 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3753 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3754 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3755 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3756 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3757 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3758 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3759 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3760 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3761 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3762 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3763 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3764 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3765 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3766 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3767 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3768 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3769 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3770 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3771 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3772   lisp_add_del_map_request_itr_rlocs_reply)                             \
3773 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3774   lisp_get_map_request_itr_rlocs_reply)                                 \
3775 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3776 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3777 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3778 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3779 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3780 _(POLICER_DETAILS, policer_details)                                     \
3781 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3782 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3783 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3784 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3785 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3786 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3787 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3788 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3789 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3790 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3791 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3792 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3793 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3794 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3795 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3796 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3797 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3798 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3799 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3800 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3801 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3802 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3803 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3804 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3805  ip_source_and_port_range_check_add_del_reply)                          \
3806 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3807  ip_source_and_port_range_check_interface_add_del_reply)                \
3808 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3809 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3810 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3811 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3812 _(PUNT_REPLY, punt_reply)
3813
3814 /* M: construct, but don't yet send a message */
3815
3816 #define M(T,t)                                  \
3817 do {                                            \
3818     vam->result_ready = 0;                      \
3819     mp = vl_msg_api_alloc(sizeof(*mp));         \
3820     memset (mp, 0, sizeof (*mp));               \
3821     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3822     mp->client_index = vam->my_client_index;    \
3823 } while(0);
3824
3825 #define M2(T,t,n)                               \
3826 do {                                            \
3827     vam->result_ready = 0;                      \
3828     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3829     memset (mp, 0, sizeof (*mp));               \
3830     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3831     mp->client_index = vam->my_client_index;    \
3832 } while(0);
3833
3834
3835 /* S: send a message */
3836 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3837
3838 /* W: wait for results, with timeout */
3839 #define W                                       \
3840 do {                                            \
3841     timeout = vat_time_now (vam) + 1.0;         \
3842                                                 \
3843     while (vat_time_now (vam) < timeout) {      \
3844         if (vam->result_ready == 1) {           \
3845             return (vam->retval);               \
3846         }                                       \
3847     }                                           \
3848     return -99;                                 \
3849 } while(0);
3850
3851 /* W2: wait for results, with timeout */
3852 #define W2(body)                                \
3853 do {                                            \
3854     timeout = vat_time_now (vam) + 1.0;         \
3855                                                 \
3856     while (vat_time_now (vam) < timeout) {      \
3857         if (vam->result_ready == 1) {           \
3858           (body);                               \
3859           return (vam->retval);                 \
3860         }                                       \
3861     }                                           \
3862     return -99;                                 \
3863 } while(0);
3864
3865 typedef struct
3866 {
3867   u8 *name;
3868   u32 value;
3869 } name_sort_t;
3870
3871
3872 #define STR_VTR_OP_CASE(op)     \
3873     case L2_VTR_ ## op:         \
3874         return "" # op;
3875
3876 static const char *
3877 str_vtr_op (u32 vtr_op)
3878 {
3879   switch (vtr_op)
3880     {
3881       STR_VTR_OP_CASE (DISABLED);
3882       STR_VTR_OP_CASE (PUSH_1);
3883       STR_VTR_OP_CASE (PUSH_2);
3884       STR_VTR_OP_CASE (POP_1);
3885       STR_VTR_OP_CASE (POP_2);
3886       STR_VTR_OP_CASE (TRANSLATE_1_1);
3887       STR_VTR_OP_CASE (TRANSLATE_1_2);
3888       STR_VTR_OP_CASE (TRANSLATE_2_1);
3889       STR_VTR_OP_CASE (TRANSLATE_2_2);
3890     }
3891
3892   return "UNKNOWN";
3893 }
3894
3895 static int
3896 dump_sub_interface_table (vat_main_t * vam)
3897 {
3898   const sw_interface_subif_t *sub = NULL;
3899
3900   if (vam->json_output)
3901     {
3902       clib_warning
3903         ("JSON output supported only for VPE API calls and dump_stats_table");
3904       return -99;
3905     }
3906
3907   fformat (vam->ofp,
3908            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3909            "Interface", "sw_if_index",
3910            "sub id", "dot1ad", "tags", "outer id",
3911            "inner id", "exact", "default", "outer any", "inner any");
3912
3913   vec_foreach (sub, vam->sw_if_subif_table)
3914   {
3915     fformat (vam->ofp,
3916              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3917              sub->interface_name,
3918              sub->sw_if_index,
3919              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3920              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3921              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3922              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3923     if (sub->vtr_op != L2_VTR_DISABLED)
3924       {
3925         fformat (vam->ofp,
3926                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3927                  "tag1: %d tag2: %d ]\n",
3928                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3929                  sub->vtr_tag1, sub->vtr_tag2);
3930       }
3931   }
3932
3933   return 0;
3934 }
3935
3936 static int
3937 name_sort_cmp (void *a1, void *a2)
3938 {
3939   name_sort_t *n1 = a1;
3940   name_sort_t *n2 = a2;
3941
3942   return strcmp ((char *) n1->name, (char *) n2->name);
3943 }
3944
3945 static int
3946 dump_interface_table (vat_main_t * vam)
3947 {
3948   hash_pair_t *p;
3949   name_sort_t *nses = 0, *ns;
3950
3951   if (vam->json_output)
3952     {
3953       clib_warning
3954         ("JSON output supported only for VPE API calls and dump_stats_table");
3955       return -99;
3956     }
3957
3958   /* *INDENT-OFF* */
3959   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3960   ({
3961     vec_add2 (nses, ns, 1);
3962     ns->name = (u8 *)(p->key);
3963     ns->value = (u32) p->value[0];
3964   }));
3965   /* *INDENT-ON* */
3966
3967   vec_sort_with_function (nses, name_sort_cmp);
3968
3969   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3970   vec_foreach (ns, nses)
3971   {
3972     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3973   }
3974   vec_free (nses);
3975   return 0;
3976 }
3977
3978 static int
3979 dump_ip_table (vat_main_t * vam, int is_ipv6)
3980 {
3981   const ip_details_t *det = NULL;
3982   const ip_address_details_t *address = NULL;
3983   u32 i = ~0;
3984
3985   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3986
3987   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3988   {
3989     i++;
3990     if (!det->present)
3991       {
3992         continue;
3993       }
3994     fformat (vam->ofp, "%-12d\n", i);
3995     fformat (vam->ofp,
3996              "            %-30s%-13s\n", "Address", "Prefix length");
3997     if (!det->addr)
3998       {
3999         continue;
4000       }
4001     vec_foreach (address, det->addr)
4002     {
4003       fformat (vam->ofp,
4004                "            %-30U%-13d\n",
4005                is_ipv6 ? format_ip6_address : format_ip4_address,
4006                address->ip, address->prefix_length);
4007     }
4008   }
4009
4010   return 0;
4011 }
4012
4013 static int
4014 dump_ipv4_table (vat_main_t * vam)
4015 {
4016   if (vam->json_output)
4017     {
4018       clib_warning
4019         ("JSON output supported only for VPE API calls and dump_stats_table");
4020       return -99;
4021     }
4022
4023   return dump_ip_table (vam, 0);
4024 }
4025
4026 static int
4027 dump_ipv6_table (vat_main_t * vam)
4028 {
4029   if (vam->json_output)
4030     {
4031       clib_warning
4032         ("JSON output supported only for VPE API calls and dump_stats_table");
4033       return -99;
4034     }
4035
4036   return dump_ip_table (vam, 1);
4037 }
4038
4039 static char *
4040 counter_type_to_str (u8 counter_type, u8 is_combined)
4041 {
4042   if (!is_combined)
4043     {
4044       switch (counter_type)
4045         {
4046         case VNET_INTERFACE_COUNTER_DROP:
4047           return "drop";
4048         case VNET_INTERFACE_COUNTER_PUNT:
4049           return "punt";
4050         case VNET_INTERFACE_COUNTER_IP4:
4051           return "ip4";
4052         case VNET_INTERFACE_COUNTER_IP6:
4053           return "ip6";
4054         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4055           return "rx-no-buf";
4056         case VNET_INTERFACE_COUNTER_RX_MISS:
4057           return "rx-miss";
4058         case VNET_INTERFACE_COUNTER_RX_ERROR:
4059           return "rx-error";
4060         case VNET_INTERFACE_COUNTER_TX_ERROR:
4061           return "tx-error";
4062         default:
4063           return "INVALID-COUNTER-TYPE";
4064         }
4065     }
4066   else
4067     {
4068       switch (counter_type)
4069         {
4070         case VNET_INTERFACE_COUNTER_RX:
4071           return "rx";
4072         case VNET_INTERFACE_COUNTER_TX:
4073           return "tx";
4074         default:
4075           return "INVALID-COUNTER-TYPE";
4076         }
4077     }
4078 }
4079
4080 static int
4081 dump_stats_table (vat_main_t * vam)
4082 {
4083   vat_json_node_t node;
4084   vat_json_node_t *msg_array;
4085   vat_json_node_t *msg;
4086   vat_json_node_t *counter_array;
4087   vat_json_node_t *counter;
4088   interface_counter_t c;
4089   u64 packets;
4090   ip4_fib_counter_t *c4;
4091   ip6_fib_counter_t *c6;
4092   int i, j;
4093
4094   if (!vam->json_output)
4095     {
4096       clib_warning ("dump_stats_table supported only in JSON format");
4097       return -99;
4098     }
4099
4100   vat_json_init_object (&node);
4101
4102   /* interface counters */
4103   msg_array = vat_json_object_add (&node, "interface_counters");
4104   vat_json_init_array (msg_array);
4105   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4106     {
4107       msg = vat_json_array_add (msg_array);
4108       vat_json_init_object (msg);
4109       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4110                                        (u8 *) counter_type_to_str (i, 0));
4111       vat_json_object_add_int (msg, "is_combined", 0);
4112       counter_array = vat_json_object_add (msg, "data");
4113       vat_json_init_array (counter_array);
4114       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4115         {
4116           packets = vam->simple_interface_counters[i][j];
4117           vat_json_array_add_uint (counter_array, packets);
4118         }
4119     }
4120   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4121     {
4122       msg = vat_json_array_add (msg_array);
4123       vat_json_init_object (msg);
4124       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4125                                        (u8 *) counter_type_to_str (i, 1));
4126       vat_json_object_add_int (msg, "is_combined", 1);
4127       counter_array = vat_json_object_add (msg, "data");
4128       vat_json_init_array (counter_array);
4129       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4130         {
4131           c = vam->combined_interface_counters[i][j];
4132           counter = vat_json_array_add (counter_array);
4133           vat_json_init_object (counter);
4134           vat_json_object_add_uint (counter, "packets", c.packets);
4135           vat_json_object_add_uint (counter, "bytes", c.bytes);
4136         }
4137     }
4138
4139   /* ip4 fib counters */
4140   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4141   vat_json_init_array (msg_array);
4142   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4143     {
4144       msg = vat_json_array_add (msg_array);
4145       vat_json_init_object (msg);
4146       vat_json_object_add_uint (msg, "vrf_id",
4147                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4148       counter_array = vat_json_object_add (msg, "c");
4149       vat_json_init_array (counter_array);
4150       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4151         {
4152           counter = vat_json_array_add (counter_array);
4153           vat_json_init_object (counter);
4154           c4 = &vam->ip4_fib_counters[i][j];
4155           vat_json_object_add_ip4 (counter, "address", c4->address);
4156           vat_json_object_add_uint (counter, "address_length",
4157                                     c4->address_length);
4158           vat_json_object_add_uint (counter, "packets", c4->packets);
4159           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4160         }
4161     }
4162
4163   /* ip6 fib counters */
4164   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4165   vat_json_init_array (msg_array);
4166   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4167     {
4168       msg = vat_json_array_add (msg_array);
4169       vat_json_init_object (msg);
4170       vat_json_object_add_uint (msg, "vrf_id",
4171                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4172       counter_array = vat_json_object_add (msg, "c");
4173       vat_json_init_array (counter_array);
4174       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4175         {
4176           counter = vat_json_array_add (counter_array);
4177           vat_json_init_object (counter);
4178           c6 = &vam->ip6_fib_counters[i][j];
4179           vat_json_object_add_ip6 (counter, "address", c6->address);
4180           vat_json_object_add_uint (counter, "address_length",
4181                                     c6->address_length);
4182           vat_json_object_add_uint (counter, "packets", c6->packets);
4183           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4184         }
4185     }
4186
4187   vat_json_print (vam->ofp, &node);
4188   vat_json_free (&node);
4189
4190   return 0;
4191 }
4192
4193 int
4194 exec (vat_main_t * vam)
4195 {
4196   api_main_t *am = &api_main;
4197   vl_api_cli_request_t *mp;
4198   f64 timeout;
4199   void *oldheap;
4200   u8 *cmd = 0;
4201   unformat_input_t *i = vam->input;
4202
4203   if (vec_len (i->buffer) == 0)
4204     return -1;
4205
4206   if (vam->exec_mode == 0 && unformat (i, "mode"))
4207     {
4208       vam->exec_mode = 1;
4209       return 0;
4210     }
4211   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4212     {
4213       vam->exec_mode = 0;
4214       return 0;
4215     }
4216
4217
4218   M (CLI_REQUEST, cli_request);
4219
4220   /*
4221    * Copy cmd into shared memory.
4222    * In order for the CLI command to work, it
4223    * must be a vector ending in \n, not a C-string ending
4224    * in \n\0.
4225    */
4226   pthread_mutex_lock (&am->vlib_rp->mutex);
4227   oldheap = svm_push_data_heap (am->vlib_rp);
4228
4229   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4230   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4231
4232   svm_pop_heap (oldheap);
4233   pthread_mutex_unlock (&am->vlib_rp->mutex);
4234
4235   mp->cmd_in_shmem = (u64) cmd;
4236   S;
4237   timeout = vat_time_now (vam) + 10.0;
4238
4239   while (vat_time_now (vam) < timeout)
4240     {
4241       if (vam->result_ready == 1)
4242         {
4243           u8 *free_me;
4244           if (vam->shmem_result != NULL)
4245             fformat (vam->ofp, "%s", vam->shmem_result);
4246           pthread_mutex_lock (&am->vlib_rp->mutex);
4247           oldheap = svm_push_data_heap (am->vlib_rp);
4248
4249           free_me = (u8 *) vam->shmem_result;
4250           vec_free (free_me);
4251
4252           svm_pop_heap (oldheap);
4253           pthread_mutex_unlock (&am->vlib_rp->mutex);
4254           return 0;
4255         }
4256     }
4257   return -99;
4258 }
4259
4260 /*
4261  * Future replacement of exec() that passes CLI buffers directly in
4262  * the API messages instead of an additional shared memory area.
4263  */
4264 static int
4265 exec_inband (vat_main_t * vam)
4266 {
4267   vl_api_cli_inband_t *mp;
4268   f64 timeout;
4269   unformat_input_t *i = vam->input;
4270
4271   if (vec_len (i->buffer) == 0)
4272     return -1;
4273
4274   if (vam->exec_mode == 0 && unformat (i, "mode"))
4275     {
4276       vam->exec_mode = 1;
4277       return 0;
4278     }
4279   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4280     {
4281       vam->exec_mode = 0;
4282       return 0;
4283     }
4284
4285   /*
4286    * In order for the CLI command to work, it
4287    * must be a vector ending in \n, not a C-string ending
4288    * in \n\0.
4289    */
4290   u32 len = vec_len (vam->input->buffer);
4291   M2 (CLI_INBAND, cli_inband, len);
4292   clib_memcpy (mp->cmd, vam->input->buffer, len);
4293   mp->length = htonl (len);
4294
4295   S;
4296   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4297 }
4298
4299 static int
4300 api_create_loopback (vat_main_t * vam)
4301 {
4302   unformat_input_t *i = vam->input;
4303   vl_api_create_loopback_t *mp;
4304   f64 timeout;
4305   u8 mac_address[6];
4306   u8 mac_set = 0;
4307
4308   memset (mac_address, 0, sizeof (mac_address));
4309
4310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4311     {
4312       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4313         mac_set = 1;
4314       else
4315         break;
4316     }
4317
4318   /* Construct the API message */
4319   M (CREATE_LOOPBACK, create_loopback);
4320   if (mac_set)
4321     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4322
4323   S;
4324   W;
4325 }
4326
4327 static int
4328 api_delete_loopback (vat_main_t * vam)
4329 {
4330   unformat_input_t *i = vam->input;
4331   vl_api_delete_loopback_t *mp;
4332   f64 timeout;
4333   u32 sw_if_index = ~0;
4334
4335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4336     {
4337       if (unformat (i, "sw_if_index %d", &sw_if_index))
4338         ;
4339       else
4340         break;
4341     }
4342
4343   if (sw_if_index == ~0)
4344     {
4345       errmsg ("missing sw_if_index\n");
4346       return -99;
4347     }
4348
4349   /* Construct the API message */
4350   M (DELETE_LOOPBACK, delete_loopback);
4351   mp->sw_if_index = ntohl (sw_if_index);
4352
4353   S;
4354   W;
4355 }
4356
4357 static int
4358 api_want_stats (vat_main_t * vam)
4359 {
4360   unformat_input_t *i = vam->input;
4361   vl_api_want_stats_t *mp;
4362   f64 timeout;
4363   int enable = -1;
4364
4365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4366     {
4367       if (unformat (i, "enable"))
4368         enable = 1;
4369       else if (unformat (i, "disable"))
4370         enable = 0;
4371       else
4372         break;
4373     }
4374
4375   if (enable == -1)
4376     {
4377       errmsg ("missing enable|disable\n");
4378       return -99;
4379     }
4380
4381   M (WANT_STATS, want_stats);
4382   mp->enable_disable = enable;
4383
4384   S;
4385   W;
4386 }
4387
4388 static int
4389 api_want_interface_events (vat_main_t * vam)
4390 {
4391   unformat_input_t *i = vam->input;
4392   vl_api_want_interface_events_t *mp;
4393   f64 timeout;
4394   int enable = -1;
4395
4396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4397     {
4398       if (unformat (i, "enable"))
4399         enable = 1;
4400       else if (unformat (i, "disable"))
4401         enable = 0;
4402       else
4403         break;
4404     }
4405
4406   if (enable == -1)
4407     {
4408       errmsg ("missing enable|disable\n");
4409       return -99;
4410     }
4411
4412   M (WANT_INTERFACE_EVENTS, want_interface_events);
4413   mp->enable_disable = enable;
4414
4415   vam->interface_event_display = enable;
4416
4417   S;
4418   W;
4419 }
4420
4421
4422 /* Note: non-static, called once to set up the initial intfc table */
4423 int
4424 api_sw_interface_dump (vat_main_t * vam)
4425 {
4426   vl_api_sw_interface_dump_t *mp;
4427   f64 timeout;
4428   hash_pair_t *p;
4429   name_sort_t *nses = 0, *ns;
4430   sw_interface_subif_t *sub = NULL;
4431
4432   /* Toss the old name table */
4433   /* *INDENT-OFF* */
4434   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4435   ({
4436     vec_add2 (nses, ns, 1);
4437     ns->name = (u8 *)(p->key);
4438     ns->value = (u32) p->value[0];
4439   }));
4440   /* *INDENT-ON* */
4441
4442   hash_free (vam->sw_if_index_by_interface_name);
4443
4444   vec_foreach (ns, nses) vec_free (ns->name);
4445
4446   vec_free (nses);
4447
4448   vec_foreach (sub, vam->sw_if_subif_table)
4449   {
4450     vec_free (sub->interface_name);
4451   }
4452   vec_free (vam->sw_if_subif_table);
4453
4454   /* recreate the interface name hash table */
4455   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4456
4457   /* Get list of ethernets */
4458   M (SW_INTERFACE_DUMP, sw_interface_dump);
4459   mp->name_filter_valid = 1;
4460   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4461   S;
4462
4463   /* and local / loopback interfaces */
4464   M (SW_INTERFACE_DUMP, sw_interface_dump);
4465   mp->name_filter_valid = 1;
4466   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4467   S;
4468
4469   /* and packet-generator interfaces */
4470   M (SW_INTERFACE_DUMP, sw_interface_dump);
4471   mp->name_filter_valid = 1;
4472   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4473   S;
4474
4475   /* and vxlan-gpe tunnel interfaces */
4476   M (SW_INTERFACE_DUMP, sw_interface_dump);
4477   mp->name_filter_valid = 1;
4478   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4479            sizeof (mp->name_filter) - 1);
4480   S;
4481
4482   /* and vxlan tunnel interfaces */
4483   M (SW_INTERFACE_DUMP, sw_interface_dump);
4484   mp->name_filter_valid = 1;
4485   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4486   S;
4487
4488   /* and host (af_packet) interfaces */
4489   M (SW_INTERFACE_DUMP, sw_interface_dump);
4490   mp->name_filter_valid = 1;
4491   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4492   S;
4493
4494   /* and l2tpv3 tunnel interfaces */
4495   M (SW_INTERFACE_DUMP, sw_interface_dump);
4496   mp->name_filter_valid = 1;
4497   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4498            sizeof (mp->name_filter) - 1);
4499   S;
4500
4501   /* and GRE tunnel interfaces */
4502   M (SW_INTERFACE_DUMP, sw_interface_dump);
4503   mp->name_filter_valid = 1;
4504   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4505   S;
4506
4507   /* and LISP-GPE interfaces */
4508   M (SW_INTERFACE_DUMP, sw_interface_dump);
4509   mp->name_filter_valid = 1;
4510   strncpy ((char *) mp->name_filter, "lisp_gpe",
4511            sizeof (mp->name_filter) - 1);
4512   S;
4513
4514   /* and IPSEC tunnel interfaces */
4515   M (SW_INTERFACE_DUMP, sw_interface_dump);
4516   mp->name_filter_valid = 1;
4517   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4518   S;
4519
4520   /* Use a control ping for synchronization */
4521   {
4522     vl_api_control_ping_t *mp;
4523     M (CONTROL_PING, control_ping);
4524     S;
4525   }
4526   W;
4527 }
4528
4529 static int
4530 api_sw_interface_set_flags (vat_main_t * vam)
4531 {
4532   unformat_input_t *i = vam->input;
4533   vl_api_sw_interface_set_flags_t *mp;
4534   f64 timeout;
4535   u32 sw_if_index;
4536   u8 sw_if_index_set = 0;
4537   u8 admin_up = 0, link_up = 0;
4538
4539   /* Parse args required to build the message */
4540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4541     {
4542       if (unformat (i, "admin-up"))
4543         admin_up = 1;
4544       else if (unformat (i, "admin-down"))
4545         admin_up = 0;
4546       else if (unformat (i, "link-up"))
4547         link_up = 1;
4548       else if (unformat (i, "link-down"))
4549         link_up = 0;
4550       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4551         sw_if_index_set = 1;
4552       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4553         sw_if_index_set = 1;
4554       else
4555         break;
4556     }
4557
4558   if (sw_if_index_set == 0)
4559     {
4560       errmsg ("missing interface name or sw_if_index\n");
4561       return -99;
4562     }
4563
4564   /* Construct the API message */
4565   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4566   mp->sw_if_index = ntohl (sw_if_index);
4567   mp->admin_up_down = admin_up;
4568   mp->link_up_down = link_up;
4569
4570   /* send it... */
4571   S;
4572
4573   /* Wait for a reply, return the good/bad news... */
4574   W;
4575 }
4576
4577 static int
4578 api_sw_interface_clear_stats (vat_main_t * vam)
4579 {
4580   unformat_input_t *i = vam->input;
4581   vl_api_sw_interface_clear_stats_t *mp;
4582   f64 timeout;
4583   u32 sw_if_index;
4584   u8 sw_if_index_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, "%U", unformat_sw_if_index, vam, &sw_if_index))
4590         sw_if_index_set = 1;
4591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4592         sw_if_index_set = 1;
4593       else
4594         break;
4595     }
4596
4597   /* Construct the API message */
4598   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4599
4600   if (sw_if_index_set == 1)
4601     mp->sw_if_index = ntohl (sw_if_index);
4602   else
4603     mp->sw_if_index = ~0;
4604
4605   /* send it... */
4606   S;
4607
4608   /* Wait for a reply, return the good/bad news... */
4609   W;
4610 }
4611
4612 static int
4613 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4614 {
4615   unformat_input_t *i = vam->input;
4616   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4617   f64 timeout;
4618   u32 sw_if_index;
4619   u8 sw_if_index_set = 0;
4620   u32 subport;
4621   u8 subport_set = 0;
4622   u32 pipe;
4623   u8 pipe_set = 0;
4624   u32 profile;
4625   u8 profile_set = 0;
4626
4627   /* Parse args required to build the message */
4628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4629     {
4630       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4631         sw_if_index_set = 1;
4632       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4633         sw_if_index_set = 1;
4634       else if (unformat (i, "subport %u", &subport))
4635         subport_set = 1;
4636       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4637         sw_if_index_set = 1;
4638       else if (unformat (i, "pipe %u", &pipe))
4639         pipe_set = 1;
4640       else if (unformat (i, "profile %u", &profile))
4641         profile_set = 1;
4642       else
4643         break;
4644     }
4645
4646   if (sw_if_index_set == 0)
4647     {
4648       errmsg ("missing interface name or sw_if_index\n");
4649       return -99;
4650     }
4651
4652   if (subport_set == 0)
4653     {
4654       errmsg ("missing subport \n");
4655       return -99;
4656     }
4657
4658   if (pipe_set == 0)
4659     {
4660       errmsg ("missing pipe\n");
4661       return -99;
4662     }
4663
4664   if (profile_set == 0)
4665     {
4666       errmsg ("missing profile\n");
4667       return -99;
4668     }
4669
4670   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4671
4672   mp->sw_if_index = ntohl (sw_if_index);
4673   mp->subport = ntohl (subport);
4674   mp->pipe = ntohl (pipe);
4675   mp->profile = ntohl (profile);
4676
4677
4678   S;
4679   W;
4680   /* NOTREACHED */
4681   return 0;
4682 }
4683
4684 static int
4685 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4686 {
4687   unformat_input_t *i = vam->input;
4688   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4689   f64 timeout;
4690   u32 sw_if_index;
4691   u8 sw_if_index_set = 0;
4692   u32 subport;
4693   u8 subport_set = 0;
4694   u32 tb_rate = 1250000000;     /* 10GbE */
4695   u32 tb_size = 1000000;
4696   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4697   u32 tc_period = 10;
4698
4699   /* Parse args required to build the message */
4700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4701     {
4702       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4703         sw_if_index_set = 1;
4704       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4705         sw_if_index_set = 1;
4706       else if (unformat (i, "subport %u", &subport))
4707         subport_set = 1;
4708       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4709         sw_if_index_set = 1;
4710       else if (unformat (i, "rate %u", &tb_rate))
4711         {
4712           u32 tc_id;
4713
4714           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4715                tc_id++)
4716             tc_rate[tc_id] = tb_rate;
4717         }
4718       else if (unformat (i, "bktsize %u", &tb_size))
4719         ;
4720       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4721         ;
4722       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4723         ;
4724       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4725         ;
4726       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4727         ;
4728       else if (unformat (i, "period %u", &tc_period))
4729         ;
4730       else
4731         break;
4732     }
4733
4734   if (sw_if_index_set == 0)
4735     {
4736       errmsg ("missing interface name or sw_if_index\n");
4737       return -99;
4738     }
4739
4740   if (subport_set == 0)
4741     {
4742       errmsg ("missing subport \n");
4743       return -99;
4744     }
4745
4746   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4747
4748   mp->sw_if_index = ntohl (sw_if_index);
4749   mp->subport = ntohl (subport);
4750   mp->tb_rate = ntohl (tb_rate);
4751   mp->tb_size = ntohl (tb_size);
4752   mp->tc_rate[0] = ntohl (tc_rate[0]);
4753   mp->tc_rate[1] = ntohl (tc_rate[1]);
4754   mp->tc_rate[2] = ntohl (tc_rate[2]);
4755   mp->tc_rate[3] = ntohl (tc_rate[3]);
4756   mp->tc_period = ntohl (tc_period);
4757
4758   S;
4759   W;
4760   /* NOTREACHED */
4761   return 0;
4762 }
4763
4764 static int
4765 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4766 {
4767   unformat_input_t *i = vam->input;
4768   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4769   f64 timeout;
4770   u32 sw_if_index;
4771   u8 sw_if_index_set = 0;
4772   u8 entry_set = 0;
4773   u8 tc_set = 0;
4774   u8 queue_set = 0;
4775   u32 entry, tc, queue;
4776
4777   /* Parse args required to build the message */
4778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4779     {
4780       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4781         sw_if_index_set = 1;
4782       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4783         sw_if_index_set = 1;
4784       else if (unformat (i, "entry %d", &entry))
4785         entry_set = 1;
4786       else if (unformat (i, "tc %d", &tc))
4787         tc_set = 1;
4788       else if (unformat (i, "queue %d", &queue))
4789         queue_set = 1;
4790       else
4791         break;
4792     }
4793
4794   if (sw_if_index_set == 0)
4795     {
4796       errmsg ("missing interface name or sw_if_index\n");
4797       return -99;
4798     }
4799
4800   if (entry_set == 0)
4801     {
4802       errmsg ("missing entry \n");
4803       return -99;
4804     }
4805
4806   if (tc_set == 0)
4807     {
4808       errmsg ("missing traffic class \n");
4809       return -99;
4810     }
4811
4812   if (queue_set == 0)
4813     {
4814       errmsg ("missing queue \n");
4815       return -99;
4816     }
4817
4818   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4819
4820   mp->sw_if_index = ntohl (sw_if_index);
4821   mp->entry = ntohl (entry);
4822   mp->tc = ntohl (tc);
4823   mp->queue = ntohl (queue);
4824
4825   S;
4826   W;
4827   /* NOTREACHED */
4828   return 0;
4829 }
4830
4831 static int
4832 api_sw_interface_add_del_address (vat_main_t * vam)
4833 {
4834   unformat_input_t *i = vam->input;
4835   vl_api_sw_interface_add_del_address_t *mp;
4836   f64 timeout;
4837   u32 sw_if_index;
4838   u8 sw_if_index_set = 0;
4839   u8 is_add = 1, del_all = 0;
4840   u32 address_length = 0;
4841   u8 v4_address_set = 0;
4842   u8 v6_address_set = 0;
4843   ip4_address_t v4address;
4844   ip6_address_t v6address;
4845
4846   /* Parse args required to build the message */
4847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4848     {
4849       if (unformat (i, "del-all"))
4850         del_all = 1;
4851       else if (unformat (i, "del"))
4852         is_add = 0;
4853       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4854         sw_if_index_set = 1;
4855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4856         sw_if_index_set = 1;
4857       else if (unformat (i, "%U/%d",
4858                          unformat_ip4_address, &v4address, &address_length))
4859         v4_address_set = 1;
4860       else if (unformat (i, "%U/%d",
4861                          unformat_ip6_address, &v6address, &address_length))
4862         v6_address_set = 1;
4863       else
4864         break;
4865     }
4866
4867   if (sw_if_index_set == 0)
4868     {
4869       errmsg ("missing interface name or sw_if_index\n");
4870       return -99;
4871     }
4872   if (v4_address_set && v6_address_set)
4873     {
4874       errmsg ("both v4 and v6 addresses set\n");
4875       return -99;
4876     }
4877   if (!v4_address_set && !v6_address_set && !del_all)
4878     {
4879       errmsg ("no addresses set\n");
4880       return -99;
4881     }
4882
4883   /* Construct the API message */
4884   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4885
4886   mp->sw_if_index = ntohl (sw_if_index);
4887   mp->is_add = is_add;
4888   mp->del_all = del_all;
4889   if (v6_address_set)
4890     {
4891       mp->is_ipv6 = 1;
4892       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4893     }
4894   else
4895     {
4896       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4897     }
4898   mp->address_length = address_length;
4899
4900   /* send it... */
4901   S;
4902
4903   /* Wait for a reply, return good/bad news  */
4904   W;
4905 }
4906
4907 static int
4908 api_sw_interface_set_table (vat_main_t * vam)
4909 {
4910   unformat_input_t *i = vam->input;
4911   vl_api_sw_interface_set_table_t *mp;
4912   f64 timeout;
4913   u32 sw_if_index, vrf_id = 0;
4914   u8 sw_if_index_set = 0;
4915   u8 is_ipv6 = 0;
4916
4917   /* Parse args required to build the message */
4918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4919     {
4920       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4921         sw_if_index_set = 1;
4922       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4923         sw_if_index_set = 1;
4924       else if (unformat (i, "vrf %d", &vrf_id))
4925         ;
4926       else if (unformat (i, "ipv6"))
4927         is_ipv6 = 1;
4928       else
4929         break;
4930     }
4931
4932   if (sw_if_index_set == 0)
4933     {
4934       errmsg ("missing interface name or sw_if_index\n");
4935       return -99;
4936     }
4937
4938   /* Construct the API message */
4939   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4940
4941   mp->sw_if_index = ntohl (sw_if_index);
4942   mp->is_ipv6 = is_ipv6;
4943   mp->vrf_id = ntohl (vrf_id);
4944
4945   /* send it... */
4946   S;
4947
4948   /* Wait for a reply... */
4949   W;
4950 }
4951
4952 static int
4953 api_sw_interface_set_vpath (vat_main_t * vam)
4954 {
4955   unformat_input_t *i = vam->input;
4956   vl_api_sw_interface_set_vpath_t *mp;
4957   f64 timeout;
4958   u32 sw_if_index = 0;
4959   u8 sw_if_index_set = 0;
4960   u8 is_enable = 0;
4961
4962   /* Parse args required to build the message */
4963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4964     {
4965       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4966         sw_if_index_set = 1;
4967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4968         sw_if_index_set = 1;
4969       else if (unformat (i, "enable"))
4970         is_enable = 1;
4971       else if (unformat (i, "disable"))
4972         is_enable = 0;
4973       else
4974         break;
4975     }
4976
4977   if (sw_if_index_set == 0)
4978     {
4979       errmsg ("missing interface name or sw_if_index\n");
4980       return -99;
4981     }
4982
4983   /* Construct the API message */
4984   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4985
4986   mp->sw_if_index = ntohl (sw_if_index);
4987   mp->enable = is_enable;
4988
4989   /* send it... */
4990   S;
4991
4992   /* Wait for a reply... */
4993   W;
4994 }
4995
4996 static int
4997 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4998 {
4999   unformat_input_t *i = vam->input;
5000   vl_api_sw_interface_set_l2_xconnect_t *mp;
5001   f64 timeout;
5002   u32 rx_sw_if_index;
5003   u8 rx_sw_if_index_set = 0;
5004   u32 tx_sw_if_index;
5005   u8 tx_sw_if_index_set = 0;
5006   u8 enable = 1;
5007
5008   /* Parse args required to build the message */
5009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5010     {
5011       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5012         rx_sw_if_index_set = 1;
5013       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5014         tx_sw_if_index_set = 1;
5015       else if (unformat (i, "rx"))
5016         {
5017           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5018             {
5019               if (unformat (i, "%U", unformat_sw_if_index, vam,
5020                             &rx_sw_if_index))
5021                 rx_sw_if_index_set = 1;
5022             }
5023           else
5024             break;
5025         }
5026       else if (unformat (i, "tx"))
5027         {
5028           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5029             {
5030               if (unformat (i, "%U", unformat_sw_if_index, vam,
5031                             &tx_sw_if_index))
5032                 tx_sw_if_index_set = 1;
5033             }
5034           else
5035             break;
5036         }
5037       else if (unformat (i, "enable"))
5038         enable = 1;
5039       else if (unformat (i, "disable"))
5040         enable = 0;
5041       else
5042         break;
5043     }
5044
5045   if (rx_sw_if_index_set == 0)
5046     {
5047       errmsg ("missing rx interface name or rx_sw_if_index\n");
5048       return -99;
5049     }
5050
5051   if (enable && (tx_sw_if_index_set == 0))
5052     {
5053       errmsg ("missing tx interface name or tx_sw_if_index\n");
5054       return -99;
5055     }
5056
5057   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5058
5059   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5060   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5061   mp->enable = enable;
5062
5063   S;
5064   W;
5065   /* NOTREACHED */
5066   return 0;
5067 }
5068
5069 static int
5070 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5071 {
5072   unformat_input_t *i = vam->input;
5073   vl_api_sw_interface_set_l2_bridge_t *mp;
5074   f64 timeout;
5075   u32 rx_sw_if_index;
5076   u8 rx_sw_if_index_set = 0;
5077   u32 bd_id;
5078   u8 bd_id_set = 0;
5079   u8 bvi = 0;
5080   u32 shg = 0;
5081   u8 enable = 1;
5082
5083   /* Parse args required to build the message */
5084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5085     {
5086       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5087         rx_sw_if_index_set = 1;
5088       else if (unformat (i, "bd_id %d", &bd_id))
5089         bd_id_set = 1;
5090       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5091         rx_sw_if_index_set = 1;
5092       else if (unformat (i, "shg %d", &shg))
5093         ;
5094       else if (unformat (i, "bvi"))
5095         bvi = 1;
5096       else if (unformat (i, "enable"))
5097         enable = 1;
5098       else if (unformat (i, "disable"))
5099         enable = 0;
5100       else
5101         break;
5102     }
5103
5104   if (rx_sw_if_index_set == 0)
5105     {
5106       errmsg ("missing rx interface name or sw_if_index\n");
5107       return -99;
5108     }
5109
5110   if (enable && (bd_id_set == 0))
5111     {
5112       errmsg ("missing bridge domain\n");
5113       return -99;
5114     }
5115
5116   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5117
5118   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5119   mp->bd_id = ntohl (bd_id);
5120   mp->shg = (u8) shg;
5121   mp->bvi = bvi;
5122   mp->enable = enable;
5123
5124   S;
5125   W;
5126   /* NOTREACHED */
5127   return 0;
5128 }
5129
5130 static int
5131 api_bridge_domain_dump (vat_main_t * vam)
5132 {
5133   unformat_input_t *i = vam->input;
5134   vl_api_bridge_domain_dump_t *mp;
5135   f64 timeout;
5136   u32 bd_id = ~0;
5137
5138   /* Parse args required to build the message */
5139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5140     {
5141       if (unformat (i, "bd_id %d", &bd_id))
5142         ;
5143       else
5144         break;
5145     }
5146
5147   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5148   mp->bd_id = ntohl (bd_id);
5149   S;
5150
5151   /* Use a control ping for synchronization */
5152   {
5153     vl_api_control_ping_t *mp;
5154     M (CONTROL_PING, control_ping);
5155     S;
5156   }
5157
5158   W;
5159   /* NOTREACHED */
5160   return 0;
5161 }
5162
5163 static int
5164 api_bridge_domain_add_del (vat_main_t * vam)
5165 {
5166   unformat_input_t *i = vam->input;
5167   vl_api_bridge_domain_add_del_t *mp;
5168   f64 timeout;
5169   u32 bd_id = ~0;
5170   u8 is_add = 1;
5171   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5172
5173   /* Parse args required to build the message */
5174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5175     {
5176       if (unformat (i, "bd_id %d", &bd_id))
5177         ;
5178       else if (unformat (i, "flood %d", &flood))
5179         ;
5180       else if (unformat (i, "uu-flood %d", &uu_flood))
5181         ;
5182       else if (unformat (i, "forward %d", &forward))
5183         ;
5184       else if (unformat (i, "learn %d", &learn))
5185         ;
5186       else if (unformat (i, "arp-term %d", &arp_term))
5187         ;
5188       else if (unformat (i, "del"))
5189         {
5190           is_add = 0;
5191           flood = uu_flood = forward = learn = 0;
5192         }
5193       else
5194         break;
5195     }
5196
5197   if (bd_id == ~0)
5198     {
5199       errmsg ("missing bridge domain\n");
5200       return -99;
5201     }
5202
5203   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5204
5205   mp->bd_id = ntohl (bd_id);
5206   mp->flood = flood;
5207   mp->uu_flood = uu_flood;
5208   mp->forward = forward;
5209   mp->learn = learn;
5210   mp->arp_term = arp_term;
5211   mp->is_add = is_add;
5212
5213   S;
5214   W;
5215   /* NOTREACHED */
5216   return 0;
5217 }
5218
5219 static int
5220 api_l2fib_add_del (vat_main_t * vam)
5221 {
5222   unformat_input_t *i = vam->input;
5223   vl_api_l2fib_add_del_t *mp;
5224   f64 timeout;
5225   u64 mac = 0;
5226   u8 mac_set = 0;
5227   u32 bd_id;
5228   u8 bd_id_set = 0;
5229   u32 sw_if_index;
5230   u8 sw_if_index_set = 0;
5231   u8 is_add = 1;
5232   u8 static_mac = 0;
5233   u8 filter_mac = 0;
5234   u8 bvi_mac = 0;
5235   int count = 1;
5236   f64 before = 0;
5237   int j;
5238
5239   /* Parse args required to build the message */
5240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5241     {
5242       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5243         mac_set = 1;
5244       else if (unformat (i, "bd_id %d", &bd_id))
5245         bd_id_set = 1;
5246       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5247         sw_if_index_set = 1;
5248       else if (unformat (i, "sw_if"))
5249         {
5250           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5251             {
5252               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5253                 sw_if_index_set = 1;
5254             }
5255           else
5256             break;
5257         }
5258       else if (unformat (i, "static"))
5259         static_mac = 1;
5260       else if (unformat (i, "filter"))
5261         {
5262           filter_mac = 1;
5263           static_mac = 1;
5264         }
5265       else if (unformat (i, "bvi"))
5266         {
5267           bvi_mac = 1;
5268           static_mac = 1;
5269         }
5270       else if (unformat (i, "del"))
5271         is_add = 0;
5272       else if (unformat (i, "count %d", &count))
5273         ;
5274       else
5275         break;
5276     }
5277
5278   if (mac_set == 0)
5279     {
5280       errmsg ("missing mac address\n");
5281       return -99;
5282     }
5283
5284   if (bd_id_set == 0)
5285     {
5286       errmsg ("missing bridge domain\n");
5287       return -99;
5288     }
5289
5290   if (is_add && (sw_if_index_set == 0))
5291     {
5292       errmsg ("missing interface name or sw_if_index\n");
5293       return -99;
5294     }
5295
5296   if (count > 1)
5297     {
5298       /* Turn on async mode */
5299       vam->async_mode = 1;
5300       vam->async_errors = 0;
5301       before = vat_time_now (vam);
5302     }
5303
5304   for (j = 0; j < count; j++)
5305     {
5306       M (L2FIB_ADD_DEL, l2fib_add_del);
5307
5308       mp->mac = mac;
5309       mp->bd_id = ntohl (bd_id);
5310       mp->is_add = is_add;
5311
5312       if (is_add)
5313         {
5314           mp->sw_if_index = ntohl (sw_if_index);
5315           mp->static_mac = static_mac;
5316           mp->filter_mac = filter_mac;
5317           mp->bvi_mac = bvi_mac;
5318         }
5319       increment_mac_address (&mac);
5320       /* send it... */
5321       S;
5322     }
5323
5324   if (count > 1)
5325     {
5326       vl_api_control_ping_t *mp;
5327       f64 after;
5328
5329       /* Shut off async mode */
5330       vam->async_mode = 0;
5331
5332       M (CONTROL_PING, control_ping);
5333       S;
5334
5335       timeout = vat_time_now (vam) + 1.0;
5336       while (vat_time_now (vam) < timeout)
5337         if (vam->result_ready == 1)
5338           goto out;
5339       vam->retval = -99;
5340
5341     out:
5342       if (vam->retval == -99)
5343         errmsg ("timeout\n");
5344
5345       if (vam->async_errors > 0)
5346         {
5347           errmsg ("%d asynchronous errors\n", vam->async_errors);
5348           vam->retval = -98;
5349         }
5350       vam->async_errors = 0;
5351       after = vat_time_now (vam);
5352
5353       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5354                count, after - before, count / (after - before));
5355     }
5356   else
5357     {
5358       /* Wait for a reply... */
5359       W;
5360     }
5361   /* Return the good/bad news */
5362   return (vam->retval);
5363 }
5364
5365 static int
5366 api_l2_flags (vat_main_t * vam)
5367 {
5368   unformat_input_t *i = vam->input;
5369   vl_api_l2_flags_t *mp;
5370   f64 timeout;
5371   u32 sw_if_index;
5372   u32 feature_bitmap = 0;
5373   u8 sw_if_index_set = 0;
5374
5375   /* Parse args required to build the message */
5376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5377     {
5378       if (unformat (i, "sw_if_index %d", &sw_if_index))
5379         sw_if_index_set = 1;
5380       else if (unformat (i, "sw_if"))
5381         {
5382           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5383             {
5384               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5385                 sw_if_index_set = 1;
5386             }
5387           else
5388             break;
5389         }
5390       else if (unformat (i, "learn"))
5391         feature_bitmap |= L2INPUT_FEAT_LEARN;
5392       else if (unformat (i, "forward"))
5393         feature_bitmap |= L2INPUT_FEAT_FWD;
5394       else if (unformat (i, "flood"))
5395         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5396       else if (unformat (i, "uu-flood"))
5397         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5398       else
5399         break;
5400     }
5401
5402   if (sw_if_index_set == 0)
5403     {
5404       errmsg ("missing interface name or sw_if_index\n");
5405       return -99;
5406     }
5407
5408   M (L2_FLAGS, l2_flags);
5409
5410   mp->sw_if_index = ntohl (sw_if_index);
5411   mp->feature_bitmap = ntohl (feature_bitmap);
5412
5413   S;
5414   W;
5415   /* NOTREACHED */
5416   return 0;
5417 }
5418
5419 static int
5420 api_bridge_flags (vat_main_t * vam)
5421 {
5422   unformat_input_t *i = vam->input;
5423   vl_api_bridge_flags_t *mp;
5424   f64 timeout;
5425   u32 bd_id;
5426   u8 bd_id_set = 0;
5427   u8 is_set = 1;
5428   u32 flags = 0;
5429
5430   /* Parse args required to build the message */
5431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5432     {
5433       if (unformat (i, "bd_id %d", &bd_id))
5434         bd_id_set = 1;
5435       else if (unformat (i, "learn"))
5436         flags |= L2_LEARN;
5437       else if (unformat (i, "forward"))
5438         flags |= L2_FWD;
5439       else if (unformat (i, "flood"))
5440         flags |= L2_FLOOD;
5441       else if (unformat (i, "uu-flood"))
5442         flags |= L2_UU_FLOOD;
5443       else if (unformat (i, "arp-term"))
5444         flags |= L2_ARP_TERM;
5445       else if (unformat (i, "off"))
5446         is_set = 0;
5447       else if (unformat (i, "disable"))
5448         is_set = 0;
5449       else
5450         break;
5451     }
5452
5453   if (bd_id_set == 0)
5454     {
5455       errmsg ("missing bridge domain\n");
5456       return -99;
5457     }
5458
5459   M (BRIDGE_FLAGS, bridge_flags);
5460
5461   mp->bd_id = ntohl (bd_id);
5462   mp->feature_bitmap = ntohl (flags);
5463   mp->is_set = is_set;
5464
5465   S;
5466   W;
5467   /* NOTREACHED */
5468   return 0;
5469 }
5470
5471 static int
5472 api_bd_ip_mac_add_del (vat_main_t * vam)
5473 {
5474   unformat_input_t *i = vam->input;
5475   vl_api_bd_ip_mac_add_del_t *mp;
5476   f64 timeout;
5477   u32 bd_id;
5478   u8 is_ipv6 = 0;
5479   u8 is_add = 1;
5480   u8 bd_id_set = 0;
5481   u8 ip_set = 0;
5482   u8 mac_set = 0;
5483   ip4_address_t v4addr;
5484   ip6_address_t v6addr;
5485   u8 macaddr[6];
5486
5487
5488   /* Parse args required to build the message */
5489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5490     {
5491       if (unformat (i, "bd_id %d", &bd_id))
5492         {
5493           bd_id_set++;
5494         }
5495       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5496         {
5497           ip_set++;
5498         }
5499       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5500         {
5501           ip_set++;
5502           is_ipv6++;
5503         }
5504       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5505         {
5506           mac_set++;
5507         }
5508       else if (unformat (i, "del"))
5509         is_add = 0;
5510       else
5511         break;
5512     }
5513
5514   if (bd_id_set == 0)
5515     {
5516       errmsg ("missing bridge domain\n");
5517       return -99;
5518     }
5519   else if (ip_set == 0)
5520     {
5521       errmsg ("missing IP address\n");
5522       return -99;
5523     }
5524   else if (mac_set == 0)
5525     {
5526       errmsg ("missing MAC address\n");
5527       return -99;
5528     }
5529
5530   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5531
5532   mp->bd_id = ntohl (bd_id);
5533   mp->is_ipv6 = is_ipv6;
5534   mp->is_add = is_add;
5535   if (is_ipv6)
5536     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5537   else
5538     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5539   clib_memcpy (mp->mac_address, macaddr, 6);
5540   S;
5541   W;
5542   /* NOTREACHED */
5543   return 0;
5544 }
5545
5546 static int
5547 api_tap_connect (vat_main_t * vam)
5548 {
5549   unformat_input_t *i = vam->input;
5550   vl_api_tap_connect_t *mp;
5551   f64 timeout;
5552   u8 mac_address[6];
5553   u8 random_mac = 1;
5554   u8 name_set = 0;
5555   u8 *tap_name;
5556
5557   memset (mac_address, 0, sizeof (mac_address));
5558
5559   /* Parse args required to build the message */
5560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5561     {
5562       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5563         {
5564           random_mac = 0;
5565         }
5566       else if (unformat (i, "random-mac"))
5567         random_mac = 1;
5568       else if (unformat (i, "tapname %s", &tap_name))
5569         name_set = 1;
5570       else
5571         break;
5572     }
5573
5574   if (name_set == 0)
5575     {
5576       errmsg ("missing tap name\n");
5577       return -99;
5578     }
5579   if (vec_len (tap_name) > 63)
5580     {
5581       errmsg ("tap name too long\n");
5582     }
5583   vec_add1 (tap_name, 0);
5584
5585   /* Construct the API message */
5586   M (TAP_CONNECT, tap_connect);
5587
5588   mp->use_random_mac = random_mac;
5589   clib_memcpy (mp->mac_address, mac_address, 6);
5590   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5591   vec_free (tap_name);
5592
5593   /* send it... */
5594   S;
5595
5596   /* Wait for a reply... */
5597   W;
5598 }
5599
5600 static int
5601 api_tap_modify (vat_main_t * vam)
5602 {
5603   unformat_input_t *i = vam->input;
5604   vl_api_tap_modify_t *mp;
5605   f64 timeout;
5606   u8 mac_address[6];
5607   u8 random_mac = 1;
5608   u8 name_set = 0;
5609   u8 *tap_name;
5610   u32 sw_if_index = ~0;
5611   u8 sw_if_index_set = 0;
5612
5613   memset (mac_address, 0, sizeof (mac_address));
5614
5615   /* Parse args required to build the message */
5616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5617     {
5618       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5619         sw_if_index_set = 1;
5620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5621         sw_if_index_set = 1;
5622       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5623         {
5624           random_mac = 0;
5625         }
5626       else if (unformat (i, "random-mac"))
5627         random_mac = 1;
5628       else if (unformat (i, "tapname %s", &tap_name))
5629         name_set = 1;
5630       else
5631         break;
5632     }
5633
5634   if (sw_if_index_set == 0)
5635     {
5636       errmsg ("missing vpp interface name");
5637       return -99;
5638     }
5639   if (name_set == 0)
5640     {
5641       errmsg ("missing tap name\n");
5642       return -99;
5643     }
5644   if (vec_len (tap_name) > 63)
5645     {
5646       errmsg ("tap name too long\n");
5647     }
5648   vec_add1 (tap_name, 0);
5649
5650   /* Construct the API message */
5651   M (TAP_MODIFY, tap_modify);
5652
5653   mp->use_random_mac = random_mac;
5654   mp->sw_if_index = ntohl (sw_if_index);
5655   clib_memcpy (mp->mac_address, mac_address, 6);
5656   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5657   vec_free (tap_name);
5658
5659   /* send it... */
5660   S;
5661
5662   /* Wait for a reply... */
5663   W;
5664 }
5665
5666 static int
5667 api_tap_delete (vat_main_t * vam)
5668 {
5669   unformat_input_t *i = vam->input;
5670   vl_api_tap_delete_t *mp;
5671   f64 timeout;
5672   u32 sw_if_index = ~0;
5673   u8 sw_if_index_set = 0;
5674
5675   /* Parse args required to build the message */
5676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5677     {
5678       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5679         sw_if_index_set = 1;
5680       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5681         sw_if_index_set = 1;
5682       else
5683         break;
5684     }
5685
5686   if (sw_if_index_set == 0)
5687     {
5688       errmsg ("missing vpp interface name");
5689       return -99;
5690     }
5691
5692   /* Construct the API message */
5693   M (TAP_DELETE, tap_delete);
5694
5695   mp->sw_if_index = ntohl (sw_if_index);
5696
5697   /* send it... */
5698   S;
5699
5700   /* Wait for a reply... */
5701   W;
5702 }
5703
5704 static int
5705 api_ip_add_del_route (vat_main_t * vam)
5706 {
5707   unformat_input_t *i = vam->input;
5708   vl_api_ip_add_del_route_t *mp;
5709   f64 timeout;
5710   u32 sw_if_index = ~0, vrf_id = 0;
5711   u8 sw_if_index_set = 0;
5712   u8 is_ipv6 = 0;
5713   u8 is_local = 0, is_drop = 0;
5714   u8 create_vrf_if_needed = 0;
5715   u8 is_add = 1;
5716   u8 next_hop_weight = 1;
5717   u8 not_last = 0;
5718   u8 is_multipath = 0;
5719   u8 address_set = 0;
5720   u8 address_length_set = 0;
5721   u32 next_hop_table_id = 0;
5722   u32 resolve_attempts = 0;
5723   u32 dst_address_length = 0;
5724   u8 next_hop_set = 0;
5725   ip4_address_t v4_dst_address, v4_next_hop_address;
5726   ip6_address_t v6_dst_address, v6_next_hop_address;
5727   int count = 1;
5728   int j;
5729   f64 before = 0;
5730   u32 random_add_del = 0;
5731   u32 *random_vector = 0;
5732   uword *random_hash;
5733   u32 random_seed = 0xdeaddabe;
5734   u32 classify_table_index = ~0;
5735   u8 is_classify = 0;
5736   u8 resolve_host = 0, resolve_attached = 0;
5737   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5738
5739   /* Parse args required to build the message */
5740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5741     {
5742       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5743         sw_if_index_set = 1;
5744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5745         sw_if_index_set = 1;
5746       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5747         {
5748           address_set = 1;
5749           is_ipv6 = 0;
5750         }
5751       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5752         {
5753           address_set = 1;
5754           is_ipv6 = 1;
5755         }
5756       else if (unformat (i, "/%d", &dst_address_length))
5757         {
5758           address_length_set = 1;
5759         }
5760
5761       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5762                                          &v4_next_hop_address))
5763         {
5764           next_hop_set = 1;
5765         }
5766       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5767                                          &v6_next_hop_address))
5768         {
5769           next_hop_set = 1;
5770         }
5771       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5772         ;
5773       else if (unformat (i, "weight %d", &next_hop_weight))
5774         ;
5775       else if (unformat (i, "drop"))
5776         {
5777           is_drop = 1;
5778         }
5779       else if (unformat (i, "local"))
5780         {
5781           is_local = 1;
5782         }
5783       else if (unformat (i, "classify %d", &classify_table_index))
5784         {
5785           is_classify = 1;
5786         }
5787       else if (unformat (i, "del"))
5788         is_add = 0;
5789       else if (unformat (i, "add"))
5790         is_add = 1;
5791       else if (unformat (i, "not-last"))
5792         not_last = 1;
5793       else if (unformat (i, "resolve-via-host"))
5794         resolve_host = 1;
5795       else if (unformat (i, "resolve-via-attached"))
5796         resolve_attached = 1;
5797       else if (unformat (i, "multipath"))
5798         is_multipath = 1;
5799       else if (unformat (i, "vrf %d", &vrf_id))
5800         ;
5801       else if (unformat (i, "create-vrf"))
5802         create_vrf_if_needed = 1;
5803       else if (unformat (i, "count %d", &count))
5804         ;
5805       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5806         ;
5807       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5808         ;
5809       else if (unformat (i, "out-label %d", &next_hop_out_label))
5810         ;
5811       else if (unformat (i, "random"))
5812         random_add_del = 1;
5813       else if (unformat (i, "seed %d", &random_seed))
5814         ;
5815       else
5816         {
5817           clib_warning ("parse error '%U'", format_unformat_error, i);
5818           return -99;
5819         }
5820     }
5821
5822   if (resolve_attempts > 0 && sw_if_index_set == 0)
5823     {
5824       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5825       return -99;
5826     }
5827
5828   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5829     {
5830       errmsg ("next hop / local / drop / classify not set\n");
5831       return -99;
5832     }
5833
5834   if (address_set == 0)
5835     {
5836       errmsg ("missing addresses\n");
5837       return -99;
5838     }
5839
5840   if (address_length_set == 0)
5841     {
5842       errmsg ("missing address length\n");
5843       return -99;
5844     }
5845
5846   /* Generate a pile of unique, random routes */
5847   if (random_add_del)
5848     {
5849       u32 this_random_address;
5850       random_hash = hash_create (count, sizeof (uword));
5851
5852       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5853       for (j = 0; j <= count; j++)
5854         {
5855           do
5856             {
5857               this_random_address = random_u32 (&random_seed);
5858               this_random_address =
5859                 clib_host_to_net_u32 (this_random_address);
5860             }
5861           while (hash_get (random_hash, this_random_address));
5862           vec_add1 (random_vector, this_random_address);
5863           hash_set (random_hash, this_random_address, 1);
5864         }
5865       hash_free (random_hash);
5866       v4_dst_address.as_u32 = random_vector[0];
5867     }
5868
5869   if (count > 1)
5870     {
5871       /* Turn on async mode */
5872       vam->async_mode = 1;
5873       vam->async_errors = 0;
5874       before = vat_time_now (vam);
5875     }
5876
5877   for (j = 0; j < count; j++)
5878     {
5879       /* Construct the API message */
5880       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5881
5882       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5883       mp->table_id = ntohl (vrf_id);
5884       if (resolve_attempts > 0)
5885         {
5886           mp->resolve_attempts = ntohl (resolve_attempts);
5887           mp->resolve_if_needed = 1;
5888         }
5889       mp->create_vrf_if_needed = create_vrf_if_needed;
5890
5891       mp->is_add = is_add;
5892       mp->is_drop = is_drop;
5893       mp->is_ipv6 = is_ipv6;
5894       mp->is_local = is_local;
5895       mp->is_classify = is_classify;
5896       mp->is_multipath = is_multipath;
5897       mp->is_resolve_host = resolve_host;
5898       mp->is_resolve_attached = resolve_attached;
5899       mp->not_last = not_last;
5900       mp->next_hop_weight = next_hop_weight;
5901       mp->dst_address_length = dst_address_length;
5902       mp->next_hop_table_id = ntohl (next_hop_table_id);
5903       mp->classify_table_index = ntohl (classify_table_index);
5904       mp->next_hop_out_label = ntohl (next_hop_out_label);
5905
5906       if (is_ipv6)
5907         {
5908           clib_memcpy (mp->dst_address, &v6_dst_address,
5909                        sizeof (v6_dst_address));
5910           if (next_hop_set)
5911             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5912                          sizeof (v6_next_hop_address));
5913           increment_v6_address (&v6_dst_address);
5914         }
5915       else
5916         {
5917           clib_memcpy (mp->dst_address, &v4_dst_address,
5918                        sizeof (v4_dst_address));
5919           if (next_hop_set)
5920             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5921                          sizeof (v4_next_hop_address));
5922           if (random_add_del)
5923             v4_dst_address.as_u32 = random_vector[j + 1];
5924           else
5925             increment_v4_address (&v4_dst_address);
5926         }
5927       /* send it... */
5928       S;
5929       /* If we receive SIGTERM, stop now... */
5930       if (vam->do_exit)
5931         break;
5932     }
5933
5934   /* When testing multiple add/del ops, use a control-ping to sync */
5935   if (count > 1)
5936     {
5937       vl_api_control_ping_t *mp;
5938       f64 after;
5939
5940       /* Shut off async mode */
5941       vam->async_mode = 0;
5942
5943       M (CONTROL_PING, control_ping);
5944       S;
5945
5946       timeout = vat_time_now (vam) + 1.0;
5947       while (vat_time_now (vam) < timeout)
5948         if (vam->result_ready == 1)
5949           goto out;
5950       vam->retval = -99;
5951
5952     out:
5953       if (vam->retval == -99)
5954         errmsg ("timeout\n");
5955
5956       if (vam->async_errors > 0)
5957         {
5958           errmsg ("%d asynchronous errors\n", vam->async_errors);
5959           vam->retval = -98;
5960         }
5961       vam->async_errors = 0;
5962       after = vat_time_now (vam);
5963
5964       /* slim chance, but we might have eaten SIGTERM on the first iteration */
5965       if (j > 0)
5966         count = j;
5967
5968       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5969                count, after - before, count / (after - before));
5970     }
5971   else
5972     {
5973       /* Wait for a reply... */
5974       W;
5975     }
5976
5977   /* Return the good/bad news */
5978   return (vam->retval);
5979 }
5980
5981 static int
5982 api_mpls_route_add_del (vat_main_t * vam)
5983 {
5984   unformat_input_t *i = vam->input;
5985   vl_api_mpls_route_add_del_t *mp;
5986   f64 timeout;
5987   u32 sw_if_index = ~0, table_id = 0;
5988   u8 create_table_if_needed = 0;
5989   u8 is_add = 1;
5990   u8 next_hop_weight = 1;
5991   u8 is_multipath = 0;
5992   u32 next_hop_table_id = 0;
5993   u8 next_hop_set = 0;
5994   ip4_address_t v4_next_hop_address = {
5995     .as_u32 = 0,
5996   };
5997   ip6_address_t v6_next_hop_address = { {0} };
5998   int count = 1;
5999   int j;
6000   f64 before = 0;
6001   u32 classify_table_index = ~0;
6002   u8 is_classify = 0;
6003   u8 resolve_host = 0, resolve_attached = 0;
6004   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6005   mpls_label_t local_label = MPLS_LABEL_INVALID;
6006   u8 is_eos = 1;
6007   u8 next_hop_proto_is_ip4 = 1;
6008
6009   /* Parse args required to build the message */
6010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6011     {
6012       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6013         ;
6014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6015         ;
6016       else if (unformat (i, "%d", &local_label))
6017         ;
6018       else if (unformat (i, "eos"))
6019         is_eos = 1;
6020       else if (unformat (i, "non-eos"))
6021         is_eos = 0;
6022       else if (unformat (i, "via %U", unformat_ip4_address,
6023                          &v4_next_hop_address))
6024         {
6025           next_hop_set = 1;
6026           next_hop_proto_is_ip4 = 1;
6027         }
6028       else if (unformat (i, "via %U", unformat_ip6_address,
6029                          &v6_next_hop_address))
6030         {
6031           next_hop_set = 1;
6032           next_hop_proto_is_ip4 = 0;
6033         }
6034       else if (unformat (i, "weight %d", &next_hop_weight))
6035         ;
6036       else if (unformat (i, "create-table"))
6037         create_table_if_needed = 1;
6038       else if (unformat (i, "classify %d", &classify_table_index))
6039         {
6040           is_classify = 1;
6041         }
6042       else if (unformat (i, "del"))
6043         is_add = 0;
6044       else if (unformat (i, "add"))
6045         is_add = 1;
6046       else if (unformat (i, "resolve-via-host"))
6047         resolve_host = 1;
6048       else if (unformat (i, "resolve-via-attached"))
6049         resolve_attached = 1;
6050       else if (unformat (i, "multipath"))
6051         is_multipath = 1;
6052       else if (unformat (i, "count %d", &count))
6053         ;
6054       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6055         {
6056           next_hop_set = 1;
6057           next_hop_proto_is_ip4 = 1;
6058         }
6059       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6060         {
6061           next_hop_set = 1;
6062           next_hop_proto_is_ip4 = 0;
6063         }
6064       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6065         ;
6066       else if (unformat (i, "out-label %d", &next_hop_out_label))
6067         ;
6068       else
6069         {
6070           clib_warning ("parse error '%U'", format_unformat_error, i);
6071           return -99;
6072         }
6073     }
6074
6075   if (!next_hop_set && !is_classify)
6076     {
6077       errmsg ("next hop / classify not set\n");
6078       return -99;
6079     }
6080
6081   if (MPLS_LABEL_INVALID == local_label)
6082     {
6083       errmsg ("missing label\n");
6084       return -99;
6085     }
6086
6087   if (count > 1)
6088     {
6089       /* Turn on async mode */
6090       vam->async_mode = 1;
6091       vam->async_errors = 0;
6092       before = vat_time_now (vam);
6093     }
6094
6095   for (j = 0; j < count; j++)
6096     {
6097       /* Construct the API message */
6098       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6099
6100       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6101       mp->mr_table_id = ntohl (table_id);
6102       mp->mr_create_table_if_needed = create_table_if_needed;
6103
6104       mp->mr_is_add = is_add;
6105       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6106       mp->mr_is_classify = is_classify;
6107       mp->mr_is_multipath = is_multipath;
6108       mp->mr_is_resolve_host = resolve_host;
6109       mp->mr_is_resolve_attached = resolve_attached;
6110       mp->mr_next_hop_weight = next_hop_weight;
6111       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6112       mp->mr_classify_table_index = ntohl (classify_table_index);
6113       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6114       mp->mr_label = ntohl (local_label);
6115       mp->mr_eos = is_eos;
6116
6117       if (next_hop_set)
6118         {
6119           if (next_hop_proto_is_ip4)
6120             {
6121               clib_memcpy (mp->mr_next_hop,
6122                            &v4_next_hop_address,
6123                            sizeof (v4_next_hop_address));
6124             }
6125           else
6126             {
6127               clib_memcpy (mp->mr_next_hop,
6128                            &v6_next_hop_address,
6129                            sizeof (v6_next_hop_address));
6130             }
6131         }
6132       local_label++;
6133
6134       /* send it... */
6135       S;
6136       /* If we receive SIGTERM, stop now... */
6137       if (vam->do_exit)
6138         break;
6139     }
6140
6141   /* When testing multiple add/del ops, use a control-ping to sync */
6142   if (count > 1)
6143     {
6144       vl_api_control_ping_t *mp;
6145       f64 after;
6146
6147       /* Shut off async mode */
6148       vam->async_mode = 0;
6149
6150       M (CONTROL_PING, control_ping);
6151       S;
6152
6153       timeout = vat_time_now (vam) + 1.0;
6154       while (vat_time_now (vam) < timeout)
6155         if (vam->result_ready == 1)
6156           goto out;
6157       vam->retval = -99;
6158
6159     out:
6160       if (vam->retval == -99)
6161         errmsg ("timeout\n");
6162
6163       if (vam->async_errors > 0)
6164         {
6165           errmsg ("%d asynchronous errors\n", vam->async_errors);
6166           vam->retval = -98;
6167         }
6168       vam->async_errors = 0;
6169       after = vat_time_now (vam);
6170
6171       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6172       if (j > 0)
6173         count = j;
6174
6175       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6176                count, after - before, count / (after - before));
6177     }
6178   else
6179     {
6180       /* Wait for a reply... */
6181       W;
6182     }
6183
6184   /* Return the good/bad news */
6185   return (vam->retval);
6186 }
6187
6188 static int
6189 api_mpls_ip_bind_unbind (vat_main_t * vam)
6190 {
6191   unformat_input_t *i = vam->input;
6192   vl_api_mpls_ip_bind_unbind_t *mp;
6193   f64 timeout;
6194   u32 ip_table_id = 0;
6195   u8 create_table_if_needed = 0;
6196   u8 is_bind = 1;
6197   u8 is_ip4 = 1;
6198   ip4_address_t v4_address;
6199   ip6_address_t v6_address;
6200   u32 address_length;
6201   u8 address_set = 0;
6202   mpls_label_t local_label = MPLS_LABEL_INVALID;
6203
6204   /* Parse args required to build the message */
6205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6206     {
6207       if (unformat (i, "%U/%d", unformat_ip4_address,
6208                     &v4_address, &address_length))
6209         {
6210           is_ip4 = 1;
6211           address_set = 1;
6212         }
6213       else if (unformat (i, "%U/%d", unformat_ip6_address,
6214                          &v6_address, &address_length))
6215         {
6216           is_ip4 = 0;
6217           address_set = 1;
6218         }
6219       else if (unformat (i, "%d", &local_label))
6220         ;
6221       else if (unformat (i, "create-table"))
6222         create_table_if_needed = 1;
6223       else if (unformat (i, "table-id %d", &ip_table_id))
6224         ;
6225       else if (unformat (i, "unbind"))
6226         is_bind = 0;
6227       else if (unformat (i, "bind"))
6228         is_bind = 1;
6229       else
6230         {
6231           clib_warning ("parse error '%U'", format_unformat_error, i);
6232           return -99;
6233         }
6234     }
6235
6236   if (!address_set)
6237     {
6238       errmsg ("IP addres not set\n");
6239       return -99;
6240     }
6241
6242   if (MPLS_LABEL_INVALID == local_label)
6243     {
6244       errmsg ("missing label\n");
6245       return -99;
6246     }
6247
6248   /* Construct the API message */
6249   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6250
6251   mp->mb_create_table_if_needed = create_table_if_needed;
6252   mp->mb_is_bind = is_bind;
6253   mp->mb_is_ip4 = is_ip4;
6254   mp->mb_ip_table_id = ntohl (ip_table_id);
6255   mp->mb_mpls_table_id = 0;
6256   mp->mb_label = ntohl (local_label);
6257   mp->mb_address_length = address_length;
6258
6259   if (is_ip4)
6260     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6261   else
6262     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6263
6264   /* send it... */
6265   S;
6266
6267   /* Wait for a reply... */
6268   W;
6269
6270   /* Return the good/bad news */
6271   return (vam->retval);
6272 }
6273
6274 static int
6275 api_proxy_arp_add_del (vat_main_t * vam)
6276 {
6277   unformat_input_t *i = vam->input;
6278   vl_api_proxy_arp_add_del_t *mp;
6279   f64 timeout;
6280   u32 vrf_id = 0;
6281   u8 is_add = 1;
6282   ip4_address_t lo, hi;
6283   u8 range_set = 0;
6284
6285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6286     {
6287       if (unformat (i, "vrf %d", &vrf_id))
6288         ;
6289       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6290                          unformat_ip4_address, &hi))
6291         range_set = 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 (range_set == 0)
6302     {
6303       errmsg ("address range not set\n");
6304       return -99;
6305     }
6306
6307   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6308
6309   mp->vrf_id = ntohl (vrf_id);
6310   mp->is_add = is_add;
6311   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6312   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6313
6314   S;
6315   W;
6316   /* NOTREACHED */
6317   return 0;
6318 }
6319
6320 static int
6321 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6322 {
6323   unformat_input_t *i = vam->input;
6324   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6325   f64 timeout;
6326   u32 sw_if_index;
6327   u8 enable = 1;
6328   u8 sw_if_index_set = 0;
6329
6330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6331     {
6332       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6333         sw_if_index_set = 1;
6334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6335         sw_if_index_set = 1;
6336       else if (unformat (i, "enable"))
6337         enable = 1;
6338       else if (unformat (i, "disable"))
6339         enable = 0;
6340       else
6341         {
6342           clib_warning ("parse error '%U'", format_unformat_error, i);
6343           return -99;
6344         }
6345     }
6346
6347   if (sw_if_index_set == 0)
6348     {
6349       errmsg ("missing interface name or sw_if_index\n");
6350       return -99;
6351     }
6352
6353   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6354
6355   mp->sw_if_index = ntohl (sw_if_index);
6356   mp->enable_disable = enable;
6357
6358   S;
6359   W;
6360   /* NOTREACHED */
6361   return 0;
6362 }
6363
6364 static int
6365 api_mpls_add_del_encap (vat_main_t * vam)
6366 {
6367   unformat_input_t *i = vam->input;
6368   vl_api_mpls_add_del_encap_t *mp;
6369   f64 timeout;
6370   u32 vrf_id = 0;
6371   u32 *labels = 0;
6372   u32 label;
6373   ip4_address_t dst_address;
6374   u8 is_add = 1;
6375
6376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6377     {
6378       if (unformat (i, "vrf %d", &vrf_id))
6379         ;
6380       else if (unformat (i, "label %d", &label))
6381         vec_add1 (labels, ntohl (label));
6382       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6383         ;
6384       else if (unformat (i, "del"))
6385         is_add = 0;
6386       else
6387         {
6388           clib_warning ("parse error '%U'", format_unformat_error, i);
6389           return -99;
6390         }
6391     }
6392
6393   if (vec_len (labels) == 0)
6394     {
6395       errmsg ("missing encap label stack\n");
6396       return -99;
6397     }
6398
6399   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6400       sizeof (u32) * vec_len (labels));
6401
6402   mp->vrf_id = ntohl (vrf_id);
6403   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6404   mp->is_add = is_add;
6405   mp->nlabels = vec_len (labels);
6406   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6407
6408   vec_free (labels);
6409
6410   S;
6411   W;
6412   /* NOTREACHED */
6413   return 0;
6414 }
6415
6416 static int
6417 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6418 {
6419   unformat_input_t *i = vam->input;
6420   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6421   f64 timeout;
6422   u32 inner_vrf_id = 0;
6423   ip4_address_t intfc_address;
6424   u8 dst_mac_address[6];
6425   int dst_set = 1;
6426   u32 tmp;
6427   u8 intfc_address_length = 0;
6428   u8 is_add = 1;
6429   u8 l2_only = 0;
6430   u32 tx_sw_if_index;
6431   int tx_sw_if_index_set = 0;
6432
6433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6434     {
6435       if (unformat (i, "vrf %d", &inner_vrf_id))
6436         ;
6437       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6438                          &intfc_address, &tmp))
6439         intfc_address_length = tmp;
6440       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6441         tx_sw_if_index_set = 1;
6442       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6443         tx_sw_if_index_set = 1;
6444       else if (unformat (i, "dst %U", unformat_ethernet_address,
6445                          dst_mac_address))
6446         dst_set = 1;
6447       else if (unformat (i, "l2-only"))
6448         l2_only = 1;
6449       else if (unformat (i, "del"))
6450         is_add = 0;
6451       else
6452         {
6453           clib_warning ("parse error '%U'", format_unformat_error, i);
6454           return -99;
6455         }
6456     }
6457
6458   if (!dst_set)
6459     {
6460       errmsg ("dst (mac address) not set\n");
6461       return -99;
6462     }
6463   if (!tx_sw_if_index_set)
6464     {
6465       errmsg ("tx-intfc not set\n");
6466       return -99;
6467     }
6468
6469   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6470
6471   mp->vrf_id = ntohl (inner_vrf_id);
6472   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6473   mp->adj_address_length = intfc_address_length;
6474   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6475                sizeof (dst_mac_address));
6476   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6477   mp->l2_only = l2_only;
6478   mp->is_add = is_add;
6479
6480   S;
6481   W;
6482   /* NOTREACHED */
6483   return 0;
6484 }
6485
6486 static int
6487 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6488 {
6489   unformat_input_t *i = vam->input;
6490   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6491   f64 timeout;
6492   u32 inner_vrf_id = 0;
6493   u32 outer_vrf_id = 0;
6494   ip4_address_t adj_address;
6495   int adj_address_set = 0;
6496   ip4_address_t next_hop_address;
6497   int next_hop_address_set = 0;
6498   u32 tmp;
6499   u8 adj_address_length = 0;
6500   u8 l2_only = 0;
6501   u8 is_add = 1;
6502   u32 resolve_attempts = 5;
6503   u8 resolve_if_needed = 1;
6504
6505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6506     {
6507       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6508         ;
6509       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6510         ;
6511       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6512                          &adj_address, &tmp))
6513         {
6514           adj_address_length = tmp;
6515           adj_address_set = 1;
6516         }
6517       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6518                          &next_hop_address))
6519         next_hop_address_set = 1;
6520       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6521         ;
6522       else if (unformat (i, "resolve-if-needed %d", &tmp))
6523         resolve_if_needed = tmp;
6524       else if (unformat (i, "l2-only"))
6525         l2_only = 1;
6526       else if (unformat (i, "del"))
6527         is_add = 0;
6528       else
6529         {
6530           clib_warning ("parse error '%U'", format_unformat_error, i);
6531           return -99;
6532         }
6533     }
6534
6535   if (!adj_address_set)
6536     {
6537       errmsg ("adjacency address/mask not set\n");
6538       return -99;
6539     }
6540   if (!next_hop_address_set)
6541     {
6542       errmsg ("ip4 next hop address (in outer fib) not set\n");
6543       return -99;
6544     }
6545
6546   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6547
6548   mp->inner_vrf_id = ntohl (inner_vrf_id);
6549   mp->outer_vrf_id = ntohl (outer_vrf_id);
6550   mp->resolve_attempts = ntohl (resolve_attempts);
6551   mp->resolve_if_needed = resolve_if_needed;
6552   mp->is_add = is_add;
6553   mp->l2_only = l2_only;
6554   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6555   mp->adj_address_length = adj_address_length;
6556   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6557                sizeof (next_hop_address));
6558
6559   S;
6560   W;
6561   /* NOTREACHED */
6562   return 0;
6563 }
6564
6565 static int
6566 api_sw_interface_set_unnumbered (vat_main_t * vam)
6567 {
6568   unformat_input_t *i = vam->input;
6569   vl_api_sw_interface_set_unnumbered_t *mp;
6570   f64 timeout;
6571   u32 sw_if_index;
6572   u32 unnum_sw_index = ~0;
6573   u8 is_add = 1;
6574   u8 sw_if_index_set = 0;
6575
6576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6577     {
6578       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6579         sw_if_index_set = 1;
6580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6581         sw_if_index_set = 1;
6582       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6583         ;
6584       else if (unformat (i, "del"))
6585         is_add = 0;
6586       else
6587         {
6588           clib_warning ("parse error '%U'", format_unformat_error, i);
6589           return -99;
6590         }
6591     }
6592
6593   if (sw_if_index_set == 0)
6594     {
6595       errmsg ("missing interface name or sw_if_index\n");
6596       return -99;
6597     }
6598
6599   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6600
6601   mp->sw_if_index = ntohl (sw_if_index);
6602   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6603   mp->is_add = is_add;
6604
6605   S;
6606   W;
6607   /* NOTREACHED */
6608   return 0;
6609 }
6610
6611 static int
6612 api_ip_neighbor_add_del (vat_main_t * vam)
6613 {
6614   unformat_input_t *i = vam->input;
6615   vl_api_ip_neighbor_add_del_t *mp;
6616   f64 timeout;
6617   u32 sw_if_index;
6618   u8 sw_if_index_set = 0;
6619   u32 vrf_id = 0;
6620   u8 is_add = 1;
6621   u8 is_static = 0;
6622   u8 mac_address[6];
6623   u8 mac_set = 0;
6624   u8 v4_address_set = 0;
6625   u8 v6_address_set = 0;
6626   ip4_address_t v4address;
6627   ip6_address_t v6address;
6628
6629   memset (mac_address, 0, sizeof (mac_address));
6630
6631   /* Parse args required to build the message */
6632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6633     {
6634       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6635         {
6636           mac_set = 1;
6637         }
6638       else if (unformat (i, "del"))
6639         is_add = 0;
6640       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6641         sw_if_index_set = 1;
6642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6643         sw_if_index_set = 1;
6644       else if (unformat (i, "is_static"))
6645         is_static = 1;
6646       else if (unformat (i, "vrf %d", &vrf_id))
6647         ;
6648       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6649         v4_address_set = 1;
6650       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6651         v6_address_set = 1;
6652       else
6653         {
6654           clib_warning ("parse error '%U'", format_unformat_error, i);
6655           return -99;
6656         }
6657     }
6658
6659   if (sw_if_index_set == 0)
6660     {
6661       errmsg ("missing interface name or sw_if_index\n");
6662       return -99;
6663     }
6664   if (v4_address_set && v6_address_set)
6665     {
6666       errmsg ("both v4 and v6 addresses set\n");
6667       return -99;
6668     }
6669   if (!v4_address_set && !v6_address_set)
6670     {
6671       errmsg ("no address set\n");
6672       return -99;
6673     }
6674
6675   /* Construct the API message */
6676   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6677
6678   mp->sw_if_index = ntohl (sw_if_index);
6679   mp->is_add = is_add;
6680   mp->vrf_id = ntohl (vrf_id);
6681   mp->is_static = is_static;
6682   if (mac_set)
6683     clib_memcpy (mp->mac_address, mac_address, 6);
6684   if (v6_address_set)
6685     {
6686       mp->is_ipv6 = 1;
6687       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6688     }
6689   else
6690     {
6691       /* mp->is_ipv6 = 0; via memset in M macro above */
6692       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6693     }
6694
6695   /* send it... */
6696   S;
6697
6698   /* Wait for a reply, return good/bad news  */
6699   W;
6700
6701   /* NOTREACHED */
6702   return 0;
6703 }
6704
6705 static int
6706 api_reset_vrf (vat_main_t * vam)
6707 {
6708   unformat_input_t *i = vam->input;
6709   vl_api_reset_vrf_t *mp;
6710   f64 timeout;
6711   u32 vrf_id = 0;
6712   u8 is_ipv6 = 0;
6713   u8 vrf_id_set = 0;
6714
6715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6716     {
6717       if (unformat (i, "vrf %d", &vrf_id))
6718         vrf_id_set = 1;
6719       else if (unformat (i, "ipv6"))
6720         is_ipv6 = 1;
6721       else
6722         {
6723           clib_warning ("parse error '%U'", format_unformat_error, i);
6724           return -99;
6725         }
6726     }
6727
6728   if (vrf_id_set == 0)
6729     {
6730       errmsg ("missing vrf id\n");
6731       return -99;
6732     }
6733
6734   M (RESET_VRF, reset_vrf);
6735
6736   mp->vrf_id = ntohl (vrf_id);
6737   mp->is_ipv6 = is_ipv6;
6738
6739   S;
6740   W;
6741   /* NOTREACHED */
6742   return 0;
6743 }
6744
6745 static int
6746 api_create_vlan_subif (vat_main_t * vam)
6747 {
6748   unformat_input_t *i = vam->input;
6749   vl_api_create_vlan_subif_t *mp;
6750   f64 timeout;
6751   u32 sw_if_index;
6752   u8 sw_if_index_set = 0;
6753   u32 vlan_id;
6754   u8 vlan_id_set = 0;
6755
6756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6757     {
6758       if (unformat (i, "sw_if_index %d", &sw_if_index))
6759         sw_if_index_set = 1;
6760       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6761         sw_if_index_set = 1;
6762       else if (unformat (i, "vlan %d", &vlan_id))
6763         vlan_id_set = 1;
6764       else
6765         {
6766           clib_warning ("parse error '%U'", format_unformat_error, i);
6767           return -99;
6768         }
6769     }
6770
6771   if (sw_if_index_set == 0)
6772     {
6773       errmsg ("missing interface name or sw_if_index\n");
6774       return -99;
6775     }
6776
6777   if (vlan_id_set == 0)
6778     {
6779       errmsg ("missing vlan_id\n");
6780       return -99;
6781     }
6782   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6783
6784   mp->sw_if_index = ntohl (sw_if_index);
6785   mp->vlan_id = ntohl (vlan_id);
6786
6787   S;
6788   W;
6789   /* NOTREACHED */
6790   return 0;
6791 }
6792
6793 #define foreach_create_subif_bit                \
6794 _(no_tags)                                      \
6795 _(one_tag)                                      \
6796 _(two_tags)                                     \
6797 _(dot1ad)                                       \
6798 _(exact_match)                                  \
6799 _(default_sub)                                  \
6800 _(outer_vlan_id_any)                            \
6801 _(inner_vlan_id_any)
6802
6803 static int
6804 api_create_subif (vat_main_t * vam)
6805 {
6806   unformat_input_t *i = vam->input;
6807   vl_api_create_subif_t *mp;
6808   f64 timeout;
6809   u32 sw_if_index;
6810   u8 sw_if_index_set = 0;
6811   u32 sub_id;
6812   u8 sub_id_set = 0;
6813   u32 no_tags = 0;
6814   u32 one_tag = 0;
6815   u32 two_tags = 0;
6816   u32 dot1ad = 0;
6817   u32 exact_match = 0;
6818   u32 default_sub = 0;
6819   u32 outer_vlan_id_any = 0;
6820   u32 inner_vlan_id_any = 0;
6821   u32 tmp;
6822   u16 outer_vlan_id = 0;
6823   u16 inner_vlan_id = 0;
6824
6825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6826     {
6827       if (unformat (i, "sw_if_index %d", &sw_if_index))
6828         sw_if_index_set = 1;
6829       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "sub_id %d", &sub_id))
6832         sub_id_set = 1;
6833       else if (unformat (i, "outer_vlan_id %d", &tmp))
6834         outer_vlan_id = tmp;
6835       else if (unformat (i, "inner_vlan_id %d", &tmp))
6836         inner_vlan_id = tmp;
6837
6838 #define _(a) else if (unformat (i, #a)) a = 1 ;
6839       foreach_create_subif_bit
6840 #undef _
6841         else
6842         {
6843           clib_warning ("parse error '%U'", format_unformat_error, i);
6844           return -99;
6845         }
6846     }
6847
6848   if (sw_if_index_set == 0)
6849     {
6850       errmsg ("missing interface name or sw_if_index\n");
6851       return -99;
6852     }
6853
6854   if (sub_id_set == 0)
6855     {
6856       errmsg ("missing sub_id\n");
6857       return -99;
6858     }
6859   M (CREATE_SUBIF, create_subif);
6860
6861   mp->sw_if_index = ntohl (sw_if_index);
6862   mp->sub_id = ntohl (sub_id);
6863
6864 #define _(a) mp->a = a;
6865   foreach_create_subif_bit;
6866 #undef _
6867
6868   mp->outer_vlan_id = ntohs (outer_vlan_id);
6869   mp->inner_vlan_id = ntohs (inner_vlan_id);
6870
6871   S;
6872   W;
6873   /* NOTREACHED */
6874   return 0;
6875 }
6876
6877 static int
6878 api_oam_add_del (vat_main_t * vam)
6879 {
6880   unformat_input_t *i = vam->input;
6881   vl_api_oam_add_del_t *mp;
6882   f64 timeout;
6883   u32 vrf_id = 0;
6884   u8 is_add = 1;
6885   ip4_address_t src, dst;
6886   u8 src_set = 0;
6887   u8 dst_set = 0;
6888
6889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6890     {
6891       if (unformat (i, "vrf %d", &vrf_id))
6892         ;
6893       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6894         src_set = 1;
6895       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6896         dst_set = 1;
6897       else if (unformat (i, "del"))
6898         is_add = 0;
6899       else
6900         {
6901           clib_warning ("parse error '%U'", format_unformat_error, i);
6902           return -99;
6903         }
6904     }
6905
6906   if (src_set == 0)
6907     {
6908       errmsg ("missing src addr\n");
6909       return -99;
6910     }
6911
6912   if (dst_set == 0)
6913     {
6914       errmsg ("missing dst addr\n");
6915       return -99;
6916     }
6917
6918   M (OAM_ADD_DEL, oam_add_del);
6919
6920   mp->vrf_id = ntohl (vrf_id);
6921   mp->is_add = is_add;
6922   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6923   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6924
6925   S;
6926   W;
6927   /* NOTREACHED */
6928   return 0;
6929 }
6930
6931 static int
6932 api_reset_fib (vat_main_t * vam)
6933 {
6934   unformat_input_t *i = vam->input;
6935   vl_api_reset_fib_t *mp;
6936   f64 timeout;
6937   u32 vrf_id = 0;
6938   u8 is_ipv6 = 0;
6939   u8 vrf_id_set = 0;
6940
6941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6942     {
6943       if (unformat (i, "vrf %d", &vrf_id))
6944         vrf_id_set = 1;
6945       else if (unformat (i, "ipv6"))
6946         is_ipv6 = 1;
6947       else
6948         {
6949           clib_warning ("parse error '%U'", format_unformat_error, i);
6950           return -99;
6951         }
6952     }
6953
6954   if (vrf_id_set == 0)
6955     {
6956       errmsg ("missing vrf id\n");
6957       return -99;
6958     }
6959
6960   M (RESET_FIB, reset_fib);
6961
6962   mp->vrf_id = ntohl (vrf_id);
6963   mp->is_ipv6 = is_ipv6;
6964
6965   S;
6966   W;
6967   /* NOTREACHED */
6968   return 0;
6969 }
6970
6971 static int
6972 api_dhcp_proxy_config (vat_main_t * vam)
6973 {
6974   unformat_input_t *i = vam->input;
6975   vl_api_dhcp_proxy_config_t *mp;
6976   f64 timeout;
6977   u32 vrf_id = 0;
6978   u8 is_add = 1;
6979   u8 insert_cid = 1;
6980   u8 v4_address_set = 0;
6981   u8 v6_address_set = 0;
6982   ip4_address_t v4address;
6983   ip6_address_t v6address;
6984   u8 v4_src_address_set = 0;
6985   u8 v6_src_address_set = 0;
6986   ip4_address_t v4srcaddress;
6987   ip6_address_t v6srcaddress;
6988
6989   /* Parse args required to build the message */
6990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6991     {
6992       if (unformat (i, "del"))
6993         is_add = 0;
6994       else if (unformat (i, "vrf %d", &vrf_id))
6995         ;
6996       else if (unformat (i, "insert-cid %d", &insert_cid))
6997         ;
6998       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6999         v4_address_set = 1;
7000       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7001         v6_address_set = 1;
7002       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7003         v4_src_address_set = 1;
7004       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7005         v6_src_address_set = 1;
7006       else
7007         break;
7008     }
7009
7010   if (v4_address_set && v6_address_set)
7011     {
7012       errmsg ("both v4 and v6 server addresses set\n");
7013       return -99;
7014     }
7015   if (!v4_address_set && !v6_address_set)
7016     {
7017       errmsg ("no server addresses set\n");
7018       return -99;
7019     }
7020
7021   if (v4_src_address_set && v6_src_address_set)
7022     {
7023       errmsg ("both v4 and v6  src addresses set\n");
7024       return -99;
7025     }
7026   if (!v4_src_address_set && !v6_src_address_set)
7027     {
7028       errmsg ("no src addresses set\n");
7029       return -99;
7030     }
7031
7032   if (!(v4_src_address_set && v4_address_set) &&
7033       !(v6_src_address_set && v6_address_set))
7034     {
7035       errmsg ("no matching server and src addresses set\n");
7036       return -99;
7037     }
7038
7039   /* Construct the API message */
7040   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7041
7042   mp->insert_circuit_id = insert_cid;
7043   mp->is_add = is_add;
7044   mp->vrf_id = ntohl (vrf_id);
7045   if (v6_address_set)
7046     {
7047       mp->is_ipv6 = 1;
7048       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7049       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7050     }
7051   else
7052     {
7053       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7054       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7055     }
7056
7057   /* send it... */
7058   S;
7059
7060   /* Wait for a reply, return good/bad news  */
7061   W;
7062   /* NOTREACHED */
7063   return 0;
7064 }
7065
7066 static int
7067 api_dhcp_proxy_config_2 (vat_main_t * vam)
7068 {
7069   unformat_input_t *i = vam->input;
7070   vl_api_dhcp_proxy_config_2_t *mp;
7071   f64 timeout;
7072   u32 rx_vrf_id = 0;
7073   u32 server_vrf_id = 0;
7074   u8 is_add = 1;
7075   u8 insert_cid = 1;
7076   u8 v4_address_set = 0;
7077   u8 v6_address_set = 0;
7078   ip4_address_t v4address;
7079   ip6_address_t v6address;
7080   u8 v4_src_address_set = 0;
7081   u8 v6_src_address_set = 0;
7082   ip4_address_t v4srcaddress;
7083   ip6_address_t v6srcaddress;
7084
7085   /* Parse args required to build the message */
7086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7087     {
7088       if (unformat (i, "del"))
7089         is_add = 0;
7090       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7091         ;
7092       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7093         ;
7094       else if (unformat (i, "insert-cid %d", &insert_cid))
7095         ;
7096       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7097         v4_address_set = 1;
7098       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7099         v6_address_set = 1;
7100       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7101         v4_src_address_set = 1;
7102       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7103         v6_src_address_set = 1;
7104       else
7105         break;
7106     }
7107
7108   if (v4_address_set && v6_address_set)
7109     {
7110       errmsg ("both v4 and v6 server addresses set\n");
7111       return -99;
7112     }
7113   if (!v4_address_set && !v6_address_set)
7114     {
7115       errmsg ("no server addresses set\n");
7116       return -99;
7117     }
7118
7119   if (v4_src_address_set && v6_src_address_set)
7120     {
7121       errmsg ("both v4 and v6  src addresses set\n");
7122       return -99;
7123     }
7124   if (!v4_src_address_set && !v6_src_address_set)
7125     {
7126       errmsg ("no src addresses set\n");
7127       return -99;
7128     }
7129
7130   if (!(v4_src_address_set && v4_address_set) &&
7131       !(v6_src_address_set && v6_address_set))
7132     {
7133       errmsg ("no matching server and src addresses set\n");
7134       return -99;
7135     }
7136
7137   /* Construct the API message */
7138   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7139
7140   mp->insert_circuit_id = insert_cid;
7141   mp->is_add = is_add;
7142   mp->rx_vrf_id = ntohl (rx_vrf_id);
7143   mp->server_vrf_id = ntohl (server_vrf_id);
7144   if (v6_address_set)
7145     {
7146       mp->is_ipv6 = 1;
7147       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7148       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7149     }
7150   else
7151     {
7152       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7153       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7154     }
7155
7156   /* send it... */
7157   S;
7158
7159   /* Wait for a reply, return good/bad news  */
7160   W;
7161   /* NOTREACHED */
7162   return 0;
7163 }
7164
7165 static int
7166 api_dhcp_proxy_set_vss (vat_main_t * vam)
7167 {
7168   unformat_input_t *i = vam->input;
7169   vl_api_dhcp_proxy_set_vss_t *mp;
7170   f64 timeout;
7171   u8 is_ipv6 = 0;
7172   u8 is_add = 1;
7173   u32 tbl_id;
7174   u8 tbl_id_set = 0;
7175   u32 oui;
7176   u8 oui_set = 0;
7177   u32 fib_id;
7178   u8 fib_id_set = 0;
7179
7180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7181     {
7182       if (unformat (i, "tbl_id %d", &tbl_id))
7183         tbl_id_set = 1;
7184       if (unformat (i, "fib_id %d", &fib_id))
7185         fib_id_set = 1;
7186       if (unformat (i, "oui %d", &oui))
7187         oui_set = 1;
7188       else if (unformat (i, "ipv6"))
7189         is_ipv6 = 1;
7190       else if (unformat (i, "del"))
7191         is_add = 0;
7192       else
7193         {
7194           clib_warning ("parse error '%U'", format_unformat_error, i);
7195           return -99;
7196         }
7197     }
7198
7199   if (tbl_id_set == 0)
7200     {
7201       errmsg ("missing tbl id\n");
7202       return -99;
7203     }
7204
7205   if (fib_id_set == 0)
7206     {
7207       errmsg ("missing fib id\n");
7208       return -99;
7209     }
7210   if (oui_set == 0)
7211     {
7212       errmsg ("missing oui\n");
7213       return -99;
7214     }
7215
7216   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7217   mp->tbl_id = ntohl (tbl_id);
7218   mp->fib_id = ntohl (fib_id);
7219   mp->oui = ntohl (oui);
7220   mp->is_ipv6 = is_ipv6;
7221   mp->is_add = is_add;
7222
7223   S;
7224   W;
7225   /* NOTREACHED */
7226   return 0;
7227 }
7228
7229 static int
7230 api_dhcp_client_config (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_dhcp_client_config_t *mp;
7234   f64 timeout;
7235   u32 sw_if_index;
7236   u8 sw_if_index_set = 0;
7237   u8 is_add = 1;
7238   u8 *hostname = 0;
7239   u8 disable_event = 0;
7240
7241   /* Parse args required to build the message */
7242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7243     {
7244       if (unformat (i, "del"))
7245         is_add = 0;
7246       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7247         sw_if_index_set = 1;
7248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7249         sw_if_index_set = 1;
7250       else if (unformat (i, "hostname %s", &hostname))
7251         ;
7252       else if (unformat (i, "disable_event"))
7253         disable_event = 1;
7254       else
7255         break;
7256     }
7257
7258   if (sw_if_index_set == 0)
7259     {
7260       errmsg ("missing interface name or sw_if_index\n");
7261       return -99;
7262     }
7263
7264   if (vec_len (hostname) > 63)
7265     {
7266       errmsg ("hostname too long\n");
7267     }
7268   vec_add1 (hostname, 0);
7269
7270   /* Construct the API message */
7271   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7272
7273   mp->sw_if_index = ntohl (sw_if_index);
7274   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7275   vec_free (hostname);
7276   mp->is_add = is_add;
7277   mp->want_dhcp_event = disable_event ? 0 : 1;
7278   mp->pid = getpid ();
7279
7280   /* send it... */
7281   S;
7282
7283   /* Wait for a reply, return good/bad news  */
7284   W;
7285   /* NOTREACHED */
7286   return 0;
7287 }
7288
7289 static int
7290 api_set_ip_flow_hash (vat_main_t * vam)
7291 {
7292   unformat_input_t *i = vam->input;
7293   vl_api_set_ip_flow_hash_t *mp;
7294   f64 timeout;
7295   u32 vrf_id = 0;
7296   u8 is_ipv6 = 0;
7297   u8 vrf_id_set = 0;
7298   u8 src = 0;
7299   u8 dst = 0;
7300   u8 sport = 0;
7301   u8 dport = 0;
7302   u8 proto = 0;
7303   u8 reverse = 0;
7304
7305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7306     {
7307       if (unformat (i, "vrf %d", &vrf_id))
7308         vrf_id_set = 1;
7309       else if (unformat (i, "ipv6"))
7310         is_ipv6 = 1;
7311       else if (unformat (i, "src"))
7312         src = 1;
7313       else if (unformat (i, "dst"))
7314         dst = 1;
7315       else if (unformat (i, "sport"))
7316         sport = 1;
7317       else if (unformat (i, "dport"))
7318         dport = 1;
7319       else if (unformat (i, "proto"))
7320         proto = 1;
7321       else if (unformat (i, "reverse"))
7322         reverse = 1;
7323
7324       else
7325         {
7326           clib_warning ("parse error '%U'", format_unformat_error, i);
7327           return -99;
7328         }
7329     }
7330
7331   if (vrf_id_set == 0)
7332     {
7333       errmsg ("missing vrf id\n");
7334       return -99;
7335     }
7336
7337   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7338   mp->src = src;
7339   mp->dst = dst;
7340   mp->sport = sport;
7341   mp->dport = dport;
7342   mp->proto = proto;
7343   mp->reverse = reverse;
7344   mp->vrf_id = ntohl (vrf_id);
7345   mp->is_ipv6 = is_ipv6;
7346
7347   S;
7348   W;
7349   /* NOTREACHED */
7350   return 0;
7351 }
7352
7353 static int
7354 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7355 {
7356   unformat_input_t *i = vam->input;
7357   vl_api_sw_interface_ip6_enable_disable_t *mp;
7358   f64 timeout;
7359   u32 sw_if_index;
7360   u8 sw_if_index_set = 0;
7361   u8 enable = 0;
7362
7363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7364     {
7365       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7366         sw_if_index_set = 1;
7367       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7368         sw_if_index_set = 1;
7369       else if (unformat (i, "enable"))
7370         enable = 1;
7371       else if (unformat (i, "disable"))
7372         enable = 0;
7373       else
7374         {
7375           clib_warning ("parse error '%U'", format_unformat_error, i);
7376           return -99;
7377         }
7378     }
7379
7380   if (sw_if_index_set == 0)
7381     {
7382       errmsg ("missing interface name or sw_if_index\n");
7383       return -99;
7384     }
7385
7386   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7387
7388   mp->sw_if_index = ntohl (sw_if_index);
7389   mp->enable = enable;
7390
7391   S;
7392   W;
7393   /* NOTREACHED */
7394   return 0;
7395 }
7396
7397 static int
7398 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7399 {
7400   unformat_input_t *i = vam->input;
7401   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7402   f64 timeout;
7403   u32 sw_if_index;
7404   u8 sw_if_index_set = 0;
7405   u32 address_length = 0;
7406   u8 v6_address_set = 0;
7407   ip6_address_t v6address;
7408
7409   /* Parse args required to build the message */
7410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7411     {
7412       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7413         sw_if_index_set = 1;
7414       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7415         sw_if_index_set = 1;
7416       else if (unformat (i, "%U/%d",
7417                          unformat_ip6_address, &v6address, &address_length))
7418         v6_address_set = 1;
7419       else
7420         break;
7421     }
7422
7423   if (sw_if_index_set == 0)
7424     {
7425       errmsg ("missing interface name or sw_if_index\n");
7426       return -99;
7427     }
7428   if (!v6_address_set)
7429     {
7430       errmsg ("no address set\n");
7431       return -99;
7432     }
7433
7434   /* Construct the API message */
7435   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7436      sw_interface_ip6_set_link_local_address);
7437
7438   mp->sw_if_index = ntohl (sw_if_index);
7439   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7440   mp->address_length = address_length;
7441
7442   /* send it... */
7443   S;
7444
7445   /* Wait for a reply, return good/bad news  */
7446   W;
7447
7448   /* NOTREACHED */
7449   return 0;
7450 }
7451
7452
7453 static int
7454 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7455 {
7456   unformat_input_t *i = vam->input;
7457   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7458   f64 timeout;
7459   u32 sw_if_index;
7460   u8 sw_if_index_set = 0;
7461   u32 address_length = 0;
7462   u8 v6_address_set = 0;
7463   ip6_address_t v6address;
7464   u8 use_default = 0;
7465   u8 no_advertise = 0;
7466   u8 off_link = 0;
7467   u8 no_autoconfig = 0;
7468   u8 no_onlink = 0;
7469   u8 is_no = 0;
7470   u32 val_lifetime = 0;
7471   u32 pref_lifetime = 0;
7472
7473   /* Parse args required to build the message */
7474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7475     {
7476       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7477         sw_if_index_set = 1;
7478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7479         sw_if_index_set = 1;
7480       else if (unformat (i, "%U/%d",
7481                          unformat_ip6_address, &v6address, &address_length))
7482         v6_address_set = 1;
7483       else if (unformat (i, "val_life %d", &val_lifetime))
7484         ;
7485       else if (unformat (i, "pref_life %d", &pref_lifetime))
7486         ;
7487       else if (unformat (i, "def"))
7488         use_default = 1;
7489       else if (unformat (i, "noadv"))
7490         no_advertise = 1;
7491       else if (unformat (i, "offl"))
7492         off_link = 1;
7493       else if (unformat (i, "noauto"))
7494         no_autoconfig = 1;
7495       else if (unformat (i, "nolink"))
7496         no_onlink = 1;
7497       else if (unformat (i, "isno"))
7498         is_no = 1;
7499       else
7500         {
7501           clib_warning ("parse error '%U'", format_unformat_error, i);
7502           return -99;
7503         }
7504     }
7505
7506   if (sw_if_index_set == 0)
7507     {
7508       errmsg ("missing interface name or sw_if_index\n");
7509       return -99;
7510     }
7511   if (!v6_address_set)
7512     {
7513       errmsg ("no address set\n");
7514       return -99;
7515     }
7516
7517   /* Construct the API message */
7518   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7519
7520   mp->sw_if_index = ntohl (sw_if_index);
7521   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7522   mp->address_length = address_length;
7523   mp->use_default = use_default;
7524   mp->no_advertise = no_advertise;
7525   mp->off_link = off_link;
7526   mp->no_autoconfig = no_autoconfig;
7527   mp->no_onlink = no_onlink;
7528   mp->is_no = is_no;
7529   mp->val_lifetime = ntohl (val_lifetime);
7530   mp->pref_lifetime = ntohl (pref_lifetime);
7531
7532   /* send it... */
7533   S;
7534
7535   /* Wait for a reply, return good/bad news  */
7536   W;
7537
7538   /* NOTREACHED */
7539   return 0;
7540 }
7541
7542 static int
7543 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7544 {
7545   unformat_input_t *i = vam->input;
7546   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7547   f64 timeout;
7548   u32 sw_if_index;
7549   u8 sw_if_index_set = 0;
7550   u8 suppress = 0;
7551   u8 managed = 0;
7552   u8 other = 0;
7553   u8 ll_option = 0;
7554   u8 send_unicast = 0;
7555   u8 cease = 0;
7556   u8 is_no = 0;
7557   u8 default_router = 0;
7558   u32 max_interval = 0;
7559   u32 min_interval = 0;
7560   u32 lifetime = 0;
7561   u32 initial_count = 0;
7562   u32 initial_interval = 0;
7563
7564
7565   /* Parse args required to build the message */
7566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7567     {
7568       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7569         sw_if_index_set = 1;
7570       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7571         sw_if_index_set = 1;
7572       else if (unformat (i, "maxint %d", &max_interval))
7573         ;
7574       else if (unformat (i, "minint %d", &min_interval))
7575         ;
7576       else if (unformat (i, "life %d", &lifetime))
7577         ;
7578       else if (unformat (i, "count %d", &initial_count))
7579         ;
7580       else if (unformat (i, "interval %d", &initial_interval))
7581         ;
7582       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7583         suppress = 1;
7584       else if (unformat (i, "managed"))
7585         managed = 1;
7586       else if (unformat (i, "other"))
7587         other = 1;
7588       else if (unformat (i, "ll"))
7589         ll_option = 1;
7590       else if (unformat (i, "send"))
7591         send_unicast = 1;
7592       else if (unformat (i, "cease"))
7593         cease = 1;
7594       else if (unformat (i, "isno"))
7595         is_no = 1;
7596       else if (unformat (i, "def"))
7597         default_router = 1;
7598       else
7599         {
7600           clib_warning ("parse error '%U'", format_unformat_error, i);
7601           return -99;
7602         }
7603     }
7604
7605   if (sw_if_index_set == 0)
7606     {
7607       errmsg ("missing interface name or sw_if_index\n");
7608       return -99;
7609     }
7610
7611   /* Construct the API message */
7612   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7613
7614   mp->sw_if_index = ntohl (sw_if_index);
7615   mp->max_interval = ntohl (max_interval);
7616   mp->min_interval = ntohl (min_interval);
7617   mp->lifetime = ntohl (lifetime);
7618   mp->initial_count = ntohl (initial_count);
7619   mp->initial_interval = ntohl (initial_interval);
7620   mp->suppress = suppress;
7621   mp->managed = managed;
7622   mp->other = other;
7623   mp->ll_option = ll_option;
7624   mp->send_unicast = send_unicast;
7625   mp->cease = cease;
7626   mp->is_no = is_no;
7627   mp->default_router = default_router;
7628
7629   /* send it... */
7630   S;
7631
7632   /* Wait for a reply, return good/bad news  */
7633   W;
7634
7635   /* NOTREACHED */
7636   return 0;
7637 }
7638
7639 static int
7640 api_set_arp_neighbor_limit (vat_main_t * vam)
7641 {
7642   unformat_input_t *i = vam->input;
7643   vl_api_set_arp_neighbor_limit_t *mp;
7644   f64 timeout;
7645   u32 arp_nbr_limit;
7646   u8 limit_set = 0;
7647   u8 is_ipv6 = 0;
7648
7649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7650     {
7651       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7652         limit_set = 1;
7653       else if (unformat (i, "ipv6"))
7654         is_ipv6 = 1;
7655       else
7656         {
7657           clib_warning ("parse error '%U'", format_unformat_error, i);
7658           return -99;
7659         }
7660     }
7661
7662   if (limit_set == 0)
7663     {
7664       errmsg ("missing limit value\n");
7665       return -99;
7666     }
7667
7668   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7669
7670   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7671   mp->is_ipv6 = is_ipv6;
7672
7673   S;
7674   W;
7675   /* NOTREACHED */
7676   return 0;
7677 }
7678
7679 static int
7680 api_l2_patch_add_del (vat_main_t * vam)
7681 {
7682   unformat_input_t *i = vam->input;
7683   vl_api_l2_patch_add_del_t *mp;
7684   f64 timeout;
7685   u32 rx_sw_if_index;
7686   u8 rx_sw_if_index_set = 0;
7687   u32 tx_sw_if_index;
7688   u8 tx_sw_if_index_set = 0;
7689   u8 is_add = 1;
7690
7691   /* Parse args required to build the message */
7692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7693     {
7694       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7695         rx_sw_if_index_set = 1;
7696       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7697         tx_sw_if_index_set = 1;
7698       else if (unformat (i, "rx"))
7699         {
7700           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7701             {
7702               if (unformat (i, "%U", unformat_sw_if_index, vam,
7703                             &rx_sw_if_index))
7704                 rx_sw_if_index_set = 1;
7705             }
7706           else
7707             break;
7708         }
7709       else if (unformat (i, "tx"))
7710         {
7711           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7712             {
7713               if (unformat (i, "%U", unformat_sw_if_index, vam,
7714                             &tx_sw_if_index))
7715                 tx_sw_if_index_set = 1;
7716             }
7717           else
7718             break;
7719         }
7720       else if (unformat (i, "del"))
7721         is_add = 0;
7722       else
7723         break;
7724     }
7725
7726   if (rx_sw_if_index_set == 0)
7727     {
7728       errmsg ("missing rx interface name or rx_sw_if_index\n");
7729       return -99;
7730     }
7731
7732   if (tx_sw_if_index_set == 0)
7733     {
7734       errmsg ("missing tx interface name or tx_sw_if_index\n");
7735       return -99;
7736     }
7737
7738   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7739
7740   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7741   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7742   mp->is_add = is_add;
7743
7744   S;
7745   W;
7746   /* NOTREACHED */
7747   return 0;
7748 }
7749
7750 static int
7751 api_ioam_enable (vat_main_t * vam)
7752 {
7753   unformat_input_t *input = vam->input;
7754   vl_api_ioam_enable_t *mp;
7755   f64 timeout;
7756   u32 id = 0;
7757   int has_trace_option = 0;
7758   int has_pow_option = 0;
7759   int has_ppc_option = 0;
7760
7761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7762     {
7763       if (unformat (input, "trace"))
7764         has_trace_option = 1;
7765       else if (unformat (input, "pow"))
7766         has_pow_option = 1;
7767       else if (unformat (input, "ppc encap"))
7768         has_ppc_option = PPC_ENCAP;
7769       else if (unformat (input, "ppc decap"))
7770         has_ppc_option = PPC_DECAP;
7771       else if (unformat (input, "ppc none"))
7772         has_ppc_option = PPC_NONE;
7773       else
7774         break;
7775     }
7776   M (IOAM_ENABLE, ioam_enable);
7777   mp->id = htons (id);
7778   mp->trace_ppc = has_ppc_option;
7779   mp->pow_enable = has_pow_option;
7780   mp->trace_enable = has_trace_option;
7781
7782   S;
7783   W;
7784
7785   return (0);
7786
7787 }
7788
7789
7790 static int
7791 api_ioam_disable (vat_main_t * vam)
7792 {
7793   vl_api_ioam_disable_t *mp;
7794   f64 timeout;
7795
7796   M (IOAM_DISABLE, ioam_disable);
7797   S;
7798   W;
7799   return 0;
7800 }
7801
7802 static int
7803 api_sr_tunnel_add_del (vat_main_t * vam)
7804 {
7805   unformat_input_t *i = vam->input;
7806   vl_api_sr_tunnel_add_del_t *mp;
7807   f64 timeout;
7808   int is_del = 0;
7809   int pl_index;
7810   ip6_address_t src_address;
7811   int src_address_set = 0;
7812   ip6_address_t dst_address;
7813   u32 dst_mask_width;
7814   int dst_address_set = 0;
7815   u16 flags = 0;
7816   u32 rx_table_id = 0;
7817   u32 tx_table_id = 0;
7818   ip6_address_t *segments = 0;
7819   ip6_address_t *this_seg;
7820   ip6_address_t *tags = 0;
7821   ip6_address_t *this_tag;
7822   ip6_address_t next_address, tag;
7823   u8 *name = 0;
7824   u8 *policy_name = 0;
7825
7826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7827     {
7828       if (unformat (i, "del"))
7829         is_del = 1;
7830       else if (unformat (i, "name %s", &name))
7831         ;
7832       else if (unformat (i, "policy %s", &policy_name))
7833         ;
7834       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7835         ;
7836       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7837         ;
7838       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7839         src_address_set = 1;
7840       else if (unformat (i, "dst %U/%d",
7841                          unformat_ip6_address, &dst_address, &dst_mask_width))
7842         dst_address_set = 1;
7843       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7844         {
7845           vec_add2 (segments, this_seg, 1);
7846           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7847                        sizeof (*this_seg));
7848         }
7849       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7850         {
7851           vec_add2 (tags, this_tag, 1);
7852           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7853         }
7854       else if (unformat (i, "clean"))
7855         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7856       else if (unformat (i, "protected"))
7857         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7858       else if (unformat (i, "InPE %d", &pl_index))
7859         {
7860           if (pl_index <= 0 || pl_index > 4)
7861             {
7862             pl_index_range_error:
7863               errmsg ("pl index %d out of range\n", pl_index);
7864               return -99;
7865             }
7866           flags |=
7867             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7868         }
7869       else if (unformat (i, "EgPE %d", &pl_index))
7870         {
7871           if (pl_index <= 0 || pl_index > 4)
7872             goto pl_index_range_error;
7873           flags |=
7874             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7875         }
7876       else if (unformat (i, "OrgSrc %d", &pl_index))
7877         {
7878           if (pl_index <= 0 || pl_index > 4)
7879             goto pl_index_range_error;
7880           flags |=
7881             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7882         }
7883       else
7884         break;
7885     }
7886
7887   if (!src_address_set)
7888     {
7889       errmsg ("src address required\n");
7890       return -99;
7891     }
7892
7893   if (!dst_address_set)
7894     {
7895       errmsg ("dst address required\n");
7896       return -99;
7897     }
7898
7899   if (!segments)
7900     {
7901       errmsg ("at least one sr segment required\n");
7902       return -99;
7903     }
7904
7905   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7906       vec_len (segments) * sizeof (ip6_address_t)
7907       + vec_len (tags) * sizeof (ip6_address_t));
7908
7909   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7910   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7911   mp->dst_mask_width = dst_mask_width;
7912   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7913   mp->n_segments = vec_len (segments);
7914   mp->n_tags = vec_len (tags);
7915   mp->is_add = is_del == 0;
7916   clib_memcpy (mp->segs_and_tags, segments,
7917                vec_len (segments) * sizeof (ip6_address_t));
7918   clib_memcpy (mp->segs_and_tags +
7919                vec_len (segments) * sizeof (ip6_address_t), tags,
7920                vec_len (tags) * sizeof (ip6_address_t));
7921
7922   mp->outer_vrf_id = ntohl (rx_table_id);
7923   mp->inner_vrf_id = ntohl (tx_table_id);
7924   memcpy (mp->name, name, vec_len (name));
7925   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7926
7927   vec_free (segments);
7928   vec_free (tags);
7929
7930   S;
7931   W;
7932   /* NOTREACHED */
7933 }
7934
7935 static int
7936 api_sr_policy_add_del (vat_main_t * vam)
7937 {
7938   unformat_input_t *input = vam->input;
7939   vl_api_sr_policy_add_del_t *mp;
7940   f64 timeout;
7941   int is_del = 0;
7942   u8 *name = 0;
7943   u8 *tunnel_name = 0;
7944   u8 **tunnel_names = 0;
7945
7946   int name_set = 0;
7947   int tunnel_set = 0;
7948   int j = 0;
7949   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7950   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7951
7952   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7953     {
7954       if (unformat (input, "del"))
7955         is_del = 1;
7956       else if (unformat (input, "name %s", &name))
7957         name_set = 1;
7958       else if (unformat (input, "tunnel %s", &tunnel_name))
7959         {
7960           if (tunnel_name)
7961             {
7962               vec_add1 (tunnel_names, tunnel_name);
7963               /* For serializer:
7964                  - length = #bytes to store in serial vector
7965                  - +1 = byte to store that length
7966                */
7967               tunnel_names_length += (vec_len (tunnel_name) + 1);
7968               tunnel_set = 1;
7969               tunnel_name = 0;
7970             }
7971         }
7972       else
7973         break;
7974     }
7975
7976   if (!name_set)
7977     {
7978       errmsg ("policy name required\n");
7979       return -99;
7980     }
7981
7982   if ((!tunnel_set) && (!is_del))
7983     {
7984       errmsg ("tunnel name required\n");
7985       return -99;
7986     }
7987
7988   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7989
7990
7991
7992   mp->is_add = !is_del;
7993
7994   memcpy (mp->name, name, vec_len (name));
7995   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7996   u8 *serial_orig = 0;
7997   vec_validate (serial_orig, tunnel_names_length);
7998   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7999   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8000
8001   for (j = 0; j < vec_len (tunnel_names); j++)
8002     {
8003       tun_name_len = vec_len (tunnel_names[j]);
8004       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8005       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8006       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8007       serial_orig += tun_name_len;      // Advance past the copy
8008     }
8009   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8010
8011   vec_free (tunnel_names);
8012   vec_free (tunnel_name);
8013
8014   S;
8015   W;
8016   /* NOTREACHED */
8017 }
8018
8019 static int
8020 api_sr_multicast_map_add_del (vat_main_t * vam)
8021 {
8022   unformat_input_t *input = vam->input;
8023   vl_api_sr_multicast_map_add_del_t *mp;
8024   f64 timeout;
8025   int is_del = 0;
8026   ip6_address_t multicast_address;
8027   u8 *policy_name = 0;
8028   int multicast_address_set = 0;
8029
8030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8031     {
8032       if (unformat (input, "del"))
8033         is_del = 1;
8034       else
8035         if (unformat
8036             (input, "address %U", unformat_ip6_address, &multicast_address))
8037         multicast_address_set = 1;
8038       else if (unformat (input, "sr-policy %s", &policy_name))
8039         ;
8040       else
8041         break;
8042     }
8043
8044   if (!is_del && !policy_name)
8045     {
8046       errmsg ("sr-policy name required\n");
8047       return -99;
8048     }
8049
8050
8051   if (!multicast_address_set)
8052     {
8053       errmsg ("address required\n");
8054       return -99;
8055     }
8056
8057   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8058
8059   mp->is_add = !is_del;
8060   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8061   clib_memcpy (mp->multicast_address, &multicast_address,
8062                sizeof (mp->multicast_address));
8063
8064
8065   vec_free (policy_name);
8066
8067   S;
8068   W;
8069   /* NOTREACHED */
8070 }
8071
8072
8073 #define foreach_tcp_proto_field                 \
8074 _(src_port)                                     \
8075 _(dst_port)
8076
8077 #define foreach_udp_proto_field                 \
8078 _(src_port)                                     \
8079 _(dst_port)
8080
8081 #define foreach_ip4_proto_field                 \
8082 _(src_address)                                  \
8083 _(dst_address)                                  \
8084 _(tos)                                          \
8085 _(length)                                       \
8086 _(fragment_id)                                  \
8087 _(ttl)                                          \
8088 _(protocol)                                     \
8089 _(checksum)
8090
8091 uword
8092 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8093 {
8094   u8 **maskp = va_arg (*args, u8 **);
8095   u8 *mask = 0;
8096   u8 found_something = 0;
8097   tcp_header_t *tcp;
8098
8099 #define _(a) u8 a=0;
8100   foreach_tcp_proto_field;
8101 #undef _
8102
8103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8104     {
8105       if (0);
8106 #define _(a) else if (unformat (input, #a)) a=1;
8107       foreach_tcp_proto_field
8108 #undef _
8109         else
8110         break;
8111     }
8112
8113 #define _(a) found_something += a;
8114   foreach_tcp_proto_field;
8115 #undef _
8116
8117   if (found_something == 0)
8118     return 0;
8119
8120   vec_validate (mask, sizeof (*tcp) - 1);
8121
8122   tcp = (tcp_header_t *) mask;
8123
8124 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8125   foreach_tcp_proto_field;
8126 #undef _
8127
8128   *maskp = mask;
8129   return 1;
8130 }
8131
8132 uword
8133 unformat_udp_mask (unformat_input_t * input, va_list * args)
8134 {
8135   u8 **maskp = va_arg (*args, u8 **);
8136   u8 *mask = 0;
8137   u8 found_something = 0;
8138   udp_header_t *udp;
8139
8140 #define _(a) u8 a=0;
8141   foreach_udp_proto_field;
8142 #undef _
8143
8144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8145     {
8146       if (0);
8147 #define _(a) else if (unformat (input, #a)) a=1;
8148       foreach_udp_proto_field
8149 #undef _
8150         else
8151         break;
8152     }
8153
8154 #define _(a) found_something += a;
8155   foreach_udp_proto_field;
8156 #undef _
8157
8158   if (found_something == 0)
8159     return 0;
8160
8161   vec_validate (mask, sizeof (*udp) - 1);
8162
8163   udp = (udp_header_t *) mask;
8164
8165 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8166   foreach_udp_proto_field;
8167 #undef _
8168
8169   *maskp = mask;
8170   return 1;
8171 }
8172
8173 typedef struct
8174 {
8175   u16 src_port, dst_port;
8176 } tcpudp_header_t;
8177
8178 uword
8179 unformat_l4_mask (unformat_input_t * input, va_list * args)
8180 {
8181   u8 **maskp = va_arg (*args, u8 **);
8182   u16 src_port = 0, dst_port = 0;
8183   tcpudp_header_t *tcpudp;
8184
8185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8186     {
8187       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8188         return 1;
8189       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8190         return 1;
8191       else if (unformat (input, "src_port"))
8192         src_port = 0xFFFF;
8193       else if (unformat (input, "dst_port"))
8194         dst_port = 0xFFFF;
8195       else
8196         return 0;
8197     }
8198
8199   if (!src_port && !dst_port)
8200     return 0;
8201
8202   u8 *mask = 0;
8203   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8204
8205   tcpudp = (tcpudp_header_t *) mask;
8206   tcpudp->src_port = src_port;
8207   tcpudp->dst_port = dst_port;
8208
8209   *maskp = mask;
8210
8211   return 1;
8212 }
8213
8214 uword
8215 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8216 {
8217   u8 **maskp = va_arg (*args, u8 **);
8218   u8 *mask = 0;
8219   u8 found_something = 0;
8220   ip4_header_t *ip;
8221
8222 #define _(a) u8 a=0;
8223   foreach_ip4_proto_field;
8224 #undef _
8225   u8 version = 0;
8226   u8 hdr_length = 0;
8227
8228
8229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8230     {
8231       if (unformat (input, "version"))
8232         version = 1;
8233       else if (unformat (input, "hdr_length"))
8234         hdr_length = 1;
8235       else if (unformat (input, "src"))
8236         src_address = 1;
8237       else if (unformat (input, "dst"))
8238         dst_address = 1;
8239       else if (unformat (input, "proto"))
8240         protocol = 1;
8241
8242 #define _(a) else if (unformat (input, #a)) a=1;
8243       foreach_ip4_proto_field
8244 #undef _
8245         else
8246         break;
8247     }
8248
8249 #define _(a) found_something += a;
8250   foreach_ip4_proto_field;
8251 #undef _
8252
8253   if (found_something == 0)
8254     return 0;
8255
8256   vec_validate (mask, sizeof (*ip) - 1);
8257
8258   ip = (ip4_header_t *) mask;
8259
8260 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8261   foreach_ip4_proto_field;
8262 #undef _
8263
8264   ip->ip_version_and_header_length = 0;
8265
8266   if (version)
8267     ip->ip_version_and_header_length |= 0xF0;
8268
8269   if (hdr_length)
8270     ip->ip_version_and_header_length |= 0x0F;
8271
8272   *maskp = mask;
8273   return 1;
8274 }
8275
8276 #define foreach_ip6_proto_field                 \
8277 _(src_address)                                  \
8278 _(dst_address)                                  \
8279 _(payload_length)                               \
8280 _(hop_limit)                                    \
8281 _(protocol)
8282
8283 uword
8284 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8285 {
8286   u8 **maskp = va_arg (*args, u8 **);
8287   u8 *mask = 0;
8288   u8 found_something = 0;
8289   ip6_header_t *ip;
8290   u32 ip_version_traffic_class_and_flow_label;
8291
8292 #define _(a) u8 a=0;
8293   foreach_ip6_proto_field;
8294 #undef _
8295   u8 version = 0;
8296   u8 traffic_class = 0;
8297   u8 flow_label = 0;
8298
8299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8300     {
8301       if (unformat (input, "version"))
8302         version = 1;
8303       else if (unformat (input, "traffic-class"))
8304         traffic_class = 1;
8305       else if (unformat (input, "flow-label"))
8306         flow_label = 1;
8307       else if (unformat (input, "src"))
8308         src_address = 1;
8309       else if (unformat (input, "dst"))
8310         dst_address = 1;
8311       else if (unformat (input, "proto"))
8312         protocol = 1;
8313
8314 #define _(a) else if (unformat (input, #a)) a=1;
8315       foreach_ip6_proto_field
8316 #undef _
8317         else
8318         break;
8319     }
8320
8321 #define _(a) found_something += a;
8322   foreach_ip6_proto_field;
8323 #undef _
8324
8325   if (found_something == 0)
8326     return 0;
8327
8328   vec_validate (mask, sizeof (*ip) - 1);
8329
8330   ip = (ip6_header_t *) mask;
8331
8332 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8333   foreach_ip6_proto_field;
8334 #undef _
8335
8336   ip_version_traffic_class_and_flow_label = 0;
8337
8338   if (version)
8339     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8340
8341   if (traffic_class)
8342     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8343
8344   if (flow_label)
8345     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8346
8347   ip->ip_version_traffic_class_and_flow_label =
8348     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8349
8350   *maskp = mask;
8351   return 1;
8352 }
8353
8354 uword
8355 unformat_l3_mask (unformat_input_t * input, va_list * args)
8356 {
8357   u8 **maskp = va_arg (*args, u8 **);
8358
8359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8360     {
8361       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8362         return 1;
8363       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8364         return 1;
8365       else
8366         break;
8367     }
8368   return 0;
8369 }
8370
8371 uword
8372 unformat_l2_mask (unformat_input_t * input, va_list * args)
8373 {
8374   u8 **maskp = va_arg (*args, u8 **);
8375   u8 *mask = 0;
8376   u8 src = 0;
8377   u8 dst = 0;
8378   u8 proto = 0;
8379   u8 tag1 = 0;
8380   u8 tag2 = 0;
8381   u8 ignore_tag1 = 0;
8382   u8 ignore_tag2 = 0;
8383   u8 cos1 = 0;
8384   u8 cos2 = 0;
8385   u8 dot1q = 0;
8386   u8 dot1ad = 0;
8387   int len = 14;
8388
8389   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8390     {
8391       if (unformat (input, "src"))
8392         src = 1;
8393       else if (unformat (input, "dst"))
8394         dst = 1;
8395       else if (unformat (input, "proto"))
8396         proto = 1;
8397       else if (unformat (input, "tag1"))
8398         tag1 = 1;
8399       else if (unformat (input, "tag2"))
8400         tag2 = 1;
8401       else if (unformat (input, "ignore-tag1"))
8402         ignore_tag1 = 1;
8403       else if (unformat (input, "ignore-tag2"))
8404         ignore_tag2 = 1;
8405       else if (unformat (input, "cos1"))
8406         cos1 = 1;
8407       else if (unformat (input, "cos2"))
8408         cos2 = 1;
8409       else if (unformat (input, "dot1q"))
8410         dot1q = 1;
8411       else if (unformat (input, "dot1ad"))
8412         dot1ad = 1;
8413       else
8414         break;
8415     }
8416   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8417        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8418     return 0;
8419
8420   if (tag1 || ignore_tag1 || cos1 || dot1q)
8421     len = 18;
8422   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8423     len = 22;
8424
8425   vec_validate (mask, len - 1);
8426
8427   if (dst)
8428     memset (mask, 0xff, 6);
8429
8430   if (src)
8431     memset (mask + 6, 0xff, 6);
8432
8433   if (tag2 || dot1ad)
8434     {
8435       /* inner vlan tag */
8436       if (tag2)
8437         {
8438           mask[19] = 0xff;
8439           mask[18] = 0x0f;
8440         }
8441       if (cos2)
8442         mask[18] |= 0xe0;
8443       if (proto)
8444         mask[21] = mask[20] = 0xff;
8445       if (tag1)
8446         {
8447           mask[15] = 0xff;
8448           mask[14] = 0x0f;
8449         }
8450       if (cos1)
8451         mask[14] |= 0xe0;
8452       *maskp = mask;
8453       return 1;
8454     }
8455   if (tag1 | dot1q)
8456     {
8457       if (tag1)
8458         {
8459           mask[15] = 0xff;
8460           mask[14] = 0x0f;
8461         }
8462       if (cos1)
8463         mask[14] |= 0xe0;
8464       if (proto)
8465         mask[16] = mask[17] = 0xff;
8466
8467       *maskp = mask;
8468       return 1;
8469     }
8470   if (cos2)
8471     mask[18] |= 0xe0;
8472   if (cos1)
8473     mask[14] |= 0xe0;
8474   if (proto)
8475     mask[12] = mask[13] = 0xff;
8476
8477   *maskp = mask;
8478   return 1;
8479 }
8480
8481 uword
8482 unformat_classify_mask (unformat_input_t * input, va_list * args)
8483 {
8484   u8 **maskp = va_arg (*args, u8 **);
8485   u32 *skipp = va_arg (*args, u32 *);
8486   u32 *matchp = va_arg (*args, u32 *);
8487   u32 match;
8488   u8 *mask = 0;
8489   u8 *l2 = 0;
8490   u8 *l3 = 0;
8491   u8 *l4 = 0;
8492   int i;
8493
8494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8495     {
8496       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8497         ;
8498       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8499         ;
8500       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8501         ;
8502       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8503         ;
8504       else
8505         break;
8506     }
8507
8508   if (l4 && !l3)
8509     {
8510       vec_free (mask);
8511       vec_free (l2);
8512       vec_free (l4);
8513       return 0;
8514     }
8515
8516   if (mask || l2 || l3 || l4)
8517     {
8518       if (l2 || l3 || l4)
8519         {
8520           /* "With a free Ethernet header in every package" */
8521           if (l2 == 0)
8522             vec_validate (l2, 13);
8523           mask = l2;
8524           if (vec_len (l3))
8525             {
8526               vec_append (mask, l3);
8527               vec_free (l3);
8528             }
8529           if (vec_len (l4))
8530             {
8531               vec_append (mask, l4);
8532               vec_free (l4);
8533             }
8534         }
8535
8536       /* Scan forward looking for the first significant mask octet */
8537       for (i = 0; i < vec_len (mask); i++)
8538         if (mask[i])
8539           break;
8540
8541       /* compute (skip, match) params */
8542       *skipp = i / sizeof (u32x4);
8543       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8544
8545       /* Pad mask to an even multiple of the vector size */
8546       while (vec_len (mask) % sizeof (u32x4))
8547         vec_add1 (mask, 0);
8548
8549       match = vec_len (mask) / sizeof (u32x4);
8550
8551       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8552         {
8553           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8554           if (*tmp || *(tmp + 1))
8555             break;
8556           match--;
8557         }
8558       if (match == 0)
8559         clib_warning ("BUG: match 0");
8560
8561       _vec_len (mask) = match * sizeof (u32x4);
8562
8563       *matchp = match;
8564       *maskp = mask;
8565
8566       return 1;
8567     }
8568
8569   return 0;
8570 }
8571
8572 #define foreach_l2_next                         \
8573 _(drop, DROP)                                   \
8574 _(ethernet, ETHERNET_INPUT)                     \
8575 _(ip4, IP4_INPUT)                               \
8576 _(ip6, IP6_INPUT)
8577
8578 uword
8579 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8580 {
8581   u32 *miss_next_indexp = va_arg (*args, u32 *);
8582   u32 next_index = 0;
8583   u32 tmp;
8584
8585 #define _(n,N) \
8586   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8587   foreach_l2_next;
8588 #undef _
8589
8590   if (unformat (input, "%d", &tmp))
8591     {
8592       next_index = tmp;
8593       goto out;
8594     }
8595
8596   return 0;
8597
8598 out:
8599   *miss_next_indexp = next_index;
8600   return 1;
8601 }
8602
8603 #define foreach_ip_next                         \
8604 _(drop, DROP)                                   \
8605 _(local, LOCAL)                                 \
8606 _(rewrite, REWRITE)
8607
8608 uword
8609 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8610 {
8611   u32 *miss_next_indexp = va_arg (*args, u32 *);
8612   u32 next_index = 0;
8613   u32 tmp;
8614
8615 #define _(n,N) \
8616   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8617   foreach_ip_next;
8618 #undef _
8619
8620   if (unformat (input, "%d", &tmp))
8621     {
8622       next_index = tmp;
8623       goto out;
8624     }
8625
8626   return 0;
8627
8628 out:
8629   *miss_next_indexp = next_index;
8630   return 1;
8631 }
8632
8633 #define foreach_acl_next                        \
8634 _(deny, DENY)
8635
8636 uword
8637 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8638 {
8639   u32 *miss_next_indexp = va_arg (*args, u32 *);
8640   u32 next_index = 0;
8641   u32 tmp;
8642
8643 #define _(n,N) \
8644   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8645   foreach_acl_next;
8646 #undef _
8647
8648   if (unformat (input, "permit"))
8649     {
8650       next_index = ~0;
8651       goto out;
8652     }
8653   else if (unformat (input, "%d", &tmp))
8654     {
8655       next_index = tmp;
8656       goto out;
8657     }
8658
8659   return 0;
8660
8661 out:
8662   *miss_next_indexp = next_index;
8663   return 1;
8664 }
8665
8666 uword
8667 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8668 {
8669   u32 *r = va_arg (*args, u32 *);
8670
8671   if (unformat (input, "conform-color"))
8672     *r = POLICE_CONFORM;
8673   else if (unformat (input, "exceed-color"))
8674     *r = POLICE_EXCEED;
8675   else
8676     return 0;
8677
8678   return 1;
8679 }
8680
8681 static int
8682 api_classify_add_del_table (vat_main_t * vam)
8683 {
8684   unformat_input_t *i = vam->input;
8685   vl_api_classify_add_del_table_t *mp;
8686
8687   u32 nbuckets = 2;
8688   u32 skip = ~0;
8689   u32 match = ~0;
8690   int is_add = 1;
8691   u32 table_index = ~0;
8692   u32 next_table_index = ~0;
8693   u32 miss_next_index = ~0;
8694   u32 memory_size = 32 << 20;
8695   u8 *mask = 0;
8696   f64 timeout;
8697
8698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8699     {
8700       if (unformat (i, "del"))
8701         is_add = 0;
8702       else if (unformat (i, "buckets %d", &nbuckets))
8703         ;
8704       else if (unformat (i, "memory_size %d", &memory_size))
8705         ;
8706       else if (unformat (i, "skip %d", &skip))
8707         ;
8708       else if (unformat (i, "match %d", &match))
8709         ;
8710       else if (unformat (i, "table %d", &table_index))
8711         ;
8712       else if (unformat (i, "mask %U", unformat_classify_mask,
8713                          &mask, &skip, &match))
8714         ;
8715       else if (unformat (i, "next-table %d", &next_table_index))
8716         ;
8717       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8718                          &miss_next_index))
8719         ;
8720       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8721                          &miss_next_index))
8722         ;
8723       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8724                          &miss_next_index))
8725         ;
8726       else
8727         break;
8728     }
8729
8730   if (is_add && mask == 0)
8731     {
8732       errmsg ("Mask required\n");
8733       return -99;
8734     }
8735
8736   if (is_add && skip == ~0)
8737     {
8738       errmsg ("skip count required\n");
8739       return -99;
8740     }
8741
8742   if (is_add && match == ~0)
8743     {
8744       errmsg ("match count required\n");
8745       return -99;
8746     }
8747
8748   if (!is_add && table_index == ~0)
8749     {
8750       errmsg ("table index required for delete\n");
8751       return -99;
8752     }
8753
8754   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8755
8756   mp->is_add = is_add;
8757   mp->table_index = ntohl (table_index);
8758   mp->nbuckets = ntohl (nbuckets);
8759   mp->memory_size = ntohl (memory_size);
8760   mp->skip_n_vectors = ntohl (skip);
8761   mp->match_n_vectors = ntohl (match);
8762   mp->next_table_index = ntohl (next_table_index);
8763   mp->miss_next_index = ntohl (miss_next_index);
8764   clib_memcpy (mp->mask, mask, vec_len (mask));
8765
8766   vec_free (mask);
8767
8768   S;
8769   W;
8770   /* NOTREACHED */
8771 }
8772
8773 uword
8774 unformat_l4_match (unformat_input_t * input, va_list * args)
8775 {
8776   u8 **matchp = va_arg (*args, u8 **);
8777
8778   u8 *proto_header = 0;
8779   int src_port = 0;
8780   int dst_port = 0;
8781
8782   tcpudp_header_t h;
8783
8784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8785     {
8786       if (unformat (input, "src_port %d", &src_port))
8787         ;
8788       else if (unformat (input, "dst_port %d", &dst_port))
8789         ;
8790       else
8791         return 0;
8792     }
8793
8794   h.src_port = clib_host_to_net_u16 (src_port);
8795   h.dst_port = clib_host_to_net_u16 (dst_port);
8796   vec_validate (proto_header, sizeof (h) - 1);
8797   memcpy (proto_header, &h, sizeof (h));
8798
8799   *matchp = proto_header;
8800
8801   return 1;
8802 }
8803
8804 uword
8805 unformat_ip4_match (unformat_input_t * input, va_list * args)
8806 {
8807   u8 **matchp = va_arg (*args, u8 **);
8808   u8 *match = 0;
8809   ip4_header_t *ip;
8810   int version = 0;
8811   u32 version_val;
8812   int hdr_length = 0;
8813   u32 hdr_length_val;
8814   int src = 0, dst = 0;
8815   ip4_address_t src_val, dst_val;
8816   int proto = 0;
8817   u32 proto_val;
8818   int tos = 0;
8819   u32 tos_val;
8820   int length = 0;
8821   u32 length_val;
8822   int fragment_id = 0;
8823   u32 fragment_id_val;
8824   int ttl = 0;
8825   int ttl_val;
8826   int checksum = 0;
8827   u32 checksum_val;
8828
8829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8830     {
8831       if (unformat (input, "version %d", &version_val))
8832         version = 1;
8833       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8834         hdr_length = 1;
8835       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8836         src = 1;
8837       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8838         dst = 1;
8839       else if (unformat (input, "proto %d", &proto_val))
8840         proto = 1;
8841       else if (unformat (input, "tos %d", &tos_val))
8842         tos = 1;
8843       else if (unformat (input, "length %d", &length_val))
8844         length = 1;
8845       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8846         fragment_id = 1;
8847       else if (unformat (input, "ttl %d", &ttl_val))
8848         ttl = 1;
8849       else if (unformat (input, "checksum %d", &checksum_val))
8850         checksum = 1;
8851       else
8852         break;
8853     }
8854
8855   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8856       + ttl + checksum == 0)
8857     return 0;
8858
8859   /*
8860    * Aligned because we use the real comparison functions
8861    */
8862   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8863
8864   ip = (ip4_header_t *) match;
8865
8866   /* These are realistically matched in practice */
8867   if (src)
8868     ip->src_address.as_u32 = src_val.as_u32;
8869
8870   if (dst)
8871     ip->dst_address.as_u32 = dst_val.as_u32;
8872
8873   if (proto)
8874     ip->protocol = proto_val;
8875
8876
8877   /* These are not, but they're included for completeness */
8878   if (version)
8879     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8880
8881   if (hdr_length)
8882     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8883
8884   if (tos)
8885     ip->tos = tos_val;
8886
8887   if (length)
8888     ip->length = clib_host_to_net_u16 (length_val);
8889
8890   if (ttl)
8891     ip->ttl = ttl_val;
8892
8893   if (checksum)
8894     ip->checksum = clib_host_to_net_u16 (checksum_val);
8895
8896   *matchp = match;
8897   return 1;
8898 }
8899
8900 uword
8901 unformat_ip6_match (unformat_input_t * input, va_list * args)
8902 {
8903   u8 **matchp = va_arg (*args, u8 **);
8904   u8 *match = 0;
8905   ip6_header_t *ip;
8906   int version = 0;
8907   u32 version_val;
8908   u8 traffic_class = 0;
8909   u32 traffic_class_val = 0;
8910   u8 flow_label = 0;
8911   u8 flow_label_val;
8912   int src = 0, dst = 0;
8913   ip6_address_t src_val, dst_val;
8914   int proto = 0;
8915   u32 proto_val;
8916   int payload_length = 0;
8917   u32 payload_length_val;
8918   int hop_limit = 0;
8919   int hop_limit_val;
8920   u32 ip_version_traffic_class_and_flow_label;
8921
8922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8923     {
8924       if (unformat (input, "version %d", &version_val))
8925         version = 1;
8926       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8927         traffic_class = 1;
8928       else if (unformat (input, "flow_label %d", &flow_label_val))
8929         flow_label = 1;
8930       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8931         src = 1;
8932       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8933         dst = 1;
8934       else if (unformat (input, "proto %d", &proto_val))
8935         proto = 1;
8936       else if (unformat (input, "payload_length %d", &payload_length_val))
8937         payload_length = 1;
8938       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8939         hop_limit = 1;
8940       else
8941         break;
8942     }
8943
8944   if (version + traffic_class + flow_label + src + dst + proto +
8945       payload_length + hop_limit == 0)
8946     return 0;
8947
8948   /*
8949    * Aligned because we use the real comparison functions
8950    */
8951   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8952
8953   ip = (ip6_header_t *) match;
8954
8955   if (src)
8956     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8957
8958   if (dst)
8959     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8960
8961   if (proto)
8962     ip->protocol = proto_val;
8963
8964   ip_version_traffic_class_and_flow_label = 0;
8965
8966   if (version)
8967     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8968
8969   if (traffic_class)
8970     ip_version_traffic_class_and_flow_label |=
8971       (traffic_class_val & 0xFF) << 20;
8972
8973   if (flow_label)
8974     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8975
8976   ip->ip_version_traffic_class_and_flow_label =
8977     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8978
8979   if (payload_length)
8980     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8981
8982   if (hop_limit)
8983     ip->hop_limit = hop_limit_val;
8984
8985   *matchp = match;
8986   return 1;
8987 }
8988
8989 uword
8990 unformat_l3_match (unformat_input_t * input, va_list * args)
8991 {
8992   u8 **matchp = va_arg (*args, u8 **);
8993
8994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8995     {
8996       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8997         return 1;
8998       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8999         return 1;
9000       else
9001         break;
9002     }
9003   return 0;
9004 }
9005
9006 uword
9007 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9008 {
9009   u8 *tagp = va_arg (*args, u8 *);
9010   u32 tag;
9011
9012   if (unformat (input, "%d", &tag))
9013     {
9014       tagp[0] = (tag >> 8) & 0x0F;
9015       tagp[1] = tag & 0xFF;
9016       return 1;
9017     }
9018
9019   return 0;
9020 }
9021
9022 uword
9023 unformat_l2_match (unformat_input_t * input, va_list * args)
9024 {
9025   u8 **matchp = va_arg (*args, u8 **);
9026   u8 *match = 0;
9027   u8 src = 0;
9028   u8 src_val[6];
9029   u8 dst = 0;
9030   u8 dst_val[6];
9031   u8 proto = 0;
9032   u16 proto_val;
9033   u8 tag1 = 0;
9034   u8 tag1_val[2];
9035   u8 tag2 = 0;
9036   u8 tag2_val[2];
9037   int len = 14;
9038   u8 ignore_tag1 = 0;
9039   u8 ignore_tag2 = 0;
9040   u8 cos1 = 0;
9041   u8 cos2 = 0;
9042   u32 cos1_val = 0;
9043   u32 cos2_val = 0;
9044
9045   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9046     {
9047       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9048         src = 1;
9049       else
9050         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9051         dst = 1;
9052       else if (unformat (input, "proto %U",
9053                          unformat_ethernet_type_host_byte_order, &proto_val))
9054         proto = 1;
9055       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9056         tag1 = 1;
9057       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9058         tag2 = 1;
9059       else if (unformat (input, "ignore-tag1"))
9060         ignore_tag1 = 1;
9061       else if (unformat (input, "ignore-tag2"))
9062         ignore_tag2 = 1;
9063       else if (unformat (input, "cos1 %d", &cos1_val))
9064         cos1 = 1;
9065       else if (unformat (input, "cos2 %d", &cos2_val))
9066         cos2 = 1;
9067       else
9068         break;
9069     }
9070   if ((src + dst + proto + tag1 + tag2 +
9071        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9072     return 0;
9073
9074   if (tag1 || ignore_tag1 || cos1)
9075     len = 18;
9076   if (tag2 || ignore_tag2 || cos2)
9077     len = 22;
9078
9079   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9080
9081   if (dst)
9082     clib_memcpy (match, dst_val, 6);
9083
9084   if (src)
9085     clib_memcpy (match + 6, src_val, 6);
9086
9087   if (tag2)
9088     {
9089       /* inner vlan tag */
9090       match[19] = tag2_val[1];
9091       match[18] = tag2_val[0];
9092       if (cos2)
9093         match[18] |= (cos2_val & 0x7) << 5;
9094       if (proto)
9095         {
9096           match[21] = proto_val & 0xff;
9097           match[20] = proto_val >> 8;
9098         }
9099       if (tag1)
9100         {
9101           match[15] = tag1_val[1];
9102           match[14] = tag1_val[0];
9103         }
9104       if (cos1)
9105         match[14] |= (cos1_val & 0x7) << 5;
9106       *matchp = match;
9107       return 1;
9108     }
9109   if (tag1)
9110     {
9111       match[15] = tag1_val[1];
9112       match[14] = tag1_val[0];
9113       if (proto)
9114         {
9115           match[17] = proto_val & 0xff;
9116           match[16] = proto_val >> 8;
9117         }
9118       if (cos1)
9119         match[14] |= (cos1_val & 0x7) << 5;
9120
9121       *matchp = match;
9122       return 1;
9123     }
9124   if (cos2)
9125     match[18] |= (cos2_val & 0x7) << 5;
9126   if (cos1)
9127     match[14] |= (cos1_val & 0x7) << 5;
9128   if (proto)
9129     {
9130       match[13] = proto_val & 0xff;
9131       match[12] = proto_val >> 8;
9132     }
9133
9134   *matchp = match;
9135   return 1;
9136 }
9137
9138
9139 uword
9140 unformat_classify_match (unformat_input_t * input, va_list * args)
9141 {
9142   u8 **matchp = va_arg (*args, u8 **);
9143   u32 skip_n_vectors = va_arg (*args, u32);
9144   u32 match_n_vectors = va_arg (*args, u32);
9145
9146   u8 *match = 0;
9147   u8 *l2 = 0;
9148   u8 *l3 = 0;
9149   u8 *l4 = 0;
9150
9151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9152     {
9153       if (unformat (input, "hex %U", unformat_hex_string, &match))
9154         ;
9155       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9156         ;
9157       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9158         ;
9159       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9160         ;
9161       else
9162         break;
9163     }
9164
9165   if (l4 && !l3)
9166     {
9167       vec_free (match);
9168       vec_free (l2);
9169       vec_free (l4);
9170       return 0;
9171     }
9172
9173   if (match || l2 || l3 || l4)
9174     {
9175       if (l2 || l3 || l4)
9176         {
9177           /* "Win a free Ethernet header in every packet" */
9178           if (l2 == 0)
9179             vec_validate_aligned (l2, 13, sizeof (u32x4));
9180           match = l2;
9181           if (vec_len (l3))
9182             {
9183               vec_append_aligned (match, l3, sizeof (u32x4));
9184               vec_free (l3);
9185             }
9186           if (vec_len (l4))
9187             {
9188               vec_append_aligned (match, l4, sizeof (u32x4));
9189               vec_free (l4);
9190             }
9191         }
9192
9193       /* Make sure the vector is big enough even if key is all 0's */
9194       vec_validate_aligned
9195         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9196          sizeof (u32x4));
9197
9198       /* Set size, include skipped vectors */
9199       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9200
9201       *matchp = match;
9202
9203       return 1;
9204     }
9205
9206   return 0;
9207 }
9208
9209 static int
9210 api_classify_add_del_session (vat_main_t * vam)
9211 {
9212   unformat_input_t *i = vam->input;
9213   vl_api_classify_add_del_session_t *mp;
9214   int is_add = 1;
9215   u32 table_index = ~0;
9216   u32 hit_next_index = ~0;
9217   u32 opaque_index = ~0;
9218   u8 *match = 0;
9219   i32 advance = 0;
9220   f64 timeout;
9221   u32 skip_n_vectors = 0;
9222   u32 match_n_vectors = 0;
9223
9224   /*
9225    * Warning: you have to supply skip_n and match_n
9226    * because the API client cant simply look at the classify
9227    * table object.
9228    */
9229
9230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9231     {
9232       if (unformat (i, "del"))
9233         is_add = 0;
9234       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9235                          &hit_next_index))
9236         ;
9237       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9238                          &hit_next_index))
9239         ;
9240       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9241                          &hit_next_index))
9242         ;
9243       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9244         ;
9245       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9246         ;
9247       else if (unformat (i, "opaque-index %d", &opaque_index))
9248         ;
9249       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9250         ;
9251       else if (unformat (i, "match_n %d", &match_n_vectors))
9252         ;
9253       else if (unformat (i, "match %U", unformat_classify_match,
9254                          &match, skip_n_vectors, match_n_vectors))
9255         ;
9256       else if (unformat (i, "advance %d", &advance))
9257         ;
9258       else if (unformat (i, "table-index %d", &table_index))
9259         ;
9260       else
9261         break;
9262     }
9263
9264   if (table_index == ~0)
9265     {
9266       errmsg ("Table index required\n");
9267       return -99;
9268     }
9269
9270   if (is_add && match == 0)
9271     {
9272       errmsg ("Match value required\n");
9273       return -99;
9274     }
9275
9276   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9277
9278   mp->is_add = is_add;
9279   mp->table_index = ntohl (table_index);
9280   mp->hit_next_index = ntohl (hit_next_index);
9281   mp->opaque_index = ntohl (opaque_index);
9282   mp->advance = ntohl (advance);
9283   clib_memcpy (mp->match, match, vec_len (match));
9284   vec_free (match);
9285
9286   S;
9287   W;
9288   /* NOTREACHED */
9289 }
9290
9291 static int
9292 api_classify_set_interface_ip_table (vat_main_t * vam)
9293 {
9294   unformat_input_t *i = vam->input;
9295   vl_api_classify_set_interface_ip_table_t *mp;
9296   f64 timeout;
9297   u32 sw_if_index;
9298   int sw_if_index_set;
9299   u32 table_index = ~0;
9300   u8 is_ipv6 = 0;
9301
9302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9303     {
9304       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9305         sw_if_index_set = 1;
9306       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9307         sw_if_index_set = 1;
9308       else if (unformat (i, "table %d", &table_index))
9309         ;
9310       else
9311         {
9312           clib_warning ("parse error '%U'", format_unformat_error, i);
9313           return -99;
9314         }
9315     }
9316
9317   if (sw_if_index_set == 0)
9318     {
9319       errmsg ("missing interface name or sw_if_index\n");
9320       return -99;
9321     }
9322
9323
9324   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9325
9326   mp->sw_if_index = ntohl (sw_if_index);
9327   mp->table_index = ntohl (table_index);
9328   mp->is_ipv6 = is_ipv6;
9329
9330   S;
9331   W;
9332   /* NOTREACHED */
9333   return 0;
9334 }
9335
9336 static int
9337 api_classify_set_interface_l2_tables (vat_main_t * vam)
9338 {
9339   unformat_input_t *i = vam->input;
9340   vl_api_classify_set_interface_l2_tables_t *mp;
9341   f64 timeout;
9342   u32 sw_if_index;
9343   int sw_if_index_set;
9344   u32 ip4_table_index = ~0;
9345   u32 ip6_table_index = ~0;
9346   u32 other_table_index = ~0;
9347   u32 is_input = 1;
9348
9349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9350     {
9351       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9352         sw_if_index_set = 1;
9353       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9354         sw_if_index_set = 1;
9355       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9356         ;
9357       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9358         ;
9359       else if (unformat (i, "other-table %d", &other_table_index))
9360         ;
9361       else if (unformat (i, "is-input %d", &is_input))
9362         ;
9363       else
9364         {
9365           clib_warning ("parse error '%U'", format_unformat_error, i);
9366           return -99;
9367         }
9368     }
9369
9370   if (sw_if_index_set == 0)
9371     {
9372       errmsg ("missing interface name or sw_if_index\n");
9373       return -99;
9374     }
9375
9376
9377   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9378
9379   mp->sw_if_index = ntohl (sw_if_index);
9380   mp->ip4_table_index = ntohl (ip4_table_index);
9381   mp->ip6_table_index = ntohl (ip6_table_index);
9382   mp->other_table_index = ntohl (other_table_index);
9383   mp->is_input = (u8) is_input;
9384
9385   S;
9386   W;
9387   /* NOTREACHED */
9388   return 0;
9389 }
9390
9391 static int
9392 api_set_ipfix_exporter (vat_main_t * vam)
9393 {
9394   unformat_input_t *i = vam->input;
9395   vl_api_set_ipfix_exporter_t *mp;
9396   ip4_address_t collector_address;
9397   u8 collector_address_set = 0;
9398   u32 collector_port = ~0;
9399   ip4_address_t src_address;
9400   u8 src_address_set = 0;
9401   u32 vrf_id = ~0;
9402   u32 path_mtu = ~0;
9403   u32 template_interval = ~0;
9404   u8 udp_checksum = 0;
9405   f64 timeout;
9406
9407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9408     {
9409       if (unformat (i, "collector_address %U", unformat_ip4_address,
9410                     &collector_address))
9411         collector_address_set = 1;
9412       else if (unformat (i, "collector_port %d", &collector_port))
9413         ;
9414       else if (unformat (i, "src_address %U", unformat_ip4_address,
9415                          &src_address))
9416         src_address_set = 1;
9417       else if (unformat (i, "vrf_id %d", &vrf_id))
9418         ;
9419       else if (unformat (i, "path_mtu %d", &path_mtu))
9420         ;
9421       else if (unformat (i, "template_interval %d", &template_interval))
9422         ;
9423       else if (unformat (i, "udp_checksum"))
9424         udp_checksum = 1;
9425       else
9426         break;
9427     }
9428
9429   if (collector_address_set == 0)
9430     {
9431       errmsg ("collector_address required\n");
9432       return -99;
9433     }
9434
9435   if (src_address_set == 0)
9436     {
9437       errmsg ("src_address required\n");
9438       return -99;
9439     }
9440
9441   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9442
9443   memcpy (mp->collector_address, collector_address.data,
9444           sizeof (collector_address.data));
9445   mp->collector_port = htons ((u16) collector_port);
9446   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9447   mp->vrf_id = htonl (vrf_id);
9448   mp->path_mtu = htonl (path_mtu);
9449   mp->template_interval = htonl (template_interval);
9450   mp->udp_checksum = udp_checksum;
9451
9452   S;
9453   W;
9454   /* NOTREACHED */
9455 }
9456
9457 static int
9458 api_set_ipfix_classify_stream (vat_main_t * vam)
9459 {
9460   unformat_input_t *i = vam->input;
9461   vl_api_set_ipfix_classify_stream_t *mp;
9462   u32 domain_id = 0;
9463   u32 src_port = UDP_DST_PORT_ipfix;
9464   f64 timeout;
9465
9466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9467     {
9468       if (unformat (i, "domain %d", &domain_id))
9469         ;
9470       else if (unformat (i, "src_port %d", &src_port))
9471         ;
9472       else
9473         {
9474           errmsg ("unknown input `%U'", format_unformat_error, i);
9475           return -99;
9476         }
9477     }
9478
9479   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9480
9481   mp->domain_id = htonl (domain_id);
9482   mp->src_port = htons ((u16) src_port);
9483
9484   S;
9485   W;
9486   /* NOTREACHED */
9487 }
9488
9489 static int
9490 api_ipfix_classify_table_add_del (vat_main_t * vam)
9491 {
9492   unformat_input_t *i = vam->input;
9493   vl_api_ipfix_classify_table_add_del_t *mp;
9494   int is_add = -1;
9495   u32 classify_table_index = ~0;
9496   u8 ip_version = 0;
9497   u8 transport_protocol = 255;
9498   f64 timeout;
9499
9500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9501     {
9502       if (unformat (i, "add"))
9503         is_add = 1;
9504       else if (unformat (i, "del"))
9505         is_add = 0;
9506       else if (unformat (i, "table %d", &classify_table_index))
9507         ;
9508       else if (unformat (i, "ip4"))
9509         ip_version = 4;
9510       else if (unformat (i, "ip6"))
9511         ip_version = 6;
9512       else if (unformat (i, "tcp"))
9513         transport_protocol = 6;
9514       else if (unformat (i, "udp"))
9515         transport_protocol = 17;
9516       else
9517         {
9518           errmsg ("unknown input `%U'", format_unformat_error, i);
9519           return -99;
9520         }
9521     }
9522
9523   if (is_add == -1)
9524     {
9525       errmsg ("expecting: add|del");
9526       return -99;
9527     }
9528   if (classify_table_index == ~0)
9529     {
9530       errmsg ("classifier table not specified");
9531       return -99;
9532     }
9533   if (ip_version == 0)
9534     {
9535       errmsg ("IP version not specified");
9536       return -99;
9537     }
9538
9539   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9540
9541   mp->is_add = is_add;
9542   mp->table_id = htonl (classify_table_index);
9543   mp->ip_version = ip_version;
9544   mp->transport_protocol = transport_protocol;
9545
9546   S;
9547   W;
9548   /* NOTREACHED */
9549 }
9550
9551 static int
9552 api_get_node_index (vat_main_t * vam)
9553 {
9554   unformat_input_t *i = vam->input;
9555   vl_api_get_node_index_t *mp;
9556   f64 timeout;
9557   u8 *name = 0;
9558
9559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9560     {
9561       if (unformat (i, "node %s", &name))
9562         ;
9563       else
9564         break;
9565     }
9566   if (name == 0)
9567     {
9568       errmsg ("node name required\n");
9569       return -99;
9570     }
9571   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9572     {
9573       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9574       return -99;
9575     }
9576
9577   M (GET_NODE_INDEX, get_node_index);
9578   clib_memcpy (mp->node_name, name, vec_len (name));
9579   vec_free (name);
9580
9581   S;
9582   W;
9583   /* NOTREACHED */
9584   return 0;
9585 }
9586
9587 static int
9588 api_get_next_index (vat_main_t * vam)
9589 {
9590   unformat_input_t *i = vam->input;
9591   vl_api_get_next_index_t *mp;
9592   f64 timeout;
9593   u8 *node_name = 0, *next_node_name = 0;
9594
9595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9596     {
9597       if (unformat (i, "node-name %s", &node_name))
9598         ;
9599       else if (unformat (i, "next-node-name %s", &next_node_name))
9600         break;
9601     }
9602
9603   if (node_name == 0)
9604     {
9605       errmsg ("node name required\n");
9606       return -99;
9607     }
9608   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9609     {
9610       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9611       return -99;
9612     }
9613
9614   if (next_node_name == 0)
9615     {
9616       errmsg ("next node name required\n");
9617       return -99;
9618     }
9619   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9620     {
9621       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9622       return -99;
9623     }
9624
9625   M (GET_NEXT_INDEX, get_next_index);
9626   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9627   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9628   vec_free (node_name);
9629   vec_free (next_node_name);
9630
9631   S;
9632   W;
9633   /* NOTREACHED */
9634   return 0;
9635 }
9636
9637 static int
9638 api_add_node_next (vat_main_t * vam)
9639 {
9640   unformat_input_t *i = vam->input;
9641   vl_api_add_node_next_t *mp;
9642   f64 timeout;
9643   u8 *name = 0;
9644   u8 *next = 0;
9645
9646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9647     {
9648       if (unformat (i, "node %s", &name))
9649         ;
9650       else if (unformat (i, "next %s", &next))
9651         ;
9652       else
9653         break;
9654     }
9655   if (name == 0)
9656     {
9657       errmsg ("node name required\n");
9658       return -99;
9659     }
9660   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9661     {
9662       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9663       return -99;
9664     }
9665   if (next == 0)
9666     {
9667       errmsg ("next node required\n");
9668       return -99;
9669     }
9670   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9671     {
9672       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9673       return -99;
9674     }
9675
9676   M (ADD_NODE_NEXT, add_node_next);
9677   clib_memcpy (mp->node_name, name, vec_len (name));
9678   clib_memcpy (mp->next_name, next, vec_len (next));
9679   vec_free (name);
9680   vec_free (next);
9681
9682   S;
9683   W;
9684   /* NOTREACHED */
9685   return 0;
9686 }
9687
9688 static int
9689 api_l2tpv3_create_tunnel (vat_main_t * vam)
9690 {
9691   unformat_input_t *i = vam->input;
9692   ip6_address_t client_address, our_address;
9693   int client_address_set = 0;
9694   int our_address_set = 0;
9695   u32 local_session_id = 0;
9696   u32 remote_session_id = 0;
9697   u64 local_cookie = 0;
9698   u64 remote_cookie = 0;
9699   u8 l2_sublayer_present = 0;
9700   vl_api_l2tpv3_create_tunnel_t *mp;
9701   f64 timeout;
9702
9703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9704     {
9705       if (unformat (i, "client_address %U", unformat_ip6_address,
9706                     &client_address))
9707         client_address_set = 1;
9708       else if (unformat (i, "our_address %U", unformat_ip6_address,
9709                          &our_address))
9710         our_address_set = 1;
9711       else if (unformat (i, "local_session_id %d", &local_session_id))
9712         ;
9713       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9714         ;
9715       else if (unformat (i, "local_cookie %lld", &local_cookie))
9716         ;
9717       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9718         ;
9719       else if (unformat (i, "l2-sublayer-present"))
9720         l2_sublayer_present = 1;
9721       else
9722         break;
9723     }
9724
9725   if (client_address_set == 0)
9726     {
9727       errmsg ("client_address required\n");
9728       return -99;
9729     }
9730
9731   if (our_address_set == 0)
9732     {
9733       errmsg ("our_address required\n");
9734       return -99;
9735     }
9736
9737   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9738
9739   clib_memcpy (mp->client_address, client_address.as_u8,
9740                sizeof (mp->client_address));
9741
9742   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9743
9744   mp->local_session_id = ntohl (local_session_id);
9745   mp->remote_session_id = ntohl (remote_session_id);
9746   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9747   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9748   mp->l2_sublayer_present = l2_sublayer_present;
9749   mp->is_ipv6 = 1;
9750
9751   S;
9752   W;
9753   /* NOTREACHED */
9754   return 0;
9755 }
9756
9757 static int
9758 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9759 {
9760   unformat_input_t *i = vam->input;
9761   u32 sw_if_index;
9762   u8 sw_if_index_set = 0;
9763   u64 new_local_cookie = 0;
9764   u64 new_remote_cookie = 0;
9765   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9766   f64 timeout;
9767
9768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9769     {
9770       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9771         sw_if_index_set = 1;
9772       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9773         sw_if_index_set = 1;
9774       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9775         ;
9776       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9777         ;
9778       else
9779         break;
9780     }
9781
9782   if (sw_if_index_set == 0)
9783     {
9784       errmsg ("missing interface name or sw_if_index\n");
9785       return -99;
9786     }
9787
9788   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9789
9790   mp->sw_if_index = ntohl (sw_if_index);
9791   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9792   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9793
9794   S;
9795   W;
9796   /* NOTREACHED */
9797   return 0;
9798 }
9799
9800 static int
9801 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9802 {
9803   unformat_input_t *i = vam->input;
9804   vl_api_l2tpv3_interface_enable_disable_t *mp;
9805   f64 timeout;
9806   u32 sw_if_index;
9807   u8 sw_if_index_set = 0;
9808   u8 enable_disable = 1;
9809
9810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9813         sw_if_index_set = 1;
9814       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9815         sw_if_index_set = 1;
9816       else if (unformat (i, "enable"))
9817         enable_disable = 1;
9818       else if (unformat (i, "disable"))
9819         enable_disable = 0;
9820       else
9821         break;
9822     }
9823
9824   if (sw_if_index_set == 0)
9825     {
9826       errmsg ("missing interface name or sw_if_index\n");
9827       return -99;
9828     }
9829
9830   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9831
9832   mp->sw_if_index = ntohl (sw_if_index);
9833   mp->enable_disable = enable_disable;
9834
9835   S;
9836   W;
9837   /* NOTREACHED */
9838   return 0;
9839 }
9840
9841 static int
9842 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9843 {
9844   unformat_input_t *i = vam->input;
9845   vl_api_l2tpv3_set_lookup_key_t *mp;
9846   f64 timeout;
9847   u8 key = ~0;
9848
9849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9850     {
9851       if (unformat (i, "lookup_v6_src"))
9852         key = L2T_LOOKUP_SRC_ADDRESS;
9853       else if (unformat (i, "lookup_v6_dst"))
9854         key = L2T_LOOKUP_DST_ADDRESS;
9855       else if (unformat (i, "lookup_session_id"))
9856         key = L2T_LOOKUP_SESSION_ID;
9857       else
9858         break;
9859     }
9860
9861   if (key == (u8) ~ 0)
9862     {
9863       errmsg ("l2tp session lookup key unset\n");
9864       return -99;
9865     }
9866
9867   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9868
9869   mp->key = key;
9870
9871   S;
9872   W;
9873   /* NOTREACHED */
9874   return 0;
9875 }
9876
9877 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9878   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9879 {
9880   vat_main_t *vam = &vat_main;
9881
9882   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9883            format_ip6_address, mp->our_address,
9884            format_ip6_address, mp->client_address,
9885            clib_net_to_host_u32 (mp->sw_if_index));
9886
9887   fformat (vam->ofp,
9888            "   local cookies %016llx %016llx remote cookie %016llx\n",
9889            clib_net_to_host_u64 (mp->local_cookie[0]),
9890            clib_net_to_host_u64 (mp->local_cookie[1]),
9891            clib_net_to_host_u64 (mp->remote_cookie));
9892
9893   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9894            clib_net_to_host_u32 (mp->local_session_id),
9895            clib_net_to_host_u32 (mp->remote_session_id));
9896
9897   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9898            mp->l2_sublayer_present ? "preset" : "absent");
9899
9900 }
9901
9902 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9903   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9904 {
9905   vat_main_t *vam = &vat_main;
9906   vat_json_node_t *node = NULL;
9907   struct in6_addr addr;
9908
9909   if (VAT_JSON_ARRAY != vam->json_tree.type)
9910     {
9911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9912       vat_json_init_array (&vam->json_tree);
9913     }
9914   node = vat_json_array_add (&vam->json_tree);
9915
9916   vat_json_init_object (node);
9917
9918   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9919   vat_json_object_add_ip6 (node, "our_address", addr);
9920   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9921   vat_json_object_add_ip6 (node, "client_address", addr);
9922
9923   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9924   vat_json_init_array (lc);
9925   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9926   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9927   vat_json_object_add_uint (node, "remote_cookie",
9928                             clib_net_to_host_u64 (mp->remote_cookie));
9929
9930   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9931   vat_json_object_add_uint (node, "local_session_id",
9932                             clib_net_to_host_u32 (mp->local_session_id));
9933   vat_json_object_add_uint (node, "remote_session_id",
9934                             clib_net_to_host_u32 (mp->remote_session_id));
9935   vat_json_object_add_string_copy (node, "l2_sublayer",
9936                                    mp->l2_sublayer_present ? (u8 *) "present"
9937                                    : (u8 *) "absent");
9938 }
9939
9940 static int
9941 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9942 {
9943   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9944   f64 timeout;
9945
9946   /* Get list of l2tpv3-tunnel interfaces */
9947   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9948   S;
9949
9950   /* Use a control ping for synchronization */
9951   {
9952     vl_api_control_ping_t *mp;
9953     M (CONTROL_PING, control_ping);
9954     S;
9955   }
9956   W;
9957 }
9958
9959
9960 static void vl_api_sw_interface_tap_details_t_handler
9961   (vl_api_sw_interface_tap_details_t * mp)
9962 {
9963   vat_main_t *vam = &vat_main;
9964
9965   fformat (vam->ofp, "%-16s %d\n",
9966            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9967 }
9968
9969 static void vl_api_sw_interface_tap_details_t_handler_json
9970   (vl_api_sw_interface_tap_details_t * mp)
9971 {
9972   vat_main_t *vam = &vat_main;
9973   vat_json_node_t *node = NULL;
9974
9975   if (VAT_JSON_ARRAY != vam->json_tree.type)
9976     {
9977       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9978       vat_json_init_array (&vam->json_tree);
9979     }
9980   node = vat_json_array_add (&vam->json_tree);
9981
9982   vat_json_init_object (node);
9983   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9984   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9985 }
9986
9987 static int
9988 api_sw_interface_tap_dump (vat_main_t * vam)
9989 {
9990   vl_api_sw_interface_tap_dump_t *mp;
9991   f64 timeout;
9992
9993   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9994   /* Get list of tap interfaces */
9995   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9996   S;
9997
9998   /* Use a control ping for synchronization */
9999   {
10000     vl_api_control_ping_t *mp;
10001     M (CONTROL_PING, control_ping);
10002     S;
10003   }
10004   W;
10005 }
10006
10007 static uword unformat_vxlan_decap_next
10008   (unformat_input_t * input, va_list * args)
10009 {
10010   u32 *result = va_arg (*args, u32 *);
10011   u32 tmp;
10012
10013   if (unformat (input, "drop"))
10014     *result = VXLAN_INPUT_NEXT_DROP;
10015   else if (unformat (input, "ip4"))
10016     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
10017   else if (unformat (input, "ip6"))
10018     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
10019   else if (unformat (input, "l2"))
10020     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10021   else if (unformat (input, "%d", &tmp))
10022     *result = tmp;
10023   else
10024     return 0;
10025   return 1;
10026 }
10027
10028 static int
10029 api_vxlan_add_del_tunnel (vat_main_t * vam)
10030 {
10031   unformat_input_t *line_input = vam->input;
10032   vl_api_vxlan_add_del_tunnel_t *mp;
10033   f64 timeout;
10034   ip4_address_t src4, dst4;
10035   ip6_address_t src6, dst6;
10036   u8 is_add = 1;
10037   u8 ipv4_set = 0, ipv6_set = 0;
10038   u8 src_set = 0;
10039   u8 dst_set = 0;
10040   u32 encap_vrf_id = 0;
10041   u32 decap_next_index = ~0;
10042   u32 vni = 0;
10043
10044   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10045     {
10046       if (unformat (line_input, "del"))
10047         is_add = 0;
10048       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10049         {
10050           ipv4_set = 1;
10051           src_set = 1;
10052         }
10053       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10054         {
10055           ipv4_set = 1;
10056           dst_set = 1;
10057         }
10058       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10059         {
10060           ipv6_set = 1;
10061           src_set = 1;
10062         }
10063       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10064         {
10065           ipv6_set = 1;
10066           dst_set = 1;
10067         }
10068       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10069         ;
10070       else if (unformat (line_input, "decap-next %U",
10071                          unformat_vxlan_decap_next, &decap_next_index))
10072         ;
10073       else if (unformat (line_input, "vni %d", &vni))
10074         ;
10075       else
10076         {
10077           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10078           return -99;
10079         }
10080     }
10081
10082   if (src_set == 0)
10083     {
10084       errmsg ("tunnel src address not specified\n");
10085       return -99;
10086     }
10087   if (dst_set == 0)
10088     {
10089       errmsg ("tunnel dst address not specified\n");
10090       return -99;
10091     }
10092
10093   if (ipv4_set && ipv6_set)
10094     {
10095       errmsg ("both IPv4 and IPv6 addresses specified");
10096       return -99;
10097     }
10098
10099   if ((vni == 0) || (vni >> 24))
10100     {
10101       errmsg ("vni not specified or out of range\n");
10102       return -99;
10103     }
10104
10105   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10106
10107   if (ipv6_set)
10108     {
10109       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10110       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10111     }
10112   else
10113     {
10114       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10115       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10116     }
10117   mp->encap_vrf_id = ntohl (encap_vrf_id);
10118   mp->decap_next_index = ntohl (decap_next_index);
10119   mp->vni = ntohl (vni);
10120   mp->is_add = is_add;
10121   mp->is_ipv6 = ipv6_set;
10122
10123   S;
10124   W;
10125   /* NOTREACHED */
10126   return 0;
10127 }
10128
10129 static void vl_api_vxlan_tunnel_details_t_handler
10130   (vl_api_vxlan_tunnel_details_t * mp)
10131 {
10132   vat_main_t *vam = &vat_main;
10133
10134   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10135            ntohl (mp->sw_if_index),
10136            format_ip46_address, &(mp->src_address[0]),
10137            IP46_TYPE_ANY,
10138            format_ip46_address, &(mp->dst_address[0]),
10139            IP46_TYPE_ANY,
10140            ntohl (mp->encap_vrf_id),
10141            ntohl (mp->decap_next_index), ntohl (mp->vni));
10142 }
10143
10144 static void vl_api_vxlan_tunnel_details_t_handler_json
10145   (vl_api_vxlan_tunnel_details_t * mp)
10146 {
10147   vat_main_t *vam = &vat_main;
10148   vat_json_node_t *node = NULL;
10149   struct in_addr ip4;
10150   struct in6_addr ip6;
10151
10152   if (VAT_JSON_ARRAY != vam->json_tree.type)
10153     {
10154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10155       vat_json_init_array (&vam->json_tree);
10156     }
10157   node = vat_json_array_add (&vam->json_tree);
10158
10159   vat_json_init_object (node);
10160   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10161   if (mp->is_ipv6)
10162     {
10163       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10164       vat_json_object_add_ip6 (node, "src_address", ip6);
10165       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10166       vat_json_object_add_ip6 (node, "dst_address", ip6);
10167     }
10168   else
10169     {
10170       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10171       vat_json_object_add_ip4 (node, "src_address", ip4);
10172       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10173       vat_json_object_add_ip4 (node, "dst_address", ip4);
10174     }
10175   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10176   vat_json_object_add_uint (node, "decap_next_index",
10177                             ntohl (mp->decap_next_index));
10178   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10179   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10180 }
10181
10182 static int
10183 api_vxlan_tunnel_dump (vat_main_t * vam)
10184 {
10185   unformat_input_t *i = vam->input;
10186   vl_api_vxlan_tunnel_dump_t *mp;
10187   f64 timeout;
10188   u32 sw_if_index;
10189   u8 sw_if_index_set = 0;
10190
10191   /* Parse args required to build the message */
10192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10193     {
10194       if (unformat (i, "sw_if_index %d", &sw_if_index))
10195         sw_if_index_set = 1;
10196       else
10197         break;
10198     }
10199
10200   if (sw_if_index_set == 0)
10201     {
10202       sw_if_index = ~0;
10203     }
10204
10205   if (!vam->json_output)
10206     {
10207       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10208                "sw_if_index", "src_address", "dst_address",
10209                "encap_vrf_id", "decap_next_index", "vni");
10210     }
10211
10212   /* Get list of vxlan-tunnel interfaces */
10213   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10214
10215   mp->sw_if_index = htonl (sw_if_index);
10216
10217   S;
10218
10219   /* Use a control ping for synchronization */
10220   {
10221     vl_api_control_ping_t *mp;
10222     M (CONTROL_PING, control_ping);
10223     S;
10224   }
10225   W;
10226 }
10227
10228 static int
10229 api_gre_add_del_tunnel (vat_main_t * vam)
10230 {
10231   unformat_input_t *line_input = vam->input;
10232   vl_api_gre_add_del_tunnel_t *mp;
10233   f64 timeout;
10234   ip4_address_t src4, dst4;
10235   u8 is_add = 1;
10236   u8 teb = 0;
10237   u8 src_set = 0;
10238   u8 dst_set = 0;
10239   u32 outer_fib_id = 0;
10240
10241   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10242     {
10243       if (unformat (line_input, "del"))
10244         is_add = 0;
10245       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10246         src_set = 1;
10247       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10248         dst_set = 1;
10249       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10250         ;
10251       else if (unformat (line_input, "teb"))
10252         teb = 1;
10253       else
10254         {
10255           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10256           return -99;
10257         }
10258     }
10259
10260   if (src_set == 0)
10261     {
10262       errmsg ("tunnel src address not specified\n");
10263       return -99;
10264     }
10265   if (dst_set == 0)
10266     {
10267       errmsg ("tunnel dst address not specified\n");
10268       return -99;
10269     }
10270
10271
10272   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10273
10274   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10275   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10276   mp->outer_fib_id = ntohl (outer_fib_id);
10277   mp->is_add = is_add;
10278   mp->teb = teb;
10279
10280   S;
10281   W;
10282   /* NOTREACHED */
10283   return 0;
10284 }
10285
10286 static void vl_api_gre_tunnel_details_t_handler
10287   (vl_api_gre_tunnel_details_t * mp)
10288 {
10289   vat_main_t *vam = &vat_main;
10290
10291   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10292            ntohl (mp->sw_if_index),
10293            format_ip4_address, &mp->src_address,
10294            format_ip4_address, &mp->dst_address,
10295            mp->teb, ntohl (mp->outer_fib_id));
10296 }
10297
10298 static void vl_api_gre_tunnel_details_t_handler_json
10299   (vl_api_gre_tunnel_details_t * mp)
10300 {
10301   vat_main_t *vam = &vat_main;
10302   vat_json_node_t *node = NULL;
10303   struct in_addr ip4;
10304
10305   if (VAT_JSON_ARRAY != vam->json_tree.type)
10306     {
10307       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10308       vat_json_init_array (&vam->json_tree);
10309     }
10310   node = vat_json_array_add (&vam->json_tree);
10311
10312   vat_json_init_object (node);
10313   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10314   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10315   vat_json_object_add_ip4 (node, "src_address", ip4);
10316   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10317   vat_json_object_add_ip4 (node, "dst_address", ip4);
10318   vat_json_object_add_uint (node, "teb", mp->teb);
10319   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10320 }
10321
10322 static int
10323 api_gre_tunnel_dump (vat_main_t * vam)
10324 {
10325   unformat_input_t *i = vam->input;
10326   vl_api_gre_tunnel_dump_t *mp;
10327   f64 timeout;
10328   u32 sw_if_index;
10329   u8 sw_if_index_set = 0;
10330
10331   /* Parse args required to build the message */
10332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10333     {
10334       if (unformat (i, "sw_if_index %d", &sw_if_index))
10335         sw_if_index_set = 1;
10336       else
10337         break;
10338     }
10339
10340   if (sw_if_index_set == 0)
10341     {
10342       sw_if_index = ~0;
10343     }
10344
10345   if (!vam->json_output)
10346     {
10347       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10348                "sw_if_index", "src_address", "dst_address", "teb",
10349                "outer_fib_id");
10350     }
10351
10352   /* Get list of gre-tunnel interfaces */
10353   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10354
10355   mp->sw_if_index = htonl (sw_if_index);
10356
10357   S;
10358
10359   /* Use a control ping for synchronization */
10360   {
10361     vl_api_control_ping_t *mp;
10362     M (CONTROL_PING, control_ping);
10363     S;
10364   }
10365   W;
10366 }
10367
10368 static int
10369 api_l2_fib_clear_table (vat_main_t * vam)
10370 {
10371 //  unformat_input_t * i = vam->input;
10372   vl_api_l2_fib_clear_table_t *mp;
10373   f64 timeout;
10374
10375   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10376
10377   S;
10378   W;
10379   /* NOTREACHED */
10380   return 0;
10381 }
10382
10383 static int
10384 api_l2_interface_efp_filter (vat_main_t * vam)
10385 {
10386   unformat_input_t *i = vam->input;
10387   vl_api_l2_interface_efp_filter_t *mp;
10388   f64 timeout;
10389   u32 sw_if_index;
10390   u8 enable = 1;
10391   u8 sw_if_index_set = 0;
10392
10393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10394     {
10395       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10396         sw_if_index_set = 1;
10397       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10398         sw_if_index_set = 1;
10399       else if (unformat (i, "enable"))
10400         enable = 1;
10401       else if (unformat (i, "disable"))
10402         enable = 0;
10403       else
10404         {
10405           clib_warning ("parse error '%U'", format_unformat_error, i);
10406           return -99;
10407         }
10408     }
10409
10410   if (sw_if_index_set == 0)
10411     {
10412       errmsg ("missing sw_if_index\n");
10413       return -99;
10414     }
10415
10416   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10417
10418   mp->sw_if_index = ntohl (sw_if_index);
10419   mp->enable_disable = enable;
10420
10421   S;
10422   W;
10423   /* NOTREACHED */
10424   return 0;
10425 }
10426
10427 #define foreach_vtr_op                          \
10428 _("disable",  L2_VTR_DISABLED)                  \
10429 _("push-1",  L2_VTR_PUSH_1)                     \
10430 _("push-2",  L2_VTR_PUSH_2)                     \
10431 _("pop-1",  L2_VTR_POP_1)                       \
10432 _("pop-2",  L2_VTR_POP_2)                       \
10433 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10434 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10435 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10436 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10437
10438 static int
10439 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10440 {
10441   unformat_input_t *i = vam->input;
10442   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10443   f64 timeout;
10444   u32 sw_if_index;
10445   u8 sw_if_index_set = 0;
10446   u8 vtr_op_set = 0;
10447   u32 vtr_op = 0;
10448   u32 push_dot1q = 1;
10449   u32 tag1 = ~0;
10450   u32 tag2 = ~0;
10451
10452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10453     {
10454       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10455         sw_if_index_set = 1;
10456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10457         sw_if_index_set = 1;
10458       else if (unformat (i, "vtr_op %d", &vtr_op))
10459         vtr_op_set = 1;
10460 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10461       foreach_vtr_op
10462 #undef _
10463         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10464         ;
10465       else if (unformat (i, "tag1 %d", &tag1))
10466         ;
10467       else if (unformat (i, "tag2 %d", &tag2))
10468         ;
10469       else
10470         {
10471           clib_warning ("parse error '%U'", format_unformat_error, i);
10472           return -99;
10473         }
10474     }
10475
10476   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10477     {
10478       errmsg ("missing vtr operation or sw_if_index\n");
10479       return -99;
10480     }
10481
10482   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10483     mp->sw_if_index = ntohl (sw_if_index);
10484   mp->vtr_op = ntohl (vtr_op);
10485   mp->push_dot1q = ntohl (push_dot1q);
10486   mp->tag1 = ntohl (tag1);
10487   mp->tag2 = ntohl (tag2);
10488
10489   S;
10490   W;
10491   /* NOTREACHED */
10492   return 0;
10493 }
10494
10495 static int
10496 api_create_vhost_user_if (vat_main_t * vam)
10497 {
10498   unformat_input_t *i = vam->input;
10499   vl_api_create_vhost_user_if_t *mp;
10500   f64 timeout;
10501   u8 *file_name;
10502   u8 is_server = 0;
10503   u8 file_name_set = 0;
10504   u32 custom_dev_instance = ~0;
10505   u8 hwaddr[6];
10506   u8 use_custom_mac = 0;
10507
10508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10509     {
10510       if (unformat (i, "socket %s", &file_name))
10511         {
10512           file_name_set = 1;
10513         }
10514       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10515         ;
10516       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10517         use_custom_mac = 1;
10518       else if (unformat (i, "server"))
10519         is_server = 1;
10520       else
10521         break;
10522     }
10523
10524   if (file_name_set == 0)
10525     {
10526       errmsg ("missing socket file name\n");
10527       return -99;
10528     }
10529
10530   if (vec_len (file_name) > 255)
10531     {
10532       errmsg ("socket file name too long\n");
10533       return -99;
10534     }
10535   vec_add1 (file_name, 0);
10536
10537   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10538
10539   mp->is_server = is_server;
10540   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10541   vec_free (file_name);
10542   if (custom_dev_instance != ~0)
10543     {
10544       mp->renumber = 1;
10545       mp->custom_dev_instance = ntohl (custom_dev_instance);
10546     }
10547   mp->use_custom_mac = use_custom_mac;
10548   clib_memcpy (mp->mac_address, hwaddr, 6);
10549
10550   S;
10551   W;
10552   /* NOTREACHED */
10553   return 0;
10554 }
10555
10556 static int
10557 api_modify_vhost_user_if (vat_main_t * vam)
10558 {
10559   unformat_input_t *i = vam->input;
10560   vl_api_modify_vhost_user_if_t *mp;
10561   f64 timeout;
10562   u8 *file_name;
10563   u8 is_server = 0;
10564   u8 file_name_set = 0;
10565   u32 custom_dev_instance = ~0;
10566   u8 sw_if_index_set = 0;
10567   u32 sw_if_index = (u32) ~ 0;
10568
10569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10570     {
10571       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10572         sw_if_index_set = 1;
10573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10574         sw_if_index_set = 1;
10575       else if (unformat (i, "socket %s", &file_name))
10576         {
10577           file_name_set = 1;
10578         }
10579       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10580         ;
10581       else if (unformat (i, "server"))
10582         is_server = 1;
10583       else
10584         break;
10585     }
10586
10587   if (sw_if_index_set == 0)
10588     {
10589       errmsg ("missing sw_if_index or interface name\n");
10590       return -99;
10591     }
10592
10593   if (file_name_set == 0)
10594     {
10595       errmsg ("missing socket file name\n");
10596       return -99;
10597     }
10598
10599   if (vec_len (file_name) > 255)
10600     {
10601       errmsg ("socket file name too long\n");
10602       return -99;
10603     }
10604   vec_add1 (file_name, 0);
10605
10606   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10607
10608   mp->sw_if_index = ntohl (sw_if_index);
10609   mp->is_server = is_server;
10610   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10611   vec_free (file_name);
10612   if (custom_dev_instance != ~0)
10613     {
10614       mp->renumber = 1;
10615       mp->custom_dev_instance = ntohl (custom_dev_instance);
10616     }
10617
10618   S;
10619   W;
10620   /* NOTREACHED */
10621   return 0;
10622 }
10623
10624 static int
10625 api_delete_vhost_user_if (vat_main_t * vam)
10626 {
10627   unformat_input_t *i = vam->input;
10628   vl_api_delete_vhost_user_if_t *mp;
10629   f64 timeout;
10630   u32 sw_if_index = ~0;
10631   u8 sw_if_index_set = 0;
10632
10633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10634     {
10635       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10636         sw_if_index_set = 1;
10637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10638         sw_if_index_set = 1;
10639       else
10640         break;
10641     }
10642
10643   if (sw_if_index_set == 0)
10644     {
10645       errmsg ("missing sw_if_index or interface name\n");
10646       return -99;
10647     }
10648
10649
10650   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10651
10652   mp->sw_if_index = ntohl (sw_if_index);
10653
10654   S;
10655   W;
10656   /* NOTREACHED */
10657   return 0;
10658 }
10659
10660 static void vl_api_sw_interface_vhost_user_details_t_handler
10661   (vl_api_sw_interface_vhost_user_details_t * mp)
10662 {
10663   vat_main_t *vam = &vat_main;
10664
10665   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10666            (char *) mp->interface_name,
10667            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10668            clib_net_to_host_u64 (mp->features), mp->is_server,
10669            ntohl (mp->num_regions), (char *) mp->sock_filename);
10670   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10671 }
10672
10673 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10674   (vl_api_sw_interface_vhost_user_details_t * mp)
10675 {
10676   vat_main_t *vam = &vat_main;
10677   vat_json_node_t *node = NULL;
10678
10679   if (VAT_JSON_ARRAY != vam->json_tree.type)
10680     {
10681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10682       vat_json_init_array (&vam->json_tree);
10683     }
10684   node = vat_json_array_add (&vam->json_tree);
10685
10686   vat_json_init_object (node);
10687   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10688   vat_json_object_add_string_copy (node, "interface_name",
10689                                    mp->interface_name);
10690   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10691                             ntohl (mp->virtio_net_hdr_sz));
10692   vat_json_object_add_uint (node, "features",
10693                             clib_net_to_host_u64 (mp->features));
10694   vat_json_object_add_uint (node, "is_server", mp->is_server);
10695   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10696   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10697   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10698 }
10699
10700 static int
10701 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10702 {
10703   vl_api_sw_interface_vhost_user_dump_t *mp;
10704   f64 timeout;
10705   fformat (vam->ofp,
10706            "Interface name           idx hdr_sz features server regions filename\n");
10707
10708   /* Get list of vhost-user interfaces */
10709   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10710   S;
10711
10712   /* Use a control ping for synchronization */
10713   {
10714     vl_api_control_ping_t *mp;
10715     M (CONTROL_PING, control_ping);
10716     S;
10717   }
10718   W;
10719 }
10720
10721 static int
10722 api_show_version (vat_main_t * vam)
10723 {
10724   vl_api_show_version_t *mp;
10725   f64 timeout;
10726
10727   M (SHOW_VERSION, show_version);
10728
10729   S;
10730   W;
10731   /* NOTREACHED */
10732   return 0;
10733 }
10734
10735
10736 static int
10737 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10738 {
10739   unformat_input_t *line_input = vam->input;
10740   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10741   f64 timeout;
10742   ip4_address_t local4, remote4;
10743   ip6_address_t local6, remote6;
10744   u8 is_add = 1;
10745   u8 ipv4_set = 0, ipv6_set = 0;
10746   u8 local_set = 0;
10747   u8 remote_set = 0;
10748   u32 encap_vrf_id = 0;
10749   u32 decap_vrf_id = 0;
10750   u8 protocol = ~0;
10751   u32 vni;
10752   u8 vni_set = 0;
10753
10754   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10755     {
10756       if (unformat (line_input, "del"))
10757         is_add = 0;
10758       else if (unformat (line_input, "local %U",
10759                          unformat_ip4_address, &local4))
10760         {
10761           local_set = 1;
10762           ipv4_set = 1;
10763         }
10764       else if (unformat (line_input, "remote %U",
10765                          unformat_ip4_address, &remote4))
10766         {
10767           remote_set = 1;
10768           ipv4_set = 1;
10769         }
10770       else if (unformat (line_input, "local %U",
10771                          unformat_ip6_address, &local6))
10772         {
10773           local_set = 1;
10774           ipv6_set = 1;
10775         }
10776       else if (unformat (line_input, "remote %U",
10777                          unformat_ip6_address, &remote6))
10778         {
10779           remote_set = 1;
10780           ipv6_set = 1;
10781         }
10782       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10783         ;
10784       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10785         ;
10786       else if (unformat (line_input, "vni %d", &vni))
10787         vni_set = 1;
10788       else if (unformat (line_input, "next-ip4"))
10789         protocol = 1;
10790       else if (unformat (line_input, "next-ip6"))
10791         protocol = 2;
10792       else if (unformat (line_input, "next-ethernet"))
10793         protocol = 3;
10794       else if (unformat (line_input, "next-nsh"))
10795         protocol = 4;
10796       else
10797         {
10798           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10799           return -99;
10800         }
10801     }
10802
10803   if (local_set == 0)
10804     {
10805       errmsg ("tunnel local address not specified\n");
10806       return -99;
10807     }
10808   if (remote_set == 0)
10809     {
10810       errmsg ("tunnel remote address not specified\n");
10811       return -99;
10812     }
10813   if (ipv4_set && ipv6_set)
10814     {
10815       errmsg ("both IPv4 and IPv6 addresses specified");
10816       return -99;
10817     }
10818
10819   if (vni_set == 0)
10820     {
10821       errmsg ("vni not specified\n");
10822       return -99;
10823     }
10824
10825   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10826
10827
10828   if (ipv6_set)
10829     {
10830       clib_memcpy (&mp->local, &local6, sizeof (local6));
10831       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10832     }
10833   else
10834     {
10835       clib_memcpy (&mp->local, &local4, sizeof (local4));
10836       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10837     }
10838
10839   mp->encap_vrf_id = ntohl (encap_vrf_id);
10840   mp->decap_vrf_id = ntohl (decap_vrf_id);
10841   mp->protocol = ntohl (protocol);
10842   mp->vni = ntohl (vni);
10843   mp->is_add = is_add;
10844   mp->is_ipv6 = ipv6_set;
10845
10846   S;
10847   W;
10848   /* NOTREACHED */
10849   return 0;
10850 }
10851
10852 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10853   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10854 {
10855   vat_main_t *vam = &vat_main;
10856
10857   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10858            ntohl (mp->sw_if_index),
10859            format_ip46_address, &(mp->local[0]),
10860            format_ip46_address, &(mp->remote[0]),
10861            ntohl (mp->vni),
10862            ntohl (mp->protocol),
10863            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10864 }
10865
10866 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10867   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10868 {
10869   vat_main_t *vam = &vat_main;
10870   vat_json_node_t *node = NULL;
10871   struct in_addr ip4;
10872   struct in6_addr ip6;
10873
10874   if (VAT_JSON_ARRAY != vam->json_tree.type)
10875     {
10876       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10877       vat_json_init_array (&vam->json_tree);
10878     }
10879   node = vat_json_array_add (&vam->json_tree);
10880
10881   vat_json_init_object (node);
10882   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10883   if (mp->is_ipv6)
10884     {
10885       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10886       vat_json_object_add_ip6 (node, "local", ip6);
10887       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10888       vat_json_object_add_ip6 (node, "remote", ip6);
10889     }
10890   else
10891     {
10892       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10893       vat_json_object_add_ip4 (node, "local", ip4);
10894       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10895       vat_json_object_add_ip4 (node, "remote", ip4);
10896     }
10897   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10898   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10899   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10900   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10901   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10902 }
10903
10904 static int
10905 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10906 {
10907   unformat_input_t *i = vam->input;
10908   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10909   f64 timeout;
10910   u32 sw_if_index;
10911   u8 sw_if_index_set = 0;
10912
10913   /* Parse args required to build the message */
10914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10915     {
10916       if (unformat (i, "sw_if_index %d", &sw_if_index))
10917         sw_if_index_set = 1;
10918       else
10919         break;
10920     }
10921
10922   if (sw_if_index_set == 0)
10923     {
10924       sw_if_index = ~0;
10925     }
10926
10927   if (!vam->json_output)
10928     {
10929       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10930                "sw_if_index", "local", "remote", "vni",
10931                "protocol", "encap_vrf_id", "decap_vrf_id");
10932     }
10933
10934   /* Get list of vxlan-tunnel interfaces */
10935   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10936
10937   mp->sw_if_index = htonl (sw_if_index);
10938
10939   S;
10940
10941   /* Use a control ping for synchronization */
10942   {
10943     vl_api_control_ping_t *mp;
10944     M (CONTROL_PING, control_ping);
10945     S;
10946   }
10947   W;
10948 }
10949
10950 u8 *
10951 format_l2_fib_mac_address (u8 * s, va_list * args)
10952 {
10953   u8 *a = va_arg (*args, u8 *);
10954
10955   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10956                  a[2], a[3], a[4], a[5], a[6], a[7]);
10957 }
10958
10959 static void vl_api_l2_fib_table_entry_t_handler
10960   (vl_api_l2_fib_table_entry_t * mp)
10961 {
10962   vat_main_t *vam = &vat_main;
10963
10964   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10965            "       %d       %d     %d\n",
10966            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10967            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10968            mp->bvi_mac);
10969 }
10970
10971 static void vl_api_l2_fib_table_entry_t_handler_json
10972   (vl_api_l2_fib_table_entry_t * mp)
10973 {
10974   vat_main_t *vam = &vat_main;
10975   vat_json_node_t *node = NULL;
10976
10977   if (VAT_JSON_ARRAY != vam->json_tree.type)
10978     {
10979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10980       vat_json_init_array (&vam->json_tree);
10981     }
10982   node = vat_json_array_add (&vam->json_tree);
10983
10984   vat_json_init_object (node);
10985   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10986   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10987   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10988   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10989   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10990   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10991 }
10992
10993 static int
10994 api_l2_fib_table_dump (vat_main_t * vam)
10995 {
10996   unformat_input_t *i = vam->input;
10997   vl_api_l2_fib_table_dump_t *mp;
10998   f64 timeout;
10999   u32 bd_id;
11000   u8 bd_id_set = 0;
11001
11002   /* Parse args required to build the message */
11003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11004     {
11005       if (unformat (i, "bd_id %d", &bd_id))
11006         bd_id_set = 1;
11007       else
11008         break;
11009     }
11010
11011   if (bd_id_set == 0)
11012     {
11013       errmsg ("missing bridge domain\n");
11014       return -99;
11015     }
11016
11017   fformat (vam->ofp,
11018            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11019
11020   /* Get list of l2 fib entries */
11021   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11022
11023   mp->bd_id = ntohl (bd_id);
11024   S;
11025
11026   /* Use a control ping for synchronization */
11027   {
11028     vl_api_control_ping_t *mp;
11029     M (CONTROL_PING, control_ping);
11030     S;
11031   }
11032   W;
11033 }
11034
11035
11036 static int
11037 api_interface_name_renumber (vat_main_t * vam)
11038 {
11039   unformat_input_t *line_input = vam->input;
11040   vl_api_interface_name_renumber_t *mp;
11041   u32 sw_if_index = ~0;
11042   f64 timeout;
11043   u32 new_show_dev_instance = ~0;
11044
11045   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11046     {
11047       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11048                     &sw_if_index))
11049         ;
11050       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11051         ;
11052       else if (unformat (line_input, "new_show_dev_instance %d",
11053                          &new_show_dev_instance))
11054         ;
11055       else
11056         break;
11057     }
11058
11059   if (sw_if_index == ~0)
11060     {
11061       errmsg ("missing interface name or sw_if_index\n");
11062       return -99;
11063     }
11064
11065   if (new_show_dev_instance == ~0)
11066     {
11067       errmsg ("missing new_show_dev_instance\n");
11068       return -99;
11069     }
11070
11071   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11072
11073   mp->sw_if_index = ntohl (sw_if_index);
11074   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11075
11076   S;
11077   W;
11078 }
11079
11080 static int
11081 api_want_ip4_arp_events (vat_main_t * vam)
11082 {
11083   unformat_input_t *line_input = vam->input;
11084   vl_api_want_ip4_arp_events_t *mp;
11085   f64 timeout;
11086   ip4_address_t address;
11087   int address_set = 0;
11088   u32 enable_disable = 1;
11089
11090   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11091     {
11092       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11093         address_set = 1;
11094       else if (unformat (line_input, "del"))
11095         enable_disable = 0;
11096       else
11097         break;
11098     }
11099
11100   if (address_set == 0)
11101     {
11102       errmsg ("missing addresses\n");
11103       return -99;
11104     }
11105
11106   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11107   mp->enable_disable = enable_disable;
11108   mp->pid = getpid ();
11109   mp->address = address.as_u32;
11110
11111   S;
11112   W;
11113 }
11114
11115 static int
11116 api_want_ip6_nd_events (vat_main_t * vam)
11117 {
11118   unformat_input_t *line_input = vam->input;
11119   vl_api_want_ip6_nd_events_t *mp;
11120   f64 timeout;
11121   ip6_address_t address;
11122   int address_set = 0;
11123   u32 enable_disable = 1;
11124
11125   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11126     {
11127       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11128         address_set = 1;
11129       else if (unformat (line_input, "del"))
11130         enable_disable = 0;
11131       else
11132         break;
11133     }
11134
11135   if (address_set == 0)
11136     {
11137       errmsg ("missing addresses\n");
11138       return -99;
11139     }
11140
11141   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11142   mp->enable_disable = enable_disable;
11143   mp->pid = getpid ();
11144   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11145
11146   S;
11147   W;
11148 }
11149
11150 static int
11151 api_input_acl_set_interface (vat_main_t * vam)
11152 {
11153   unformat_input_t *i = vam->input;
11154   vl_api_input_acl_set_interface_t *mp;
11155   f64 timeout;
11156   u32 sw_if_index;
11157   int sw_if_index_set;
11158   u32 ip4_table_index = ~0;
11159   u32 ip6_table_index = ~0;
11160   u32 l2_table_index = ~0;
11161   u8 is_add = 1;
11162
11163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11164     {
11165       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11166         sw_if_index_set = 1;
11167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11168         sw_if_index_set = 1;
11169       else if (unformat (i, "del"))
11170         is_add = 0;
11171       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11172         ;
11173       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11174         ;
11175       else if (unformat (i, "l2-table %d", &l2_table_index))
11176         ;
11177       else
11178         {
11179           clib_warning ("parse error '%U'", format_unformat_error, i);
11180           return -99;
11181         }
11182     }
11183
11184   if (sw_if_index_set == 0)
11185     {
11186       errmsg ("missing interface name or sw_if_index\n");
11187       return -99;
11188     }
11189
11190   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11191
11192   mp->sw_if_index = ntohl (sw_if_index);
11193   mp->ip4_table_index = ntohl (ip4_table_index);
11194   mp->ip6_table_index = ntohl (ip6_table_index);
11195   mp->l2_table_index = ntohl (l2_table_index);
11196   mp->is_add = is_add;
11197
11198   S;
11199   W;
11200   /* NOTREACHED */
11201   return 0;
11202 }
11203
11204 static int
11205 api_ip_address_dump (vat_main_t * vam)
11206 {
11207   unformat_input_t *i = vam->input;
11208   vl_api_ip_address_dump_t *mp;
11209   u32 sw_if_index = ~0;
11210   u8 sw_if_index_set = 0;
11211   u8 ipv4_set = 0;
11212   u8 ipv6_set = 0;
11213   f64 timeout;
11214
11215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11216     {
11217       if (unformat (i, "sw_if_index %d", &sw_if_index))
11218         sw_if_index_set = 1;
11219       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11220         sw_if_index_set = 1;
11221       else if (unformat (i, "ipv4"))
11222         ipv4_set = 1;
11223       else if (unformat (i, "ipv6"))
11224         ipv6_set = 1;
11225       else
11226         break;
11227     }
11228
11229   if (ipv4_set && ipv6_set)
11230     {
11231       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11232       return -99;
11233     }
11234
11235   if ((!ipv4_set) && (!ipv6_set))
11236     {
11237       errmsg ("no ipv4 nor ipv6 flag set\n");
11238       return -99;
11239     }
11240
11241   if (sw_if_index_set == 0)
11242     {
11243       errmsg ("missing interface name or sw_if_index\n");
11244       return -99;
11245     }
11246
11247   vam->current_sw_if_index = sw_if_index;
11248   vam->is_ipv6 = ipv6_set;
11249
11250   M (IP_ADDRESS_DUMP, ip_address_dump);
11251   mp->sw_if_index = ntohl (sw_if_index);
11252   mp->is_ipv6 = ipv6_set;
11253   S;
11254
11255   /* Use a control ping for synchronization */
11256   {
11257     vl_api_control_ping_t *mp;
11258     M (CONTROL_PING, control_ping);
11259     S;
11260   }
11261   W;
11262 }
11263
11264 static int
11265 api_ip_dump (vat_main_t * vam)
11266 {
11267   vl_api_ip_dump_t *mp;
11268   unformat_input_t *in = vam->input;
11269   int ipv4_set = 0;
11270   int ipv6_set = 0;
11271   int is_ipv6;
11272   f64 timeout;
11273   int i;
11274
11275   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11276     {
11277       if (unformat (in, "ipv4"))
11278         ipv4_set = 1;
11279       else if (unformat (in, "ipv6"))
11280         ipv6_set = 1;
11281       else
11282         break;
11283     }
11284
11285   if (ipv4_set && ipv6_set)
11286     {
11287       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11288       return -99;
11289     }
11290
11291   if ((!ipv4_set) && (!ipv6_set))
11292     {
11293       errmsg ("no ipv4 nor ipv6 flag set\n");
11294       return -99;
11295     }
11296
11297   is_ipv6 = ipv6_set;
11298   vam->is_ipv6 = is_ipv6;
11299
11300   /* free old data */
11301   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11302     {
11303       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11304     }
11305   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11306
11307   M (IP_DUMP, ip_dump);
11308   mp->is_ipv6 = ipv6_set;
11309   S;
11310
11311   /* Use a control ping for synchronization */
11312   {
11313     vl_api_control_ping_t *mp;
11314     M (CONTROL_PING, control_ping);
11315     S;
11316   }
11317   W;
11318 }
11319
11320 static int
11321 api_ipsec_spd_add_del (vat_main_t * vam)
11322 {
11323 #if DPDK > 0
11324   unformat_input_t *i = vam->input;
11325   vl_api_ipsec_spd_add_del_t *mp;
11326   f64 timeout;
11327   u32 spd_id = ~0;
11328   u8 is_add = 1;
11329
11330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11331     {
11332       if (unformat (i, "spd_id %d", &spd_id))
11333         ;
11334       else if (unformat (i, "del"))
11335         is_add = 0;
11336       else
11337         {
11338           clib_warning ("parse error '%U'", format_unformat_error, i);
11339           return -99;
11340         }
11341     }
11342   if (spd_id == ~0)
11343     {
11344       errmsg ("spd_id must be set\n");
11345       return -99;
11346     }
11347
11348   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11349
11350   mp->spd_id = ntohl (spd_id);
11351   mp->is_add = is_add;
11352
11353   S;
11354   W;
11355   /* NOTREACHED */
11356   return 0;
11357 #else
11358   clib_warning ("unsupported (no dpdk)");
11359   return -99;
11360 #endif
11361 }
11362
11363 static int
11364 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11365 {
11366 #if DPDK > 0
11367   unformat_input_t *i = vam->input;
11368   vl_api_ipsec_interface_add_del_spd_t *mp;
11369   f64 timeout;
11370   u32 sw_if_index;
11371   u8 sw_if_index_set = 0;
11372   u32 spd_id = (u32) ~ 0;
11373   u8 is_add = 1;
11374
11375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11376     {
11377       if (unformat (i, "del"))
11378         is_add = 0;
11379       else if (unformat (i, "spd_id %d", &spd_id))
11380         ;
11381       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11382         sw_if_index_set = 1;
11383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11384         sw_if_index_set = 1;
11385       else
11386         {
11387           clib_warning ("parse error '%U'", format_unformat_error, i);
11388           return -99;
11389         }
11390
11391     }
11392
11393   if (spd_id == (u32) ~ 0)
11394     {
11395       errmsg ("spd_id must be set\n");
11396       return -99;
11397     }
11398
11399   if (sw_if_index_set == 0)
11400     {
11401       errmsg ("missing interface name or sw_if_index\n");
11402       return -99;
11403     }
11404
11405   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11406
11407   mp->spd_id = ntohl (spd_id);
11408   mp->sw_if_index = ntohl (sw_if_index);
11409   mp->is_add = is_add;
11410
11411   S;
11412   W;
11413   /* NOTREACHED */
11414   return 0;
11415 #else
11416   clib_warning ("unsupported (no dpdk)");
11417   return -99;
11418 #endif
11419 }
11420
11421 static int
11422 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11423 {
11424 #if DPDK > 0
11425   unformat_input_t *i = vam->input;
11426   vl_api_ipsec_spd_add_del_entry_t *mp;
11427   f64 timeout;
11428   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11429   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11430   i32 priority = 0;
11431   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11432   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11433   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11434   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11435
11436   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11437   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11438   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11439   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11440   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11441   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11442
11443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11444     {
11445       if (unformat (i, "del"))
11446         is_add = 0;
11447       if (unformat (i, "outbound"))
11448         is_outbound = 1;
11449       if (unformat (i, "inbound"))
11450         is_outbound = 0;
11451       else if (unformat (i, "spd_id %d", &spd_id))
11452         ;
11453       else if (unformat (i, "sa_id %d", &sa_id))
11454         ;
11455       else if (unformat (i, "priority %d", &priority))
11456         ;
11457       else if (unformat (i, "protocol %d", &protocol))
11458         ;
11459       else if (unformat (i, "lport_start %d", &lport_start))
11460         ;
11461       else if (unformat (i, "lport_stop %d", &lport_stop))
11462         ;
11463       else if (unformat (i, "rport_start %d", &rport_start))
11464         ;
11465       else if (unformat (i, "rport_stop %d", &rport_stop))
11466         ;
11467       else
11468         if (unformat
11469             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11470         {
11471           is_ipv6 = 0;
11472           is_ip_any = 0;
11473         }
11474       else
11475         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11476         {
11477           is_ipv6 = 0;
11478           is_ip_any = 0;
11479         }
11480       else
11481         if (unformat
11482             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11483         {
11484           is_ipv6 = 0;
11485           is_ip_any = 0;
11486         }
11487       else
11488         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11489         {
11490           is_ipv6 = 0;
11491           is_ip_any = 0;
11492         }
11493       else
11494         if (unformat
11495             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11496         {
11497           is_ipv6 = 1;
11498           is_ip_any = 0;
11499         }
11500       else
11501         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11502         {
11503           is_ipv6 = 1;
11504           is_ip_any = 0;
11505         }
11506       else
11507         if (unformat
11508             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11509         {
11510           is_ipv6 = 1;
11511           is_ip_any = 0;
11512         }
11513       else
11514         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11515         {
11516           is_ipv6 = 1;
11517           is_ip_any = 0;
11518         }
11519       else
11520         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11521         {
11522           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11523             {
11524               clib_warning ("unsupported action: 'resolve'");
11525               return -99;
11526             }
11527         }
11528       else
11529         {
11530           clib_warning ("parse error '%U'", format_unformat_error, i);
11531           return -99;
11532         }
11533
11534     }
11535
11536   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11537
11538   mp->spd_id = ntohl (spd_id);
11539   mp->priority = ntohl (priority);
11540   mp->is_outbound = is_outbound;
11541
11542   mp->is_ipv6 = is_ipv6;
11543   if (is_ipv6 || is_ip_any)
11544     {
11545       clib_memcpy (mp->remote_address_start, &raddr6_start,
11546                    sizeof (ip6_address_t));
11547       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11548                    sizeof (ip6_address_t));
11549       clib_memcpy (mp->local_address_start, &laddr6_start,
11550                    sizeof (ip6_address_t));
11551       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11552                    sizeof (ip6_address_t));
11553     }
11554   else
11555     {
11556       clib_memcpy (mp->remote_address_start, &raddr4_start,
11557                    sizeof (ip4_address_t));
11558       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11559                    sizeof (ip4_address_t));
11560       clib_memcpy (mp->local_address_start, &laddr4_start,
11561                    sizeof (ip4_address_t));
11562       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11563                    sizeof (ip4_address_t));
11564     }
11565   mp->protocol = (u8) protocol;
11566   mp->local_port_start = ntohs ((u16) lport_start);
11567   mp->local_port_stop = ntohs ((u16) lport_stop);
11568   mp->remote_port_start = ntohs ((u16) rport_start);
11569   mp->remote_port_stop = ntohs ((u16) rport_stop);
11570   mp->policy = (u8) policy;
11571   mp->sa_id = ntohl (sa_id);
11572   mp->is_add = is_add;
11573   mp->is_ip_any = is_ip_any;
11574   S;
11575   W;
11576   /* NOTREACHED */
11577   return 0;
11578 #else
11579   clib_warning ("unsupported (no dpdk)");
11580   return -99;
11581 #endif
11582 }
11583
11584 static int
11585 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11586 {
11587 #if DPDK > 0
11588   unformat_input_t *i = vam->input;
11589   vl_api_ipsec_sad_add_del_entry_t *mp;
11590   f64 timeout;
11591   u32 sad_id = 0, spi = 0;
11592   u8 *ck = 0, *ik = 0;
11593   u8 is_add = 1;
11594
11595   u8 protocol = IPSEC_PROTOCOL_AH;
11596   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11597   u32 crypto_alg = 0, integ_alg = 0;
11598   ip4_address_t tun_src4;
11599   ip4_address_t tun_dst4;
11600   ip6_address_t tun_src6;
11601   ip6_address_t tun_dst6;
11602
11603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11604     {
11605       if (unformat (i, "del"))
11606         is_add = 0;
11607       else if (unformat (i, "sad_id %d", &sad_id))
11608         ;
11609       else if (unformat (i, "spi %d", &spi))
11610         ;
11611       else if (unformat (i, "esp"))
11612         protocol = IPSEC_PROTOCOL_ESP;
11613       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11614         {
11615           is_tunnel = 1;
11616           is_tunnel_ipv6 = 0;
11617         }
11618       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11619         {
11620           is_tunnel = 1;
11621           is_tunnel_ipv6 = 0;
11622         }
11623       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11624         {
11625           is_tunnel = 1;
11626           is_tunnel_ipv6 = 1;
11627         }
11628       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11629         {
11630           is_tunnel = 1;
11631           is_tunnel_ipv6 = 1;
11632         }
11633       else
11634         if (unformat
11635             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11636         {
11637           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11638               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11639             {
11640               clib_warning ("unsupported crypto-alg: '%U'",
11641                             format_ipsec_crypto_alg, crypto_alg);
11642               return -99;
11643             }
11644         }
11645       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11646         ;
11647       else
11648         if (unformat
11649             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11650         {
11651           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11652               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11653             {
11654               clib_warning ("unsupported integ-alg: '%U'",
11655                             format_ipsec_integ_alg, integ_alg);
11656               return -99;
11657             }
11658         }
11659       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11660         ;
11661       else
11662         {
11663           clib_warning ("parse error '%U'", format_unformat_error, i);
11664           return -99;
11665         }
11666
11667     }
11668
11669   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11670
11671   mp->sad_id = ntohl (sad_id);
11672   mp->is_add = is_add;
11673   mp->protocol = protocol;
11674   mp->spi = ntohl (spi);
11675   mp->is_tunnel = is_tunnel;
11676   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11677   mp->crypto_algorithm = crypto_alg;
11678   mp->integrity_algorithm = integ_alg;
11679   mp->crypto_key_length = vec_len (ck);
11680   mp->integrity_key_length = vec_len (ik);
11681
11682   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11683     mp->crypto_key_length = sizeof (mp->crypto_key);
11684
11685   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11686     mp->integrity_key_length = sizeof (mp->integrity_key);
11687
11688   if (ck)
11689     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11690   if (ik)
11691     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11692
11693   if (is_tunnel)
11694     {
11695       if (is_tunnel_ipv6)
11696         {
11697           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11698                        sizeof (ip6_address_t));
11699           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11700                        sizeof (ip6_address_t));
11701         }
11702       else
11703         {
11704           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11705                        sizeof (ip4_address_t));
11706           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11707                        sizeof (ip4_address_t));
11708         }
11709     }
11710
11711   S;
11712   W;
11713   /* NOTREACHED */
11714   return 0;
11715 #else
11716   clib_warning ("unsupported (no dpdk)");
11717   return -99;
11718 #endif
11719 }
11720
11721 static int
11722 api_ipsec_sa_set_key (vat_main_t * vam)
11723 {
11724 #if DPDK > 0
11725   unformat_input_t *i = vam->input;
11726   vl_api_ipsec_sa_set_key_t *mp;
11727   f64 timeout;
11728   u32 sa_id;
11729   u8 *ck = 0, *ik = 0;
11730
11731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11732     {
11733       if (unformat (i, "sa_id %d", &sa_id))
11734         ;
11735       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11736         ;
11737       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11738         ;
11739       else
11740         {
11741           clib_warning ("parse error '%U'", format_unformat_error, i);
11742           return -99;
11743         }
11744     }
11745
11746   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11747
11748   mp->sa_id = ntohl (sa_id);
11749   mp->crypto_key_length = vec_len (ck);
11750   mp->integrity_key_length = vec_len (ik);
11751
11752   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11753     mp->crypto_key_length = sizeof (mp->crypto_key);
11754
11755   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11756     mp->integrity_key_length = sizeof (mp->integrity_key);
11757
11758   if (ck)
11759     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11760   if (ik)
11761     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11762
11763   S;
11764   W;
11765   /* NOTREACHED */
11766   return 0;
11767 #else
11768   clib_warning ("unsupported (no dpdk)");
11769   return -99;
11770 #endif
11771 }
11772
11773 static int
11774 api_ikev2_profile_add_del (vat_main_t * vam)
11775 {
11776 #if DPDK > 0
11777   unformat_input_t *i = vam->input;
11778   vl_api_ikev2_profile_add_del_t *mp;
11779   f64 timeout;
11780   u8 is_add = 1;
11781   u8 *name = 0;
11782
11783   const char *valid_chars = "a-zA-Z0-9_";
11784
11785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11786     {
11787       if (unformat (i, "del"))
11788         is_add = 0;
11789       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11790         vec_add1 (name, 0);
11791       else
11792         {
11793           errmsg ("parse error '%U'", format_unformat_error, i);
11794           return -99;
11795         }
11796     }
11797
11798   if (!vec_len (name))
11799     {
11800       errmsg ("profile name must be specified");
11801       return -99;
11802     }
11803
11804   if (vec_len (name) > 64)
11805     {
11806       errmsg ("profile name too long");
11807       return -99;
11808     }
11809
11810   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11811
11812   clib_memcpy (mp->name, name, vec_len (name));
11813   mp->is_add = is_add;
11814   vec_free (name);
11815
11816   S;
11817   W;
11818   /* NOTREACHED */
11819   return 0;
11820 #else
11821   clib_warning ("unsupported (no dpdk)");
11822   return -99;
11823 #endif
11824 }
11825
11826 static int
11827 api_ikev2_profile_set_auth (vat_main_t * vam)
11828 {
11829 #if DPDK > 0
11830   unformat_input_t *i = vam->input;
11831   vl_api_ikev2_profile_set_auth_t *mp;
11832   f64 timeout;
11833   u8 *name = 0;
11834   u8 *data = 0;
11835   u32 auth_method = 0;
11836   u8 is_hex = 0;
11837
11838   const char *valid_chars = "a-zA-Z0-9_";
11839
11840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11841     {
11842       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11843         vec_add1 (name, 0);
11844       else if (unformat (i, "auth_method %U",
11845                          unformat_ikev2_auth_method, &auth_method))
11846         ;
11847       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11848         is_hex = 1;
11849       else if (unformat (i, "auth_data %v", &data))
11850         ;
11851       else
11852         {
11853           errmsg ("parse error '%U'", format_unformat_error, i);
11854           return -99;
11855         }
11856     }
11857
11858   if (!vec_len (name))
11859     {
11860       errmsg ("profile name must be specified");
11861       return -99;
11862     }
11863
11864   if (vec_len (name) > 64)
11865     {
11866       errmsg ("profile name too long");
11867       return -99;
11868     }
11869
11870   if (!vec_len (data))
11871     {
11872       errmsg ("auth_data must be specified");
11873       return -99;
11874     }
11875
11876   if (!auth_method)
11877     {
11878       errmsg ("auth_method must be specified");
11879       return -99;
11880     }
11881
11882   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11883
11884   mp->is_hex = is_hex;
11885   mp->auth_method = (u8) auth_method;
11886   mp->data_len = vec_len (data);
11887   clib_memcpy (mp->name, name, vec_len (name));
11888   clib_memcpy (mp->data, data, vec_len (data));
11889   vec_free (name);
11890   vec_free (data);
11891
11892   S;
11893   W;
11894   /* NOTREACHED */
11895   return 0;
11896 #else
11897   clib_warning ("unsupported (no dpdk)");
11898   return -99;
11899 #endif
11900 }
11901
11902 static int
11903 api_ikev2_profile_set_id (vat_main_t * vam)
11904 {
11905 #if DPDK > 0
11906   unformat_input_t *i = vam->input;
11907   vl_api_ikev2_profile_set_id_t *mp;
11908   f64 timeout;
11909   u8 *name = 0;
11910   u8 *data = 0;
11911   u8 is_local = 0;
11912   u32 id_type = 0;
11913   ip4_address_t ip4;
11914
11915   const char *valid_chars = "a-zA-Z0-9_";
11916
11917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11918     {
11919       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11920         vec_add1 (name, 0);
11921       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11922         ;
11923       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11924         {
11925           data = vec_new (u8, 4);
11926           clib_memcpy (data, ip4.as_u8, 4);
11927         }
11928       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11929         ;
11930       else if (unformat (i, "id_data %v", &data))
11931         ;
11932       else if (unformat (i, "local"))
11933         is_local = 1;
11934       else if (unformat (i, "remote"))
11935         is_local = 0;
11936       else
11937         {
11938           errmsg ("parse error '%U'", format_unformat_error, i);
11939           return -99;
11940         }
11941     }
11942
11943   if (!vec_len (name))
11944     {
11945       errmsg ("profile name must be specified");
11946       return -99;
11947     }
11948
11949   if (vec_len (name) > 64)
11950     {
11951       errmsg ("profile name too long");
11952       return -99;
11953     }
11954
11955   if (!vec_len (data))
11956     {
11957       errmsg ("id_data must be specified");
11958       return -99;
11959     }
11960
11961   if (!id_type)
11962     {
11963       errmsg ("id_type must be specified");
11964       return -99;
11965     }
11966
11967   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11968
11969   mp->is_local = is_local;
11970   mp->id_type = (u8) id_type;
11971   mp->data_len = vec_len (data);
11972   clib_memcpy (mp->name, name, vec_len (name));
11973   clib_memcpy (mp->data, data, vec_len (data));
11974   vec_free (name);
11975   vec_free (data);
11976
11977   S;
11978   W;
11979   /* NOTREACHED */
11980   return 0;
11981 #else
11982   clib_warning ("unsupported (no dpdk)");
11983   return -99;
11984 #endif
11985 }
11986
11987 static int
11988 api_ikev2_profile_set_ts (vat_main_t * vam)
11989 {
11990 #if DPDK > 0
11991   unformat_input_t *i = vam->input;
11992   vl_api_ikev2_profile_set_ts_t *mp;
11993   f64 timeout;
11994   u8 *name = 0;
11995   u8 is_local = 0;
11996   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11997   ip4_address_t start_addr, end_addr;
11998
11999   const char *valid_chars = "a-zA-Z0-9_";
12000
12001   start_addr.as_u32 = 0;
12002   end_addr.as_u32 = (u32) ~ 0;
12003
12004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12005     {
12006       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12007         vec_add1 (name, 0);
12008       else if (unformat (i, "protocol %d", &proto))
12009         ;
12010       else if (unformat (i, "start_port %d", &start_port))
12011         ;
12012       else if (unformat (i, "end_port %d", &end_port))
12013         ;
12014       else
12015         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12016         ;
12017       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12018         ;
12019       else if (unformat (i, "local"))
12020         is_local = 1;
12021       else if (unformat (i, "remote"))
12022         is_local = 0;
12023       else
12024         {
12025           errmsg ("parse error '%U'", format_unformat_error, i);
12026           return -99;
12027         }
12028     }
12029
12030   if (!vec_len (name))
12031     {
12032       errmsg ("profile name must be specified");
12033       return -99;
12034     }
12035
12036   if (vec_len (name) > 64)
12037     {
12038       errmsg ("profile name too long");
12039       return -99;
12040     }
12041
12042   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12043
12044   mp->is_local = is_local;
12045   mp->proto = (u8) proto;
12046   mp->start_port = (u16) start_port;
12047   mp->end_port = (u16) end_port;
12048   mp->start_addr = start_addr.as_u32;
12049   mp->end_addr = end_addr.as_u32;
12050   clib_memcpy (mp->name, name, vec_len (name));
12051   vec_free (name);
12052
12053   S;
12054   W;
12055   /* NOTREACHED */
12056   return 0;
12057 #else
12058   clib_warning ("unsupported (no dpdk)");
12059   return -99;
12060 #endif
12061 }
12062
12063 static int
12064 api_ikev2_set_local_key (vat_main_t * vam)
12065 {
12066 #if DPDK > 0
12067   unformat_input_t *i = vam->input;
12068   vl_api_ikev2_set_local_key_t *mp;
12069   f64 timeout;
12070   u8 *file = 0;
12071
12072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12073     {
12074       if (unformat (i, "file %v", &file))
12075         vec_add1 (file, 0);
12076       else
12077         {
12078           errmsg ("parse error '%U'", format_unformat_error, i);
12079           return -99;
12080         }
12081     }
12082
12083   if (!vec_len (file))
12084     {
12085       errmsg ("RSA key file must be specified");
12086       return -99;
12087     }
12088
12089   if (vec_len (file) > 256)
12090     {
12091       errmsg ("file name too long");
12092       return -99;
12093     }
12094
12095   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12096
12097   clib_memcpy (mp->key_file, file, vec_len (file));
12098   vec_free (file);
12099
12100   S;
12101   W;
12102   /* NOTREACHED */
12103   return 0;
12104 #else
12105   clib_warning ("unsupported (no dpdk)");
12106   return -99;
12107 #endif
12108 }
12109
12110 /*
12111  * MAP
12112  */
12113 static int
12114 api_map_add_domain (vat_main_t * vam)
12115 {
12116   unformat_input_t *i = vam->input;
12117   vl_api_map_add_domain_t *mp;
12118   f64 timeout;
12119
12120   ip4_address_t ip4_prefix;
12121   ip6_address_t ip6_prefix;
12122   ip6_address_t ip6_src;
12123   u32 num_m_args = 0;
12124   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12125     0, psid_length = 0;
12126   u8 is_translation = 0;
12127   u32 mtu = 0;
12128   u32 ip6_src_len = 128;
12129
12130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12131     {
12132       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12133                     &ip4_prefix, &ip4_prefix_len))
12134         num_m_args++;
12135       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12136                          &ip6_prefix, &ip6_prefix_len))
12137         num_m_args++;
12138       else
12139         if (unformat
12140             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12141              &ip6_src_len))
12142         num_m_args++;
12143       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12144         num_m_args++;
12145       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12146         num_m_args++;
12147       else if (unformat (i, "psid-offset %d", &psid_offset))
12148         num_m_args++;
12149       else if (unformat (i, "psid-len %d", &psid_length))
12150         num_m_args++;
12151       else if (unformat (i, "mtu %d", &mtu))
12152         num_m_args++;
12153       else if (unformat (i, "map-t"))
12154         is_translation = 1;
12155       else
12156         {
12157           clib_warning ("parse error '%U'", format_unformat_error, i);
12158           return -99;
12159         }
12160     }
12161
12162   if (num_m_args < 3)
12163     {
12164       errmsg ("mandatory argument(s) missing\n");
12165       return -99;
12166     }
12167
12168   /* Construct the API message */
12169   M (MAP_ADD_DOMAIN, map_add_domain);
12170
12171   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12172   mp->ip4_prefix_len = ip4_prefix_len;
12173
12174   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12175   mp->ip6_prefix_len = ip6_prefix_len;
12176
12177   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12178   mp->ip6_src_prefix_len = ip6_src_len;
12179
12180   mp->ea_bits_len = ea_bits_len;
12181   mp->psid_offset = psid_offset;
12182   mp->psid_length = psid_length;
12183   mp->is_translation = is_translation;
12184   mp->mtu = htons (mtu);
12185
12186   /* send it... */
12187   S;
12188
12189   /* Wait for a reply, return good/bad news  */
12190   W;
12191 }
12192
12193 static int
12194 api_map_del_domain (vat_main_t * vam)
12195 {
12196   unformat_input_t *i = vam->input;
12197   vl_api_map_del_domain_t *mp;
12198   f64 timeout;
12199
12200   u32 num_m_args = 0;
12201   u32 index;
12202
12203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12204     {
12205       if (unformat (i, "index %d", &index))
12206         num_m_args++;
12207       else
12208         {
12209           clib_warning ("parse error '%U'", format_unformat_error, i);
12210           return -99;
12211         }
12212     }
12213
12214   if (num_m_args != 1)
12215     {
12216       errmsg ("mandatory argument(s) missing\n");
12217       return -99;
12218     }
12219
12220   /* Construct the API message */
12221   M (MAP_DEL_DOMAIN, map_del_domain);
12222
12223   mp->index = ntohl (index);
12224
12225   /* send it... */
12226   S;
12227
12228   /* Wait for a reply, return good/bad news  */
12229   W;
12230 }
12231
12232 static int
12233 api_map_add_del_rule (vat_main_t * vam)
12234 {
12235   unformat_input_t *i = vam->input;
12236   vl_api_map_add_del_rule_t *mp;
12237   f64 timeout;
12238   u8 is_add = 1;
12239   ip6_address_t ip6_dst;
12240   u32 num_m_args = 0, index, psid = 0;
12241
12242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12243     {
12244       if (unformat (i, "index %d", &index))
12245         num_m_args++;
12246       else if (unformat (i, "psid %d", &psid))
12247         num_m_args++;
12248       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12249         num_m_args++;
12250       else if (unformat (i, "del"))
12251         {
12252           is_add = 0;
12253         }
12254       else
12255         {
12256           clib_warning ("parse error '%U'", format_unformat_error, i);
12257           return -99;
12258         }
12259     }
12260
12261   /* Construct the API message */
12262   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12263
12264   mp->index = ntohl (index);
12265   mp->is_add = is_add;
12266   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12267   mp->psid = ntohs (psid);
12268
12269   /* send it... */
12270   S;
12271
12272   /* Wait for a reply, return good/bad news  */
12273   W;
12274 }
12275
12276 static int
12277 api_map_domain_dump (vat_main_t * vam)
12278 {
12279   vl_api_map_domain_dump_t *mp;
12280   f64 timeout;
12281
12282   /* Construct the API message */
12283   M (MAP_DOMAIN_DUMP, map_domain_dump);
12284
12285   /* send it... */
12286   S;
12287
12288   /* Use a control ping for synchronization */
12289   {
12290     vl_api_control_ping_t *mp;
12291     M (CONTROL_PING, control_ping);
12292     S;
12293   }
12294   W;
12295 }
12296
12297 static int
12298 api_map_rule_dump (vat_main_t * vam)
12299 {
12300   unformat_input_t *i = vam->input;
12301   vl_api_map_rule_dump_t *mp;
12302   f64 timeout;
12303   u32 domain_index = ~0;
12304
12305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12306     {
12307       if (unformat (i, "index %u", &domain_index))
12308         ;
12309       else
12310         break;
12311     }
12312
12313   if (domain_index == ~0)
12314     {
12315       clib_warning ("parse error: domain index expected");
12316       return -99;
12317     }
12318
12319   /* Construct the API message */
12320   M (MAP_RULE_DUMP, map_rule_dump);
12321
12322   mp->domain_index = htonl (domain_index);
12323
12324   /* send it... */
12325   S;
12326
12327   /* Use a control ping for synchronization */
12328   {
12329     vl_api_control_ping_t *mp;
12330     M (CONTROL_PING, control_ping);
12331     S;
12332   }
12333   W;
12334 }
12335
12336 static void vl_api_map_add_domain_reply_t_handler
12337   (vl_api_map_add_domain_reply_t * mp)
12338 {
12339   vat_main_t *vam = &vat_main;
12340   i32 retval = ntohl (mp->retval);
12341
12342   if (vam->async_mode)
12343     {
12344       vam->async_errors += (retval < 0);
12345     }
12346   else
12347     {
12348       vam->retval = retval;
12349       vam->result_ready = 1;
12350     }
12351 }
12352
12353 static void vl_api_map_add_domain_reply_t_handler_json
12354   (vl_api_map_add_domain_reply_t * mp)
12355 {
12356   vat_main_t *vam = &vat_main;
12357   vat_json_node_t node;
12358
12359   vat_json_init_object (&node);
12360   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12361   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12362
12363   vat_json_print (vam->ofp, &node);
12364   vat_json_free (&node);
12365
12366   vam->retval = ntohl (mp->retval);
12367   vam->result_ready = 1;
12368 }
12369
12370 static int
12371 api_get_first_msg_id (vat_main_t * vam)
12372 {
12373   vl_api_get_first_msg_id_t *mp;
12374   f64 timeout;
12375   unformat_input_t *i = vam->input;
12376   u8 *name;
12377   u8 name_set = 0;
12378
12379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12380     {
12381       if (unformat (i, "client %s", &name))
12382         name_set = 1;
12383       else
12384         break;
12385     }
12386
12387   if (name_set == 0)
12388     {
12389       errmsg ("missing client name\n");
12390       return -99;
12391     }
12392   vec_add1 (name, 0);
12393
12394   if (vec_len (name) > 63)
12395     {
12396       errmsg ("client name too long\n");
12397       return -99;
12398     }
12399
12400   M (GET_FIRST_MSG_ID, get_first_msg_id);
12401   clib_memcpy (mp->name, name, vec_len (name));
12402   S;
12403   W;
12404   /* NOTREACHED */
12405   return 0;
12406 }
12407
12408 static int
12409 api_cop_interface_enable_disable (vat_main_t * vam)
12410 {
12411   unformat_input_t *line_input = vam->input;
12412   vl_api_cop_interface_enable_disable_t *mp;
12413   f64 timeout;
12414   u32 sw_if_index = ~0;
12415   u8 enable_disable = 1;
12416
12417   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12418     {
12419       if (unformat (line_input, "disable"))
12420         enable_disable = 0;
12421       if (unformat (line_input, "enable"))
12422         enable_disable = 1;
12423       else if (unformat (line_input, "%U", unformat_sw_if_index,
12424                          vam, &sw_if_index))
12425         ;
12426       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12427         ;
12428       else
12429         break;
12430     }
12431
12432   if (sw_if_index == ~0)
12433     {
12434       errmsg ("missing interface name or sw_if_index\n");
12435       return -99;
12436     }
12437
12438   /* Construct the API message */
12439   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12440   mp->sw_if_index = ntohl (sw_if_index);
12441   mp->enable_disable = enable_disable;
12442
12443   /* send it... */
12444   S;
12445   /* Wait for the reply */
12446   W;
12447 }
12448
12449 static int
12450 api_cop_whitelist_enable_disable (vat_main_t * vam)
12451 {
12452   unformat_input_t *line_input = vam->input;
12453   vl_api_cop_whitelist_enable_disable_t *mp;
12454   f64 timeout;
12455   u32 sw_if_index = ~0;
12456   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12457   u32 fib_id = 0;
12458
12459   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12460     {
12461       if (unformat (line_input, "ip4"))
12462         ip4 = 1;
12463       else if (unformat (line_input, "ip6"))
12464         ip6 = 1;
12465       else if (unformat (line_input, "default"))
12466         default_cop = 1;
12467       else if (unformat (line_input, "%U", unformat_sw_if_index,
12468                          vam, &sw_if_index))
12469         ;
12470       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12471         ;
12472       else if (unformat (line_input, "fib-id %d", &fib_id))
12473         ;
12474       else
12475         break;
12476     }
12477
12478   if (sw_if_index == ~0)
12479     {
12480       errmsg ("missing interface name or sw_if_index\n");
12481       return -99;
12482     }
12483
12484   /* Construct the API message */
12485   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12486   mp->sw_if_index = ntohl (sw_if_index);
12487   mp->fib_id = ntohl (fib_id);
12488   mp->ip4 = ip4;
12489   mp->ip6 = ip6;
12490   mp->default_cop = default_cop;
12491
12492   /* send it... */
12493   S;
12494   /* Wait for the reply */
12495   W;
12496 }
12497
12498 static int
12499 api_get_node_graph (vat_main_t * vam)
12500 {
12501   vl_api_get_node_graph_t *mp;
12502   f64 timeout;
12503
12504   M (GET_NODE_GRAPH, get_node_graph);
12505
12506   /* send it... */
12507   S;
12508   /* Wait for the reply */
12509   W;
12510 }
12511
12512 /* *INDENT-OFF* */
12513 /** Used for parsing LISP eids */
12514 typedef CLIB_PACKED(struct{
12515   u8 addr[16];   /**< eid address */
12516   u32 len;       /**< prefix length if IP */
12517   u8 type;      /**< type of eid */
12518 }) lisp_eid_vat_t;
12519 /* *INDENT-ON* */
12520
12521 static uword
12522 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12523 {
12524   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12525
12526   memset (a, 0, sizeof (a[0]));
12527
12528   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12529     {
12530       a->type = 0;              /* ipv4 type */
12531     }
12532   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12533     {
12534       a->type = 1;              /* ipv6 type */
12535     }
12536   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12537     {
12538       a->type = 2;              /* mac type */
12539     }
12540   else
12541     {
12542       return 0;
12543     }
12544
12545   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12546     {
12547       return 0;
12548     }
12549
12550   return 1;
12551 }
12552
12553 static int
12554 lisp_eid_size_vat (u8 type)
12555 {
12556   switch (type)
12557     {
12558     case 0:
12559       return 4;
12560     case 1:
12561       return 16;
12562     case 2:
12563       return 6;
12564     }
12565   return 0;
12566 }
12567
12568 static void
12569 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12570 {
12571   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12572 }
12573
12574 /* *INDENT-OFF* */
12575 /** Used for transferring locators via VPP API */
12576 typedef CLIB_PACKED(struct
12577 {
12578   u32 sw_if_index; /**< locator sw_if_index */
12579   u8 priority; /**< locator priority */
12580   u8 weight;   /**< locator weight */
12581 }) ls_locator_t;
12582 /* *INDENT-ON* */
12583
12584 static int
12585 api_lisp_add_del_locator_set (vat_main_t * vam)
12586 {
12587   unformat_input_t *input = vam->input;
12588   vl_api_lisp_add_del_locator_set_t *mp;
12589   f64 timeout = ~0;
12590   u8 is_add = 1;
12591   u8 *locator_set_name = NULL;
12592   u8 locator_set_name_set = 0;
12593   ls_locator_t locator, *locators = 0;
12594   u32 sw_if_index, priority, weight;
12595   u32 data_len = 0;
12596
12597   /* Parse args required to build the message */
12598   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12599     {
12600       if (unformat (input, "del"))
12601         {
12602           is_add = 0;
12603         }
12604       else if (unformat (input, "locator-set %s", &locator_set_name))
12605         {
12606           locator_set_name_set = 1;
12607         }
12608       else if (unformat (input, "sw_if_index %u p %u w %u",
12609                          &sw_if_index, &priority, &weight))
12610         {
12611           locator.sw_if_index = htonl (sw_if_index);
12612           locator.priority = priority;
12613           locator.weight = weight;
12614           vec_add1 (locators, locator);
12615         }
12616       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12617                          vam, &sw_if_index, &priority, &weight))
12618         {
12619           locator.sw_if_index = htonl (sw_if_index);
12620           locator.priority = priority;
12621           locator.weight = weight;
12622           vec_add1 (locators, locator);
12623         }
12624       else
12625         break;
12626     }
12627
12628   if (locator_set_name_set == 0)
12629     {
12630       errmsg ("missing locator-set name");
12631       vec_free (locators);
12632       return -99;
12633     }
12634
12635   if (vec_len (locator_set_name) > 64)
12636     {
12637       errmsg ("locator-set name too long\n");
12638       vec_free (locator_set_name);
12639       vec_free (locators);
12640       return -99;
12641     }
12642   vec_add1 (locator_set_name, 0);
12643
12644   data_len = sizeof (ls_locator_t) * vec_len (locators);
12645
12646   /* Construct the API message */
12647   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12648
12649   mp->is_add = is_add;
12650   clib_memcpy (mp->locator_set_name, locator_set_name,
12651                vec_len (locator_set_name));
12652   vec_free (locator_set_name);
12653
12654   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12655   if (locators)
12656     clib_memcpy (mp->locators, locators, data_len);
12657   vec_free (locators);
12658
12659   /* send it... */
12660   S;
12661
12662   /* Wait for a reply... */
12663   W;
12664
12665   /* NOTREACHED */
12666   return 0;
12667 }
12668
12669 static int
12670 api_lisp_add_del_locator (vat_main_t * vam)
12671 {
12672   unformat_input_t *input = vam->input;
12673   vl_api_lisp_add_del_locator_t *mp;
12674   f64 timeout = ~0;
12675   u32 tmp_if_index = ~0;
12676   u32 sw_if_index = ~0;
12677   u8 sw_if_index_set = 0;
12678   u8 sw_if_index_if_name_set = 0;
12679   u32 priority = ~0;
12680   u8 priority_set = 0;
12681   u32 weight = ~0;
12682   u8 weight_set = 0;
12683   u8 is_add = 1;
12684   u8 *locator_set_name = NULL;
12685   u8 locator_set_name_set = 0;
12686
12687   /* Parse args required to build the message */
12688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat (input, "del"))
12691         {
12692           is_add = 0;
12693         }
12694       else if (unformat (input, "locator-set %s", &locator_set_name))
12695         {
12696           locator_set_name_set = 1;
12697         }
12698       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12699                          &tmp_if_index))
12700         {
12701           sw_if_index_if_name_set = 1;
12702           sw_if_index = tmp_if_index;
12703         }
12704       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12705         {
12706           sw_if_index_set = 1;
12707           sw_if_index = tmp_if_index;
12708         }
12709       else if (unformat (input, "p %d", &priority))
12710         {
12711           priority_set = 1;
12712         }
12713       else if (unformat (input, "w %d", &weight))
12714         {
12715           weight_set = 1;
12716         }
12717       else
12718         break;
12719     }
12720
12721   if (locator_set_name_set == 0)
12722     {
12723       errmsg ("missing locator-set name");
12724       return -99;
12725     }
12726
12727   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12728     {
12729       errmsg ("missing sw_if_index");
12730       vec_free (locator_set_name);
12731       return -99;
12732     }
12733
12734   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12735     {
12736       errmsg ("cannot use both params interface name and sw_if_index");
12737       vec_free (locator_set_name);
12738       return -99;
12739     }
12740
12741   if (priority_set == 0)
12742     {
12743       errmsg ("missing locator-set priority\n");
12744       vec_free (locator_set_name);
12745       return -99;
12746     }
12747
12748   if (weight_set == 0)
12749     {
12750       errmsg ("missing locator-set weight\n");
12751       vec_free (locator_set_name);
12752       return -99;
12753     }
12754
12755   if (vec_len (locator_set_name) > 64)
12756     {
12757       errmsg ("locator-set name too long\n");
12758       vec_free (locator_set_name);
12759       return -99;
12760     }
12761   vec_add1 (locator_set_name, 0);
12762
12763   /* Construct the API message */
12764   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12765
12766   mp->is_add = is_add;
12767   mp->sw_if_index = ntohl (sw_if_index);
12768   mp->priority = priority;
12769   mp->weight = weight;
12770   clib_memcpy (mp->locator_set_name, locator_set_name,
12771                vec_len (locator_set_name));
12772   vec_free (locator_set_name);
12773
12774   /* send it... */
12775   S;
12776
12777   /* Wait for a reply... */
12778   W;
12779
12780   /* NOTREACHED */
12781   return 0;
12782 }
12783
12784 static int
12785 api_lisp_add_del_local_eid (vat_main_t * vam)
12786 {
12787   unformat_input_t *input = vam->input;
12788   vl_api_lisp_add_del_local_eid_t *mp;
12789   f64 timeout = ~0;
12790   u8 is_add = 1;
12791   u8 eid_set = 0;
12792   lisp_eid_vat_t _eid, *eid = &_eid;
12793   u8 *locator_set_name = 0;
12794   u8 locator_set_name_set = 0;
12795   u32 vni = 0;
12796
12797   /* Parse args required to build the message */
12798   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12799     {
12800       if (unformat (input, "del"))
12801         {
12802           is_add = 0;
12803         }
12804       else if (unformat (input, "vni %d", &vni))
12805         {
12806           ;
12807         }
12808       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12809         {
12810           eid_set = 1;
12811         }
12812       else if (unformat (input, "locator-set %s", &locator_set_name))
12813         {
12814           locator_set_name_set = 1;
12815         }
12816       else
12817         break;
12818     }
12819
12820   if (locator_set_name_set == 0)
12821     {
12822       errmsg ("missing locator-set name\n");
12823       return -99;
12824     }
12825
12826   if (0 == eid_set)
12827     {
12828       errmsg ("EID address not set!");
12829       vec_free (locator_set_name);
12830       return -99;
12831     }
12832
12833   if (vec_len (locator_set_name) > 64)
12834     {
12835       errmsg ("locator-set name too long\n");
12836       vec_free (locator_set_name);
12837       return -99;
12838     }
12839   vec_add1 (locator_set_name, 0);
12840
12841   /* Construct the API message */
12842   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12843
12844   mp->is_add = is_add;
12845   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12846   mp->eid_type = eid->type;
12847   mp->prefix_len = eid->len;
12848   mp->vni = clib_host_to_net_u32 (vni);
12849   clib_memcpy (mp->locator_set_name, locator_set_name,
12850                vec_len (locator_set_name));
12851
12852   vec_free (locator_set_name);
12853
12854   /* send it... */
12855   S;
12856
12857   /* Wait for a reply... */
12858   W;
12859
12860   /* NOTREACHED */
12861   return 0;
12862 }
12863
12864 /* *INDENT-OFF* */
12865 /** Used for transferring locators via VPP API */
12866 typedef CLIB_PACKED(struct
12867 {
12868   u8 is_ip4; /**< is locator an IPv4 address? */
12869   u8 priority; /**< locator priority */
12870   u8 weight;   /**< locator weight */
12871   u8 addr[16]; /**< IPv4/IPv6 address */
12872 }) rloc_t;
12873 /* *INDENT-ON* */
12874
12875 static int
12876 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12877 {
12878   unformat_input_t *input = vam->input;
12879   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12880   f64 timeout = ~0;
12881   u8 is_add = 1;
12882   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12883   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12884   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12885   u32 action = ~0, p, w;
12886   ip4_address_t rmt_rloc4, lcl_rloc4;
12887   ip6_address_t rmt_rloc6, lcl_rloc6;
12888   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12889
12890   memset (&rloc, 0, sizeof (rloc));
12891
12892   /* Parse args required to build the message */
12893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12894     {
12895       if (unformat (input, "del"))
12896         {
12897           is_add = 0;
12898         }
12899       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12900         {
12901           rmt_eid_set = 1;
12902         }
12903       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12904         {
12905           lcl_eid_set = 1;
12906         }
12907       else if (unformat (input, "p %d w %d", &p, &w))
12908         {
12909           if (!curr_rloc)
12910             {
12911               errmsg ("No RLOC configured for setting priority/weight!");
12912               return -99;
12913             }
12914           curr_rloc->priority = p;
12915           curr_rloc->weight = w;
12916         }
12917       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12918                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12919         {
12920           rloc.is_ip4 = 1;
12921
12922           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12923           rloc.priority = rloc.weight = 0;
12924           vec_add1 (lcl_locs, rloc);
12925
12926           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12927           vec_add1 (rmt_locs, rloc);
12928           /* priority and weight saved in rmt loc */
12929           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12930         }
12931       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12932                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12933         {
12934           rloc.is_ip4 = 0;
12935           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12936           rloc.priority = rloc.weight = 0;
12937           vec_add1 (lcl_locs, rloc);
12938
12939           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12940           vec_add1 (rmt_locs, rloc);
12941           /* priority and weight saved in rmt loc */
12942           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12943         }
12944       else if (unformat (input, "action %d", &action))
12945         {
12946           ;
12947         }
12948       else
12949         {
12950           clib_warning ("parse error '%U'", format_unformat_error, input);
12951           return -99;
12952         }
12953     }
12954
12955   if (!rmt_eid_set)
12956     {
12957       errmsg ("remote eid addresses not set\n");
12958       return -99;
12959     }
12960
12961   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12962     {
12963       errmsg ("eid types don't match\n");
12964       return -99;
12965     }
12966
12967   if (0 == rmt_locs && (u32) ~ 0 == action)
12968     {
12969       errmsg ("action not set for negative mapping\n");
12970       return -99;
12971     }
12972
12973   /* Construct the API message */
12974   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12975
12976   mp->is_add = is_add;
12977   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12978   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12979   mp->eid_type = rmt_eid->type;
12980   mp->rmt_len = rmt_eid->len;
12981   mp->lcl_len = lcl_eid->len;
12982   mp->action = action;
12983
12984   if (0 != rmt_locs && 0 != lcl_locs)
12985     {
12986       mp->loc_num = vec_len (rmt_locs);
12987       clib_memcpy (mp->lcl_locs, lcl_locs,
12988                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12989       clib_memcpy (mp->rmt_locs, rmt_locs,
12990                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12991     }
12992   vec_free (lcl_locs);
12993   vec_free (rmt_locs);
12994
12995   /* send it... */
12996   S;
12997
12998   /* Wait for a reply... */
12999   W;
13000
13001   /* NOTREACHED */
13002   return 0;
13003 }
13004
13005 static int
13006 api_lisp_add_del_map_resolver (vat_main_t * vam)
13007 {
13008   unformat_input_t *input = vam->input;
13009   vl_api_lisp_add_del_map_resolver_t *mp;
13010   f64 timeout = ~0;
13011   u8 is_add = 1;
13012   u8 ipv4_set = 0;
13013   u8 ipv6_set = 0;
13014   ip4_address_t ipv4;
13015   ip6_address_t ipv6;
13016
13017   /* Parse args required to build the message */
13018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13019     {
13020       if (unformat (input, "del"))
13021         {
13022           is_add = 0;
13023         }
13024       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13025         {
13026           ipv4_set = 1;
13027         }
13028       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13029         {
13030           ipv6_set = 1;
13031         }
13032       else
13033         break;
13034     }
13035
13036   if (ipv4_set && ipv6_set)
13037     {
13038       errmsg ("both eid v4 and v6 addresses set\n");
13039       return -99;
13040     }
13041
13042   if (!ipv4_set && !ipv6_set)
13043     {
13044       errmsg ("eid addresses not set\n");
13045       return -99;
13046     }
13047
13048   /* Construct the API message */
13049   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13050
13051   mp->is_add = is_add;
13052   if (ipv6_set)
13053     {
13054       mp->is_ipv6 = 1;
13055       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13056     }
13057   else
13058     {
13059       mp->is_ipv6 = 0;
13060       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13061     }
13062
13063   /* send it... */
13064   S;
13065
13066   /* Wait for a reply... */
13067   W;
13068
13069   /* NOTREACHED */
13070   return 0;
13071 }
13072
13073 static int
13074 api_lisp_gpe_enable_disable (vat_main_t * vam)
13075 {
13076   unformat_input_t *input = vam->input;
13077   vl_api_lisp_gpe_enable_disable_t *mp;
13078   f64 timeout = ~0;
13079   u8 is_set = 0;
13080   u8 is_en = 1;
13081
13082   /* Parse args required to build the message */
13083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13084     {
13085       if (unformat (input, "enable"))
13086         {
13087           is_set = 1;
13088           is_en = 1;
13089         }
13090       else if (unformat (input, "disable"))
13091         {
13092           is_set = 1;
13093           is_en = 0;
13094         }
13095       else
13096         break;
13097     }
13098
13099   if (is_set == 0)
13100     {
13101       errmsg ("Value not set\n");
13102       return -99;
13103     }
13104
13105   /* Construct the API message */
13106   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13107
13108   mp->is_en = is_en;
13109
13110   /* send it... */
13111   S;
13112
13113   /* Wait for a reply... */
13114   W;
13115
13116   /* NOTREACHED */
13117   return 0;
13118 }
13119
13120 static int
13121 api_lisp_enable_disable (vat_main_t * vam)
13122 {
13123   unformat_input_t *input = vam->input;
13124   vl_api_lisp_enable_disable_t *mp;
13125   f64 timeout = ~0;
13126   u8 is_set = 0;
13127   u8 is_en = 0;
13128
13129   /* Parse args required to build the message */
13130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13131     {
13132       if (unformat (input, "enable"))
13133         {
13134           is_set = 1;
13135           is_en = 1;
13136         }
13137       else if (unformat (input, "disable"))
13138         {
13139           is_set = 1;
13140         }
13141       else
13142         break;
13143     }
13144
13145   if (!is_set)
13146     {
13147       errmsg ("Value not set\n");
13148       return -99;
13149     }
13150
13151   /* Construct the API message */
13152   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13153
13154   mp->is_en = is_en;
13155
13156   /* send it... */
13157   S;
13158
13159   /* Wait for a reply... */
13160   W;
13161
13162   /* NOTREACHED */
13163   return 0;
13164 }
13165
13166 static int
13167 api_show_lisp_map_request_mode (vat_main_t * vam)
13168 {
13169   f64 timeout = ~0;
13170   vl_api_show_lisp_map_request_mode_t *mp;
13171
13172   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13173
13174   /* send */
13175   S;
13176
13177   /* wait for reply */
13178   W;
13179
13180   return 0;
13181 }
13182
13183 static int
13184 api_lisp_map_request_mode (vat_main_t * vam)
13185 {
13186   f64 timeout = ~0;
13187   unformat_input_t *input = vam->input;
13188   vl_api_lisp_map_request_mode_t *mp;
13189   u8 mode = 0;
13190
13191   /* Parse args required to build the message */
13192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13193     {
13194       if (unformat (input, "dst-only"))
13195         mode = 0;
13196       else if (unformat (input, "src-dst"))
13197         mode = 1;
13198       else
13199         {
13200           errmsg ("parse error '%U'", format_unformat_error, input);
13201           return -99;
13202         }
13203     }
13204
13205   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13206
13207   mp->mode = mode;
13208
13209   /* send */
13210   S;
13211
13212   /* wait for reply */
13213   W;
13214
13215   /* notreached */
13216   return 0;
13217 }
13218
13219 /**
13220  * Enable/disable LISP proxy ITR.
13221  *
13222  * @param vam vpp API test context
13223  * @return return code
13224  */
13225 static int
13226 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13227 {
13228   f64 timeout = ~0;
13229   u8 ls_name_set = 0;
13230   unformat_input_t *input = vam->input;
13231   vl_api_lisp_pitr_set_locator_set_t *mp;
13232   u8 is_add = 1;
13233   u8 *ls_name = 0;
13234
13235   /* Parse args required to build the message */
13236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13237     {
13238       if (unformat (input, "del"))
13239         is_add = 0;
13240       else if (unformat (input, "locator-set %s", &ls_name))
13241         ls_name_set = 1;
13242       else
13243         {
13244           errmsg ("parse error '%U'", format_unformat_error, input);
13245           return -99;
13246         }
13247     }
13248
13249   if (!ls_name_set)
13250     {
13251       errmsg ("locator-set name not set!");
13252       return -99;
13253     }
13254
13255   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13256
13257   mp->is_add = is_add;
13258   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13259   vec_free (ls_name);
13260
13261   /* send */
13262   S;
13263
13264   /* wait for reply */
13265   W;
13266
13267   /* notreached */
13268   return 0;
13269 }
13270
13271 static int
13272 api_show_lisp_pitr (vat_main_t * vam)
13273 {
13274   vl_api_show_lisp_pitr_t *mp;
13275   f64 timeout = ~0;
13276
13277   if (!vam->json_output)
13278     {
13279       fformat (vam->ofp, "%=20s\n", "lisp status:");
13280     }
13281
13282   M (SHOW_LISP_PITR, show_lisp_pitr);
13283   /* send it... */
13284   S;
13285
13286   /* Wait for a reply... */
13287   W;
13288
13289   /* NOTREACHED */
13290   return 0;
13291 }
13292
13293 /**
13294  * Add/delete mapping between vni and vrf
13295  */
13296 static int
13297 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13298 {
13299   f64 timeout = ~0;
13300   unformat_input_t *input = vam->input;
13301   vl_api_lisp_eid_table_add_del_map_t *mp;
13302   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13303   u32 vni, vrf, bd_index;
13304
13305   /* Parse args required to build the message */
13306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13307     {
13308       if (unformat (input, "del"))
13309         is_add = 0;
13310       else if (unformat (input, "vrf %d", &vrf))
13311         vrf_set = 1;
13312       else if (unformat (input, "bd_index %d", &bd_index))
13313         bd_index_set = 1;
13314       else if (unformat (input, "vni %d", &vni))
13315         vni_set = 1;
13316       else
13317         break;
13318     }
13319
13320   if (!vni_set || (!vrf_set && !bd_index_set))
13321     {
13322       errmsg ("missing arguments!");
13323       return -99;
13324     }
13325
13326   if (vrf_set && bd_index_set)
13327     {
13328       errmsg ("error: both vrf and bd entered!");
13329       return -99;
13330     }
13331
13332   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13333
13334   mp->is_add = is_add;
13335   mp->vni = htonl (vni);
13336   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13337   mp->is_l2 = bd_index_set;
13338
13339   /* send */
13340   S;
13341
13342   /* wait for reply */
13343   W;
13344
13345   /* notreached */
13346   return 0;
13347 }
13348
13349 uword
13350 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13351 {
13352   u32 *action = va_arg (*args, u32 *);
13353   u8 *s = 0;
13354
13355   if (unformat (input, "%s", &s))
13356     {
13357       if (!strcmp ((char *) s, "no-action"))
13358         action[0] = 0;
13359       else if (!strcmp ((char *) s, "natively-forward"))
13360         action[0] = 1;
13361       else if (!strcmp ((char *) s, "send-map-request"))
13362         action[0] = 2;
13363       else if (!strcmp ((char *) s, "drop"))
13364         action[0] = 3;
13365       else
13366         {
13367           clib_warning ("invalid action: '%s'", s);
13368           action[0] = 3;
13369         }
13370     }
13371   else
13372     return 0;
13373
13374   vec_free (s);
13375   return 1;
13376 }
13377
13378 /**
13379  * Add/del remote mapping to/from LISP control plane
13380  *
13381  * @param vam vpp API test context
13382  * @return return code
13383  */
13384 static int
13385 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13386 {
13387   unformat_input_t *input = vam->input;
13388   vl_api_lisp_add_del_remote_mapping_t *mp;
13389   f64 timeout = ~0;
13390   u32 vni = 0;
13391   lisp_eid_vat_t _eid, *eid = &_eid;
13392   lisp_eid_vat_t _seid, *seid = &_seid;
13393   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13394   u32 action = ~0, p, w, data_len;
13395   ip4_address_t rloc4;
13396   ip6_address_t rloc6;
13397   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13398
13399   memset (&rloc, 0, sizeof (rloc));
13400
13401   /* Parse args required to build the message */
13402   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13403     {
13404       if (unformat (input, "del-all"))
13405         {
13406           del_all = 1;
13407         }
13408       else if (unformat (input, "del"))
13409         {
13410           is_add = 0;
13411         }
13412       else if (unformat (input, "add"))
13413         {
13414           is_add = 1;
13415         }
13416       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13417         {
13418           eid_set = 1;
13419         }
13420       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13421         {
13422           seid_set = 1;
13423         }
13424       else if (unformat (input, "vni %d", &vni))
13425         {
13426           ;
13427         }
13428       else if (unformat (input, "p %d w %d", &p, &w))
13429         {
13430           if (!curr_rloc)
13431             {
13432               errmsg ("No RLOC configured for setting priority/weight!");
13433               return -99;
13434             }
13435           curr_rloc->priority = p;
13436           curr_rloc->weight = w;
13437         }
13438       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13439         {
13440           rloc.is_ip4 = 1;
13441           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13442           vec_add1 (rlocs, rloc);
13443           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13444         }
13445       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13446         {
13447           rloc.is_ip4 = 0;
13448           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13449           vec_add1 (rlocs, rloc);
13450           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13451         }
13452       else if (unformat (input, "action %U",
13453                          unformat_negative_mapping_action, &action))
13454         {
13455           ;
13456         }
13457       else
13458         {
13459           clib_warning ("parse error '%U'", format_unformat_error, input);
13460           return -99;
13461         }
13462     }
13463
13464   if (0 == eid_set)
13465     {
13466       errmsg ("missing params!");
13467       return -99;
13468     }
13469
13470   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13471     {
13472       errmsg ("no action set for negative map-reply!");
13473       return -99;
13474     }
13475
13476   data_len = vec_len (rlocs) * sizeof (rloc_t);
13477
13478   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13479   mp->is_add = is_add;
13480   mp->vni = htonl (vni);
13481   mp->action = (u8) action;
13482   mp->is_src_dst = seid_set;
13483   mp->eid_len = eid->len;
13484   mp->seid_len = seid->len;
13485   mp->del_all = del_all;
13486   mp->eid_type = eid->type;
13487   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13488   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13489
13490   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13491   clib_memcpy (mp->rlocs, rlocs, data_len);
13492   vec_free (rlocs);
13493
13494   /* send it... */
13495   S;
13496
13497   /* Wait for a reply... */
13498   W;
13499
13500   /* NOTREACHED */
13501   return 0;
13502 }
13503
13504 /**
13505  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13506  * forwarding entries in data-plane accordingly.
13507  *
13508  * @param vam vpp API test context
13509  * @return return code
13510  */
13511 static int
13512 api_lisp_add_del_adjacency (vat_main_t * vam)
13513 {
13514   unformat_input_t *input = vam->input;
13515   vl_api_lisp_add_del_adjacency_t *mp;
13516   f64 timeout = ~0;
13517   u32 vni = 0;
13518   ip4_address_t leid4, reid4;
13519   ip6_address_t leid6, reid6;
13520   u8 reid_mac[6] = { 0 };
13521   u8 leid_mac[6] = { 0 };
13522   u8 reid_type, leid_type;
13523   u32 leid_len = 0, reid_len = 0, len;
13524   u8 is_add = 1;
13525
13526   leid_type = reid_type = (u8) ~ 0;
13527
13528   /* Parse args required to build the message */
13529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13530     {
13531       if (unformat (input, "del"))
13532         {
13533           is_add = 0;
13534         }
13535       else if (unformat (input, "add"))
13536         {
13537           is_add = 1;
13538         }
13539       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13540                          &reid4, &len))
13541         {
13542           reid_type = 0;        /* ipv4 */
13543           reid_len = len;
13544         }
13545       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13546                          &reid6, &len))
13547         {
13548           reid_type = 1;        /* ipv6 */
13549           reid_len = len;
13550         }
13551       else if (unformat (input, "reid %U", unformat_ethernet_address,
13552                          reid_mac))
13553         {
13554           reid_type = 2;        /* mac */
13555         }
13556       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13557                          &leid4, &len))
13558         {
13559           leid_type = 0;        /* ipv4 */
13560           leid_len = len;
13561         }
13562       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13563                          &leid6, &len))
13564         {
13565           leid_type = 1;        /* ipv6 */
13566           leid_len = len;
13567         }
13568       else if (unformat (input, "leid %U", unformat_ethernet_address,
13569                          leid_mac))
13570         {
13571           leid_type = 2;        /* mac */
13572         }
13573       else if (unformat (input, "vni %d", &vni))
13574         {
13575           ;
13576         }
13577       else
13578         {
13579           errmsg ("parse error '%U'", format_unformat_error, input);
13580           return -99;
13581         }
13582     }
13583
13584   if ((u8) ~ 0 == reid_type)
13585     {
13586       errmsg ("missing params!");
13587       return -99;
13588     }
13589
13590   if (leid_type != reid_type)
13591     {
13592       errmsg ("remote and local EIDs are of different types!");
13593       return -99;
13594     }
13595
13596   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13597   mp->is_add = is_add;
13598   mp->vni = htonl (vni);
13599   mp->leid_len = leid_len;
13600   mp->reid_len = reid_len;
13601   mp->eid_type = reid_type;
13602
13603   switch (mp->eid_type)
13604     {
13605     case 0:
13606       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13607       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13608       break;
13609     case 1:
13610       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13611       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13612       break;
13613     case 2:
13614       clib_memcpy (mp->leid, leid_mac, 6);
13615       clib_memcpy (mp->reid, reid_mac, 6);
13616       break;
13617     default:
13618       errmsg ("unknown EID type %d!", mp->eid_type);
13619       return 0;
13620     }
13621
13622   /* send it... */
13623   S;
13624
13625   /* Wait for a reply... */
13626   W;
13627
13628   /* NOTREACHED */
13629   return 0;
13630 }
13631
13632 static int
13633 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13634 {
13635   unformat_input_t *input = vam->input;
13636   vl_api_lisp_gpe_add_del_iface_t *mp;
13637   f64 timeout = ~0;
13638   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13639   u32 dp_table = 0, vni = 0;
13640
13641   /* Parse args required to build the message */
13642   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13643     {
13644       if (unformat (input, "up"))
13645         {
13646           action_set = 1;
13647           is_add = 1;
13648         }
13649       else if (unformat (input, "down"))
13650         {
13651           action_set = 1;
13652           is_add = 0;
13653         }
13654       else if (unformat (input, "table_id %d", &dp_table))
13655         {
13656           dp_table_set = 1;
13657         }
13658       else if (unformat (input, "bd_id %d", &dp_table))
13659         {
13660           dp_table_set = 1;
13661           is_l2 = 1;
13662         }
13663       else if (unformat (input, "vni %d", &vni))
13664         {
13665           vni_set = 1;
13666         }
13667       else
13668         break;
13669     }
13670
13671   if (action_set == 0)
13672     {
13673       errmsg ("Action not set\n");
13674       return -99;
13675     }
13676   if (dp_table_set == 0 || vni_set == 0)
13677     {
13678       errmsg ("vni and dp_table must be set\n");
13679       return -99;
13680     }
13681
13682   /* Construct the API message */
13683   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13684
13685   mp->is_add = is_add;
13686   mp->dp_table = dp_table;
13687   mp->is_l2 = is_l2;
13688   mp->vni = vni;
13689
13690   /* send it... */
13691   S;
13692
13693   /* Wait for a reply... */
13694   W;
13695
13696   /* NOTREACHED */
13697   return 0;
13698 }
13699
13700 /**
13701  * Add/del map request itr rlocs from LISP control plane and updates
13702  *
13703  * @param vam vpp API test context
13704  * @return return code
13705  */
13706 static int
13707 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13708 {
13709   unformat_input_t *input = vam->input;
13710   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13711   f64 timeout = ~0;
13712   u8 *locator_set_name = 0;
13713   u8 locator_set_name_set = 0;
13714   u8 is_add = 1;
13715
13716   /* Parse args required to build the message */
13717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13718     {
13719       if (unformat (input, "del"))
13720         {
13721           is_add = 0;
13722         }
13723       else if (unformat (input, "%_%v%_", &locator_set_name))
13724         {
13725           locator_set_name_set = 1;
13726         }
13727       else
13728         {
13729           clib_warning ("parse error '%U'", format_unformat_error, input);
13730           return -99;
13731         }
13732     }
13733
13734   if (is_add && !locator_set_name_set)
13735     {
13736       errmsg ("itr-rloc is not set!");
13737       return -99;
13738     }
13739
13740   if (is_add && vec_len (locator_set_name) > 64)
13741     {
13742       errmsg ("itr-rloc locator-set name too long\n");
13743       vec_free (locator_set_name);
13744       return -99;
13745     }
13746
13747   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13748   mp->is_add = is_add;
13749   if (is_add)
13750     {
13751       clib_memcpy (mp->locator_set_name, locator_set_name,
13752                    vec_len (locator_set_name));
13753     }
13754   else
13755     {
13756       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13757     }
13758   vec_free (locator_set_name);
13759
13760   /* send it... */
13761   S;
13762
13763   /* Wait for a reply... */
13764   W;
13765
13766   /* NOTREACHED */
13767   return 0;
13768 }
13769
13770 static int
13771 api_lisp_locator_dump (vat_main_t * vam)
13772 {
13773   unformat_input_t *input = vam->input;
13774   vl_api_lisp_locator_dump_t *mp;
13775   f64 timeout = ~0;
13776   u8 is_index_set = 0, is_name_set = 0;
13777   u8 *ls_name = 0;
13778   u32 ls_index = ~0;
13779
13780   /* Parse args required to build the message */
13781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13782     {
13783       if (unformat (input, "ls_name %_%v%_", &ls_name))
13784         {
13785           is_name_set = 1;
13786         }
13787       else if (unformat (input, "ls_index %d", &ls_index))
13788         {
13789           is_index_set = 1;
13790         }
13791       else
13792         {
13793           errmsg ("parse error '%U'", format_unformat_error, input);
13794           return -99;
13795         }
13796     }
13797
13798   if (!is_index_set && !is_name_set)
13799     {
13800       errmsg ("error: expected one of index or name!\n");
13801       return -99;
13802     }
13803
13804   if (is_index_set && is_name_set)
13805     {
13806       errmsg ("error: only one param expected!\n");
13807       return -99;
13808     }
13809
13810   if (vec_len (ls_name) > 62)
13811     {
13812       errmsg ("error: locator set name too long!");
13813       return -99;
13814     }
13815
13816   if (!vam->json_output)
13817     {
13818       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13819                "weight");
13820     }
13821
13822   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13823   mp->is_index_set = is_index_set;
13824
13825   if (is_index_set)
13826     mp->ls_index = clib_host_to_net_u32 (ls_index);
13827   else
13828     {
13829       vec_add1 (ls_name, 0);
13830       strncpy ((char *) mp->ls_name, (char *) ls_name,
13831                sizeof (mp->ls_name) - 1);
13832     }
13833
13834   /* send it... */
13835   S;
13836
13837   /* Use a control ping for synchronization */
13838   {
13839     vl_api_control_ping_t *mp;
13840     M (CONTROL_PING, control_ping);
13841     S;
13842   }
13843   /* Wait for a reply... */
13844   W;
13845
13846   /* NOTREACHED */
13847   return 0;
13848 }
13849
13850 static int
13851 api_lisp_locator_set_dump (vat_main_t * vam)
13852 {
13853   vl_api_lisp_locator_set_dump_t *mp;
13854   unformat_input_t *input = vam->input;
13855   f64 timeout = ~0;
13856   u8 filter = 0;
13857
13858   /* Parse args required to build the message */
13859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13860     {
13861       if (unformat (input, "local"))
13862         {
13863           filter = 1;
13864         }
13865       else if (unformat (input, "remote"))
13866         {
13867           filter = 2;
13868         }
13869       else
13870         {
13871           errmsg ("parse error '%U'", format_unformat_error, input);
13872           return -99;
13873         }
13874     }
13875
13876   if (!vam->json_output)
13877     {
13878       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13879     }
13880
13881   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13882
13883   mp->filter = filter;
13884
13885   /* send it... */
13886   S;
13887
13888   /* Use a control ping for synchronization */
13889   {
13890     vl_api_control_ping_t *mp;
13891     M (CONTROL_PING, control_ping);
13892     S;
13893   }
13894   /* Wait for a reply... */
13895   W;
13896
13897   /* NOTREACHED */
13898   return 0;
13899 }
13900
13901 static int
13902 api_lisp_eid_table_map_dump (vat_main_t * vam)
13903 {
13904   u8 is_l2 = 0;
13905   u8 mode_set = 0;
13906   unformat_input_t *input = vam->input;
13907   vl_api_lisp_eid_table_map_dump_t *mp;
13908   f64 timeout = ~0;
13909
13910   /* Parse args required to build the message */
13911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13912     {
13913       if (unformat (input, "l2"))
13914         {
13915           is_l2 = 1;
13916           mode_set = 1;
13917         }
13918       else if (unformat (input, "l3"))
13919         {
13920           is_l2 = 0;
13921           mode_set = 1;
13922         }
13923       else
13924         {
13925           errmsg ("parse error '%U'", format_unformat_error, input);
13926           return -99;
13927         }
13928     }
13929
13930   if (!mode_set)
13931     {
13932       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13933       return -99;
13934     }
13935
13936   if (!vam->json_output)
13937     {
13938       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13939     }
13940
13941   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13942   mp->is_l2 = is_l2;
13943
13944   /* send it... */
13945   S;
13946
13947   /* Use a control ping for synchronization */
13948   {
13949     vl_api_control_ping_t *mp;
13950     M (CONTROL_PING, control_ping);
13951     S;
13952   }
13953   /* Wait for a reply... */
13954   W;
13955
13956   /* NOTREACHED */
13957   return 0;
13958 }
13959
13960 static int
13961 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13962 {
13963   vl_api_lisp_eid_table_vni_dump_t *mp;
13964   f64 timeout = ~0;
13965
13966   if (!vam->json_output)
13967     {
13968       fformat (vam->ofp, "VNI\n");
13969     }
13970
13971   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13972
13973   /* send it... */
13974   S;
13975
13976   /* Use a control ping for synchronization */
13977   {
13978     vl_api_control_ping_t *mp;
13979     M (CONTROL_PING, control_ping);
13980     S;
13981   }
13982   /* Wait for a reply... */
13983   W;
13984
13985   /* NOTREACHED */
13986   return 0;
13987 }
13988
13989 static int
13990 api_lisp_eid_table_dump (vat_main_t * vam)
13991 {
13992   unformat_input_t *i = vam->input;
13993   vl_api_lisp_eid_table_dump_t *mp;
13994   f64 timeout = ~0;
13995   struct in_addr ip4;
13996   struct in6_addr ip6;
13997   u8 mac[6];
13998   u8 eid_type = ~0, eid_set = 0;
13999   u32 prefix_length = ~0, t, vni = 0;
14000   u8 filter = 0;
14001
14002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14003     {
14004       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14005         {
14006           eid_set = 1;
14007           eid_type = 0;
14008           prefix_length = t;
14009         }
14010       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14011         {
14012           eid_set = 1;
14013           eid_type = 1;
14014           prefix_length = t;
14015         }
14016       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14017         {
14018           eid_set = 1;
14019           eid_type = 2;
14020         }
14021       else if (unformat (i, "vni %d", &t))
14022         {
14023           vni = t;
14024         }
14025       else if (unformat (i, "local"))
14026         {
14027           filter = 1;
14028         }
14029       else if (unformat (i, "remote"))
14030         {
14031           filter = 2;
14032         }
14033       else
14034         {
14035           errmsg ("parse error '%U'", format_unformat_error, i);
14036           return -99;
14037         }
14038     }
14039
14040   if (!vam->json_output)
14041     {
14042       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14043                "ls_index", "ttl", "authoritative");
14044     }
14045
14046   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14047
14048   mp->filter = filter;
14049   if (eid_set)
14050     {
14051       mp->eid_set = 1;
14052       mp->vni = htonl (vni);
14053       mp->eid_type = eid_type;
14054       switch (eid_type)
14055         {
14056         case 0:
14057           mp->prefix_length = prefix_length;
14058           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14059           break;
14060         case 1:
14061           mp->prefix_length = prefix_length;
14062           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14063           break;
14064         case 2:
14065           clib_memcpy (mp->eid, mac, sizeof (mac));
14066           break;
14067         default:
14068           errmsg ("unknown EID type %d!", eid_type);
14069           return -99;
14070         }
14071     }
14072
14073   /* send it... */
14074   S;
14075
14076   /* Use a control ping for synchronization */
14077   {
14078     vl_api_control_ping_t *mp;
14079     M (CONTROL_PING, control_ping);
14080     S;
14081   }
14082
14083   /* Wait for a reply... */
14084   W;
14085
14086   /* NOTREACHED */
14087   return 0;
14088 }
14089
14090 static int
14091 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14092 {
14093   vl_api_lisp_gpe_tunnel_dump_t *mp;
14094   f64 timeout = ~0;
14095
14096   if (!vam->json_output)
14097     {
14098       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14099                "%=16s%=16s%=16s%=16s%=16s\n",
14100                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14101                "Decap next", "Lisp version", "Flags", "Next protocol",
14102                "ver_res", "res", "iid");
14103     }
14104
14105   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14106   /* send it... */
14107   S;
14108
14109   /* Use a control ping for synchronization */
14110   {
14111     vl_api_control_ping_t *mp;
14112     M (CONTROL_PING, control_ping);
14113     S;
14114   }
14115   /* Wait for a reply... */
14116   W;
14117
14118   /* NOTREACHED */
14119   return 0;
14120 }
14121
14122 static int
14123 api_lisp_adjacencies_get (vat_main_t * vam)
14124 {
14125   unformat_input_t *i = vam->input;
14126   vl_api_lisp_adjacencies_get_t *mp;
14127   f64 timeout = ~0;
14128   u8 vni_set = 0;
14129   u32 vni = ~0;
14130
14131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14132     {
14133       if (unformat (i, "vni %d", &vni))
14134         {
14135           vni_set = 1;
14136         }
14137       else
14138         {
14139           errmsg ("parse error '%U'\n", format_unformat_error, i);
14140           return -99;
14141         }
14142     }
14143
14144   if (!vni_set)
14145     {
14146       errmsg ("vni not set!\n");
14147       return -99;
14148     }
14149
14150   if (!vam->json_output)
14151     {
14152       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14153     }
14154
14155   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14156   mp->vni = clib_host_to_net_u32 (vni);
14157
14158   /* send it... */
14159   S;
14160
14161   /* Wait for a reply... */
14162   W;
14163
14164   /* NOTREACHED */
14165   return 0;
14166 }
14167
14168 static int
14169 api_lisp_map_resolver_dump (vat_main_t * vam)
14170 {
14171   vl_api_lisp_map_resolver_dump_t *mp;
14172   f64 timeout = ~0;
14173
14174   if (!vam->json_output)
14175     {
14176       fformat (vam->ofp, "%=20s\n", "Map resolver");
14177     }
14178
14179   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14180   /* send it... */
14181   S;
14182
14183   /* Use a control ping for synchronization */
14184   {
14185     vl_api_control_ping_t *mp;
14186     M (CONTROL_PING, control_ping);
14187     S;
14188   }
14189   /* Wait for a reply... */
14190   W;
14191
14192   /* NOTREACHED */
14193   return 0;
14194 }
14195
14196 static int
14197 api_show_lisp_status (vat_main_t * vam)
14198 {
14199   vl_api_show_lisp_status_t *mp;
14200   f64 timeout = ~0;
14201
14202   if (!vam->json_output)
14203     {
14204       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14205     }
14206
14207   M (SHOW_LISP_STATUS, show_lisp_status);
14208   /* send it... */
14209   S;
14210   /* Wait for a reply... */
14211   W;
14212
14213   /* NOTREACHED */
14214   return 0;
14215 }
14216
14217 static int
14218 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14219 {
14220   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14221   f64 timeout = ~0;
14222
14223   if (!vam->json_output)
14224     {
14225       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14226     }
14227
14228   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14229   /* send it... */
14230   S;
14231   /* Wait for a reply... */
14232   W;
14233
14234   /* NOTREACHED */
14235   return 0;
14236 }
14237
14238 static int
14239 api_af_packet_create (vat_main_t * vam)
14240 {
14241   unformat_input_t *i = vam->input;
14242   vl_api_af_packet_create_t *mp;
14243   f64 timeout;
14244   u8 *host_if_name = 0;
14245   u8 hw_addr[6];
14246   u8 random_hw_addr = 1;
14247
14248   memset (hw_addr, 0, sizeof (hw_addr));
14249
14250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14251     {
14252       if (unformat (i, "name %s", &host_if_name))
14253         vec_add1 (host_if_name, 0);
14254       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14255         random_hw_addr = 0;
14256       else
14257         break;
14258     }
14259
14260   if (!vec_len (host_if_name))
14261     {
14262       errmsg ("host-interface name must be specified");
14263       return -99;
14264     }
14265
14266   if (vec_len (host_if_name) > 64)
14267     {
14268       errmsg ("host-interface name too long");
14269       return -99;
14270     }
14271
14272   M (AF_PACKET_CREATE, af_packet_create);
14273
14274   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14275   clib_memcpy (mp->hw_addr, hw_addr, 6);
14276   mp->use_random_hw_addr = random_hw_addr;
14277   vec_free (host_if_name);
14278
14279   S;
14280   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14281   /* NOTREACHED */
14282   return 0;
14283 }
14284
14285 static int
14286 api_af_packet_delete (vat_main_t * vam)
14287 {
14288   unformat_input_t *i = vam->input;
14289   vl_api_af_packet_delete_t *mp;
14290   f64 timeout;
14291   u8 *host_if_name = 0;
14292
14293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14294     {
14295       if (unformat (i, "name %s", &host_if_name))
14296         vec_add1 (host_if_name, 0);
14297       else
14298         break;
14299     }
14300
14301   if (!vec_len (host_if_name))
14302     {
14303       errmsg ("host-interface name must be specified");
14304       return -99;
14305     }
14306
14307   if (vec_len (host_if_name) > 64)
14308     {
14309       errmsg ("host-interface name too long");
14310       return -99;
14311     }
14312
14313   M (AF_PACKET_DELETE, af_packet_delete);
14314
14315   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14316   vec_free (host_if_name);
14317
14318   S;
14319   W;
14320   /* NOTREACHED */
14321   return 0;
14322 }
14323
14324 static int
14325 api_policer_add_del (vat_main_t * vam)
14326 {
14327   unformat_input_t *i = vam->input;
14328   vl_api_policer_add_del_t *mp;
14329   f64 timeout;
14330   u8 is_add = 1;
14331   u8 *name = 0;
14332   u32 cir = 0;
14333   u32 eir = 0;
14334   u64 cb = 0;
14335   u64 eb = 0;
14336   u8 rate_type = 0;
14337   u8 round_type = 0;
14338   u8 type = 0;
14339   u8 color_aware = 0;
14340   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14341
14342   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14343   conform_action.dscp = 0;
14344   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14345   exceed_action.dscp = 0;
14346   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14347   violate_action.dscp = 0;
14348
14349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14350     {
14351       if (unformat (i, "del"))
14352         is_add = 0;
14353       else if (unformat (i, "name %s", &name))
14354         vec_add1 (name, 0);
14355       else if (unformat (i, "cir %u", &cir))
14356         ;
14357       else if (unformat (i, "eir %u", &eir))
14358         ;
14359       else if (unformat (i, "cb %u", &cb))
14360         ;
14361       else if (unformat (i, "eb %u", &eb))
14362         ;
14363       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14364                          &rate_type))
14365         ;
14366       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14367                          &round_type))
14368         ;
14369       else if (unformat (i, "type %U", unformat_policer_type, &type))
14370         ;
14371       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14372                          &conform_action))
14373         ;
14374       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14375                          &exceed_action))
14376         ;
14377       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14378                          &violate_action))
14379         ;
14380       else if (unformat (i, "color-aware"))
14381         color_aware = 1;
14382       else
14383         break;
14384     }
14385
14386   if (!vec_len (name))
14387     {
14388       errmsg ("policer name must be specified");
14389       return -99;
14390     }
14391
14392   if (vec_len (name) > 64)
14393     {
14394       errmsg ("policer name too long");
14395       return -99;
14396     }
14397
14398   M (POLICER_ADD_DEL, policer_add_del);
14399
14400   clib_memcpy (mp->name, name, vec_len (name));
14401   vec_free (name);
14402   mp->is_add = is_add;
14403   mp->cir = cir;
14404   mp->eir = eir;
14405   mp->cb = cb;
14406   mp->eb = eb;
14407   mp->rate_type = rate_type;
14408   mp->round_type = round_type;
14409   mp->type = type;
14410   mp->conform_action_type = conform_action.action_type;
14411   mp->conform_dscp = conform_action.dscp;
14412   mp->exceed_action_type = exceed_action.action_type;
14413   mp->exceed_dscp = exceed_action.dscp;
14414   mp->violate_action_type = violate_action.action_type;
14415   mp->violate_dscp = violate_action.dscp;
14416   mp->color_aware = color_aware;
14417
14418   S;
14419   W;
14420   /* NOTREACHED */
14421   return 0;
14422 }
14423
14424 static int
14425 api_policer_dump (vat_main_t * vam)
14426 {
14427   unformat_input_t *i = vam->input;
14428   vl_api_policer_dump_t *mp;
14429   f64 timeout = ~0;
14430   u8 *match_name = 0;
14431   u8 match_name_valid = 0;
14432
14433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14434     {
14435       if (unformat (i, "name %s", &match_name))
14436         {
14437           vec_add1 (match_name, 0);
14438           match_name_valid = 1;
14439         }
14440       else
14441         break;
14442     }
14443
14444   M (POLICER_DUMP, policer_dump);
14445   mp->match_name_valid = match_name_valid;
14446   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14447   vec_free (match_name);
14448   /* send it... */
14449   S;
14450
14451   /* Use a control ping for synchronization */
14452   {
14453     vl_api_control_ping_t *mp;
14454     M (CONTROL_PING, control_ping);
14455     S;
14456   }
14457   /* Wait for a reply... */
14458   W;
14459
14460   /* NOTREACHED */
14461   return 0;
14462 }
14463
14464 static int
14465 api_policer_classify_set_interface (vat_main_t * vam)
14466 {
14467   unformat_input_t *i = vam->input;
14468   vl_api_policer_classify_set_interface_t *mp;
14469   f64 timeout;
14470   u32 sw_if_index;
14471   int sw_if_index_set;
14472   u32 ip4_table_index = ~0;
14473   u32 ip6_table_index = ~0;
14474   u32 l2_table_index = ~0;
14475   u8 is_add = 1;
14476
14477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14478     {
14479       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14480         sw_if_index_set = 1;
14481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14482         sw_if_index_set = 1;
14483       else if (unformat (i, "del"))
14484         is_add = 0;
14485       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14486         ;
14487       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14488         ;
14489       else if (unformat (i, "l2-table %d", &l2_table_index))
14490         ;
14491       else
14492         {
14493           clib_warning ("parse error '%U'", format_unformat_error, i);
14494           return -99;
14495         }
14496     }
14497
14498   if (sw_if_index_set == 0)
14499     {
14500       errmsg ("missing interface name or sw_if_index\n");
14501       return -99;
14502     }
14503
14504   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14505
14506   mp->sw_if_index = ntohl (sw_if_index);
14507   mp->ip4_table_index = ntohl (ip4_table_index);
14508   mp->ip6_table_index = ntohl (ip6_table_index);
14509   mp->l2_table_index = ntohl (l2_table_index);
14510   mp->is_add = is_add;
14511
14512   S;
14513   W;
14514   /* NOTREACHED */
14515   return 0;
14516 }
14517
14518 static int
14519 api_policer_classify_dump (vat_main_t * vam)
14520 {
14521   unformat_input_t *i = vam->input;
14522   vl_api_policer_classify_dump_t *mp;
14523   f64 timeout = ~0;
14524   u8 type = POLICER_CLASSIFY_N_TABLES;
14525
14526   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14527     ;
14528   else
14529     {
14530       errmsg ("classify table type must be specified\n");
14531       return -99;
14532     }
14533
14534   if (!vam->json_output)
14535     {
14536       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14537     }
14538
14539   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14540   mp->type = type;
14541   /* send it... */
14542   S;
14543
14544   /* Use a control ping for synchronization */
14545   {
14546     vl_api_control_ping_t *mp;
14547     M (CONTROL_PING, control_ping);
14548     S;
14549   }
14550   /* Wait for a reply... */
14551   W;
14552
14553   /* NOTREACHED */
14554   return 0;
14555 }
14556
14557 static int
14558 api_netmap_create (vat_main_t * vam)
14559 {
14560   unformat_input_t *i = vam->input;
14561   vl_api_netmap_create_t *mp;
14562   f64 timeout;
14563   u8 *if_name = 0;
14564   u8 hw_addr[6];
14565   u8 random_hw_addr = 1;
14566   u8 is_pipe = 0;
14567   u8 is_master = 0;
14568
14569   memset (hw_addr, 0, sizeof (hw_addr));
14570
14571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14572     {
14573       if (unformat (i, "name %s", &if_name))
14574         vec_add1 (if_name, 0);
14575       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14576         random_hw_addr = 0;
14577       else if (unformat (i, "pipe"))
14578         is_pipe = 1;
14579       else if (unformat (i, "master"))
14580         is_master = 1;
14581       else if (unformat (i, "slave"))
14582         is_master = 0;
14583       else
14584         break;
14585     }
14586
14587   if (!vec_len (if_name))
14588     {
14589       errmsg ("interface name must be specified");
14590       return -99;
14591     }
14592
14593   if (vec_len (if_name) > 64)
14594     {
14595       errmsg ("interface name too long");
14596       return -99;
14597     }
14598
14599   M (NETMAP_CREATE, netmap_create);
14600
14601   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14602   clib_memcpy (mp->hw_addr, hw_addr, 6);
14603   mp->use_random_hw_addr = random_hw_addr;
14604   mp->is_pipe = is_pipe;
14605   mp->is_master = is_master;
14606   vec_free (if_name);
14607
14608   S;
14609   W;
14610   /* NOTREACHED */
14611   return 0;
14612 }
14613
14614 static int
14615 api_netmap_delete (vat_main_t * vam)
14616 {
14617   unformat_input_t *i = vam->input;
14618   vl_api_netmap_delete_t *mp;
14619   f64 timeout;
14620   u8 *if_name = 0;
14621
14622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14623     {
14624       if (unformat (i, "name %s", &if_name))
14625         vec_add1 (if_name, 0);
14626       else
14627         break;
14628     }
14629
14630   if (!vec_len (if_name))
14631     {
14632       errmsg ("interface name must be specified");
14633       return -99;
14634     }
14635
14636   if (vec_len (if_name) > 64)
14637     {
14638       errmsg ("interface name too long");
14639       return -99;
14640     }
14641
14642   M (NETMAP_DELETE, netmap_delete);
14643
14644   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14645   vec_free (if_name);
14646
14647   S;
14648   W;
14649   /* NOTREACHED */
14650   return 0;
14651 }
14652
14653 static void vl_api_mpls_eth_tunnel_details_t_handler
14654   (vl_api_mpls_eth_tunnel_details_t * mp)
14655 {
14656   vat_main_t *vam = &vat_main;
14657   i32 i;
14658   i32 len = ntohl (mp->nlabels);
14659
14660   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14661            ntohl (mp->tunnel_index),
14662            format_ethernet_address, &mp->tunnel_dst_mac,
14663            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14664   for (i = 0; i < len; i++)
14665     {
14666       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14667     }
14668   fformat (vam->ofp, "\n");
14669   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14670            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14671 }
14672
14673 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14674   (vl_api_mpls_eth_tunnel_details_t * mp)
14675 {
14676   vat_main_t *vam = &vat_main;
14677   vat_json_node_t *node = NULL;
14678   struct in_addr ip4;
14679   i32 i;
14680   i32 len = ntohl (mp->nlabels);
14681
14682   if (VAT_JSON_ARRAY != vam->json_tree.type)
14683     {
14684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14685       vat_json_init_array (&vam->json_tree);
14686     }
14687   node = vat_json_array_add (&vam->json_tree);
14688
14689   vat_json_init_object (node);
14690   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14691   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14692   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14693   vat_json_object_add_uint (node, "inner_fib_index",
14694                             ntohl (mp->inner_fib_index));
14695   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14696   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14697   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14698   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14699   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14700                                    format (0, "%U", format_ethernet_address,
14701                                            &mp->tunnel_dst_mac));
14702   vat_json_object_add_uint (node, "tx_sw_if_index",
14703                             ntohl (mp->tx_sw_if_index));
14704   vat_json_object_add_uint (node, "label_count", len);
14705   for (i = 0; i < len; i++)
14706     {
14707       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14708     }
14709 }
14710
14711 static int
14712 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14713 {
14714   vl_api_mpls_eth_tunnel_dump_t *mp;
14715   f64 timeout;
14716   i32 index = -1;
14717
14718   /* Parse args required to build the message */
14719   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14720     {
14721       if (!unformat (vam->input, "tunnel_index %d", &index))
14722         {
14723           index = -1;
14724           break;
14725         }
14726     }
14727
14728   fformat (vam->ofp, "  tunnel_index %d\n", index);
14729
14730   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14731   mp->tunnel_index = htonl (index);
14732   S;
14733
14734   /* Use a control ping for synchronization */
14735   {
14736     vl_api_control_ping_t *mp;
14737     M (CONTROL_PING, control_ping);
14738     S;
14739   }
14740   W;
14741 }
14742
14743 static void vl_api_mpls_fib_encap_details_t_handler
14744   (vl_api_mpls_fib_encap_details_t * mp)
14745 {
14746   vat_main_t *vam = &vat_main;
14747   i32 i;
14748   i32 len = ntohl (mp->nlabels);
14749
14750   fformat (vam->ofp, "table %d, dest %U, label ",
14751            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14752   for (i = 0; i < len; i++)
14753     {
14754       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14755     }
14756   fformat (vam->ofp, "\n");
14757 }
14758
14759 static void vl_api_mpls_fib_encap_details_t_handler_json
14760   (vl_api_mpls_fib_encap_details_t * mp)
14761 {
14762   vat_main_t *vam = &vat_main;
14763   vat_json_node_t *node = NULL;
14764   i32 i;
14765   i32 len = ntohl (mp->nlabels);
14766   struct in_addr ip4;
14767
14768   if (VAT_JSON_ARRAY != vam->json_tree.type)
14769     {
14770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14771       vat_json_init_array (&vam->json_tree);
14772     }
14773   node = vat_json_array_add (&vam->json_tree);
14774
14775   vat_json_init_object (node);
14776   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14777   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14778   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14779   vat_json_object_add_ip4 (node, "dest", ip4);
14780   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14781   vat_json_object_add_uint (node, "label_count", len);
14782   for (i = 0; i < len; i++)
14783     {
14784       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14785     }
14786 }
14787
14788 static int
14789 api_mpls_fib_encap_dump (vat_main_t * vam)
14790 {
14791   vl_api_mpls_fib_encap_dump_t *mp;
14792   f64 timeout;
14793
14794   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14795   S;
14796
14797   /* Use a control ping for synchronization */
14798   {
14799     vl_api_control_ping_t *mp;
14800     M (CONTROL_PING, control_ping);
14801     S;
14802   }
14803   W;
14804 }
14805
14806 static void
14807 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14808 {
14809   vat_main_t *vam = &vat_main;
14810
14811   fformat (vam->ofp,
14812            "table-id %d, label %u, ess_bit %u\n",
14813            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14814 }
14815
14816 static void vl_api_mpls_fib_details_t_handler_json
14817   (vl_api_mpls_fib_details_t * mp)
14818 {
14819   vat_main_t *vam = &vat_main;
14820   vat_json_node_t *node = NULL;
14821
14822   if (VAT_JSON_ARRAY != vam->json_tree.type)
14823     {
14824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14825       vat_json_init_array (&vam->json_tree);
14826     }
14827   node = vat_json_array_add (&vam->json_tree);
14828
14829   vat_json_init_object (node);
14830   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14831   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14832   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14833 }
14834
14835 static int
14836 api_mpls_fib_dump (vat_main_t * vam)
14837 {
14838   vl_api_mpls_fib_dump_t *mp;
14839   f64 timeout;
14840
14841   M (MPLS_FIB_DUMP, mpls_fib_dump);
14842   S;
14843
14844   /* Use a control ping for synchronization */
14845   {
14846     vl_api_control_ping_t *mp;
14847     M (CONTROL_PING, control_ping);
14848     S;
14849   }
14850   W;
14851 }
14852
14853 int
14854 api_classify_table_ids (vat_main_t * vam)
14855 {
14856   vl_api_classify_table_ids_t *mp;
14857   f64 timeout;
14858
14859   /* Construct the API message */
14860   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14861   mp->context = 0;
14862
14863   S;
14864   W;
14865   /* NOTREACHED */
14866   return 0;
14867 }
14868
14869 int
14870 api_classify_table_by_interface (vat_main_t * vam)
14871 {
14872   unformat_input_t *input = vam->input;
14873   vl_api_classify_table_by_interface_t *mp;
14874   f64 timeout;
14875
14876   u32 sw_if_index = ~0;
14877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14878     {
14879       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14880         ;
14881       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14882         ;
14883       else
14884         break;
14885     }
14886   if (sw_if_index == ~0)
14887     {
14888       errmsg ("missing interface name or sw_if_index\n");
14889       return -99;
14890     }
14891
14892   /* Construct the API message */
14893   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14894   mp->context = 0;
14895   mp->sw_if_index = ntohl (sw_if_index);
14896
14897   S;
14898   W;
14899   /* NOTREACHED */
14900   return 0;
14901 }
14902
14903 int
14904 api_classify_table_info (vat_main_t * vam)
14905 {
14906   unformat_input_t *input = vam->input;
14907   vl_api_classify_table_info_t *mp;
14908   f64 timeout;
14909
14910   u32 table_id = ~0;
14911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14912     {
14913       if (unformat (input, "table_id %d", &table_id))
14914         ;
14915       else
14916         break;
14917     }
14918   if (table_id == ~0)
14919     {
14920       errmsg ("missing table id\n");
14921       return -99;
14922     }
14923
14924   /* Construct the API message */
14925   M (CLASSIFY_TABLE_INFO, classify_table_info);
14926   mp->context = 0;
14927   mp->table_id = ntohl (table_id);
14928
14929   S;
14930   W;
14931   /* NOTREACHED */
14932   return 0;
14933 }
14934
14935 int
14936 api_classify_session_dump (vat_main_t * vam)
14937 {
14938   unformat_input_t *input = vam->input;
14939   vl_api_classify_session_dump_t *mp;
14940   f64 timeout;
14941
14942   u32 table_id = ~0;
14943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14944     {
14945       if (unformat (input, "table_id %d", &table_id))
14946         ;
14947       else
14948         break;
14949     }
14950   if (table_id == ~0)
14951     {
14952       errmsg ("missing table id\n");
14953       return -99;
14954     }
14955
14956   /* Construct the API message */
14957   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14958   mp->context = 0;
14959   mp->table_id = ntohl (table_id);
14960   S;
14961
14962   /* Use a control ping for synchronization */
14963   {
14964     vl_api_control_ping_t *mp;
14965     M (CONTROL_PING, control_ping);
14966     S;
14967   }
14968   W;
14969   /* NOTREACHED */
14970   return 0;
14971 }
14972
14973 static void
14974 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14975 {
14976   vat_main_t *vam = &vat_main;
14977
14978   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14979            "src_address %U, vrf_id %d, path_mtu %u, "
14980            "template_interval %u, udp_checksum %d\n",
14981            format_ip4_address, mp->collector_address,
14982            ntohs (mp->collector_port),
14983            format_ip4_address, mp->src_address,
14984            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14985            ntohl (mp->template_interval), mp->udp_checksum);
14986
14987   vam->retval = 0;
14988   vam->result_ready = 1;
14989 }
14990
14991 static void
14992   vl_api_ipfix_exporter_details_t_handler_json
14993   (vl_api_ipfix_exporter_details_t * mp)
14994 {
14995   vat_main_t *vam = &vat_main;
14996   vat_json_node_t node;
14997   struct in_addr collector_address;
14998   struct in_addr src_address;
14999
15000   vat_json_init_object (&node);
15001   clib_memcpy (&collector_address, &mp->collector_address,
15002                sizeof (collector_address));
15003   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15004   vat_json_object_add_uint (&node, "collector_port",
15005                             ntohs (mp->collector_port));
15006   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15007   vat_json_object_add_ip4 (&node, "src_address", src_address);
15008   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15009   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15010   vat_json_object_add_uint (&node, "template_interval",
15011                             ntohl (mp->template_interval));
15012   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15013
15014   vat_json_print (vam->ofp, &node);
15015   vat_json_free (&node);
15016   vam->retval = 0;
15017   vam->result_ready = 1;
15018 }
15019
15020 int
15021 api_ipfix_exporter_dump (vat_main_t * vam)
15022 {
15023   vl_api_ipfix_exporter_dump_t *mp;
15024   f64 timeout;
15025
15026   /* Construct the API message */
15027   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15028   mp->context = 0;
15029
15030   S;
15031   W;
15032   /* NOTREACHED */
15033   return 0;
15034 }
15035
15036 static int
15037 api_ipfix_classify_stream_dump (vat_main_t * vam)
15038 {
15039   vl_api_ipfix_classify_stream_dump_t *mp;
15040   f64 timeout;
15041
15042   /* Construct the API message */
15043   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15044   mp->context = 0;
15045
15046   S;
15047   W;
15048   /* NOTREACHED */
15049   return 0;
15050 }
15051
15052 static void
15053   vl_api_ipfix_classify_stream_details_t_handler
15054   (vl_api_ipfix_classify_stream_details_t * mp)
15055 {
15056   vat_main_t *vam = &vat_main;
15057   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15058            ntohl (mp->domain_id), ntohs (mp->src_port));
15059   vam->retval = 0;
15060   vam->result_ready = 1;
15061 }
15062
15063 static void
15064   vl_api_ipfix_classify_stream_details_t_handler_json
15065   (vl_api_ipfix_classify_stream_details_t * mp)
15066 {
15067   vat_main_t *vam = &vat_main;
15068   vat_json_node_t node;
15069
15070   vat_json_init_object (&node);
15071   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15072   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15073
15074   vat_json_print (vam->ofp, &node);
15075   vat_json_free (&node);
15076   vam->retval = 0;
15077   vam->result_ready = 1;
15078 }
15079
15080 static int
15081 api_ipfix_classify_table_dump (vat_main_t * vam)
15082 {
15083   vl_api_ipfix_classify_table_dump_t *mp;
15084   f64 timeout;
15085
15086   if (!vam->json_output)
15087     {
15088       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15089                "transport_protocol");
15090     }
15091
15092   /* Construct the API message */
15093   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15094
15095   /* send it... */
15096   S;
15097
15098   /* Use a control ping for synchronization */
15099   {
15100     vl_api_control_ping_t *mp;
15101     M (CONTROL_PING, control_ping);
15102     S;
15103   }
15104   W;
15105 }
15106
15107 static void
15108   vl_api_ipfix_classify_table_details_t_handler
15109   (vl_api_ipfix_classify_table_details_t * mp)
15110 {
15111   vat_main_t *vam = &vat_main;
15112   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15113            mp->transport_protocol);
15114 }
15115
15116 static void
15117   vl_api_ipfix_classify_table_details_t_handler_json
15118   (vl_api_ipfix_classify_table_details_t * mp)
15119 {
15120   vat_json_node_t *node = NULL;
15121   vat_main_t *vam = &vat_main;
15122
15123   if (VAT_JSON_ARRAY != vam->json_tree.type)
15124     {
15125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15126       vat_json_init_array (&vam->json_tree);
15127     }
15128
15129   node = vat_json_array_add (&vam->json_tree);
15130   vat_json_init_object (node);
15131
15132   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15133   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15134   vat_json_object_add_uint (node, "transport_protocol",
15135                             mp->transport_protocol);
15136 }
15137
15138 int
15139 api_pg_create_interface (vat_main_t * vam)
15140 {
15141   unformat_input_t *input = vam->input;
15142   vl_api_pg_create_interface_t *mp;
15143   f64 timeout;
15144
15145   u32 if_id = ~0;
15146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15147     {
15148       if (unformat (input, "if_id %d", &if_id))
15149         ;
15150       else
15151         break;
15152     }
15153   if (if_id == ~0)
15154     {
15155       errmsg ("missing pg interface index\n");
15156       return -99;
15157     }
15158
15159   /* Construct the API message */
15160   M (PG_CREATE_INTERFACE, pg_create_interface);
15161   mp->context = 0;
15162   mp->interface_id = ntohl (if_id);
15163
15164   S;
15165   W;
15166   /* NOTREACHED */
15167   return 0;
15168 }
15169
15170 int
15171 api_pg_capture (vat_main_t * vam)
15172 {
15173   unformat_input_t *input = vam->input;
15174   vl_api_pg_capture_t *mp;
15175   f64 timeout;
15176
15177   u32 if_id = ~0;
15178   u8 enable = 1;
15179   u32 count = 1;
15180   u8 pcap_file_set = 0;
15181   u8 *pcap_file = 0;
15182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15183     {
15184       if (unformat (input, "if_id %d", &if_id))
15185         ;
15186       else if (unformat (input, "pcap %s", &pcap_file))
15187         pcap_file_set = 1;
15188       else if (unformat (input, "count %d", &count))
15189         ;
15190       else if (unformat (input, "disable"))
15191         enable = 0;
15192       else
15193         break;
15194     }
15195   if (if_id == ~0)
15196     {
15197       errmsg ("missing pg interface index\n");
15198       return -99;
15199     }
15200   if (pcap_file_set > 0)
15201     {
15202       if (vec_len (pcap_file) > 255)
15203         {
15204           errmsg ("pcap file name is too long\n");
15205           return -99;
15206         }
15207     }
15208
15209   u32 name_len = vec_len (pcap_file);
15210   /* Construct the API message */
15211   M (PG_CAPTURE, pg_capture);
15212   mp->context = 0;
15213   mp->interface_id = ntohl (if_id);
15214   mp->is_enabled = enable;
15215   mp->count = ntohl (count);
15216   mp->pcap_name_length = ntohl (name_len);
15217   if (pcap_file_set != 0)
15218     {
15219       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15220     }
15221   vec_free (pcap_file);
15222
15223   S;
15224   W;
15225   /* NOTREACHED */
15226   return 0;
15227 }
15228
15229 int
15230 api_pg_enable_disable (vat_main_t * vam)
15231 {
15232   unformat_input_t *input = vam->input;
15233   vl_api_pg_enable_disable_t *mp;
15234   f64 timeout;
15235
15236   u8 enable = 1;
15237   u8 stream_name_set = 0;
15238   u8 *stream_name = 0;
15239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15240     {
15241       if (unformat (input, "stream %s", &stream_name))
15242         stream_name_set = 1;
15243       else if (unformat (input, "disable"))
15244         enable = 0;
15245       else
15246         break;
15247     }
15248
15249   if (stream_name_set > 0)
15250     {
15251       if (vec_len (stream_name) > 255)
15252         {
15253           errmsg ("stream name too long\n");
15254           return -99;
15255         }
15256     }
15257
15258   u32 name_len = vec_len (stream_name);
15259   /* Construct the API message */
15260   M (PG_ENABLE_DISABLE, pg_enable_disable);
15261   mp->context = 0;
15262   mp->is_enabled = enable;
15263   if (stream_name_set != 0)
15264     {
15265       mp->stream_name_length = ntohl (name_len);
15266       clib_memcpy (mp->stream_name, stream_name, name_len);
15267     }
15268   vec_free (stream_name);
15269
15270   S;
15271   W;
15272   /* NOTREACHED */
15273   return 0;
15274 }
15275
15276 int
15277 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15278 {
15279   unformat_input_t *input = vam->input;
15280   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15281   f64 timeout;
15282
15283   u16 *low_ports = 0;
15284   u16 *high_ports = 0;
15285   u16 this_low;
15286   u16 this_hi;
15287   ip4_address_t ip4_addr;
15288   ip6_address_t ip6_addr;
15289   u32 length;
15290   u32 tmp, tmp2;
15291   u8 prefix_set = 0;
15292   u32 vrf_id = ~0;
15293   u8 is_add = 1;
15294   u8 is_ipv6 = 0;
15295
15296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15297     {
15298       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15299         {
15300           prefix_set = 1;
15301         }
15302       else
15303         if (unformat
15304             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15305         {
15306           prefix_set = 1;
15307           is_ipv6 = 1;
15308         }
15309       else if (unformat (input, "vrf %d", &vrf_id))
15310         ;
15311       else if (unformat (input, "del"))
15312         is_add = 0;
15313       else if (unformat (input, "port %d", &tmp))
15314         {
15315           if (tmp == 0 || tmp > 65535)
15316             {
15317               errmsg ("port %d out of range", tmp);
15318               return -99;
15319             }
15320           this_low = tmp;
15321           this_hi = this_low + 1;
15322           vec_add1 (low_ports, this_low);
15323           vec_add1 (high_ports, this_hi);
15324         }
15325       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15326         {
15327           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15328             {
15329               errmsg ("incorrect range parameters\n");
15330               return -99;
15331             }
15332           this_low = tmp;
15333           /* Note: in debug CLI +1 is added to high before
15334              passing to real fn that does "the work"
15335              (ip_source_and_port_range_check_add_del).
15336              This fn is a wrapper around the binary API fn a
15337              control plane will call, which expects this increment
15338              to have occurred. Hence letting the binary API control
15339              plane fn do the increment for consistency between VAT
15340              and other control planes.
15341            */
15342           this_hi = tmp2;
15343           vec_add1 (low_ports, this_low);
15344           vec_add1 (high_ports, this_hi);
15345         }
15346       else
15347         break;
15348     }
15349
15350   if (prefix_set == 0)
15351     {
15352       errmsg ("<address>/<mask> not specified\n");
15353       return -99;
15354     }
15355
15356   if (vrf_id == ~0)
15357     {
15358       errmsg ("VRF ID required, not specified\n");
15359       return -99;
15360     }
15361
15362   if (vrf_id == 0)
15363     {
15364       errmsg
15365         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15366       return -99;
15367     }
15368
15369   if (vec_len (low_ports) == 0)
15370     {
15371       errmsg ("At least one port or port range required\n");
15372       return -99;
15373     }
15374
15375   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15376      ip_source_and_port_range_check_add_del);
15377
15378   mp->is_add = is_add;
15379
15380   if (is_ipv6)
15381     {
15382       mp->is_ipv6 = 1;
15383       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15384     }
15385   else
15386     {
15387       mp->is_ipv6 = 0;
15388       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15389     }
15390
15391   mp->mask_length = length;
15392   mp->number_of_ranges = vec_len (low_ports);
15393
15394   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15395   vec_free (low_ports);
15396
15397   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15398   vec_free (high_ports);
15399
15400   mp->vrf_id = ntohl (vrf_id);
15401
15402   S;
15403   W;
15404   /* NOTREACHED */
15405   return 0;
15406 }
15407
15408 int
15409 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15410 {
15411   unformat_input_t *input = vam->input;
15412   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15413   f64 timeout;
15414   u32 sw_if_index = ~0;
15415   int vrf_set = 0;
15416   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15417   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15418   u8 is_add = 1;
15419
15420   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15421     {
15422       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15423         ;
15424       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15425         ;
15426       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15427         vrf_set = 1;
15428       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15429         vrf_set = 1;
15430       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15431         vrf_set = 1;
15432       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15433         vrf_set = 1;
15434       else if (unformat (input, "del"))
15435         is_add = 0;
15436       else
15437         break;
15438     }
15439
15440   if (sw_if_index == ~0)
15441     {
15442       errmsg ("Interface required but not specified\n");
15443       return -99;
15444     }
15445
15446   if (vrf_set == 0)
15447     {
15448       errmsg ("VRF ID required but not specified\n");
15449       return -99;
15450     }
15451
15452   if (tcp_out_vrf_id == 0
15453       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15454     {
15455       errmsg
15456         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15457       return -99;
15458     }
15459
15460   /* Construct the API message */
15461   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15462      ip_source_and_port_range_check_interface_add_del);
15463
15464   mp->sw_if_index = ntohl (sw_if_index);
15465   mp->is_add = is_add;
15466   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15467   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15468   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15469   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15470
15471   /* send it... */
15472   S;
15473
15474   /* Wait for a reply... */
15475   W;
15476 }
15477
15478 static int
15479 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15480 {
15481   unformat_input_t *i = vam->input;
15482   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15483   f64 timeout;
15484   u32 local_sa_id = 0;
15485   u32 remote_sa_id = 0;
15486   ip4_address_t src_address;
15487   ip4_address_t dst_address;
15488   u8 is_add = 1;
15489
15490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15491     {
15492       if (unformat (i, "local_sa %d", &local_sa_id))
15493         ;
15494       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15495         ;
15496       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15497         ;
15498       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15499         ;
15500       else if (unformat (i, "del"))
15501         is_add = 0;
15502       else
15503         {
15504           clib_warning ("parse error '%U'", format_unformat_error, i);
15505           return -99;
15506         }
15507     }
15508
15509   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15510
15511   mp->local_sa_id = ntohl (local_sa_id);
15512   mp->remote_sa_id = ntohl (remote_sa_id);
15513   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15514   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15515   mp->is_add = is_add;
15516
15517   S;
15518   W;
15519   /* NOTREACHED */
15520   return 0;
15521 }
15522
15523 static int
15524 api_punt (vat_main_t * vam)
15525 {
15526   unformat_input_t *i = vam->input;
15527   vl_api_punt_t *mp;
15528   f64 timeout;
15529   u32 ipv = ~0;
15530   u32 protocol = ~0;
15531   u32 port = ~0;
15532   int is_add = 1;
15533
15534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15535     {
15536       if (unformat (i, "ip %d", &ipv))
15537         ;
15538       else if (unformat (i, "protocol %d", &protocol))
15539         ;
15540       else if (unformat (i, "port %d", &port))
15541         ;
15542       else if (unformat (i, "del"))
15543         is_add = 0;
15544       else
15545         {
15546           clib_warning ("parse error '%U'", format_unformat_error, i);
15547           return -99;
15548         }
15549     }
15550
15551   M (PUNT, punt);
15552
15553   mp->is_add = (u8) is_add;
15554   mp->ipv = (u8) ipv;
15555   mp->l4_protocol = (u8) protocol;
15556   mp->l4_port = htons ((u16) port);
15557
15558   S;
15559   W;
15560   /* NOTREACHED */
15561   return 0;
15562 }
15563
15564 static void vl_api_ipsec_gre_tunnel_details_t_handler
15565   (vl_api_ipsec_gre_tunnel_details_t * mp)
15566 {
15567   vat_main_t *vam = &vat_main;
15568
15569   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15570            ntohl (mp->sw_if_index),
15571            format_ip4_address, &mp->src_address,
15572            format_ip4_address, &mp->dst_address,
15573            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15574 }
15575
15576 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15577   (vl_api_ipsec_gre_tunnel_details_t * mp)
15578 {
15579   vat_main_t *vam = &vat_main;
15580   vat_json_node_t *node = NULL;
15581   struct in_addr ip4;
15582
15583   if (VAT_JSON_ARRAY != vam->json_tree.type)
15584     {
15585       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15586       vat_json_init_array (&vam->json_tree);
15587     }
15588   node = vat_json_array_add (&vam->json_tree);
15589
15590   vat_json_init_object (node);
15591   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15592   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15593   vat_json_object_add_ip4 (node, "src_address", ip4);
15594   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15595   vat_json_object_add_ip4 (node, "dst_address", ip4);
15596   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15597   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15598 }
15599
15600 static int
15601 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15602 {
15603   unformat_input_t *i = vam->input;
15604   vl_api_ipsec_gre_tunnel_dump_t *mp;
15605   f64 timeout;
15606   u32 sw_if_index;
15607   u8 sw_if_index_set = 0;
15608
15609   /* Parse args required to build the message */
15610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15611     {
15612       if (unformat (i, "sw_if_index %d", &sw_if_index))
15613         sw_if_index_set = 1;
15614       else
15615         break;
15616     }
15617
15618   if (sw_if_index_set == 0)
15619     {
15620       sw_if_index = ~0;
15621     }
15622
15623   if (!vam->json_output)
15624     {
15625       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15626                "sw_if_index", "src_address", "dst_address",
15627                "local_sa_id", "remote_sa_id");
15628     }
15629
15630   /* Get list of gre-tunnel interfaces */
15631   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15632
15633   mp->sw_if_index = htonl (sw_if_index);
15634
15635   S;
15636
15637   /* Use a control ping for synchronization */
15638   {
15639     vl_api_control_ping_t *mp;
15640     M (CONTROL_PING, control_ping);
15641     S;
15642   }
15643   W;
15644 }
15645
15646 static int
15647 api_delete_subif (vat_main_t * vam)
15648 {
15649   unformat_input_t *i = vam->input;
15650   vl_api_delete_subif_t *mp;
15651   f64 timeout;
15652   u32 sw_if_index = ~0;
15653
15654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15655     {
15656       if (unformat (i, "sw_if_index %d", &sw_if_index))
15657         ;
15658       else
15659         break;
15660     }
15661
15662   if (sw_if_index == ~0)
15663     {
15664       errmsg ("missing sw_if_index\n");
15665       return -99;
15666     }
15667
15668   /* Construct the API message */
15669   M (DELETE_SUBIF, delete_subif);
15670   mp->sw_if_index = ntohl (sw_if_index);
15671
15672   S;
15673   W;
15674 }
15675
15676 #define foreach_pbb_vtr_op      \
15677 _("disable",  L2_VTR_DISABLED)  \
15678 _("pop",  L2_VTR_POP_2)         \
15679 _("push",  L2_VTR_PUSH_2)
15680
15681 static int
15682 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15683 {
15684   unformat_input_t *i = vam->input;
15685   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15686   f64 timeout;
15687   u32 sw_if_index = ~0, vtr_op = ~0;
15688   u16 outer_tag = ~0;
15689   u8 dmac[6], smac[6];
15690   u8 dmac_set = 0, smac_set = 0;
15691   u16 vlanid = 0;
15692   u32 sid = ~0;
15693   u32 tmp;
15694
15695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15696     {
15697       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15698         ;
15699       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15700         ;
15701       else if (unformat (i, "vtr_op %d", &vtr_op))
15702         ;
15703 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15704       foreach_pbb_vtr_op
15705 #undef _
15706         else if (unformat (i, "translate_pbb_stag"))
15707         {
15708           if (unformat (i, "%d", &tmp))
15709             {
15710               vtr_op = L2_VTR_TRANSLATE_2_1;
15711               outer_tag = tmp;
15712             }
15713           else
15714             {
15715               errmsg
15716                 ("translate_pbb_stag operation requires outer tag definition\n");
15717               return -99;
15718             }
15719         }
15720       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15721         dmac_set++;
15722       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15723         smac_set++;
15724       else if (unformat (i, "sid %d", &sid))
15725         ;
15726       else if (unformat (i, "vlanid %d", &tmp))
15727         vlanid = tmp;
15728       else
15729         {
15730           clib_warning ("parse error '%U'", format_unformat_error, i);
15731           return -99;
15732         }
15733     }
15734
15735   if ((sw_if_index == ~0) || (vtr_op == ~0))
15736     {
15737       errmsg ("missing sw_if_index or vtr operation\n");
15738       return -99;
15739     }
15740   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15741       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15742     {
15743       errmsg
15744         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15745       return -99;
15746     }
15747
15748   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15749   mp->sw_if_index = ntohl (sw_if_index);
15750   mp->vtr_op = ntohl (vtr_op);
15751   mp->outer_tag = ntohs (outer_tag);
15752   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15753   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15754   mp->b_vlanid = ntohs (vlanid);
15755   mp->i_sid = ntohl (sid);
15756
15757   S;
15758   W;
15759   /* NOTREACHED */
15760   return 0;
15761 }
15762
15763 static int
15764 api_flow_classify_set_interface (vat_main_t * vam)
15765 {
15766   unformat_input_t *i = vam->input;
15767   vl_api_flow_classify_set_interface_t *mp;
15768   f64 timeout;
15769   u32 sw_if_index;
15770   int sw_if_index_set;
15771   u32 ip4_table_index = ~0;
15772   u32 ip6_table_index = ~0;
15773   u8 is_add = 1;
15774
15775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15776     {
15777       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15778         sw_if_index_set = 1;
15779       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15780         sw_if_index_set = 1;
15781       else if (unformat (i, "del"))
15782         is_add = 0;
15783       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15784         ;
15785       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15786         ;
15787       else
15788         {
15789           clib_warning ("parse error '%U'", format_unformat_error, i);
15790           return -99;
15791         }
15792     }
15793
15794   if (sw_if_index_set == 0)
15795     {
15796       errmsg ("missing interface name or sw_if_index\n");
15797       return -99;
15798     }
15799
15800   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
15801
15802   mp->sw_if_index = ntohl (sw_if_index);
15803   mp->ip4_table_index = ntohl (ip4_table_index);
15804   mp->ip6_table_index = ntohl (ip6_table_index);
15805   mp->is_add = is_add;
15806
15807   S;
15808   W;
15809   /* NOTREACHED */
15810   return 0;
15811 }
15812
15813 static int
15814 api_flow_classify_dump (vat_main_t * vam)
15815 {
15816   unformat_input_t *i = vam->input;
15817   vl_api_flow_classify_dump_t *mp;
15818   f64 timeout = ~0;
15819   u8 type = FLOW_CLASSIFY_N_TABLES;
15820
15821   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
15822     ;
15823   else
15824     {
15825       errmsg ("classify table type must be specified\n");
15826       return -99;
15827     }
15828
15829   if (!vam->json_output)
15830     {
15831       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15832     }
15833
15834   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
15835   mp->type = type;
15836   /* send it... */
15837   S;
15838
15839   /* Use a control ping for synchronization */
15840   {
15841     vl_api_control_ping_t *mp;
15842     M (CONTROL_PING, control_ping);
15843     S;
15844   }
15845   /* Wait for a reply... */
15846   W;
15847
15848   /* NOTREACHED */
15849   return 0;
15850 }
15851
15852 static int
15853 q_or_quit (vat_main_t * vam)
15854 {
15855   longjmp (vam->jump_buf, 1);
15856   return 0;                     /* not so much */
15857 }
15858
15859 static int
15860 q (vat_main_t * vam)
15861 {
15862   return q_or_quit (vam);
15863 }
15864
15865 static int
15866 quit (vat_main_t * vam)
15867 {
15868   return q_or_quit (vam);
15869 }
15870
15871 static int
15872 comment (vat_main_t * vam)
15873 {
15874   return 0;
15875 }
15876
15877 static int
15878 cmd_cmp (void *a1, void *a2)
15879 {
15880   u8 **c1 = a1;
15881   u8 **c2 = a2;
15882
15883   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15884 }
15885
15886 static int
15887 help (vat_main_t * vam)
15888 {
15889   u8 **cmds = 0;
15890   u8 *name = 0;
15891   hash_pair_t *p;
15892   unformat_input_t *i = vam->input;
15893   int j;
15894
15895   if (unformat (i, "%s", &name))
15896     {
15897       uword *hs;
15898
15899       vec_add1 (name, 0);
15900
15901       hs = hash_get_mem (vam->help_by_name, name);
15902       if (hs)
15903         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15904       else
15905         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15906       vec_free (name);
15907       return 0;
15908     }
15909
15910   fformat (vam->ofp, "Help is available for the following:\n");
15911
15912     /* *INDENT-OFF* */
15913     hash_foreach_pair (p, vam->function_by_name,
15914     ({
15915       vec_add1 (cmds, (u8 *)(p->key));
15916     }));
15917     /* *INDENT-ON* */
15918
15919   vec_sort_with_function (cmds, cmd_cmp);
15920
15921   for (j = 0; j < vec_len (cmds); j++)
15922     fformat (vam->ofp, "%s\n", cmds[j]);
15923
15924   vec_free (cmds);
15925   return 0;
15926 }
15927
15928 static int
15929 set (vat_main_t * vam)
15930 {
15931   u8 *name = 0, *value = 0;
15932   unformat_input_t *i = vam->input;
15933
15934   if (unformat (i, "%s", &name))
15935     {
15936       /* The input buffer is a vector, not a string. */
15937       value = vec_dup (i->buffer);
15938       vec_delete (value, i->index, 0);
15939       /* Almost certainly has a trailing newline */
15940       if (value[vec_len (value) - 1] == '\n')
15941         value[vec_len (value) - 1] = 0;
15942       /* Make sure it's a proper string, one way or the other */
15943       vec_add1 (value, 0);
15944       (void) clib_macro_set_value (&vam->macro_main,
15945                                    (char *) name, (char *) value);
15946     }
15947   else
15948     errmsg ("usage: set <name> <value>\n");
15949
15950   vec_free (name);
15951   vec_free (value);
15952   return 0;
15953 }
15954
15955 static int
15956 unset (vat_main_t * vam)
15957 {
15958   u8 *name = 0;
15959
15960   if (unformat (vam->input, "%s", &name))
15961     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15962       errmsg ("unset: %s wasn't set\n", name);
15963   vec_free (name);
15964   return 0;
15965 }
15966
15967 typedef struct
15968 {
15969   u8 *name;
15970   u8 *value;
15971 } macro_sort_t;
15972
15973
15974 static int
15975 macro_sort_cmp (void *a1, void *a2)
15976 {
15977   macro_sort_t *s1 = a1;
15978   macro_sort_t *s2 = a2;
15979
15980   return strcmp ((char *) (s1->name), (char *) (s2->name));
15981 }
15982
15983 static int
15984 dump_macro_table (vat_main_t * vam)
15985 {
15986   macro_sort_t *sort_me = 0, *sm;
15987   int i;
15988   hash_pair_t *p;
15989
15990     /* *INDENT-OFF* */
15991     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15992     ({
15993       vec_add2 (sort_me, sm, 1);
15994       sm->name = (u8 *)(p->key);
15995       sm->value = (u8 *) (p->value[0]);
15996     }));
15997     /* *INDENT-ON* */
15998
15999   vec_sort_with_function (sort_me, macro_sort_cmp);
16000
16001   if (vec_len (sort_me))
16002     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16003   else
16004     fformat (vam->ofp, "The macro table is empty...\n");
16005
16006   for (i = 0; i < vec_len (sort_me); i++)
16007     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16008   return 0;
16009 }
16010
16011 static int
16012 dump_node_table (vat_main_t * vam)
16013 {
16014   int i, j;
16015   vlib_node_t *node, *next_node;
16016
16017   if (vec_len (vam->graph_nodes) == 0)
16018     {
16019       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16020       return 0;
16021     }
16022
16023   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16024     {
16025       node = vam->graph_nodes[i];
16026       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16027       for (j = 0; j < vec_len (node->next_nodes); j++)
16028         {
16029           if (node->next_nodes[j] != ~0)
16030             {
16031               next_node = vam->graph_nodes[node->next_nodes[j]];
16032               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16033             }
16034         }
16035     }
16036   return 0;
16037 }
16038
16039 static int
16040 search_node_table (vat_main_t * vam)
16041 {
16042   unformat_input_t *line_input = vam->input;
16043   u8 *node_to_find;
16044   int j;
16045   vlib_node_t *node, *next_node;
16046   uword *p;
16047
16048   if (vam->graph_node_index_by_name == 0)
16049     {
16050       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16051       return 0;
16052     }
16053
16054   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16055     {
16056       if (unformat (line_input, "%s", &node_to_find))
16057         {
16058           vec_add1 (node_to_find, 0);
16059           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16060           if (p == 0)
16061             {
16062               fformat (vam->ofp, "%s not found...\n", node_to_find);
16063               goto out;
16064             }
16065           node = vam->graph_nodes[p[0]];
16066           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16067           for (j = 0; j < vec_len (node->next_nodes); j++)
16068             {
16069               if (node->next_nodes[j] != ~0)
16070                 {
16071                   next_node = vam->graph_nodes[node->next_nodes[j]];
16072                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16073                 }
16074             }
16075         }
16076
16077       else
16078         {
16079           clib_warning ("parse error '%U'", format_unformat_error,
16080                         line_input);
16081           return -99;
16082         }
16083
16084     out:
16085       vec_free (node_to_find);
16086
16087     }
16088
16089   return 0;
16090 }
16091
16092
16093 static int
16094 script (vat_main_t * vam)
16095 {
16096   u8 *s = 0;
16097   char *save_current_file;
16098   unformat_input_t save_input;
16099   jmp_buf save_jump_buf;
16100   u32 save_line_number;
16101
16102   FILE *new_fp, *save_ifp;
16103
16104   if (unformat (vam->input, "%s", &s))
16105     {
16106       new_fp = fopen ((char *) s, "r");
16107       if (new_fp == 0)
16108         {
16109           errmsg ("Couldn't open script file %s\n", s);
16110           vec_free (s);
16111           return -99;
16112         }
16113     }
16114   else
16115     {
16116       errmsg ("Missing script name\n");
16117       return -99;
16118     }
16119
16120   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16121   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16122   save_ifp = vam->ifp;
16123   save_line_number = vam->input_line_number;
16124   save_current_file = (char *) vam->current_file;
16125
16126   vam->input_line_number = 0;
16127   vam->ifp = new_fp;
16128   vam->current_file = s;
16129   do_one_file (vam);
16130
16131   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16132   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16133   vam->ifp = save_ifp;
16134   vam->input_line_number = save_line_number;
16135   vam->current_file = (u8 *) save_current_file;
16136   vec_free (s);
16137
16138   return 0;
16139 }
16140
16141 static int
16142 echo (vat_main_t * vam)
16143 {
16144   fformat (vam->ofp, "%v", vam->input->buffer);
16145   return 0;
16146 }
16147
16148 /* List of API message constructors, CLI names map to api_xxx */
16149 #define foreach_vpe_api_msg                                             \
16150 _(create_loopback,"[mac <mac-addr>]")                                   \
16151 _(sw_interface_dump,"")                                                 \
16152 _(sw_interface_set_flags,                                               \
16153   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16154 _(sw_interface_add_del_address,                                         \
16155   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16156 _(sw_interface_set_table,                                               \
16157   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16158 _(sw_interface_set_vpath,                                               \
16159   "<intfc> | sw_if_index <id> enable | disable")                        \
16160 _(sw_interface_set_l2_xconnect,                                         \
16161   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16162   "enable | disable")                                                   \
16163 _(sw_interface_set_l2_bridge,                                           \
16164   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16165   "[shg <split-horizon-group>] [bvi]\n"                                 \
16166   "enable | disable")                                                   \
16167 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16168   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16169   "profile <profile-id>\n")                                             \
16170 _(sw_interface_set_dpdk_hqos_subport,                                   \
16171   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16172   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16173 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16174   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16175 _(bridge_domain_add_del,                                                \
16176   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16177 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16178 _(l2fib_add_del,                                                        \
16179   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16180 _(l2_flags,                                                             \
16181   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16182 _(bridge_flags,                                                         \
16183   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16184 _(tap_connect,                                                          \
16185   "tapname <name> mac <mac-addr> | random-mac")                         \
16186 _(tap_modify,                                                           \
16187   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16188 _(tap_delete,                                                           \
16189   "<vpp-if-name> | sw_if_index <id>")                                   \
16190 _(sw_interface_tap_dump, "")                                            \
16191 _(ip_add_del_route,                                                     \
16192   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16193   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16194   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16195   "[multipath] [count <n>]")                                            \
16196 _(mpls_route_add_del,                                                   \
16197   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16198   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16199   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16200   "[multipath] [count <n>]")                                            \
16201 _(mpls_ip_bind_unbind,                                                  \
16202   "<label> <addr/len>")                                                 \
16203 _(proxy_arp_add_del,                                                    \
16204   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16205 _(proxy_arp_intfc_enable_disable,                                       \
16206   "<intfc> | sw_if_index <id> enable | disable")                        \
16207 _(mpls_add_del_encap,                                                   \
16208   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16209 _(sw_interface_set_unnumbered,                                          \
16210   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16211 _(ip_neighbor_add_del,                                                  \
16212   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16213   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16214 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16215 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16216 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16217   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16218   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16219   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16220 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16221 _(reset_fib, "vrf <n> [ipv6]")                                          \
16222 _(dhcp_proxy_config,                                                    \
16223   "svr <v46-address> src <v46-address>\n"                               \
16224    "insert-cid <n> [del]")                                              \
16225 _(dhcp_proxy_config_2,                                                  \
16226   "svr <v46-address> src <v46-address>\n"                               \
16227    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16228 _(dhcp_proxy_set_vss,                                                   \
16229   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16230 _(dhcp_client_config,                                                   \
16231   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16232 _(set_ip_flow_hash,                                                     \
16233   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16234 _(sw_interface_ip6_enable_disable,                                      \
16235   "<intfc> | sw_if_index <id> enable | disable")                        \
16236 _(sw_interface_ip6_set_link_local_address,                              \
16237   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16238 _(sw_interface_ip6nd_ra_prefix,                                         \
16239   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16240   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16241   "[nolink] [isno]")                                                    \
16242 _(sw_interface_ip6nd_ra_config,                                         \
16243   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16244   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16245   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16246 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16247 _(l2_patch_add_del,                                                     \
16248   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16249   "enable | disable")                                                   \
16250 _(mpls_ethernet_add_del_tunnel,                                         \
16251   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16252   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16253 _(mpls_ethernet_add_del_tunnel_2,                                       \
16254   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16255   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16256 _(sr_tunnel_add_del,                                                    \
16257   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16258   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16259   "[policy <policy_name>]")                                             \
16260 _(sr_policy_add_del,                                                    \
16261   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16262 _(sr_multicast_map_add_del,                                             \
16263   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16264 _(classify_add_del_table,                                               \
16265   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16266   "[del] mask <mask-value>\n"                                           \
16267   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
16268 _(classify_add_del_session,                                             \
16269   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16270   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16271   "  [l3 [ip4|ip6]]")                                                   \
16272 _(classify_set_interface_ip_table,                                      \
16273   "<intfc> | sw_if_index <nn> table <nn>")                              \
16274 _(classify_set_interface_l2_tables,                                     \
16275   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16276   "  [other-table <nn>]")                                               \
16277 _(get_node_index, "node <node-name")                                    \
16278 _(add_node_next, "node <node-name> next <next-node-name>")              \
16279 _(l2tpv3_create_tunnel,                                                 \
16280   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16281   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16282   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16283 _(l2tpv3_set_tunnel_cookies,                                            \
16284   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16285   "[new_remote_cookie <nn>]\n")                                         \
16286 _(l2tpv3_interface_enable_disable,                                      \
16287   "<intfc> | sw_if_index <nn> enable | disable")                        \
16288 _(l2tpv3_set_lookup_key,                                                \
16289   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16290 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16291 _(vxlan_add_del_tunnel,                                                 \
16292   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16293   " [decap-next l2|ip4|ip6] [del]")                                     \
16294 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16295 _(gre_add_del_tunnel,                                                   \
16296   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16297 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16298 _(l2_fib_clear_table, "")                                               \
16299 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16300 _(l2_interface_vlan_tag_rewrite,                                        \
16301   "<intfc> | sw_if_index <nn> \n"                                       \
16302   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16303   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16304 _(create_vhost_user_if,                                                 \
16305         "socket <filename> [server] [renumber <dev_instance>] "         \
16306         "[mac <mac_address>]")                                          \
16307 _(modify_vhost_user_if,                                                 \
16308         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16309         "[server] [renumber <dev_instance>]")                           \
16310 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16311 _(sw_interface_vhost_user_dump, "")                                     \
16312 _(show_version, "")                                                     \
16313 _(vxlan_gpe_add_del_tunnel,                                             \
16314   "local <addr> remote <addr> vni <nn>\n"                               \
16315     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16316   "[next-ethernet] [next-nsh]\n")                                       \
16317 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16318 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16319 _(interface_name_renumber,                                              \
16320   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16321 _(input_acl_set_interface,                                              \
16322   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16323   "  [l2-table <nn>] [del]")                                            \
16324 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16325 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16326 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16327 _(ip_dump, "ipv4 | ipv6")                                               \
16328 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16329 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16330   "  spid_id <n> ")                                                     \
16331 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16332   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16333   "  integ_alg <alg> integ_key <hex>")                                  \
16334 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16335   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16336   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16337   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16338 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16339 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16340 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16341   "(auth_data 0x<data> | auth_data <data>)")                            \
16342 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16343   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16344 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16345   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16346   "(local|remote)")                                                     \
16347 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16348 _(delete_loopback,"sw_if_index <nn>")                                   \
16349 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16350 _(map_add_domain,                                                       \
16351   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16352   "ip6-src <ip6addr> "                                                  \
16353   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16354 _(map_del_domain, "index <n>")                                          \
16355 _(map_add_del_rule,                                                     \
16356   "index <n> psid <n> dst <ip6addr> [del]")                             \
16357 _(map_domain_dump, "")                                                  \
16358 _(map_rule_dump, "index <map-domain>")                                  \
16359 _(want_interface_events,  "enable|disable")                             \
16360 _(want_stats,"enable|disable")                                          \
16361 _(get_first_msg_id, "client <name>")                                    \
16362 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16363 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16364   "fib-id <nn> [ip4][ip6][default]")                                    \
16365 _(get_node_graph, " ")                                                  \
16366 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16367 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16368 _(ioam_disable, "")                                                \
16369 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16370                             " sw_if_index <sw_if_index> p <priority> "  \
16371                             "w <weight>] [del]")                        \
16372 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16373                         "iface <intf> | sw_if_index <sw_if_index> "     \
16374                         "p <priority> w <weight> [del]")                \
16375 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16376                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16377                           "locator-set <locator_name> [del]")           \
16378 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16379   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16380 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16381 _(lisp_gpe_enable_disable, "enable|disable")                            \
16382 _(lisp_enable_disable, "enable|disable")                                \
16383 _(lisp_gpe_add_del_iface, "up|down")                                    \
16384 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16385                                "[seid <seid>] "                         \
16386                                "rloc <locator> p <prio> "               \
16387                                "w <weight> [rloc <loc> ... ] "          \
16388                                "action <action> [del-all]")             \
16389 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16390                           "<local-eid>")                                \
16391 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16392 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16393 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16394 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16395 _(lisp_locator_set_dump, "[local | remote]")                            \
16396 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16397 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16398                        "[local] | [remote]")                            \
16399 _(lisp_eid_table_vni_dump, "")                                          \
16400 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16401 _(lisp_gpe_tunnel_dump, "")                                             \
16402 _(lisp_map_resolver_dump, "")                                           \
16403 _(lisp_adjacencies_get, "vni <vni>")                                    \
16404 _(show_lisp_status, "")                                                 \
16405 _(lisp_get_map_request_itr_rlocs, "")                                   \
16406 _(show_lisp_pitr, "")                                                   \
16407 _(show_lisp_map_request_mode, "")                                       \
16408 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16409 _(af_packet_delete, "name <host interface name>")                       \
16410 _(policer_add_del, "name <policer name> <params> [del]")                \
16411 _(policer_dump, "[name <policer name>]")                                \
16412 _(policer_classify_set_interface,                                       \
16413   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16414   "  [l2-table <nn>] [del]")                                            \
16415 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16416 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16417     "[master|slave]")                                                   \
16418 _(netmap_delete, "name <interface name>")                               \
16419 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16420 _(mpls_fib_encap_dump, "")                                              \
16421 _(mpls_fib_dump, "")                                                    \
16422 _(classify_table_ids, "")                                               \
16423 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16424 _(classify_table_info, "table_id <nn>")                                 \
16425 _(classify_session_dump, "table_id <nn>")                               \
16426 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16427     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16428     "[template_interval <nn>] [udp_checksum]")                          \
16429 _(ipfix_exporter_dump, "")                                              \
16430 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16431 _(ipfix_classify_stream_dump, "")                                       \
16432 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16433 _(ipfix_classify_table_dump, "")                                        \
16434 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16435 _(pg_create_interface, "if_id <nn>")                                    \
16436 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16437 _(pg_enable_disable, "[stream <id>] disable")                           \
16438 _(ip_source_and_port_range_check_add_del,                               \
16439   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16440 _(ip_source_and_port_range_check_interface_add_del,                     \
16441   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16442   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16443 _(ipsec_gre_add_del_tunnel,                                             \
16444   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16445 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16446 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
16447 _(l2_interface_pbb_tag_rewrite,                                         \
16448   "<intfc> | sw_if_index <nn> \n"                                       \
16449   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16450   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16451 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16452 _(flow_classify_set_interface,                                          \
16453   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16454 _(flow_classify_dump, "type [ip4|ip6]")
16455
16456 /* List of command functions, CLI names map directly to functions */
16457 #define foreach_cli_function                                    \
16458 _(comment, "usage: comment <ignore-rest-of-line>")              \
16459 _(dump_interface_table, "usage: dump_interface_table")          \
16460 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16461 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16462 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16463 _(dump_stats_table, "usage: dump_stats_table")                  \
16464 _(dump_macro_table, "usage: dump_macro_table ")                 \
16465 _(dump_node_table, "usage: dump_node_table")                    \
16466 _(echo, "usage: echo <message>")                                \
16467 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16468 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16469 _(help, "usage: help")                                          \
16470 _(q, "usage: quit")                                             \
16471 _(quit, "usage: quit")                                          \
16472 _(search_node_table, "usage: search_node_table <name>...")      \
16473 _(set, "usage: set <variable-name> <value>")                    \
16474 _(script, "usage: script <file-name>")                          \
16475 _(unset, "usage: unset <variable-name>")
16476
16477 #define _(N,n)                                  \
16478     static void vl_api_##n##_t_handler_uni      \
16479     (vl_api_##n##_t * mp)                       \
16480     {                                           \
16481         vat_main_t * vam = &vat_main;           \
16482         if (vam->json_output) {                 \
16483             vl_api_##n##_t_handler_json(mp);    \
16484         } else {                                \
16485             vl_api_##n##_t_handler(mp);         \
16486         }                                       \
16487     }
16488 foreach_vpe_api_reply_msg;
16489 #undef _
16490
16491 void
16492 vat_api_hookup (vat_main_t * vam)
16493 {
16494 #define _(N,n)                                                  \
16495     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16496                            vl_api_##n##_t_handler_uni,          \
16497                            vl_noop_handler,                     \
16498                            vl_api_##n##_t_endian,               \
16499                            vl_api_##n##_t_print,                \
16500                            sizeof(vl_api_##n##_t), 1);
16501   foreach_vpe_api_reply_msg;
16502 #undef _
16503
16504   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16505
16506   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16507
16508   vam->function_by_name = hash_create_string (0, sizeof (uword));
16509
16510   vam->help_by_name = hash_create_string (0, sizeof (uword));
16511
16512   /* API messages we can send */
16513 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16514   foreach_vpe_api_msg;
16515 #undef _
16516
16517   /* Help strings */
16518 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16519   foreach_vpe_api_msg;
16520 #undef _
16521
16522   /* CLI functions */
16523 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16524   foreach_cli_function;
16525 #undef _
16526
16527   /* Help strings */
16528 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16529   foreach_cli_function;
16530 #undef _
16531 }
16532
16533 #undef vl_api_version
16534 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16535 #include <vpp-api/vpe.api.h>
16536 #undef vl_api_version
16537
16538 void
16539 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16540 {
16541   /*
16542    * Send the main API signature in slot 0. This bit of code must
16543    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16544    */
16545   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16546 }
16547
16548 /*
16549  * fd.io coding-style-patch-verification: ON
16550  *
16551  * Local Variables:
16552  * eval: (c-set-style "gnu")
16553  * End:
16554  */