08c1079294a1efcc70664d634f2cff4584cf7d80
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53
54 #include "vat/json_format.h"
55
56 #include <sys/stat.h>
57
58 #define vl_typedefs             /* define message structures */
59 #include <vpp-api/vpe_all_api_h.h>
60 #undef vl_typedefs
61
62 /* declare message handlers for each api */
63
64 #define vl_endianfun            /* define message structures */
65 #include <vpp-api/vpe_all_api_h.h>
66 #undef vl_endianfun
67
68 /* instantiate all the print functions we know about */
69 #define vl_print(handle, ...)
70 #define vl_printfun
71 #include <vpp-api/vpe_all_api_h.h>
72 #undef vl_printfun
73
74 uword
75 unformat_sw_if_index (unformat_input_t * input, va_list * args)
76 {
77   vat_main_t *vam = va_arg (*args, vat_main_t *);
78   u32 *result = va_arg (*args, u32 *);
79   u8 *if_name;
80   uword *p;
81
82   if (!unformat (input, "%s", &if_name))
83     return 0;
84
85   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
86   if (p == 0)
87     return 0;
88   *result = p[0];
89   return 1;
90 }
91
92 /* Parse an IP4 address %d.%d.%d.%d. */
93 uword
94 unformat_ip4_address (unformat_input_t * input, va_list * args)
95 {
96   u8 *result = va_arg (*args, u8 *);
97   unsigned a[4];
98
99   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
100     return 0;
101
102   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
103     return 0;
104
105   result[0] = a[0];
106   result[1] = a[1];
107   result[2] = a[2];
108   result[3] = a[3];
109
110   return 1;
111 }
112
113
114 uword
115 unformat_ethernet_address (unformat_input_t * input, va_list * args)
116 {
117   u8 *result = va_arg (*args, u8 *);
118   u32 i, a[6];
119
120   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
121                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
122     return 0;
123
124   /* Check range. */
125   for (i = 0; i < 6; i++)
126     if (a[i] >= (1 << 8))
127       return 0;
128
129   for (i = 0; i < 6; i++)
130     result[i] = a[i];
131
132   return 1;
133 }
134
135 /* Returns ethernet type as an int in host byte order. */
136 uword
137 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
138                                         va_list * args)
139 {
140   u16 *result = va_arg (*args, u16 *);
141   int type;
142
143   /* Numeric type. */
144   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
145     {
146       if (type >= (1 << 16))
147         return 0;
148       *result = type;
149       return 1;
150     }
151   return 0;
152 }
153
154 /* Parse an IP6 address. */
155 uword
156 unformat_ip6_address (unformat_input_t * input, va_list * args)
157 {
158   ip6_address_t *result = va_arg (*args, ip6_address_t *);
159   u16 hex_quads[8];
160   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
161   uword c, n_colon, double_colon_index;
162
163   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
164   double_colon_index = ARRAY_LEN (hex_quads);
165   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
166     {
167       hex_digit = 16;
168       if (c >= '0' && c <= '9')
169         hex_digit = c - '0';
170       else if (c >= 'a' && c <= 'f')
171         hex_digit = c + 10 - 'a';
172       else if (c >= 'A' && c <= 'F')
173         hex_digit = c + 10 - 'A';
174       else if (c == ':' && n_colon < 2)
175         n_colon++;
176       else
177         {
178           unformat_put_input (input);
179           break;
180         }
181
182       /* Too many hex quads. */
183       if (n_hex_quads >= ARRAY_LEN (hex_quads))
184         return 0;
185
186       if (hex_digit < 16)
187         {
188           hex_quad = (hex_quad << 4) | hex_digit;
189
190           /* Hex quad must fit in 16 bits. */
191           if (n_hex_digits >= 4)
192             return 0;
193
194           n_colon = 0;
195           n_hex_digits++;
196         }
197
198       /* Save position of :: */
199       if (n_colon == 2)
200         {
201           /* More than one :: ? */
202           if (double_colon_index < ARRAY_LEN (hex_quads))
203             return 0;
204           double_colon_index = n_hex_quads;
205         }
206
207       if (n_colon > 0 && n_hex_digits > 0)
208         {
209           hex_quads[n_hex_quads++] = hex_quad;
210           hex_quad = 0;
211           n_hex_digits = 0;
212         }
213     }
214
215   if (n_hex_digits > 0)
216     hex_quads[n_hex_quads++] = hex_quad;
217
218   {
219     word i;
220
221     /* Expand :: to appropriate number of zero hex quads. */
222     if (double_colon_index < ARRAY_LEN (hex_quads))
223       {
224         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
225
226         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
227           hex_quads[n_zero + i] = hex_quads[i];
228
229         for (i = 0; i < n_zero; i++)
230           hex_quads[double_colon_index + i] = 0;
231
232         n_hex_quads = ARRAY_LEN (hex_quads);
233       }
234
235     /* Too few hex quads given. */
236     if (n_hex_quads < ARRAY_LEN (hex_quads))
237       return 0;
238
239     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
240       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
241
242     return 1;
243   }
244 }
245
246 uword
247 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
248 {
249 #if DPDK > 0
250   u32 *r = va_arg (*args, u32 *);
251
252   if (0);
253 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254   foreach_ipsec_policy_action
255 #undef _
256     else
257     return 0;
258   return 1;
259 #else
260   return 0;
261 #endif
262 }
263
264 uword
265 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
266 {
267 #if DPDK > 0
268   u32 *r = va_arg (*args, u32 *);
269
270   if (0);
271 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
272   foreach_ipsec_crypto_alg
273 #undef _
274     else
275     return 0;
276   return 1;
277 #else
278   return 0;
279 #endif
280 }
281
282 u8 *
283 format_ipsec_crypto_alg (u8 * s, va_list * args)
284 {
285 #if DPDK > 0
286   u32 i = va_arg (*args, u32);
287   u8 *t = 0;
288
289   switch (i)
290     {
291 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
292       foreach_ipsec_crypto_alg
293 #undef _
294     default:
295       return format (s, "unknown");
296     }
297   return format (s, "%s", t);
298 #else
299   return format (s, "Unimplemented");
300 #endif
301 }
302
303 uword
304 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
305 {
306 #if DPDK > 0
307   u32 *r = va_arg (*args, u32 *);
308
309   if (0);
310 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
311   foreach_ipsec_integ_alg
312 #undef _
313     else
314     return 0;
315   return 1;
316 #else
317   return 0;
318 #endif
319 }
320
321 u8 *
322 format_ipsec_integ_alg (u8 * s, va_list * args)
323 {
324 #if DPDK > 0
325   u32 i = va_arg (*args, u32);
326   u8 *t = 0;
327
328   switch (i)
329     {
330 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
331       foreach_ipsec_integ_alg
332 #undef _
333     default:
334       return format (s, "unknown");
335     }
336   return format (s, "%s", t);
337 #else
338   return format (s, "Unsupported");
339 #endif
340 }
341
342 uword
343 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
344 {
345 #if DPDK > 0
346   u32 *r = va_arg (*args, u32 *);
347
348   if (0);
349 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
350   foreach_ikev2_auth_method
351 #undef _
352     else
353     return 0;
354   return 1;
355 #else
356   return 0;
357 #endif
358 }
359
360 uword
361 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
362 {
363 #if DPDK > 0
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
368   foreach_ikev2_id_type
369 #undef _
370     else
371     return 0;
372   return 1;
373 #else
374   return 0;
375 #endif
376 }
377
378 uword
379 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
380 {
381   u8 *r = va_arg (*args, u8 *);
382
383   if (unformat (input, "kbps"))
384     *r = SSE2_QOS_RATE_KBPS;
385   else if (unformat (input, "pps"))
386     *r = SSE2_QOS_RATE_PPS;
387   else
388     return 0;
389   return 1;
390 }
391
392 uword
393 unformat_policer_round_type (unformat_input_t * input, va_list * args)
394 {
395   u8 *r = va_arg (*args, u8 *);
396
397   if (unformat (input, "closest"))
398     *r = SSE2_QOS_ROUND_TO_CLOSEST;
399   else if (unformat (input, "up"))
400     *r = SSE2_QOS_ROUND_TO_UP;
401   else if (unformat (input, "down"))
402     *r = SSE2_QOS_ROUND_TO_DOWN;
403   else
404     return 0;
405   return 1;
406 }
407
408 uword
409 unformat_policer_type (unformat_input_t * input, va_list * args)
410 {
411   u8 *r = va_arg (*args, u8 *);
412
413   if (unformat (input, "1r2c"))
414     *r = SSE2_QOS_POLICER_TYPE_1R2C;
415   else if (unformat (input, "1r3c"))
416     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
417   else if (unformat (input, "2r3c-2698"))
418     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
419   else if (unformat (input, "2r3c-4115"))
420     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
421   else if (unformat (input, "2r3c-mef5cf1"))
422     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
423   else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_dscp (unformat_input_t * input, va_list * va)
430 {
431   u8 *r = va_arg (*va, u8 *);
432
433   if (0);
434 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
435   foreach_vnet_dscp
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441
442 uword
443 unformat_policer_action_type (unformat_input_t * input, va_list * va)
444 {
445   sse2_qos_pol_action_params_st *a
446     = va_arg (*va, sse2_qos_pol_action_params_st *);
447
448   if (unformat (input, "drop"))
449     a->action_type = SSE2_QOS_ACTION_DROP;
450   else if (unformat (input, "transmit"))
451     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
452   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
453     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
454   else
455     return 0;
456   return 1;
457 }
458
459 uword
460 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
461 {
462   u32 *r = va_arg (*va, u32 *);
463   u32 tid;
464
465   if (unformat (input, "ip4"))
466     tid = POLICER_CLASSIFY_TABLE_IP4;
467   else if (unformat (input, "ip6"))
468     tid = POLICER_CLASSIFY_TABLE_IP6;
469   else if (unformat (input, "l2"))
470     tid = POLICER_CLASSIFY_TABLE_L2;
471   else
472     return 0;
473
474   *r = tid;
475   return 1;
476 }
477
478 uword
479 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
480 {
481   u32 *r = va_arg (*va, u32 *);
482   u32 tid;
483
484   if (unformat (input, "ip4"))
485     tid = FLOW_CLASSIFY_TABLE_IP4;
486   else if (unformat (input, "ip6"))
487     tid = FLOW_CLASSIFY_TABLE_IP6;
488   else
489     return 0;
490
491   *r = tid;
492   return 1;
493 }
494
495 u8 *
496 format_ip4_address (u8 * s, va_list * args)
497 {
498   u8 *a = va_arg (*args, u8 *);
499   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
500 }
501
502 u8 *
503 format_ip6_address (u8 * s, va_list * args)
504 {
505   ip6_address_t *a = va_arg (*args, ip6_address_t *);
506   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
507
508   i_max_n_zero = ARRAY_LEN (a->as_u16);
509   max_n_zeros = 0;
510   i_first_zero = i_max_n_zero;
511   n_zeros = 0;
512   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
513     {
514       u32 is_zero = a->as_u16[i] == 0;
515       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
516         {
517           i_first_zero = i;
518           n_zeros = 0;
519         }
520       n_zeros += is_zero;
521       if ((!is_zero && n_zeros > max_n_zeros)
522           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
523         {
524           i_max_n_zero = i_first_zero;
525           max_n_zeros = n_zeros;
526           i_first_zero = ARRAY_LEN (a->as_u16);
527           n_zeros = 0;
528         }
529     }
530
531   last_double_colon = 0;
532   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
533     {
534       if (i == i_max_n_zero && max_n_zeros > 1)
535         {
536           s = format (s, "::");
537           i += max_n_zeros - 1;
538           last_double_colon = 1;
539         }
540       else
541         {
542           s = format (s, "%s%x",
543                       (last_double_colon || i == 0) ? "" : ":",
544                       clib_net_to_host_u16 (a->as_u16[i]));
545           last_double_colon = 0;
546         }
547     }
548
549   return s;
550 }
551
552 /* Format an IP46 address. */
553 u8 *
554 format_ip46_address (u8 * s, va_list * args)
555 {
556   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
557   ip46_type_t type = va_arg (*args, ip46_type_t);
558   int is_ip4 = 1;
559
560   switch (type)
561     {
562     case IP46_TYPE_ANY:
563       is_ip4 = ip46_address_is_ip4 (ip46);
564       break;
565     case IP46_TYPE_IP4:
566       is_ip4 = 1;
567       break;
568     case IP46_TYPE_IP6:
569       is_ip4 = 0;
570       break;
571     }
572
573   return is_ip4 ?
574     format (s, "%U", format_ip4_address, &ip46->ip4) :
575     format (s, "%U", format_ip6_address, &ip46->ip6);
576 }
577
578 u8 *
579 format_ethernet_address (u8 * s, va_list * args)
580 {
581   u8 *a = va_arg (*args, u8 *);
582
583   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
584                  a[0], a[1], a[2], a[3], a[4], a[5]);
585 }
586
587 void
588 increment_v4_address (ip4_address_t * a)
589 {
590   u32 v;
591
592   v = ntohl (a->as_u32) + 1;
593   a->as_u32 = ntohl (v);
594 }
595
596 void
597 increment_v6_address (ip6_address_t * a)
598 {
599   u64 v0, v1;
600
601   v0 = clib_net_to_host_u64 (a->as_u64[0]);
602   v1 = clib_net_to_host_u64 (a->as_u64[1]);
603
604   v1 += 1;
605   if (v1 == 0)
606     v0 += 1;
607   a->as_u64[0] = clib_net_to_host_u64 (v0);
608   a->as_u64[1] = clib_net_to_host_u64 (v1);
609 }
610
611 void
612 increment_mac_address (u64 * mac)
613 {
614   u64 tmp = *mac;
615
616   tmp = clib_net_to_host_u64 (tmp);
617   tmp += 1 << 16;               /* skip unused (least significant) octets */
618   tmp = clib_host_to_net_u64 (tmp);
619   *mac = tmp;
620 }
621
622 static void vl_api_create_loopback_reply_t_handler
623   (vl_api_create_loopback_reply_t * mp)
624 {
625   vat_main_t *vam = &vat_main;
626   i32 retval = ntohl (mp->retval);
627
628   vam->retval = retval;
629   vam->regenerate_interface_table = 1;
630   vam->sw_if_index = ntohl (mp->sw_if_index);
631   vam->result_ready = 1;
632 }
633
634 static void vl_api_create_loopback_reply_t_handler_json
635   (vl_api_create_loopback_reply_t * mp)
636 {
637   vat_main_t *vam = &vat_main;
638   vat_json_node_t node;
639
640   vat_json_init_object (&node);
641   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
642   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
643
644   vat_json_print (vam->ofp, &node);
645   vat_json_free (&node);
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_af_packet_create_reply_t_handler
651   (vl_api_af_packet_create_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_af_packet_create_reply_t_handler_json
663   (vl_api_af_packet_create_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_vlan_subif_reply_t_handler
680   (vl_api_create_vlan_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_vlan_subif_reply_t_handler_json
692   (vl_api_create_vlan_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_create_subif_reply_t_handler
709   (vl_api_create_subif_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->sw_if_index = ntohl (mp->sw_if_index);
717   vam->result_ready = 1;
718 }
719
720 static void vl_api_create_subif_reply_t_handler_json
721   (vl_api_create_subif_reply_t * mp)
722 {
723   vat_main_t *vam = &vat_main;
724   vat_json_node_t node;
725
726   vat_json_init_object (&node);
727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
729
730   vat_json_print (vam->ofp, &node);
731   vat_json_free (&node);
732
733   vam->retval = ntohl (mp->retval);
734   vam->result_ready = 1;
735 }
736
737 static void vl_api_interface_name_renumber_reply_t_handler
738   (vl_api_interface_name_renumber_reply_t * mp)
739 {
740   vat_main_t *vam = &vat_main;
741   i32 retval = ntohl (mp->retval);
742
743   vam->retval = retval;
744   vam->regenerate_interface_table = 1;
745   vam->result_ready = 1;
746 }
747
748 static void vl_api_interface_name_renumber_reply_t_handler_json
749   (vl_api_interface_name_renumber_reply_t * mp)
750 {
751   vat_main_t *vam = &vat_main;
752   vat_json_node_t node;
753
754   vat_json_init_object (&node);
755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
756
757   vat_json_print (vam->ofp, &node);
758   vat_json_free (&node);
759
760   vam->retval = ntohl (mp->retval);
761   vam->result_ready = 1;
762 }
763
764 /*
765  * Special-case: build the interface table, maintain
766  * the next loopback sw_if_index vbl.
767  */
768 static void vl_api_sw_interface_details_t_handler
769   (vl_api_sw_interface_details_t * mp)
770 {
771   vat_main_t *vam = &vat_main;
772   u8 *s = format (0, "%s%c", mp->interface_name, 0);
773
774   hash_set_mem (vam->sw_if_index_by_interface_name, s,
775                 ntohl (mp->sw_if_index));
776
777   /* In sub interface case, fill the sub interface table entry */
778   if (mp->sw_if_index != mp->sup_sw_if_index)
779     {
780       sw_interface_subif_t *sub = NULL;
781
782       vec_add2 (vam->sw_if_subif_table, sub, 1);
783
784       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
785       strncpy ((char *) sub->interface_name, (char *) s,
786                vec_len (sub->interface_name));
787       sub->sw_if_index = ntohl (mp->sw_if_index);
788       sub->sub_id = ntohl (mp->sub_id);
789
790       sub->sub_dot1ad = mp->sub_dot1ad;
791       sub->sub_number_of_tags = mp->sub_number_of_tags;
792       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
793       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
794       sub->sub_exact_match = mp->sub_exact_match;
795       sub->sub_default = mp->sub_default;
796       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
797       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
798
799       /* vlan tag rewrite */
800       sub->vtr_op = ntohl (mp->vtr_op);
801       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
802       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
803       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
804     }
805 }
806
807 static void vl_api_sw_interface_details_t_handler_json
808   (vl_api_sw_interface_details_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t *node = NULL;
812
813   if (VAT_JSON_ARRAY != vam->json_tree.type)
814     {
815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
816       vat_json_init_array (&vam->json_tree);
817     }
818   node = vat_json_array_add (&vam->json_tree);
819
820   vat_json_init_object (node);
821   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
822   vat_json_object_add_uint (node, "sup_sw_if_index",
823                             ntohl (mp->sup_sw_if_index));
824   vat_json_object_add_uint (node, "l2_address_length",
825                             ntohl (mp->l2_address_length));
826   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
827                              sizeof (mp->l2_address));
828   vat_json_object_add_string_copy (node, "interface_name",
829                                    mp->interface_name);
830   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
831   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
832   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
833   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
834   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
835   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
836   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
837   vat_json_object_add_uint (node, "sub_number_of_tags",
838                             mp->sub_number_of_tags);
839   vat_json_object_add_uint (node, "sub_outer_vlan_id",
840                             ntohs (mp->sub_outer_vlan_id));
841   vat_json_object_add_uint (node, "sub_inner_vlan_id",
842                             ntohs (mp->sub_inner_vlan_id));
843   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
844   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
845   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
846                             mp->sub_outer_vlan_id_any);
847   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
848                             mp->sub_inner_vlan_id_any);
849   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
850   vat_json_object_add_uint (node, "vtr_push_dot1q",
851                             ntohl (mp->vtr_push_dot1q));
852   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
853   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
854 }
855
856 static void vl_api_sw_interface_set_flags_t_handler
857   (vl_api_sw_interface_set_flags_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   if (vam->interface_event_display)
861     errmsg ("interface flags: sw_if_index %d %s %s\n",
862             ntohl (mp->sw_if_index),
863             mp->admin_up_down ? "admin-up" : "admin-down",
864             mp->link_up_down ? "link-up" : "link-down");
865 }
866
867 static void vl_api_sw_interface_set_flags_t_handler_json
868   (vl_api_sw_interface_set_flags_t * mp)
869 {
870   /* JSON output not supported */
871 }
872
873 static void
874 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   i32 retval = ntohl (mp->retval);
878
879   vam->retval = retval;
880   vam->shmem_result = (u8 *) mp->reply_in_shmem;
881   vam->result_ready = 1;
882 }
883
884 static void
885 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   vat_json_node_t node;
889   api_main_t *am = &api_main;
890   void *oldheap;
891   u8 *reply;
892
893   vat_json_init_object (&node);
894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
895   vat_json_object_add_uint (&node, "reply_in_shmem",
896                             ntohl (mp->reply_in_shmem));
897   /* Toss the shared-memory original... */
898   pthread_mutex_lock (&am->vlib_rp->mutex);
899   oldheap = svm_push_data_heap (am->vlib_rp);
900
901   reply = (u8 *) (mp->reply_in_shmem);
902   vec_free (reply);
903
904   svm_pop_heap (oldheap);
905   pthread_mutex_unlock (&am->vlib_rp->mutex);
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 static void
915 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   i32 retval = ntohl (mp->retval);
919
920   vam->retval = retval;
921   vam->cmd_reply = mp->reply;
922   vam->result_ready = 1;
923 }
924
925 static void
926 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_string_copy (&node, "reply", mp->reply);
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_classify_add_del_table_reply_t_handler
943   (vl_api_classify_add_del_table_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947   if (vam->async_mode)
948     {
949       vam->async_errors += (retval < 0);
950     }
951   else
952     {
953       vam->retval = retval;
954       if (retval == 0 &&
955           ((mp->new_table_index != 0xFFFFFFFF) ||
956            (mp->skip_n_vectors != 0xFFFFFFFF) ||
957            (mp->match_n_vectors != 0xFFFFFFFF)))
958         /*
959          * Note: this is just barely thread-safe, depends on
960          * the main thread spinning waiting for an answer...
961          */
962         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
963                 ntohl (mp->new_table_index),
964                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
965       vam->result_ready = 1;
966     }
967 }
968
969 static void vl_api_classify_add_del_table_reply_t_handler_json
970   (vl_api_classify_add_del_table_reply_t * mp)
971 {
972   vat_main_t *vam = &vat_main;
973   vat_json_node_t node;
974
975   vat_json_init_object (&node);
976   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
977   vat_json_object_add_uint (&node, "new_table_index",
978                             ntohl (mp->new_table_index));
979   vat_json_object_add_uint (&node, "skip_n_vectors",
980                             ntohl (mp->skip_n_vectors));
981   vat_json_object_add_uint (&node, "match_n_vectors",
982                             ntohl (mp->match_n_vectors));
983
984   vat_json_print (vam->ofp, &node);
985   vat_json_free (&node);
986
987   vam->retval = ntohl (mp->retval);
988   vam->result_ready = 1;
989 }
990
991 static void vl_api_get_node_index_reply_t_handler
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   i32 retval = ntohl (mp->retval);
996   if (vam->async_mode)
997     {
998       vam->async_errors += (retval < 0);
999     }
1000   else
1001     {
1002       vam->retval = retval;
1003       if (retval == 0)
1004         errmsg ("node index %d\n", ntohl (mp->node_index));
1005       vam->result_ready = 1;
1006     }
1007 }
1008
1009 static void vl_api_get_node_index_reply_t_handler_json
1010   (vl_api_get_node_index_reply_t * mp)
1011 {
1012   vat_main_t *vam = &vat_main;
1013   vat_json_node_t node;
1014
1015   vat_json_init_object (&node);
1016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1017   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1018
1019   vat_json_print (vam->ofp, &node);
1020   vat_json_free (&node);
1021
1022   vam->retval = ntohl (mp->retval);
1023   vam->result_ready = 1;
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   i32 retval = ntohl (mp->retval);
1031   if (vam->async_mode)
1032     {
1033       vam->async_errors += (retval < 0);
1034     }
1035   else
1036     {
1037       vam->retval = retval;
1038       if (retval == 0)
1039         errmsg ("next node index %d\n", ntohl (mp->next_index));
1040       vam->result_ready = 1;
1041     }
1042 }
1043
1044 static void vl_api_get_next_index_reply_t_handler_json
1045   (vl_api_get_next_index_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049
1050   vat_json_init_object (&node);
1051   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1052   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1053
1054   vat_json_print (vam->ofp, &node);
1055   vat_json_free (&node);
1056
1057   vam->retval = ntohl (mp->retval);
1058   vam->result_ready = 1;
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   i32 retval = ntohl (mp->retval);
1066   if (vam->async_mode)
1067     {
1068       vam->async_errors += (retval < 0);
1069     }
1070   else
1071     {
1072       vam->retval = retval;
1073       if (retval == 0)
1074         errmsg ("next index %d\n", ntohl (mp->next_index));
1075       vam->result_ready = 1;
1076     }
1077 }
1078
1079 static void vl_api_add_node_next_reply_t_handler_json
1080   (vl_api_add_node_next_reply_t * mp)
1081 {
1082   vat_main_t *vam = &vat_main;
1083   vat_json_node_t node;
1084
1085   vat_json_init_object (&node);
1086   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1087   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1088
1089   vat_json_print (vam->ofp, &node);
1090   vat_json_free (&node);
1091
1092   vam->retval = ntohl (mp->retval);
1093   vam->result_ready = 1;
1094 }
1095
1096 static void vl_api_show_version_reply_t_handler
1097   (vl_api_show_version_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   i32 retval = ntohl (mp->retval);
1101
1102   if (retval >= 0)
1103     {
1104       errmsg ("        program: %s\n", mp->program);
1105       errmsg ("        version: %s\n", mp->version);
1106       errmsg ("     build date: %s\n", mp->build_date);
1107       errmsg ("build directory: %s\n", mp->build_directory);
1108     }
1109   vam->retval = retval;
1110   vam->result_ready = 1;
1111 }
1112
1113 static void vl_api_show_version_reply_t_handler_json
1114   (vl_api_show_version_reply_t * mp)
1115 {
1116   vat_main_t *vam = &vat_main;
1117   vat_json_node_t node;
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "program", mp->program);
1122   vat_json_object_add_string_copy (&node, "version", mp->version);
1123   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1124   vat_json_object_add_string_copy (&node, "build_directory",
1125                                    mp->build_directory);
1126
1127   vat_json_print (vam->ofp, &node);
1128   vat_json_free (&node);
1129
1130   vam->retval = ntohl (mp->retval);
1131   vam->result_ready = 1;
1132 }
1133
1134 static void
1135 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1136 {
1137   vat_main_t *vam = &vat_main;
1138   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1139           mp->mac_ip ? "mac/ip binding" : "address resolution",
1140           format_ip4_address, &mp->address,
1141           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1142 }
1143
1144 static void
1145 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1146 {
1147   /* JSON output not supported */
1148 }
1149
1150 static void
1151 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip6_address, mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 /*
1167  * Special-case: build the bridge domain table, maintain
1168  * the next bd id vbl.
1169  */
1170 static void vl_api_bridge_domain_details_t_handler
1171   (vl_api_bridge_domain_details_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1175
1176   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1177            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1178
1179   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1180            ntohl (mp->bd_id), mp->learn, mp->forward,
1181            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1182
1183   if (n_sw_ifs)
1184     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1185              "Interface Name");
1186 }
1187
1188 static void vl_api_bridge_domain_details_t_handler_json
1189   (vl_api_bridge_domain_details_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   vat_json_node_t *node, *array = NULL;
1193
1194   if (VAT_JSON_ARRAY != vam->json_tree.type)
1195     {
1196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1197       vat_json_init_array (&vam->json_tree);
1198     }
1199   node = vat_json_array_add (&vam->json_tree);
1200
1201   vat_json_init_object (node);
1202   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1203   vat_json_object_add_uint (node, "flood", mp->flood);
1204   vat_json_object_add_uint (node, "forward", mp->forward);
1205   vat_json_object_add_uint (node, "learn", mp->learn);
1206   vat_json_object_add_uint (node, "bvi_sw_if_index",
1207                             ntohl (mp->bvi_sw_if_index));
1208   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1209   array = vat_json_object_add (node, "sw_if");
1210   vat_json_init_array (array);
1211 }
1212
1213 /*
1214  * Special-case: build the bridge domain sw if table.
1215  */
1216 static void vl_api_bridge_domain_sw_if_details_t_handler
1217   (vl_api_bridge_domain_sw_if_details_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   hash_pair_t *p;
1221   u8 *sw_if_name = 0;
1222   u32 sw_if_index;
1223
1224   sw_if_index = ntohl (mp->sw_if_index);
1225   /* *INDENT-OFF* */
1226   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1227   ({
1228     if ((u32) p->value[0] == sw_if_index)
1229       {
1230         sw_if_name = (u8 *)(p->key);
1231         break;
1232       }
1233   }));
1234   /* *INDENT-ON* */
1235
1236   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1237            mp->shg, sw_if_name ? (char *) sw_if_name :
1238            "sw_if_index not found!");
1239 }
1240
1241 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1242   (vl_api_bridge_domain_sw_if_details_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t *node = NULL;
1246   uword last_index = 0;
1247
1248   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1249   ASSERT (vec_len (vam->json_tree.array) >= 1);
1250   last_index = vec_len (vam->json_tree.array) - 1;
1251   node = &vam->json_tree.array[last_index];
1252   node = vat_json_object_get_element (node, "sw_if");
1253   ASSERT (NULL != node);
1254   node = vat_json_array_add (node);
1255
1256   vat_json_init_object (node);
1257   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1258   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1259   vat_json_object_add_uint (node, "shg", mp->shg);
1260 }
1261
1262 static void vl_api_control_ping_reply_t_handler
1263   (vl_api_control_ping_reply_t * mp)
1264 {
1265   vat_main_t *vam = &vat_main;
1266   i32 retval = ntohl (mp->retval);
1267   if (vam->async_mode)
1268     {
1269       vam->async_errors += (retval < 0);
1270     }
1271   else
1272     {
1273       vam->retval = retval;
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler_json
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283
1284   if (VAT_JSON_NONE != vam->json_tree.type)
1285     {
1286       vat_json_print (vam->ofp, &vam->json_tree);
1287       vat_json_free (&vam->json_tree);
1288       vam->json_tree.type = VAT_JSON_NONE;
1289     }
1290   else
1291     {
1292       /* just print [] */
1293       vat_json_init_array (&vam->json_tree);
1294       vat_json_print (vam->ofp, &vam->json_tree);
1295       vam->json_tree.type = VAT_JSON_NONE;
1296     }
1297
1298   vam->retval = retval;
1299   vam->result_ready = 1;
1300 }
1301
1302 static void
1303 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   i32 retval = ntohl (mp->retval);
1307   if (vam->async_mode)
1308     {
1309       vam->async_errors += (retval < 0);
1310     }
1311   else
1312     {
1313       vam->retval = retval;
1314       vam->result_ready = 1;
1315     }
1316 }
1317
1318 static void vl_api_l2_flags_reply_t_handler_json
1319   (vl_api_l2_flags_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   vat_json_node_t node;
1323
1324   vat_json_init_object (&node);
1325   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1326   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1327                             ntohl (mp->resulting_feature_bitmap));
1328
1329   vat_json_print (vam->ofp, &node);
1330   vat_json_free (&node);
1331
1332   vam->retval = ntohl (mp->retval);
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_bridge_flags_reply_t_handler
1337   (vl_api_bridge_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   i32 retval = ntohl (mp->retval);
1341   if (vam->async_mode)
1342     {
1343       vam->async_errors += (retval < 0);
1344     }
1345   else
1346     {
1347       vam->retval = retval;
1348       vam->result_ready = 1;
1349     }
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler_json
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   vat_json_node_t node;
1357
1358   vat_json_init_object (&node);
1359   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1360   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1361                             ntohl (mp->resulting_feature_bitmap));
1362
1363   vat_json_print (vam->ofp, &node);
1364   vat_json_free (&node);
1365
1366   vam->retval = ntohl (mp->retval);
1367   vam->result_ready = 1;
1368 }
1369
1370 static void vl_api_tap_connect_reply_t_handler
1371   (vl_api_tap_connect_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   i32 retval = ntohl (mp->retval);
1375   if (vam->async_mode)
1376     {
1377       vam->async_errors += (retval < 0);
1378     }
1379   else
1380     {
1381       vam->retval = retval;
1382       vam->sw_if_index = ntohl (mp->sw_if_index);
1383       vam->result_ready = 1;
1384     }
1385
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler_json
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   vat_json_node_t node;
1393
1394   vat_json_init_object (&node);
1395   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1396   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1397
1398   vat_json_print (vam->ofp, &node);
1399   vat_json_free (&node);
1400
1401   vam->retval = ntohl (mp->retval);
1402   vam->result_ready = 1;
1403
1404 }
1405
1406 static void
1407 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   i32 retval = ntohl (mp->retval);
1411   if (vam->async_mode)
1412     {
1413       vam->async_errors += (retval < 0);
1414     }
1415   else
1416     {
1417       vam->retval = retval;
1418       vam->sw_if_index = ntohl (mp->sw_if_index);
1419       vam->result_ready = 1;
1420     }
1421 }
1422
1423 static void vl_api_tap_modify_reply_t_handler_json
1424   (vl_api_tap_modify_reply_t * mp)
1425 {
1426   vat_main_t *vam = &vat_main;
1427   vat_json_node_t node;
1428
1429   vat_json_init_object (&node);
1430   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1431   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1432
1433   vat_json_print (vam->ofp, &node);
1434   vat_json_free (&node);
1435
1436   vam->retval = ntohl (mp->retval);
1437   vam->result_ready = 1;
1438 }
1439
1440 static void
1441 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1442 {
1443   vat_main_t *vam = &vat_main;
1444   i32 retval = ntohl (mp->retval);
1445   if (vam->async_mode)
1446     {
1447       vam->async_errors += (retval < 0);
1448     }
1449   else
1450     {
1451       vam->retval = retval;
1452       vam->result_ready = 1;
1453     }
1454 }
1455
1456 static void vl_api_tap_delete_reply_t_handler_json
1457   (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   vat_json_node_t node;
1461
1462   vat_json_init_object (&node);
1463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1464
1465   vat_json_print (vam->ofp, &node);
1466   vat_json_free (&node);
1467
1468   vam->retval = ntohl (mp->retval);
1469   vam->result_ready = 1;
1470 }
1471
1472 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1473   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   i32 retval = ntohl (mp->retval);
1477   if (vam->async_mode)
1478     {
1479       vam->async_errors += (retval < 0);
1480     }
1481   else
1482     {
1483       vam->retval = retval;
1484       vam->result_ready = 1;
1485     }
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   vat_json_node_t node;
1493
1494   vat_json_init_object (&node);
1495   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1496   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1497                             ntohl (mp->tunnel_sw_if_index));
1498
1499   vat_json_print (vam->ofp, &node);
1500   vat_json_free (&node);
1501
1502   vam->retval = ntohl (mp->retval);
1503   vam->result_ready = 1;
1504 }
1505
1506 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1507   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   i32 retval = ntohl (mp->retval);
1511   if (vam->async_mode)
1512     {
1513       vam->async_errors += (retval < 0);
1514     }
1515   else
1516     {
1517       vam->retval = retval;
1518       vam->sw_if_index = ntohl (mp->sw_if_index);
1519       vam->result_ready = 1;
1520     }
1521 }
1522
1523 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1524   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1525 {
1526   vat_main_t *vam = &vat_main;
1527   vat_json_node_t node;
1528
1529   vat_json_init_object (&node);
1530   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1531   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1532
1533   vat_json_print (vam->ofp, &node);
1534   vat_json_free (&node);
1535
1536   vam->retval = ntohl (mp->retval);
1537   vam->result_ready = 1;
1538 }
1539
1540
1541 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1542   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   i32 retval = ntohl (mp->retval);
1546   if (vam->async_mode)
1547     {
1548       vam->async_errors += (retval < 0);
1549     }
1550   else
1551     {
1552       vam->retval = retval;
1553       vam->result_ready = 1;
1554     }
1555 }
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   vat_json_node_t node;
1562
1563   vat_json_init_object (&node);
1564   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1565   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1566
1567   vat_json_print (vam->ofp, &node);
1568   vat_json_free (&node);
1569
1570   vam->retval = ntohl (mp->retval);
1571   vam->result_ready = 1;
1572 }
1573
1574 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1575   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->sw_if_index = ntohl (mp->sw_if_index);
1587       vam->result_ready = 1;
1588     }
1589 }
1590
1591 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1592   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   vat_json_node_t node;
1596
1597   vat_json_init_object (&node);
1598   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1599   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1600
1601   vat_json_print (vam->ofp, &node);
1602   vat_json_free (&node);
1603
1604   vam->retval = ntohl (mp->retval);
1605   vam->result_ready = 1;
1606 }
1607
1608 static void vl_api_gre_add_del_tunnel_reply_t_handler
1609   (vl_api_gre_add_del_tunnel_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613   if (vam->async_mode)
1614     {
1615       vam->async_errors += (retval < 0);
1616     }
1617   else
1618     {
1619       vam->retval = retval;
1620       vam->sw_if_index = ntohl (mp->sw_if_index);
1621       vam->result_ready = 1;
1622     }
1623 }
1624
1625 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1626   (vl_api_gre_add_del_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   vat_json_node_t node;
1630
1631   vat_json_init_object (&node);
1632   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1633   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1634
1635   vat_json_print (vam->ofp, &node);
1636   vat_json_free (&node);
1637
1638   vam->retval = ntohl (mp->retval);
1639   vam->result_ready = 1;
1640 }
1641
1642 static void vl_api_create_vhost_user_if_reply_t_handler
1643   (vl_api_create_vhost_user_if_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   i32 retval = ntohl (mp->retval);
1647   if (vam->async_mode)
1648     {
1649       vam->async_errors += (retval < 0);
1650     }
1651   else
1652     {
1653       vam->retval = retval;
1654       vam->sw_if_index = ntohl (mp->sw_if_index);
1655       vam->result_ready = 1;
1656     }
1657 }
1658
1659 static void vl_api_create_vhost_user_if_reply_t_handler_json
1660   (vl_api_create_vhost_user_if_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   vat_json_node_t node;
1664
1665   vat_json_init_object (&node);
1666   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1667   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1668
1669   vat_json_print (vam->ofp, &node);
1670   vat_json_free (&node);
1671
1672   vam->retval = ntohl (mp->retval);
1673   vam->result_ready = 1;
1674 }
1675
1676 static void vl_api_ip_address_details_t_handler
1677   (vl_api_ip_address_details_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   static ip_address_details_t empty_ip_address_details = { {0} };
1681   ip_address_details_t *address = NULL;
1682   ip_details_t *current_ip_details = NULL;
1683   ip_details_t *details = NULL;
1684
1685   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1686
1687   if (!details || vam->current_sw_if_index >= vec_len (details)
1688       || !details[vam->current_sw_if_index].present)
1689     {
1690       errmsg ("ip address details arrived but not stored\n");
1691       errmsg ("ip_dump should be called first\n");
1692       return;
1693     }
1694
1695   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1696
1697 #define addresses (current_ip_details->addr)
1698
1699   vec_validate_init_empty (addresses, vec_len (addresses),
1700                            empty_ip_address_details);
1701
1702   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1703
1704   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1705   address->prefix_length = mp->prefix_length;
1706 #undef addresses
1707 }
1708
1709 static void vl_api_ip_address_details_t_handler_json
1710   (vl_api_ip_address_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   vat_json_node_t *node = NULL;
1714   struct in6_addr ip6;
1715   struct in_addr ip4;
1716
1717   if (VAT_JSON_ARRAY != vam->json_tree.type)
1718     {
1719       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1720       vat_json_init_array (&vam->json_tree);
1721     }
1722   node = vat_json_array_add (&vam->json_tree);
1723
1724   vat_json_init_object (node);
1725   if (vam->is_ipv6)
1726     {
1727       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1728       vat_json_object_add_ip6 (node, "ip", ip6);
1729     }
1730   else
1731     {
1732       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1733       vat_json_object_add_ip4 (node, "ip", ip4);
1734     }
1735   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1736 }
1737
1738 static void
1739 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   static ip_details_t empty_ip_details = { 0 };
1743   ip_details_t *ip = NULL;
1744   u32 sw_if_index = ~0;
1745
1746   sw_if_index = ntohl (mp->sw_if_index);
1747
1748   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1749                            sw_if_index, empty_ip_details);
1750
1751   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1752                          sw_if_index);
1753
1754   ip->present = 1;
1755 }
1756
1757 static void
1758 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1759 {
1760   vat_main_t *vam = &vat_main;
1761
1762   if (VAT_JSON_ARRAY != vam->json_tree.type)
1763     {
1764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1765       vat_json_init_array (&vam->json_tree);
1766     }
1767   vat_json_array_add_uint (&vam->json_tree,
1768                            clib_net_to_host_u32 (mp->sw_if_index));
1769 }
1770
1771 static void vl_api_map_domain_details_t_handler_json
1772   (vl_api_map_domain_details_t * mp)
1773 {
1774   vat_json_node_t *node = NULL;
1775   vat_main_t *vam = &vat_main;
1776   struct in6_addr ip6;
1777   struct in_addr ip4;
1778
1779   if (VAT_JSON_ARRAY != vam->json_tree.type)
1780     {
1781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1782       vat_json_init_array (&vam->json_tree);
1783     }
1784
1785   node = vat_json_array_add (&vam->json_tree);
1786   vat_json_init_object (node);
1787
1788   vat_json_object_add_uint (node, "domain_index",
1789                             clib_net_to_host_u32 (mp->domain_index));
1790   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1791   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1792   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1793   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1794   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1795   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1796   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1797   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1798   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1799   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1800   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1801   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1802   vat_json_object_add_uint (node, "flags", mp->flags);
1803   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1804   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1805 }
1806
1807 static void vl_api_map_domain_details_t_handler
1808   (vl_api_map_domain_details_t * mp)
1809 {
1810   vat_main_t *vam = &vat_main;
1811
1812   if (mp->is_translation)
1813     {
1814       fformat (vam->ofp,
1815                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1816                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1817                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1818                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1819                clib_net_to_host_u32 (mp->domain_index));
1820     }
1821   else
1822     {
1823       fformat (vam->ofp,
1824                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1825                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1826                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1827                format_ip6_address, mp->ip6_src,
1828                clib_net_to_host_u32 (mp->domain_index));
1829     }
1830   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1831            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1832            mp->is_translation ? "map-t" : "");
1833 }
1834
1835 static void vl_api_map_rule_details_t_handler_json
1836   (vl_api_map_rule_details_t * mp)
1837 {
1838   struct in6_addr ip6;
1839   vat_json_node_t *node = NULL;
1840   vat_main_t *vam = &vat_main;
1841
1842   if (VAT_JSON_ARRAY != vam->json_tree.type)
1843     {
1844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1845       vat_json_init_array (&vam->json_tree);
1846     }
1847
1848   node = vat_json_array_add (&vam->json_tree);
1849   vat_json_init_object (node);
1850
1851   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1852   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1853   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1854 }
1855
1856 static void
1857 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1861            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1862 }
1863
1864 static void
1865 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1869           "router_addr %U host_mac %U\n",
1870           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1871           format_ip4_address, &mp->host_address,
1872           format_ip4_address, &mp->router_address,
1873           format_ethernet_address, mp->host_mac);
1874 }
1875
1876 static void vl_api_dhcp_compl_event_t_handler_json
1877   (vl_api_dhcp_compl_event_t * mp)
1878 {
1879   /* JSON output not supported */
1880 }
1881
1882 static void
1883 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1884                               u32 counter)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   static u64 default_counter = 0;
1888
1889   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1890                            NULL);
1891   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1892                            sw_if_index, default_counter);
1893   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1894 }
1895
1896 static void
1897 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1898                                 interface_counter_t counter)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   static interface_counter_t default_counter = { 0, };
1902
1903   vec_validate_init_empty (vam->combined_interface_counters,
1904                            vnet_counter_type, NULL);
1905   vec_validate_init_empty (vam->combined_interface_counters
1906                            [vnet_counter_type], sw_if_index, default_counter);
1907   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1908 }
1909
1910 static void vl_api_vnet_interface_counters_t_handler
1911   (vl_api_vnet_interface_counters_t * mp)
1912 {
1913   /* not supported */
1914 }
1915
1916 static void vl_api_vnet_interface_counters_t_handler_json
1917   (vl_api_vnet_interface_counters_t * mp)
1918 {
1919   interface_counter_t counter;
1920   vlib_counter_t *v;
1921   u64 *v_packets;
1922   u64 packets;
1923   u32 count;
1924   u32 first_sw_if_index;
1925   int i;
1926
1927   count = ntohl (mp->count);
1928   first_sw_if_index = ntohl (mp->first_sw_if_index);
1929
1930   if (!mp->is_combined)
1931     {
1932       v_packets = (u64 *) & mp->data;
1933       for (i = 0; i < count; i++)
1934         {
1935           packets =
1936             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1937           set_simple_interface_counter (mp->vnet_counter_type,
1938                                         first_sw_if_index + i, packets);
1939           v_packets++;
1940         }
1941     }
1942   else
1943     {
1944       v = (vlib_counter_t *) & mp->data;
1945       for (i = 0; i < count; i++)
1946         {
1947           counter.packets =
1948             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1949           counter.bytes =
1950             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1951           set_combined_interface_counter (mp->vnet_counter_type,
1952                                           first_sw_if_index + i, counter);
1953           v++;
1954         }
1955     }
1956 }
1957
1958 static u32
1959 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   u32 i;
1963
1964   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1965     {
1966       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1967         {
1968           return i;
1969         }
1970     }
1971   return ~0;
1972 }
1973
1974 static u32
1975 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static void vl_api_vnet_ip4_fib_counters_t_handler
1991   (vl_api_vnet_ip4_fib_counters_t * mp)
1992 {
1993   /* not supported */
1994 }
1995
1996 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1997   (vl_api_vnet_ip4_fib_counters_t * mp)
1998 {
1999   vat_main_t *vam = &vat_main;
2000   vl_api_ip4_fib_counter_t *v;
2001   ip4_fib_counter_t *counter;
2002   struct in_addr ip4;
2003   u32 vrf_id;
2004   u32 vrf_index;
2005   u32 count;
2006   int i;
2007
2008   vrf_id = ntohl (mp->vrf_id);
2009   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2010   if (~0 == vrf_index)
2011     {
2012       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2013       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2014       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2015       vec_validate (vam->ip4_fib_counters, vrf_index);
2016       vam->ip4_fib_counters[vrf_index] = NULL;
2017     }
2018
2019   vec_free (vam->ip4_fib_counters[vrf_index]);
2020   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2021   count = ntohl (mp->count);
2022   for (i = 0; i < count; i++)
2023     {
2024       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2025       counter = &vam->ip4_fib_counters[vrf_index][i];
2026       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2027       counter->address = ip4;
2028       counter->address_length = v->address_length;
2029       counter->packets = clib_net_to_host_u64 (v->packets);
2030       counter->bytes = clib_net_to_host_u64 (v->bytes);
2031       v++;
2032     }
2033 }
2034
2035 static void vl_api_vnet_ip6_fib_counters_t_handler
2036   (vl_api_vnet_ip6_fib_counters_t * mp)
2037 {
2038   /* not supported */
2039 }
2040
2041 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2042   (vl_api_vnet_ip6_fib_counters_t * mp)
2043 {
2044   vat_main_t *vam = &vat_main;
2045   vl_api_ip6_fib_counter_t *v;
2046   ip6_fib_counter_t *counter;
2047   struct in6_addr ip6;
2048   u32 vrf_id;
2049   u32 vrf_index;
2050   u32 count;
2051   int i;
2052
2053   vrf_id = ntohl (mp->vrf_id);
2054   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2055   if (~0 == vrf_index)
2056     {
2057       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2058       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2059       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2060       vec_validate (vam->ip6_fib_counters, vrf_index);
2061       vam->ip6_fib_counters[vrf_index] = NULL;
2062     }
2063
2064   vec_free (vam->ip6_fib_counters[vrf_index]);
2065   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2066   count = ntohl (mp->count);
2067   for (i = 0; i < count; i++)
2068     {
2069       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2070       counter = &vam->ip6_fib_counters[vrf_index][i];
2071       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2072       counter->address = ip6;
2073       counter->address_length = v->address_length;
2074       counter->packets = clib_net_to_host_u64 (v->packets);
2075       counter->bytes = clib_net_to_host_u64 (v->bytes);
2076       v++;
2077     }
2078 }
2079
2080 static void vl_api_get_first_msg_id_reply_t_handler
2081   (vl_api_get_first_msg_id_reply_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   i32 retval = ntohl (mp->retval);
2085
2086   if (vam->async_mode)
2087     {
2088       vam->async_errors += (retval < 0);
2089     }
2090   else
2091     {
2092       vam->retval = retval;
2093       vam->result_ready = 1;
2094     }
2095   if (retval >= 0)
2096     {
2097       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2098     }
2099 }
2100
2101 static void vl_api_get_first_msg_id_reply_t_handler_json
2102   (vl_api_get_first_msg_id_reply_t * mp)
2103 {
2104   vat_main_t *vam = &vat_main;
2105   vat_json_node_t node;
2106
2107   vat_json_init_object (&node);
2108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2109   vat_json_object_add_uint (&node, "first_msg_id",
2110                             (uint) ntohs (mp->first_msg_id));
2111
2112   vat_json_print (vam->ofp, &node);
2113   vat_json_free (&node);
2114
2115   vam->retval = ntohl (mp->retval);
2116   vam->result_ready = 1;
2117 }
2118
2119 static void vl_api_get_node_graph_reply_t_handler
2120   (vl_api_get_node_graph_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   api_main_t *am = &api_main;
2124   i32 retval = ntohl (mp->retval);
2125   u8 *pvt_copy, *reply;
2126   void *oldheap;
2127   vlib_node_t *node;
2128   int i;
2129
2130   if (vam->async_mode)
2131     {
2132       vam->async_errors += (retval < 0);
2133     }
2134   else
2135     {
2136       vam->retval = retval;
2137       vam->result_ready = 1;
2138     }
2139
2140   /* "Should never happen..." */
2141   if (retval != 0)
2142     return;
2143
2144   reply = (u8 *) (mp->reply_in_shmem);
2145   pvt_copy = vec_dup (reply);
2146
2147   /* Toss the shared-memory original... */
2148   pthread_mutex_lock (&am->vlib_rp->mutex);
2149   oldheap = svm_push_data_heap (am->vlib_rp);
2150
2151   vec_free (reply);
2152
2153   svm_pop_heap (oldheap);
2154   pthread_mutex_unlock (&am->vlib_rp->mutex);
2155
2156   if (vam->graph_nodes)
2157     {
2158       hash_free (vam->graph_node_index_by_name);
2159
2160       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2161         {
2162           node = vam->graph_nodes[i];
2163           vec_free (node->name);
2164           vec_free (node->next_nodes);
2165           vec_free (node);
2166         }
2167       vec_free (vam->graph_nodes);
2168     }
2169
2170   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2171   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2172   vec_free (pvt_copy);
2173
2174   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2175     {
2176       node = vam->graph_nodes[i];
2177       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2178     }
2179 }
2180
2181 static void vl_api_get_node_graph_reply_t_handler_json
2182   (vl_api_get_node_graph_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   api_main_t *am = &api_main;
2186   void *oldheap;
2187   vat_json_node_t node;
2188   u8 *reply;
2189
2190   /* $$$$ make this real? */
2191   vat_json_init_object (&node);
2192   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2193   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2194
2195   reply = (u8 *) (mp->reply_in_shmem);
2196
2197   /* Toss the shared-memory original... */
2198   pthread_mutex_lock (&am->vlib_rp->mutex);
2199   oldheap = svm_push_data_heap (am->vlib_rp);
2200
2201   vec_free (reply);
2202
2203   svm_pop_heap (oldheap);
2204   pthread_mutex_unlock (&am->vlib_rp->mutex);
2205
2206   vat_json_print (vam->ofp, &node);
2207   vat_json_free (&node);
2208
2209   vam->retval = ntohl (mp->retval);
2210   vam->result_ready = 1;
2211 }
2212
2213 static void
2214 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2215 {
2216   vat_main_t *vam = &vat_main;
2217   u8 *s = 0;
2218
2219   if (mp->local)
2220     {
2221       s = format (s, "%=16d%=16d%=16d\n",
2222                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2223     }
2224   else
2225     {
2226       s = format (s, "%=16U%=16d%=16d\n",
2227                   mp->is_ipv6 ? format_ip6_address :
2228                   format_ip4_address,
2229                   mp->ip_address, mp->priority, mp->weight);
2230     }
2231
2232   fformat (vam->ofp, "%v", s);
2233   vec_free (s);
2234 }
2235
2236 static void
2237 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2238                                             mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   vat_json_node_t *node = NULL;
2242   struct in6_addr ip6;
2243   struct in_addr ip4;
2244
2245   if (VAT_JSON_ARRAY != vam->json_tree.type)
2246     {
2247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2248       vat_json_init_array (&vam->json_tree);
2249     }
2250   node = vat_json_array_add (&vam->json_tree);
2251   vat_json_init_object (node);
2252
2253   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2254   vat_json_object_add_uint (node, "priority", mp->priority);
2255   vat_json_object_add_uint (node, "weight", mp->weight);
2256
2257   if (mp->local)
2258     vat_json_object_add_uint (node, "sw_if_index",
2259                               clib_net_to_host_u32 (mp->sw_if_index));
2260   else
2261     {
2262       if (mp->is_ipv6)
2263         {
2264           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2265           vat_json_object_add_ip6 (node, "address", ip6);
2266         }
2267       else
2268         {
2269           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2270           vat_json_object_add_ip4 (node, "address", ip4);
2271         }
2272     }
2273 }
2274
2275 static void
2276 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2277                                            mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   u8 *ls_name = 0;
2281
2282   ls_name = format (0, "%s", mp->ls_name);
2283
2284   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2285            ls_name);
2286   vec_free (ls_name);
2287 }
2288
2289 static void
2290   vl_api_lisp_locator_set_details_t_handler_json
2291   (vl_api_lisp_locator_set_details_t * mp)
2292 {
2293   vat_main_t *vam = &vat_main;
2294   vat_json_node_t *node = 0;
2295   u8 *ls_name = 0;
2296
2297   ls_name = format (0, "%s", mp->ls_name);
2298   vec_add1 (ls_name, 0);
2299
2300   if (VAT_JSON_ARRAY != vam->json_tree.type)
2301     {
2302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2303       vat_json_init_array (&vam->json_tree);
2304     }
2305   node = vat_json_array_add (&vam->json_tree);
2306
2307   vat_json_init_object (node);
2308   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2309   vat_json_object_add_uint (node, "ls_index",
2310                             clib_net_to_host_u32 (mp->ls_index));
2311   vec_free (ls_name);
2312 }
2313
2314 static u8 *
2315 format_lisp_flat_eid (u8 * s, va_list * args)
2316 {
2317   u32 type = va_arg (*args, u32);
2318   u8 *eid = va_arg (*args, u8 *);
2319   u32 eid_len = va_arg (*args, u32);
2320
2321   switch (type)
2322     {
2323     case 0:
2324       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2325     case 1:
2326       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2327     case 2:
2328       return format (s, "%U", format_ethernet_address, eid);
2329     }
2330   return 0;
2331 }
2332
2333 static u8 *
2334 format_lisp_eid_vat (u8 * s, va_list * args)
2335 {
2336   u32 type = va_arg (*args, u32);
2337   u8 *eid = va_arg (*args, u8 *);
2338   u32 eid_len = va_arg (*args, u32);
2339   u8 *seid = va_arg (*args, u8 *);
2340   u32 seid_len = va_arg (*args, u32);
2341   u32 is_src_dst = va_arg (*args, u32);
2342
2343   if (is_src_dst)
2344     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2345
2346   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2347
2348   return s;
2349 }
2350
2351 static void
2352 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   u8 *s = 0, *eid = 0;
2356
2357   if (~0 == mp->locator_set_index)
2358     s = format (0, "action: %d", mp->action);
2359   else
2360     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2361
2362   eid = format (0, "%U", format_lisp_eid_vat,
2363                 mp->eid_type,
2364                 mp->eid,
2365                 mp->eid_prefix_len,
2366                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2367   vec_add1 (eid, 0);
2368
2369   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2370            clib_net_to_host_u32 (mp->vni),
2371            eid,
2372            mp->is_local ? "local" : "remote",
2373            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2374   vec_free (s);
2375   vec_free (eid);
2376 }
2377
2378 static void
2379 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2380                                               * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   vat_json_node_t *node = 0;
2384   u8 *eid = 0;
2385
2386   if (VAT_JSON_ARRAY != vam->json_tree.type)
2387     {
2388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2389       vat_json_init_array (&vam->json_tree);
2390     }
2391   node = vat_json_array_add (&vam->json_tree);
2392
2393   vat_json_init_object (node);
2394   if (~0 == mp->locator_set_index)
2395     vat_json_object_add_uint (node, "action", mp->action);
2396   else
2397     vat_json_object_add_uint (node, "locator_set_index",
2398                               clib_net_to_host_u32 (mp->locator_set_index));
2399
2400   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2401   eid = format (0, "%U", format_lisp_eid_vat,
2402                 mp->eid_type,
2403                 mp->eid,
2404                 mp->eid_prefix_len,
2405                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2406   vec_add1 (eid, 0);
2407   vat_json_object_add_string_copy (node, "eid", eid);
2408   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2409   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2410   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2411   vec_free (eid);
2412 }
2413
2414 static void
2415   vl_api_lisp_eid_table_map_details_t_handler
2416   (vl_api_lisp_eid_table_map_details_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419
2420   u8 *line = format (0, "%=10d%=10d",
2421                      clib_net_to_host_u32 (mp->vni),
2422                      clib_net_to_host_u32 (mp->dp_table));
2423   fformat (vam->ofp, "%v\n", line);
2424   vec_free (line);
2425 }
2426
2427 static void
2428   vl_api_lisp_eid_table_map_details_t_handler_json
2429   (vl_api_lisp_eid_table_map_details_t * mp)
2430 {
2431   vat_main_t *vam = &vat_main;
2432   vat_json_node_t *node = NULL;
2433
2434   if (VAT_JSON_ARRAY != vam->json_tree.type)
2435     {
2436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2437       vat_json_init_array (&vam->json_tree);
2438     }
2439   node = vat_json_array_add (&vam->json_tree);
2440   vat_json_init_object (node);
2441   vat_json_object_add_uint (node, "dp_table",
2442                             clib_net_to_host_u32 (mp->dp_table));
2443   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2444 }
2445
2446 static void
2447   vl_api_lisp_eid_table_vni_details_t_handler
2448   (vl_api_lisp_eid_table_vni_details_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451
2452   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2453   fformat (vam->ofp, "%v\n", line);
2454   vec_free (line);
2455 }
2456
2457 static void
2458   vl_api_lisp_eid_table_vni_details_t_handler_json
2459   (vl_api_lisp_eid_table_vni_details_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   vat_json_node_t *node = NULL;
2463
2464   if (VAT_JSON_ARRAY != vam->json_tree.type)
2465     {
2466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2467       vat_json_init_array (&vam->json_tree);
2468     }
2469   node = vat_json_array_add (&vam->json_tree);
2470   vat_json_init_object (node);
2471   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2472 }
2473
2474 static u8 *
2475 format_decap_next (u8 * s, va_list * args)
2476 {
2477   u32 next_index = va_arg (*args, u32);
2478
2479   switch (next_index)
2480     {
2481     case LISP_GPE_INPUT_NEXT_DROP:
2482       return format (s, "drop");
2483     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2484       return format (s, "ip4");
2485     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2486       return format (s, "ip6");
2487     default:
2488       return format (s, "unknown %d", next_index);
2489     }
2490   return s;
2491 }
2492
2493 static void
2494 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2495                                           mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   u8 *iid_str;
2499   u8 *flag_str = NULL;
2500
2501   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2502
2503 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2504   foreach_lisp_gpe_flag_bit;
2505 #undef _
2506
2507   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2508            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2509            mp->tunnels,
2510            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2511            mp->source_ip,
2512            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2513            mp->destination_ip,
2514            ntohl (mp->encap_fib_id),
2515            ntohl (mp->decap_fib_id),
2516            format_decap_next, ntohl (mp->dcap_next),
2517            mp->ver_res >> 6,
2518            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2519
2520   vec_free (iid_str);
2521 }
2522
2523 static void
2524   vl_api_lisp_gpe_tunnel_details_t_handler_json
2525   (vl_api_lisp_gpe_tunnel_details_t * mp)
2526 {
2527   vat_main_t *vam = &vat_main;
2528   vat_json_node_t *node = NULL;
2529   struct in6_addr ip6;
2530   struct in_addr ip4;
2531   u8 *next_decap_str;
2532
2533   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2534
2535   if (VAT_JSON_ARRAY != vam->json_tree.type)
2536     {
2537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2538       vat_json_init_array (&vam->json_tree);
2539     }
2540   node = vat_json_array_add (&vam->json_tree);
2541
2542   vat_json_init_object (node);
2543   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2544   if (mp->is_ipv6)
2545     {
2546       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2547       vat_json_object_add_ip6 (node, "source address", ip6);
2548       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2549       vat_json_object_add_ip6 (node, "destination address", ip6);
2550     }
2551   else
2552     {
2553       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2554       vat_json_object_add_ip4 (node, "source address", ip4);
2555       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2556       vat_json_object_add_ip4 (node, "destination address", ip4);
2557     }
2558   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2559   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2560   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2561   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2562   vat_json_object_add_uint (node, "flags", mp->flags);
2563   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2564   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2565   vat_json_object_add_uint (node, "res", mp->res);
2566   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2567
2568   vec_free (next_decap_str);
2569 }
2570
2571 static void
2572   vl_api_lisp_adjacencies_get_reply_t_handler
2573   (vl_api_lisp_adjacencies_get_reply_t * mp)
2574 {
2575   vat_main_t *vam = &vat_main;
2576   u32 i, n;
2577   int retval = clib_net_to_host_u32 (mp->retval);
2578   vl_api_lisp_adjacency_t *a;
2579
2580   if (retval)
2581     goto end;
2582
2583   n = clib_net_to_host_u32 (mp->count);
2584
2585   for (i = 0; i < n; i++)
2586     {
2587       a = &mp->adjacencies[i];
2588       fformat (vam->ofp, "%U %40U\n",
2589                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2590                format_lisp_flat_eid, a->eid_type, a->reid,
2591                a->reid_prefix_len);
2592     }
2593
2594 end:
2595   vam->retval = retval;
2596   vam->result_ready = 1;
2597 }
2598
2599 static void
2600   vl_api_lisp_adjacencies_get_reply_t_handler_json
2601   (vl_api_lisp_adjacencies_get_reply_t * mp)
2602 {
2603   u8 *s = 0;
2604   vat_main_t *vam = &vat_main;
2605   vat_json_node_t *e = 0, root;
2606   u32 i, n;
2607   int retval = clib_net_to_host_u32 (mp->retval);
2608   vl_api_lisp_adjacency_t *a;
2609
2610   if (retval)
2611     goto end;
2612
2613   n = clib_net_to_host_u32 (mp->count);
2614   vat_json_init_array (&root);
2615
2616   for (i = 0; i < n; i++)
2617     {
2618       e = vat_json_array_add (&root);
2619       a = &mp->adjacencies[i];
2620
2621       vat_json_init_object (e);
2622       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2623                   a->leid_prefix_len);
2624       vec_add1 (s, 0);
2625       vat_json_object_add_string_copy (e, "leid", s);
2626       vec_free (s);
2627
2628       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2629                   a->reid_prefix_len);
2630       vec_add1 (s, 0);
2631       vat_json_object_add_string_copy (e, "reid", s);
2632       vec_free (s);
2633     }
2634
2635   vat_json_print (vam->ofp, &root);
2636   vat_json_free (&root);
2637
2638 end:
2639   vam->retval = retval;
2640   vam->result_ready = 1;
2641 }
2642
2643 static void
2644 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2645                                             * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648
2649   fformat (vam->ofp, "%=20U\n",
2650            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2651            mp->ip_address);
2652 }
2653
2654 static void
2655   vl_api_lisp_map_resolver_details_t_handler_json
2656   (vl_api_lisp_map_resolver_details_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   vat_json_node_t *node = NULL;
2660   struct in6_addr ip6;
2661   struct in_addr ip4;
2662
2663   if (VAT_JSON_ARRAY != vam->json_tree.type)
2664     {
2665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2666       vat_json_init_array (&vam->json_tree);
2667     }
2668   node = vat_json_array_add (&vam->json_tree);
2669
2670   vat_json_init_object (node);
2671   if (mp->is_ipv6)
2672     {
2673       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2674       vat_json_object_add_ip6 (node, "map resolver", ip6);
2675     }
2676   else
2677     {
2678       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2679       vat_json_object_add_ip4 (node, "map resolver", ip4);
2680     }
2681 }
2682
2683 static void
2684   vl_api_show_lisp_status_reply_t_handler
2685   (vl_api_show_lisp_status_reply_t * mp)
2686 {
2687   vat_main_t *vam = &vat_main;
2688   i32 retval = ntohl (mp->retval);
2689
2690   if (0 <= retval)
2691     {
2692       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2693                mp->feature_status ? "enabled" : "disabled",
2694                mp->gpe_status ? "enabled" : "disabled");
2695     }
2696
2697   vam->retval = retval;
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_show_lisp_status_reply_t_handler_json
2703   (vl_api_show_lisp_status_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   vat_json_node_t node;
2707   u8 *gpe_status = NULL;
2708   u8 *feature_status = NULL;
2709
2710   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2711   feature_status = format (0, "%s",
2712                            mp->feature_status ? "enabled" : "disabled");
2713   vec_add1 (gpe_status, 0);
2714   vec_add1 (feature_status, 0);
2715
2716   vat_json_init_object (&node);
2717   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2718   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2719
2720   vec_free (gpe_status);
2721   vec_free (feature_status);
2722
2723   vat_json_print (vam->ofp, &node);
2724   vat_json_free (&node);
2725
2726   vam->retval = ntohl (mp->retval);
2727   vam->result_ready = 1;
2728 }
2729
2730 static void
2731   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2732   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2733 {
2734   vat_main_t *vam = &vat_main;
2735   i32 retval = ntohl (mp->retval);
2736
2737   if (retval >= 0)
2738     {
2739       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2740     }
2741
2742   vam->retval = retval;
2743   vam->result_ready = 1;
2744 }
2745
2746 static void
2747   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2748   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2749 {
2750   vat_main_t *vam = &vat_main;
2751   vat_json_node_t *node = NULL;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2762
2763   vat_json_print (vam->ofp, node);
2764   vat_json_free (node);
2765
2766   vam->retval = ntohl (mp->retval);
2767   vam->result_ready = 1;
2768 }
2769
2770 static u8 *
2771 format_lisp_map_request_mode (u8 * s, va_list * args)
2772 {
2773   u32 mode = va_arg (*args, u32);
2774
2775   switch (mode)
2776     {
2777     case 0:
2778       return format (0, "dst-only");
2779     case 1:
2780       return format (0, "src-dst");
2781     }
2782   return 0;
2783 }
2784
2785 static void
2786   vl_api_show_lisp_map_request_mode_reply_t_handler
2787   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   i32 retval = ntohl (mp->retval);
2791
2792   if (0 <= retval)
2793     {
2794       u32 mode = mp->mode;
2795       fformat (vam->ofp, "map_request_mode: %U\n",
2796                format_lisp_map_request_mode, mode);
2797     }
2798
2799   vam->retval = retval;
2800   vam->result_ready = 1;
2801 }
2802
2803 static void
2804   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2805   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   vat_json_node_t node;
2809   u8 *s = 0;
2810   u32 mode;
2811
2812   mode = mp->mode;
2813   s = format (0, "%U", format_lisp_map_request_mode, mode);
2814   vec_add1 (s, 0);
2815
2816   vat_json_init_object (&node);
2817   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2818   vat_json_print (vam->ofp, &node);
2819   vat_json_free (&node);
2820
2821   vec_free (s);
2822   vam->retval = ntohl (mp->retval);
2823   vam->result_ready = 1;
2824 }
2825
2826 static void
2827 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   i32 retval = ntohl (mp->retval);
2831
2832   if (0 <= retval)
2833     {
2834       fformat (vam->ofp, "%-20s%-16s\n",
2835                mp->status ? "enabled" : "disabled",
2836                mp->status ? (char *) mp->locator_set_name : "");
2837     }
2838
2839   vam->retval = retval;
2840   vam->result_ready = 1;
2841 }
2842
2843 static void
2844 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2845                                             mp)
2846 {
2847   vat_main_t *vam = &vat_main;
2848   vat_json_node_t node;
2849   u8 *status = 0;
2850
2851   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2852   vec_add1 (status, 0);
2853
2854   vat_json_init_object (&node);
2855   vat_json_object_add_string_copy (&node, "status", status);
2856   if (mp->status)
2857     {
2858       vat_json_object_add_string_copy (&node, "locator_set",
2859                                        mp->locator_set_name);
2860     }
2861
2862   vec_free (status);
2863
2864   vat_json_print (vam->ofp, &node);
2865   vat_json_free (&node);
2866
2867   vam->retval = ntohl (mp->retval);
2868   vam->result_ready = 1;
2869 }
2870
2871 static u8 *
2872 format_policer_type (u8 * s, va_list * va)
2873 {
2874   u32 i = va_arg (*va, u32);
2875
2876   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2877     s = format (s, "1r2c");
2878   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2879     s = format (s, "1r3c");
2880   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2881     s = format (s, "2r3c-2698");
2882   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2883     s = format (s, "2r3c-4115");
2884   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2885     s = format (s, "2r3c-mef5cf1");
2886   else
2887     s = format (s, "ILLEGAL");
2888   return s;
2889 }
2890
2891 static u8 *
2892 format_policer_rate_type (u8 * s, va_list * va)
2893 {
2894   u32 i = va_arg (*va, u32);
2895
2896   if (i == SSE2_QOS_RATE_KBPS)
2897     s = format (s, "kbps");
2898   else if (i == SSE2_QOS_RATE_PPS)
2899     s = format (s, "pps");
2900   else
2901     s = format (s, "ILLEGAL");
2902   return s;
2903 }
2904
2905 static u8 *
2906 format_policer_round_type (u8 * s, va_list * va)
2907 {
2908   u32 i = va_arg (*va, u32);
2909
2910   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2911     s = format (s, "closest");
2912   else if (i == SSE2_QOS_ROUND_TO_UP)
2913     s = format (s, "up");
2914   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2915     s = format (s, "down");
2916   else
2917     s = format (s, "ILLEGAL");
2918   return s;
2919 }
2920
2921 static u8 *
2922 format_policer_action_type (u8 * s, va_list * va)
2923 {
2924   u32 i = va_arg (*va, u32);
2925
2926   if (i == SSE2_QOS_ACTION_DROP)
2927     s = format (s, "drop");
2928   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2929     s = format (s, "transmit");
2930   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2931     s = format (s, "mark-and-transmit");
2932   else
2933     s = format (s, "ILLEGAL");
2934   return s;
2935 }
2936
2937 static u8 *
2938 format_dscp (u8 * s, va_list * va)
2939 {
2940   u32 i = va_arg (*va, u32);
2941   char *t = 0;
2942
2943   switch (i)
2944     {
2945 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2946       foreach_vnet_dscp
2947 #undef _
2948     default:
2949       return format (s, "ILLEGAL");
2950     }
2951   s = format (s, "%s", t);
2952   return s;
2953 }
2954
2955 static void
2956 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2957 {
2958   vat_main_t *vam = &vat_main;
2959   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2960
2961   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2962     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2963   else
2964     conform_dscp_str = format (0, "");
2965
2966   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2967     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2968   else
2969     exceed_dscp_str = format (0, "");
2970
2971   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2972     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2973   else
2974     violate_dscp_str = format (0, "");
2975
2976   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2977            "rate type %U, round type %U, %s rate, %s color-aware, "
2978            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2979            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2980            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2981            mp->name,
2982            format_policer_type, mp->type,
2983            ntohl (mp->cir),
2984            ntohl (mp->eir),
2985            clib_net_to_host_u64 (mp->cb),
2986            clib_net_to_host_u64 (mp->eb),
2987            format_policer_rate_type, mp->rate_type,
2988            format_policer_round_type, mp->round_type,
2989            mp->single_rate ? "single" : "dual",
2990            mp->color_aware ? "is" : "not",
2991            ntohl (mp->cir_tokens_per_period),
2992            ntohl (mp->pir_tokens_per_period),
2993            ntohl (mp->scale),
2994            ntohl (mp->current_limit),
2995            ntohl (mp->current_bucket),
2996            ntohl (mp->extended_limit),
2997            ntohl (mp->extended_bucket),
2998            clib_net_to_host_u64 (mp->last_update_time),
2999            format_policer_action_type, mp->conform_action_type,
3000            conform_dscp_str,
3001            format_policer_action_type, mp->exceed_action_type,
3002            exceed_dscp_str,
3003            format_policer_action_type, mp->violate_action_type,
3004            violate_dscp_str);
3005
3006   vec_free (conform_dscp_str);
3007   vec_free (exceed_dscp_str);
3008   vec_free (violate_dscp_str);
3009 }
3010
3011 static void vl_api_policer_details_t_handler_json
3012   (vl_api_policer_details_t * mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   vat_json_node_t *node;
3016   u8 *rate_type_str, *round_type_str, *type_str;
3017   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3018
3019   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3020   round_type_str =
3021     format (0, "%U", format_policer_round_type, mp->round_type);
3022   type_str = format (0, "%U", format_policer_type, mp->type);
3023   conform_action_str = format (0, "%U", format_policer_action_type,
3024                                mp->conform_action_type);
3025   exceed_action_str = format (0, "%U", format_policer_action_type,
3026                               mp->exceed_action_type);
3027   violate_action_str = format (0, "%U", format_policer_action_type,
3028                                mp->violate_action_type);
3029
3030   if (VAT_JSON_ARRAY != vam->json_tree.type)
3031     {
3032       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3033       vat_json_init_array (&vam->json_tree);
3034     }
3035   node = vat_json_array_add (&vam->json_tree);
3036
3037   vat_json_init_object (node);
3038   vat_json_object_add_string_copy (node, "name", mp->name);
3039   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3040   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3041   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3042   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3043   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3044   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3045   vat_json_object_add_string_copy (node, "type", type_str);
3046   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3047   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3048   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3049   vat_json_object_add_uint (node, "cir_tokens_per_period",
3050                             ntohl (mp->cir_tokens_per_period));
3051   vat_json_object_add_uint (node, "eir_tokens_per_period",
3052                             ntohl (mp->pir_tokens_per_period));
3053   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3054   vat_json_object_add_uint (node, "current_bucket",
3055                             ntohl (mp->current_bucket));
3056   vat_json_object_add_uint (node, "extended_limit",
3057                             ntohl (mp->extended_limit));
3058   vat_json_object_add_uint (node, "extended_bucket",
3059                             ntohl (mp->extended_bucket));
3060   vat_json_object_add_uint (node, "last_update_time",
3061                             ntohl (mp->last_update_time));
3062   vat_json_object_add_string_copy (node, "conform_action",
3063                                    conform_action_str);
3064   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3065     {
3066       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3067       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3068       vec_free (dscp_str);
3069     }
3070   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3071   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3072     {
3073       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3074       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3075       vec_free (dscp_str);
3076     }
3077   vat_json_object_add_string_copy (node, "violate_action",
3078                                    violate_action_str);
3079   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3080     {
3081       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3082       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3083       vec_free (dscp_str);
3084     }
3085
3086   vec_free (rate_type_str);
3087   vec_free (round_type_str);
3088   vec_free (type_str);
3089   vec_free (conform_action_str);
3090   vec_free (exceed_action_str);
3091   vec_free (violate_action_str);
3092 }
3093
3094 static void
3095 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3096                                            mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   int i, count = ntohl (mp->count);
3100
3101   if (count > 0)
3102     fformat (vam->ofp, "classify table ids (%d) : ", count);
3103   for (i = 0; i < count; i++)
3104     {
3105       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3106       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3107     }
3108   vam->retval = ntohl (mp->retval);
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_classify_table_ids_reply_t_handler_json
3114   (vl_api_classify_table_ids_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   int i, count = ntohl (mp->count);
3118
3119   if (count > 0)
3120     {
3121       vat_json_node_t node;
3122
3123       vat_json_init_object (&node);
3124       for (i = 0; i < count; i++)
3125         {
3126           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3127         }
3128       vat_json_print (vam->ofp, &node);
3129       vat_json_free (&node);
3130     }
3131   vam->retval = ntohl (mp->retval);
3132   vam->result_ready = 1;
3133 }
3134
3135 static void
3136   vl_api_classify_table_by_interface_reply_t_handler
3137   (vl_api_classify_table_by_interface_reply_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   u32 table_id;
3141
3142   table_id = ntohl (mp->l2_table_id);
3143   if (table_id != ~0)
3144     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3145   else
3146     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3147   table_id = ntohl (mp->ip4_table_id);
3148   if (table_id != ~0)
3149     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3150   else
3151     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3152   table_id = ntohl (mp->ip6_table_id);
3153   if (table_id != ~0)
3154     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3155   else
3156     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3157   vam->retval = ntohl (mp->retval);
3158   vam->result_ready = 1;
3159 }
3160
3161 static void
3162   vl_api_classify_table_by_interface_reply_t_handler_json
3163   (vl_api_classify_table_by_interface_reply_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166   vat_json_node_t node;
3167
3168   vat_json_init_object (&node);
3169
3170   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3171   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3172   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3173
3174   vat_json_print (vam->ofp, &node);
3175   vat_json_free (&node);
3176
3177   vam->retval = ntohl (mp->retval);
3178   vam->result_ready = 1;
3179 }
3180
3181 static void vl_api_policer_add_del_reply_t_handler
3182   (vl_api_policer_add_del_reply_t * mp)
3183 {
3184   vat_main_t *vam = &vat_main;
3185   i32 retval = ntohl (mp->retval);
3186   if (vam->async_mode)
3187     {
3188       vam->async_errors += (retval < 0);
3189     }
3190   else
3191     {
3192       vam->retval = retval;
3193       vam->result_ready = 1;
3194       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3195         /*
3196          * Note: this is just barely thread-safe, depends on
3197          * the main thread spinning waiting for an answer...
3198          */
3199         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3200     }
3201 }
3202
3203 static void vl_api_policer_add_del_reply_t_handler_json
3204   (vl_api_policer_add_del_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t node;
3208
3209   vat_json_init_object (&node);
3210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3211   vat_json_object_add_uint (&node, "policer_index",
3212                             ntohl (mp->policer_index));
3213
3214   vat_json_print (vam->ofp, &node);
3215   vat_json_free (&node);
3216
3217   vam->retval = ntohl (mp->retval);
3218   vam->result_ready = 1;
3219 }
3220
3221 /* Format hex dump. */
3222 u8 *
3223 format_hex_bytes (u8 * s, va_list * va)
3224 {
3225   u8 *bytes = va_arg (*va, u8 *);
3226   int n_bytes = va_arg (*va, int);
3227   uword i;
3228
3229   /* Print short or long form depending on byte count. */
3230   uword short_form = n_bytes <= 32;
3231   uword indent = format_get_indent (s);
3232
3233   if (n_bytes == 0)
3234     return s;
3235
3236   for (i = 0; i < n_bytes; i++)
3237     {
3238       if (!short_form && (i % 32) == 0)
3239         s = format (s, "%08x: ", i);
3240       s = format (s, "%02x", bytes[i]);
3241       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3242         s = format (s, "\n%U", format_white_space, indent);
3243     }
3244
3245   return s;
3246 }
3247
3248 static void
3249 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3250                                             * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   i32 retval = ntohl (mp->retval);
3254   if (retval == 0)
3255     {
3256       fformat (vam->ofp, "classify table info :\n");
3257       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3258                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3259                ntohl (mp->miss_next_index));
3260       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3261                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3262                ntohl (mp->match_n_vectors));
3263       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3264                ntohl (mp->mask_length));
3265     }
3266   vam->retval = retval;
3267   vam->result_ready = 1;
3268 }
3269
3270 static void
3271   vl_api_classify_table_info_reply_t_handler_json
3272   (vl_api_classify_table_info_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   vat_json_node_t node;
3276
3277   i32 retval = ntohl (mp->retval);
3278   if (retval == 0)
3279     {
3280       vat_json_init_object (&node);
3281
3282       vat_json_object_add_int (&node, "sessions",
3283                                ntohl (mp->active_sessions));
3284       vat_json_object_add_int (&node, "nexttbl",
3285                                ntohl (mp->next_table_index));
3286       vat_json_object_add_int (&node, "nextnode",
3287                                ntohl (mp->miss_next_index));
3288       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3289       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3290       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3291       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3292                       ntohl (mp->mask_length), 0);
3293       vat_json_object_add_string_copy (&node, "mask", s);
3294
3295       vat_json_print (vam->ofp, &node);
3296       vat_json_free (&node);
3297     }
3298   vam->retval = ntohl (mp->retval);
3299   vam->result_ready = 1;
3300 }
3301
3302 static void
3303 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3304                                            mp)
3305 {
3306   vat_main_t *vam = &vat_main;
3307
3308   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3309            ntohl (mp->hit_next_index), ntohl (mp->advance),
3310            ntohl (mp->opaque_index));
3311   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3312            ntohl (mp->match_length));
3313 }
3314
3315 static void
3316   vl_api_classify_session_details_t_handler_json
3317   (vl_api_classify_session_details_t * mp)
3318 {
3319   vat_main_t *vam = &vat_main;
3320   vat_json_node_t *node = NULL;
3321
3322   if (VAT_JSON_ARRAY != vam->json_tree.type)
3323     {
3324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3325       vat_json_init_array (&vam->json_tree);
3326     }
3327   node = vat_json_array_add (&vam->json_tree);
3328
3329   vat_json_init_object (node);
3330   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3331   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3332   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3333   u8 *s =
3334     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3335             0);
3336   vat_json_object_add_string_copy (node, "match", s);
3337 }
3338
3339 static void vl_api_pg_create_interface_reply_t_handler
3340   (vl_api_pg_create_interface_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   vam->retval = ntohl (mp->retval);
3345   vam->result_ready = 1;
3346 }
3347
3348 static void vl_api_pg_create_interface_reply_t_handler_json
3349   (vl_api_pg_create_interface_reply_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t node;
3353
3354   i32 retval = ntohl (mp->retval);
3355   if (retval == 0)
3356     {
3357       vat_json_init_object (&node);
3358
3359       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3360
3361       vat_json_print (vam->ofp, &node);
3362       vat_json_free (&node);
3363     }
3364   vam->retval = ntohl (mp->retval);
3365   vam->result_ready = 1;
3366 }
3367
3368 static void vl_api_policer_classify_details_t_handler
3369   (vl_api_policer_classify_details_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372
3373   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3374            ntohl (mp->table_index));
3375 }
3376
3377 static void vl_api_policer_classify_details_t_handler_json
3378   (vl_api_policer_classify_details_t * mp)
3379 {
3380   vat_main_t *vam = &vat_main;
3381   vat_json_node_t *node;
3382
3383   if (VAT_JSON_ARRAY != vam->json_tree.type)
3384     {
3385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3386       vat_json_init_array (&vam->json_tree);
3387     }
3388   node = vat_json_array_add (&vam->json_tree);
3389
3390   vat_json_init_object (node);
3391   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3392   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3393 }
3394
3395 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3396   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399   i32 retval = ntohl (mp->retval);
3400   if (vam->async_mode)
3401     {
3402       vam->async_errors += (retval < 0);
3403     }
3404   else
3405     {
3406       vam->retval = retval;
3407       vam->sw_if_index = ntohl (mp->sw_if_index);
3408       vam->result_ready = 1;
3409     }
3410 }
3411
3412 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3413   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3414 {
3415   vat_main_t *vam = &vat_main;
3416   vat_json_node_t node;
3417
3418   vat_json_init_object (&node);
3419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3420   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3421
3422   vat_json_print (vam->ofp, &node);
3423   vat_json_free (&node);
3424
3425   vam->retval = ntohl (mp->retval);
3426   vam->result_ready = 1;
3427 }
3428
3429 static void vl_api_flow_classify_details_t_handler
3430   (vl_api_flow_classify_details_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3435            ntohl (mp->table_index));
3436 }
3437
3438 static void vl_api_flow_classify_details_t_handler_json
3439   (vl_api_flow_classify_details_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t *node;
3443
3444   if (VAT_JSON_ARRAY != vam->json_tree.type)
3445     {
3446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3447       vat_json_init_array (&vam->json_tree);
3448     }
3449   node = vat_json_array_add (&vam->json_tree);
3450
3451   vat_json_init_object (node);
3452   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3453   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3454 }
3455
3456
3457
3458 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3459 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3460 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3461 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3462 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3463 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3464
3465 /*
3466  * Generate boilerplate reply handlers, which
3467  * dig the return value out of the xxx_reply_t API message,
3468  * stick it into vam->retval, and set vam->result_ready
3469  *
3470  * Could also do this by pointing N message decode slots at
3471  * a single function, but that could break in subtle ways.
3472  */
3473
3474 #define foreach_standard_reply_retval_handler           \
3475 _(sw_interface_set_flags_reply)                         \
3476 _(sw_interface_add_del_address_reply)                   \
3477 _(sw_interface_set_table_reply)                         \
3478 _(sw_interface_set_mpls_enable_reply)                   \
3479 _(sw_interface_set_vpath_reply)                         \
3480 _(sw_interface_set_l2_bridge_reply)                     \
3481 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3482 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3483 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3484 _(bridge_domain_add_del_reply)                          \
3485 _(sw_interface_set_l2_xconnect_reply)                   \
3486 _(l2fib_add_del_reply)                                  \
3487 _(ip_add_del_route_reply)                               \
3488 _(mpls_route_add_del_reply)                             \
3489 _(mpls_ip_bind_unbind_reply)                            \
3490 _(proxy_arp_add_del_reply)                              \
3491 _(proxy_arp_intfc_enable_disable_reply)                 \
3492 _(mpls_add_del_encap_reply)                             \
3493 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3494 _(sw_interface_set_unnumbered_reply)                    \
3495 _(ip_neighbor_add_del_reply)                            \
3496 _(reset_vrf_reply)                                      \
3497 _(oam_add_del_reply)                                    \
3498 _(reset_fib_reply)                                      \
3499 _(dhcp_proxy_config_reply)                              \
3500 _(dhcp_proxy_config_2_reply)                            \
3501 _(dhcp_proxy_set_vss_reply)                             \
3502 _(dhcp_client_config_reply)                             \
3503 _(set_ip_flow_hash_reply)                               \
3504 _(sw_interface_ip6_enable_disable_reply)                \
3505 _(sw_interface_ip6_set_link_local_address_reply)        \
3506 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3507 _(sw_interface_ip6nd_ra_config_reply)                   \
3508 _(set_arp_neighbor_limit_reply)                         \
3509 _(l2_patch_add_del_reply)                               \
3510 _(sr_tunnel_add_del_reply)                              \
3511 _(sr_policy_add_del_reply)                              \
3512 _(sr_multicast_map_add_del_reply)                       \
3513 _(classify_add_del_session_reply)                       \
3514 _(classify_set_interface_ip_table_reply)                \
3515 _(classify_set_interface_l2_tables_reply)               \
3516 _(l2tpv3_set_tunnel_cookies_reply)                      \
3517 _(l2tpv3_interface_enable_disable_reply)                \
3518 _(l2tpv3_set_lookup_key_reply)                          \
3519 _(l2_fib_clear_table_reply)                             \
3520 _(l2_interface_efp_filter_reply)                        \
3521 _(l2_interface_vlan_tag_rewrite_reply)                  \
3522 _(modify_vhost_user_if_reply)                           \
3523 _(delete_vhost_user_if_reply)                           \
3524 _(want_ip4_arp_events_reply)                            \
3525 _(want_ip6_nd_events_reply)                             \
3526 _(input_acl_set_interface_reply)                        \
3527 _(ipsec_spd_add_del_reply)                              \
3528 _(ipsec_interface_add_del_spd_reply)                    \
3529 _(ipsec_spd_add_del_entry_reply)                        \
3530 _(ipsec_sad_add_del_entry_reply)                        \
3531 _(ipsec_sa_set_key_reply)                               \
3532 _(ikev2_profile_add_del_reply)                          \
3533 _(ikev2_profile_set_auth_reply)                         \
3534 _(ikev2_profile_set_id_reply)                           \
3535 _(ikev2_profile_set_ts_reply)                           \
3536 _(ikev2_set_local_key_reply)                            \
3537 _(delete_loopback_reply)                                \
3538 _(bd_ip_mac_add_del_reply)                              \
3539 _(map_del_domain_reply)                                 \
3540 _(map_add_del_rule_reply)                               \
3541 _(want_interface_events_reply)                          \
3542 _(want_stats_reply)                                     \
3543 _(cop_interface_enable_disable_reply)                   \
3544 _(cop_whitelist_enable_disable_reply)                   \
3545 _(sw_interface_clear_stats_reply)                       \
3546 _(ioam_enable_reply)                              \
3547 _(ioam_disable_reply)                              \
3548 _(lisp_add_del_locator_reply)                           \
3549 _(lisp_add_del_local_eid_reply)                         \
3550 _(lisp_add_del_remote_mapping_reply)                    \
3551 _(lisp_add_del_adjacency_reply)                         \
3552 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3553 _(lisp_add_del_map_resolver_reply)                      \
3554 _(lisp_gpe_enable_disable_reply)                        \
3555 _(lisp_gpe_add_del_iface_reply)                         \
3556 _(lisp_enable_disable_reply)                            \
3557 _(lisp_pitr_set_locator_set_reply)                      \
3558 _(lisp_map_request_mode_reply)                          \
3559 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3560 _(lisp_eid_table_add_del_map_reply)                     \
3561 _(vxlan_gpe_add_del_tunnel_reply)                       \
3562 _(af_packet_delete_reply)                               \
3563 _(policer_classify_set_interface_reply)                 \
3564 _(netmap_create_reply)                                  \
3565 _(netmap_delete_reply)                                  \
3566 _(set_ipfix_exporter_reply)                             \
3567 _(set_ipfix_classify_stream_reply)                      \
3568 _(ipfix_classify_table_add_del_reply)                   \
3569 _(flow_classify_set_interface_reply)                    \
3570 _(pg_capture_reply)                                     \
3571 _(pg_enable_disable_reply)                              \
3572 _(ip_source_and_port_range_check_add_del_reply)         \
3573 _(ip_source_and_port_range_check_interface_add_del_reply)\
3574 _(delete_subif_reply)                                   \
3575 _(l2_interface_pbb_tag_rewrite_reply)                   \
3576 _(punt_reply)
3577
3578 #define _(n)                                    \
3579     static void vl_api_##n##_t_handler          \
3580     (vl_api_##n##_t * mp)                       \
3581     {                                           \
3582         vat_main_t * vam = &vat_main;           \
3583         i32 retval = ntohl(mp->retval);         \
3584         if (vam->async_mode) {                  \
3585             vam->async_errors += (retval < 0);  \
3586         } else {                                \
3587             vam->retval = retval;               \
3588             vam->result_ready = 1;              \
3589         }                                       \
3590     }
3591 foreach_standard_reply_retval_handler;
3592 #undef _
3593
3594 #define _(n)                                    \
3595     static void vl_api_##n##_t_handler_json     \
3596     (vl_api_##n##_t * mp)                       \
3597     {                                           \
3598         vat_main_t * vam = &vat_main;           \
3599         vat_json_node_t node;                   \
3600         vat_json_init_object(&node);            \
3601         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3602         vat_json_print(vam->ofp, &node);        \
3603         vam->retval = ntohl(mp->retval);        \
3604         vam->result_ready = 1;                  \
3605     }
3606 foreach_standard_reply_retval_handler;
3607 #undef _
3608
3609 /*
3610  * Table of message reply handlers, must include boilerplate handlers
3611  * we just generated
3612  */
3613
3614 #define foreach_vpe_api_reply_msg                                       \
3615 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3616 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3617 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3618 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3619 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3620 _(CLI_REPLY, cli_reply)                                                 \
3621 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3622 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3623   sw_interface_add_del_address_reply)                                   \
3624 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3625 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3626 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3627 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3628   sw_interface_set_l2_xconnect_reply)                                   \
3629 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3630   sw_interface_set_l2_bridge_reply)                                     \
3631 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3632   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3633 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3634   sw_interface_set_dpdk_hqos_subport_reply)                             \
3635 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3636   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3637 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3638 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3639 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3640 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3641 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3642 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3643 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3644 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3645 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3646 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3647 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3648 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3649 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3650 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3651 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3652   proxy_arp_intfc_enable_disable_reply)                                 \
3653 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3654 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3655   mpls_ethernet_add_del_tunnel_reply)                                   \
3656 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3657   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3658 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3659   sw_interface_set_unnumbered_reply)                                    \
3660 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3661 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3662 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3663 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3664 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3665 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3666 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3667 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3668 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3669 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3670 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3671 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3672   sw_interface_ip6_enable_disable_reply)                                \
3673 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3674   sw_interface_ip6_set_link_local_address_reply)                        \
3675 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3676   sw_interface_ip6nd_ra_prefix_reply)                                   \
3677 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3678   sw_interface_ip6nd_ra_config_reply)                                   \
3679 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3680 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3681 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3682 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3683 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3684 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3685 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3686 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3687 classify_set_interface_ip_table_reply)                                  \
3688 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3689   classify_set_interface_l2_tables_reply)                               \
3690 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3691 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3692 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3693 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3694 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3695   l2tpv3_interface_enable_disable_reply)                                \
3696 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3697 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3698 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3699 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3700 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3701 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3702 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3703 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3704 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3705 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3706 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3707 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3708 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3709 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3710 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3711 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3712 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3713 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3714 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3715 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3716 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3717 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3718 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3719 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3720 _(IP_DETAILS, ip_details)                                               \
3721 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3722 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3723 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3724 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3725 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3726 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3727 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3728 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3729 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3730 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3731 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3732 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3733 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3734 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3735 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3736 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3737 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3738 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3739 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3740 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3741 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3742 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3743 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3744 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3745 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3746 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3747 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3748 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3749 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3750 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3751 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3752 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3753 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3754 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3755 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3756 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3757 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3758 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3759 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3760 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3761 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3762 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3763 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3764 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3765 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3766 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3767 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3768 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3769 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3770 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3771 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3772 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3773 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3774   lisp_add_del_map_request_itr_rlocs_reply)                             \
3775 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3776   lisp_get_map_request_itr_rlocs_reply)                                 \
3777 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3778 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3779 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3780 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3781 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3782 _(POLICER_DETAILS, policer_details)                                     \
3783 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3784 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3785 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3786 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3787 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3788 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3789 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3790 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3791 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3792 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3793 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3794 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3795 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3796 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3797 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3798 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3799 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3800 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3801 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3802 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3803 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3804 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3805 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3806 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3807  ip_source_and_port_range_check_add_del_reply)                          \
3808 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3809  ip_source_and_port_range_check_interface_add_del_reply)                \
3810 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3811 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3812 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3813 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3814 _(PUNT_REPLY, punt_reply)
3815
3816 /* M: construct, but don't yet send a message */
3817
3818 #define M(T,t)                                  \
3819 do {                                            \
3820     vam->result_ready = 0;                      \
3821     mp = vl_msg_api_alloc(sizeof(*mp));         \
3822     memset (mp, 0, sizeof (*mp));               \
3823     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3824     mp->client_index = vam->my_client_index;    \
3825 } while(0);
3826
3827 #define M2(T,t,n)                               \
3828 do {                                            \
3829     vam->result_ready = 0;                      \
3830     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3831     memset (mp, 0, sizeof (*mp));               \
3832     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3833     mp->client_index = vam->my_client_index;    \
3834 } while(0);
3835
3836
3837 /* S: send a message */
3838 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3839
3840 /* W: wait for results, with timeout */
3841 #define W                                       \
3842 do {                                            \
3843     timeout = vat_time_now (vam) + 1.0;         \
3844                                                 \
3845     while (vat_time_now (vam) < timeout) {      \
3846         if (vam->result_ready == 1) {           \
3847             return (vam->retval);               \
3848         }                                       \
3849     }                                           \
3850     return -99;                                 \
3851 } while(0);
3852
3853 /* W2: wait for results, with timeout */
3854 #define W2(body)                                \
3855 do {                                            \
3856     timeout = vat_time_now (vam) + 1.0;         \
3857                                                 \
3858     while (vat_time_now (vam) < timeout) {      \
3859         if (vam->result_ready == 1) {           \
3860           (body);                               \
3861           return (vam->retval);                 \
3862         }                                       \
3863     }                                           \
3864     return -99;                                 \
3865 } while(0);
3866
3867 typedef struct
3868 {
3869   u8 *name;
3870   u32 value;
3871 } name_sort_t;
3872
3873
3874 #define STR_VTR_OP_CASE(op)     \
3875     case L2_VTR_ ## op:         \
3876         return "" # op;
3877
3878 static const char *
3879 str_vtr_op (u32 vtr_op)
3880 {
3881   switch (vtr_op)
3882     {
3883       STR_VTR_OP_CASE (DISABLED);
3884       STR_VTR_OP_CASE (PUSH_1);
3885       STR_VTR_OP_CASE (PUSH_2);
3886       STR_VTR_OP_CASE (POP_1);
3887       STR_VTR_OP_CASE (POP_2);
3888       STR_VTR_OP_CASE (TRANSLATE_1_1);
3889       STR_VTR_OP_CASE (TRANSLATE_1_2);
3890       STR_VTR_OP_CASE (TRANSLATE_2_1);
3891       STR_VTR_OP_CASE (TRANSLATE_2_2);
3892     }
3893
3894   return "UNKNOWN";
3895 }
3896
3897 static int
3898 dump_sub_interface_table (vat_main_t * vam)
3899 {
3900   const sw_interface_subif_t *sub = NULL;
3901
3902   if (vam->json_output)
3903     {
3904       clib_warning
3905         ("JSON output supported only for VPE API calls and dump_stats_table");
3906       return -99;
3907     }
3908
3909   fformat (vam->ofp,
3910            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3911            "Interface", "sw_if_index",
3912            "sub id", "dot1ad", "tags", "outer id",
3913            "inner id", "exact", "default", "outer any", "inner any");
3914
3915   vec_foreach (sub, vam->sw_if_subif_table)
3916   {
3917     fformat (vam->ofp,
3918              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3919              sub->interface_name,
3920              sub->sw_if_index,
3921              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3922              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3923              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3924              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3925     if (sub->vtr_op != L2_VTR_DISABLED)
3926       {
3927         fformat (vam->ofp,
3928                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3929                  "tag1: %d tag2: %d ]\n",
3930                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3931                  sub->vtr_tag1, sub->vtr_tag2);
3932       }
3933   }
3934
3935   return 0;
3936 }
3937
3938 static int
3939 name_sort_cmp (void *a1, void *a2)
3940 {
3941   name_sort_t *n1 = a1;
3942   name_sort_t *n2 = a2;
3943
3944   return strcmp ((char *) n1->name, (char *) n2->name);
3945 }
3946
3947 static int
3948 dump_interface_table (vat_main_t * vam)
3949 {
3950   hash_pair_t *p;
3951   name_sort_t *nses = 0, *ns;
3952
3953   if (vam->json_output)
3954     {
3955       clib_warning
3956         ("JSON output supported only for VPE API calls and dump_stats_table");
3957       return -99;
3958     }
3959
3960   /* *INDENT-OFF* */
3961   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3962   ({
3963     vec_add2 (nses, ns, 1);
3964     ns->name = (u8 *)(p->key);
3965     ns->value = (u32) p->value[0];
3966   }));
3967   /* *INDENT-ON* */
3968
3969   vec_sort_with_function (nses, name_sort_cmp);
3970
3971   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3972   vec_foreach (ns, nses)
3973   {
3974     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3975   }
3976   vec_free (nses);
3977   return 0;
3978 }
3979
3980 static int
3981 dump_ip_table (vat_main_t * vam, int is_ipv6)
3982 {
3983   const ip_details_t *det = NULL;
3984   const ip_address_details_t *address = NULL;
3985   u32 i = ~0;
3986
3987   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3988
3989   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3990   {
3991     i++;
3992     if (!det->present)
3993       {
3994         continue;
3995       }
3996     fformat (vam->ofp, "%-12d\n", i);
3997     fformat (vam->ofp,
3998              "            %-30s%-13s\n", "Address", "Prefix length");
3999     if (!det->addr)
4000       {
4001         continue;
4002       }
4003     vec_foreach (address, det->addr)
4004     {
4005       fformat (vam->ofp,
4006                "            %-30U%-13d\n",
4007                is_ipv6 ? format_ip6_address : format_ip4_address,
4008                address->ip, address->prefix_length);
4009     }
4010   }
4011
4012   return 0;
4013 }
4014
4015 static int
4016 dump_ipv4_table (vat_main_t * vam)
4017 {
4018   if (vam->json_output)
4019     {
4020       clib_warning
4021         ("JSON output supported only for VPE API calls and dump_stats_table");
4022       return -99;
4023     }
4024
4025   return dump_ip_table (vam, 0);
4026 }
4027
4028 static int
4029 dump_ipv6_table (vat_main_t * vam)
4030 {
4031   if (vam->json_output)
4032     {
4033       clib_warning
4034         ("JSON output supported only for VPE API calls and dump_stats_table");
4035       return -99;
4036     }
4037
4038   return dump_ip_table (vam, 1);
4039 }
4040
4041 static char *
4042 counter_type_to_str (u8 counter_type, u8 is_combined)
4043 {
4044   if (!is_combined)
4045     {
4046       switch (counter_type)
4047         {
4048         case VNET_INTERFACE_COUNTER_DROP:
4049           return "drop";
4050         case VNET_INTERFACE_COUNTER_PUNT:
4051           return "punt";
4052         case VNET_INTERFACE_COUNTER_IP4:
4053           return "ip4";
4054         case VNET_INTERFACE_COUNTER_IP6:
4055           return "ip6";
4056         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4057           return "rx-no-buf";
4058         case VNET_INTERFACE_COUNTER_RX_MISS:
4059           return "rx-miss";
4060         case VNET_INTERFACE_COUNTER_RX_ERROR:
4061           return "rx-error";
4062         case VNET_INTERFACE_COUNTER_TX_ERROR:
4063           return "tx-error";
4064         default:
4065           return "INVALID-COUNTER-TYPE";
4066         }
4067     }
4068   else
4069     {
4070       switch (counter_type)
4071         {
4072         case VNET_INTERFACE_COUNTER_RX:
4073           return "rx";
4074         case VNET_INTERFACE_COUNTER_TX:
4075           return "tx";
4076         default:
4077           return "INVALID-COUNTER-TYPE";
4078         }
4079     }
4080 }
4081
4082 static int
4083 dump_stats_table (vat_main_t * vam)
4084 {
4085   vat_json_node_t node;
4086   vat_json_node_t *msg_array;
4087   vat_json_node_t *msg;
4088   vat_json_node_t *counter_array;
4089   vat_json_node_t *counter;
4090   interface_counter_t c;
4091   u64 packets;
4092   ip4_fib_counter_t *c4;
4093   ip6_fib_counter_t *c6;
4094   int i, j;
4095
4096   if (!vam->json_output)
4097     {
4098       clib_warning ("dump_stats_table supported only in JSON format");
4099       return -99;
4100     }
4101
4102   vat_json_init_object (&node);
4103
4104   /* interface counters */
4105   msg_array = vat_json_object_add (&node, "interface_counters");
4106   vat_json_init_array (msg_array);
4107   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4108     {
4109       msg = vat_json_array_add (msg_array);
4110       vat_json_init_object (msg);
4111       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4112                                        (u8 *) counter_type_to_str (i, 0));
4113       vat_json_object_add_int (msg, "is_combined", 0);
4114       counter_array = vat_json_object_add (msg, "data");
4115       vat_json_init_array (counter_array);
4116       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4117         {
4118           packets = vam->simple_interface_counters[i][j];
4119           vat_json_array_add_uint (counter_array, packets);
4120         }
4121     }
4122   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4123     {
4124       msg = vat_json_array_add (msg_array);
4125       vat_json_init_object (msg);
4126       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4127                                        (u8 *) counter_type_to_str (i, 1));
4128       vat_json_object_add_int (msg, "is_combined", 1);
4129       counter_array = vat_json_object_add (msg, "data");
4130       vat_json_init_array (counter_array);
4131       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4132         {
4133           c = vam->combined_interface_counters[i][j];
4134           counter = vat_json_array_add (counter_array);
4135           vat_json_init_object (counter);
4136           vat_json_object_add_uint (counter, "packets", c.packets);
4137           vat_json_object_add_uint (counter, "bytes", c.bytes);
4138         }
4139     }
4140
4141   /* ip4 fib counters */
4142   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4143   vat_json_init_array (msg_array);
4144   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4145     {
4146       msg = vat_json_array_add (msg_array);
4147       vat_json_init_object (msg);
4148       vat_json_object_add_uint (msg, "vrf_id",
4149                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4150       counter_array = vat_json_object_add (msg, "c");
4151       vat_json_init_array (counter_array);
4152       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4153         {
4154           counter = vat_json_array_add (counter_array);
4155           vat_json_init_object (counter);
4156           c4 = &vam->ip4_fib_counters[i][j];
4157           vat_json_object_add_ip4 (counter, "address", c4->address);
4158           vat_json_object_add_uint (counter, "address_length",
4159                                     c4->address_length);
4160           vat_json_object_add_uint (counter, "packets", c4->packets);
4161           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4162         }
4163     }
4164
4165   /* ip6 fib counters */
4166   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4167   vat_json_init_array (msg_array);
4168   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4169     {
4170       msg = vat_json_array_add (msg_array);
4171       vat_json_init_object (msg);
4172       vat_json_object_add_uint (msg, "vrf_id",
4173                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4174       counter_array = vat_json_object_add (msg, "c");
4175       vat_json_init_array (counter_array);
4176       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4177         {
4178           counter = vat_json_array_add (counter_array);
4179           vat_json_init_object (counter);
4180           c6 = &vam->ip6_fib_counters[i][j];
4181           vat_json_object_add_ip6 (counter, "address", c6->address);
4182           vat_json_object_add_uint (counter, "address_length",
4183                                     c6->address_length);
4184           vat_json_object_add_uint (counter, "packets", c6->packets);
4185           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4186         }
4187     }
4188
4189   vat_json_print (vam->ofp, &node);
4190   vat_json_free (&node);
4191
4192   return 0;
4193 }
4194
4195 int
4196 exec (vat_main_t * vam)
4197 {
4198   api_main_t *am = &api_main;
4199   vl_api_cli_request_t *mp;
4200   f64 timeout;
4201   void *oldheap;
4202   u8 *cmd = 0;
4203   unformat_input_t *i = vam->input;
4204
4205   if (vec_len (i->buffer) == 0)
4206     return -1;
4207
4208   if (vam->exec_mode == 0 && unformat (i, "mode"))
4209     {
4210       vam->exec_mode = 1;
4211       return 0;
4212     }
4213   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4214     {
4215       vam->exec_mode = 0;
4216       return 0;
4217     }
4218
4219
4220   M (CLI_REQUEST, cli_request);
4221
4222   /*
4223    * Copy cmd into shared memory.
4224    * In order for the CLI command to work, it
4225    * must be a vector ending in \n, not a C-string ending
4226    * in \n\0.
4227    */
4228   pthread_mutex_lock (&am->vlib_rp->mutex);
4229   oldheap = svm_push_data_heap (am->vlib_rp);
4230
4231   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4232   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4233
4234   svm_pop_heap (oldheap);
4235   pthread_mutex_unlock (&am->vlib_rp->mutex);
4236
4237   mp->cmd_in_shmem = (u64) cmd;
4238   S;
4239   timeout = vat_time_now (vam) + 10.0;
4240
4241   while (vat_time_now (vam) < timeout)
4242     {
4243       if (vam->result_ready == 1)
4244         {
4245           u8 *free_me;
4246           if (vam->shmem_result != NULL)
4247             fformat (vam->ofp, "%s", vam->shmem_result);
4248           pthread_mutex_lock (&am->vlib_rp->mutex);
4249           oldheap = svm_push_data_heap (am->vlib_rp);
4250
4251           free_me = (u8 *) vam->shmem_result;
4252           vec_free (free_me);
4253
4254           svm_pop_heap (oldheap);
4255           pthread_mutex_unlock (&am->vlib_rp->mutex);
4256           return 0;
4257         }
4258     }
4259   return -99;
4260 }
4261
4262 /*
4263  * Future replacement of exec() that passes CLI buffers directly in
4264  * the API messages instead of an additional shared memory area.
4265  */
4266 static int
4267 exec_inband (vat_main_t * vam)
4268 {
4269   vl_api_cli_inband_t *mp;
4270   f64 timeout;
4271   unformat_input_t *i = vam->input;
4272
4273   if (vec_len (i->buffer) == 0)
4274     return -1;
4275
4276   if (vam->exec_mode == 0 && unformat (i, "mode"))
4277     {
4278       vam->exec_mode = 1;
4279       return 0;
4280     }
4281   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4282     {
4283       vam->exec_mode = 0;
4284       return 0;
4285     }
4286
4287   /*
4288    * In order for the CLI command to work, it
4289    * must be a vector ending in \n, not a C-string ending
4290    * in \n\0.
4291    */
4292   u32 len = vec_len (vam->input->buffer);
4293   M2 (CLI_INBAND, cli_inband, len);
4294   clib_memcpy (mp->cmd, vam->input->buffer, len);
4295   mp->length = htonl (len);
4296
4297   S;
4298   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4299 }
4300
4301 static int
4302 api_create_loopback (vat_main_t * vam)
4303 {
4304   unformat_input_t *i = vam->input;
4305   vl_api_create_loopback_t *mp;
4306   f64 timeout;
4307   u8 mac_address[6];
4308   u8 mac_set = 0;
4309
4310   memset (mac_address, 0, sizeof (mac_address));
4311
4312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4313     {
4314       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4315         mac_set = 1;
4316       else
4317         break;
4318     }
4319
4320   /* Construct the API message */
4321   M (CREATE_LOOPBACK, create_loopback);
4322   if (mac_set)
4323     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4324
4325   S;
4326   W;
4327 }
4328
4329 static int
4330 api_delete_loopback (vat_main_t * vam)
4331 {
4332   unformat_input_t *i = vam->input;
4333   vl_api_delete_loopback_t *mp;
4334   f64 timeout;
4335   u32 sw_if_index = ~0;
4336
4337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4338     {
4339       if (unformat (i, "sw_if_index %d", &sw_if_index))
4340         ;
4341       else
4342         break;
4343     }
4344
4345   if (sw_if_index == ~0)
4346     {
4347       errmsg ("missing sw_if_index\n");
4348       return -99;
4349     }
4350
4351   /* Construct the API message */
4352   M (DELETE_LOOPBACK, delete_loopback);
4353   mp->sw_if_index = ntohl (sw_if_index);
4354
4355   S;
4356   W;
4357 }
4358
4359 static int
4360 api_want_stats (vat_main_t * vam)
4361 {
4362   unformat_input_t *i = vam->input;
4363   vl_api_want_stats_t *mp;
4364   f64 timeout;
4365   int enable = -1;
4366
4367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4368     {
4369       if (unformat (i, "enable"))
4370         enable = 1;
4371       else if (unformat (i, "disable"))
4372         enable = 0;
4373       else
4374         break;
4375     }
4376
4377   if (enable == -1)
4378     {
4379       errmsg ("missing enable|disable\n");
4380       return -99;
4381     }
4382
4383   M (WANT_STATS, want_stats);
4384   mp->enable_disable = enable;
4385
4386   S;
4387   W;
4388 }
4389
4390 static int
4391 api_want_interface_events (vat_main_t * vam)
4392 {
4393   unformat_input_t *i = vam->input;
4394   vl_api_want_interface_events_t *mp;
4395   f64 timeout;
4396   int enable = -1;
4397
4398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4399     {
4400       if (unformat (i, "enable"))
4401         enable = 1;
4402       else if (unformat (i, "disable"))
4403         enable = 0;
4404       else
4405         break;
4406     }
4407
4408   if (enable == -1)
4409     {
4410       errmsg ("missing enable|disable\n");
4411       return -99;
4412     }
4413
4414   M (WANT_INTERFACE_EVENTS, want_interface_events);
4415   mp->enable_disable = enable;
4416
4417   vam->interface_event_display = enable;
4418
4419   S;
4420   W;
4421 }
4422
4423
4424 /* Note: non-static, called once to set up the initial intfc table */
4425 int
4426 api_sw_interface_dump (vat_main_t * vam)
4427 {
4428   vl_api_sw_interface_dump_t *mp;
4429   f64 timeout;
4430   hash_pair_t *p;
4431   name_sort_t *nses = 0, *ns;
4432   sw_interface_subif_t *sub = NULL;
4433
4434   /* Toss the old name table */
4435   /* *INDENT-OFF* */
4436   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4437   ({
4438     vec_add2 (nses, ns, 1);
4439     ns->name = (u8 *)(p->key);
4440     ns->value = (u32) p->value[0];
4441   }));
4442   /* *INDENT-ON* */
4443
4444   hash_free (vam->sw_if_index_by_interface_name);
4445
4446   vec_foreach (ns, nses) vec_free (ns->name);
4447
4448   vec_free (nses);
4449
4450   vec_foreach (sub, vam->sw_if_subif_table)
4451   {
4452     vec_free (sub->interface_name);
4453   }
4454   vec_free (vam->sw_if_subif_table);
4455
4456   /* recreate the interface name hash table */
4457   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4458
4459   /* Get list of ethernets */
4460   M (SW_INTERFACE_DUMP, sw_interface_dump);
4461   mp->name_filter_valid = 1;
4462   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4463   S;
4464
4465   /* and local / loopback interfaces */
4466   M (SW_INTERFACE_DUMP, sw_interface_dump);
4467   mp->name_filter_valid = 1;
4468   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4469   S;
4470
4471   /* and packet-generator interfaces */
4472   M (SW_INTERFACE_DUMP, sw_interface_dump);
4473   mp->name_filter_valid = 1;
4474   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4475   S;
4476
4477   /* and vxlan-gpe tunnel interfaces */
4478   M (SW_INTERFACE_DUMP, sw_interface_dump);
4479   mp->name_filter_valid = 1;
4480   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4481            sizeof (mp->name_filter) - 1);
4482   S;
4483
4484   /* and vxlan tunnel interfaces */
4485   M (SW_INTERFACE_DUMP, sw_interface_dump);
4486   mp->name_filter_valid = 1;
4487   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4488   S;
4489
4490   /* and host (af_packet) interfaces */
4491   M (SW_INTERFACE_DUMP, sw_interface_dump);
4492   mp->name_filter_valid = 1;
4493   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4494   S;
4495
4496   /* and l2tpv3 tunnel interfaces */
4497   M (SW_INTERFACE_DUMP, sw_interface_dump);
4498   mp->name_filter_valid = 1;
4499   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4500            sizeof (mp->name_filter) - 1);
4501   S;
4502
4503   /* and GRE tunnel interfaces */
4504   M (SW_INTERFACE_DUMP, sw_interface_dump);
4505   mp->name_filter_valid = 1;
4506   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4507   S;
4508
4509   /* and LISP-GPE interfaces */
4510   M (SW_INTERFACE_DUMP, sw_interface_dump);
4511   mp->name_filter_valid = 1;
4512   strncpy ((char *) mp->name_filter, "lisp_gpe",
4513            sizeof (mp->name_filter) - 1);
4514   S;
4515
4516   /* and IPSEC tunnel interfaces */
4517   M (SW_INTERFACE_DUMP, sw_interface_dump);
4518   mp->name_filter_valid = 1;
4519   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4520   S;
4521
4522   /* Use a control ping for synchronization */
4523   {
4524     vl_api_control_ping_t *mp;
4525     M (CONTROL_PING, control_ping);
4526     S;
4527   }
4528   W;
4529 }
4530
4531 static int
4532 api_sw_interface_set_flags (vat_main_t * vam)
4533 {
4534   unformat_input_t *i = vam->input;
4535   vl_api_sw_interface_set_flags_t *mp;
4536   f64 timeout;
4537   u32 sw_if_index;
4538   u8 sw_if_index_set = 0;
4539   u8 admin_up = 0, link_up = 0;
4540
4541   /* Parse args required to build the message */
4542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4543     {
4544       if (unformat (i, "admin-up"))
4545         admin_up = 1;
4546       else if (unformat (i, "admin-down"))
4547         admin_up = 0;
4548       else if (unformat (i, "link-up"))
4549         link_up = 1;
4550       else if (unformat (i, "link-down"))
4551         link_up = 0;
4552       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4553         sw_if_index_set = 1;
4554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4555         sw_if_index_set = 1;
4556       else
4557         break;
4558     }
4559
4560   if (sw_if_index_set == 0)
4561     {
4562       errmsg ("missing interface name or sw_if_index\n");
4563       return -99;
4564     }
4565
4566   /* Construct the API message */
4567   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4568   mp->sw_if_index = ntohl (sw_if_index);
4569   mp->admin_up_down = admin_up;
4570   mp->link_up_down = link_up;
4571
4572   /* send it... */
4573   S;
4574
4575   /* Wait for a reply, return the good/bad news... */
4576   W;
4577 }
4578
4579 static int
4580 api_sw_interface_clear_stats (vat_main_t * vam)
4581 {
4582   unformat_input_t *i = vam->input;
4583   vl_api_sw_interface_clear_stats_t *mp;
4584   f64 timeout;
4585   u32 sw_if_index;
4586   u8 sw_if_index_set = 0;
4587
4588   /* Parse args required to build the message */
4589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4590     {
4591       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4592         sw_if_index_set = 1;
4593       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4594         sw_if_index_set = 1;
4595       else
4596         break;
4597     }
4598
4599   /* Construct the API message */
4600   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4601
4602   if (sw_if_index_set == 1)
4603     mp->sw_if_index = ntohl (sw_if_index);
4604   else
4605     mp->sw_if_index = ~0;
4606
4607   /* send it... */
4608   S;
4609
4610   /* Wait for a reply, return the good/bad news... */
4611   W;
4612 }
4613
4614 static int
4615 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4616 {
4617   unformat_input_t *i = vam->input;
4618   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4619   f64 timeout;
4620   u32 sw_if_index;
4621   u8 sw_if_index_set = 0;
4622   u32 subport;
4623   u8 subport_set = 0;
4624   u32 pipe;
4625   u8 pipe_set = 0;
4626   u32 profile;
4627   u8 profile_set = 0;
4628
4629   /* Parse args required to build the message */
4630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4631     {
4632       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4633         sw_if_index_set = 1;
4634       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4635         sw_if_index_set = 1;
4636       else if (unformat (i, "subport %u", &subport))
4637         subport_set = 1;
4638       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4639         sw_if_index_set = 1;
4640       else if (unformat (i, "pipe %u", &pipe))
4641         pipe_set = 1;
4642       else if (unformat (i, "profile %u", &profile))
4643         profile_set = 1;
4644       else
4645         break;
4646     }
4647
4648   if (sw_if_index_set == 0)
4649     {
4650       errmsg ("missing interface name or sw_if_index\n");
4651       return -99;
4652     }
4653
4654   if (subport_set == 0)
4655     {
4656       errmsg ("missing subport \n");
4657       return -99;
4658     }
4659
4660   if (pipe_set == 0)
4661     {
4662       errmsg ("missing pipe\n");
4663       return -99;
4664     }
4665
4666   if (profile_set == 0)
4667     {
4668       errmsg ("missing profile\n");
4669       return -99;
4670     }
4671
4672   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4673
4674   mp->sw_if_index = ntohl (sw_if_index);
4675   mp->subport = ntohl (subport);
4676   mp->pipe = ntohl (pipe);
4677   mp->profile = ntohl (profile);
4678
4679
4680   S;
4681   W;
4682   /* NOTREACHED */
4683   return 0;
4684 }
4685
4686 static int
4687 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4688 {
4689   unformat_input_t *i = vam->input;
4690   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4691   f64 timeout;
4692   u32 sw_if_index;
4693   u8 sw_if_index_set = 0;
4694   u32 subport;
4695   u8 subport_set = 0;
4696   u32 tb_rate = 1250000000;     /* 10GbE */
4697   u32 tb_size = 1000000;
4698   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4699   u32 tc_period = 10;
4700
4701   /* Parse args required to build the message */
4702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4703     {
4704       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4705         sw_if_index_set = 1;
4706       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4707         sw_if_index_set = 1;
4708       else if (unformat (i, "subport %u", &subport))
4709         subport_set = 1;
4710       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4711         sw_if_index_set = 1;
4712       else if (unformat (i, "rate %u", &tb_rate))
4713         {
4714           u32 tc_id;
4715
4716           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4717                tc_id++)
4718             tc_rate[tc_id] = tb_rate;
4719         }
4720       else if (unformat (i, "bktsize %u", &tb_size))
4721         ;
4722       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4723         ;
4724       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4725         ;
4726       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4727         ;
4728       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4729         ;
4730       else if (unformat (i, "period %u", &tc_period))
4731         ;
4732       else
4733         break;
4734     }
4735
4736   if (sw_if_index_set == 0)
4737     {
4738       errmsg ("missing interface name or sw_if_index\n");
4739       return -99;
4740     }
4741
4742   if (subport_set == 0)
4743     {
4744       errmsg ("missing subport \n");
4745       return -99;
4746     }
4747
4748   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4749
4750   mp->sw_if_index = ntohl (sw_if_index);
4751   mp->subport = ntohl (subport);
4752   mp->tb_rate = ntohl (tb_rate);
4753   mp->tb_size = ntohl (tb_size);
4754   mp->tc_rate[0] = ntohl (tc_rate[0]);
4755   mp->tc_rate[1] = ntohl (tc_rate[1]);
4756   mp->tc_rate[2] = ntohl (tc_rate[2]);
4757   mp->tc_rate[3] = ntohl (tc_rate[3]);
4758   mp->tc_period = ntohl (tc_period);
4759
4760   S;
4761   W;
4762   /* NOTREACHED */
4763   return 0;
4764 }
4765
4766 static int
4767 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4768 {
4769   unformat_input_t *i = vam->input;
4770   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4771   f64 timeout;
4772   u32 sw_if_index;
4773   u8 sw_if_index_set = 0;
4774   u8 entry_set = 0;
4775   u8 tc_set = 0;
4776   u8 queue_set = 0;
4777   u32 entry, tc, queue;
4778
4779   /* Parse args required to build the message */
4780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4781     {
4782       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4783         sw_if_index_set = 1;
4784       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4785         sw_if_index_set = 1;
4786       else if (unformat (i, "entry %d", &entry))
4787         entry_set = 1;
4788       else if (unformat (i, "tc %d", &tc))
4789         tc_set = 1;
4790       else if (unformat (i, "queue %d", &queue))
4791         queue_set = 1;
4792       else
4793         break;
4794     }
4795
4796   if (sw_if_index_set == 0)
4797     {
4798       errmsg ("missing interface name or sw_if_index\n");
4799       return -99;
4800     }
4801
4802   if (entry_set == 0)
4803     {
4804       errmsg ("missing entry \n");
4805       return -99;
4806     }
4807
4808   if (tc_set == 0)
4809     {
4810       errmsg ("missing traffic class \n");
4811       return -99;
4812     }
4813
4814   if (queue_set == 0)
4815     {
4816       errmsg ("missing queue \n");
4817       return -99;
4818     }
4819
4820   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4821
4822   mp->sw_if_index = ntohl (sw_if_index);
4823   mp->entry = ntohl (entry);
4824   mp->tc = ntohl (tc);
4825   mp->queue = ntohl (queue);
4826
4827   S;
4828   W;
4829   /* NOTREACHED */
4830   return 0;
4831 }
4832
4833 static int
4834 api_sw_interface_add_del_address (vat_main_t * vam)
4835 {
4836   unformat_input_t *i = vam->input;
4837   vl_api_sw_interface_add_del_address_t *mp;
4838   f64 timeout;
4839   u32 sw_if_index;
4840   u8 sw_if_index_set = 0;
4841   u8 is_add = 1, del_all = 0;
4842   u32 address_length = 0;
4843   u8 v4_address_set = 0;
4844   u8 v6_address_set = 0;
4845   ip4_address_t v4address;
4846   ip6_address_t v6address;
4847
4848   /* Parse args required to build the message */
4849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4850     {
4851       if (unformat (i, "del-all"))
4852         del_all = 1;
4853       else if (unformat (i, "del"))
4854         is_add = 0;
4855       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4856         sw_if_index_set = 1;
4857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4858         sw_if_index_set = 1;
4859       else if (unformat (i, "%U/%d",
4860                          unformat_ip4_address, &v4address, &address_length))
4861         v4_address_set = 1;
4862       else if (unformat (i, "%U/%d",
4863                          unformat_ip6_address, &v6address, &address_length))
4864         v6_address_set = 1;
4865       else
4866         break;
4867     }
4868
4869   if (sw_if_index_set == 0)
4870     {
4871       errmsg ("missing interface name or sw_if_index\n");
4872       return -99;
4873     }
4874   if (v4_address_set && v6_address_set)
4875     {
4876       errmsg ("both v4 and v6 addresses set\n");
4877       return -99;
4878     }
4879   if (!v4_address_set && !v6_address_set && !del_all)
4880     {
4881       errmsg ("no addresses set\n");
4882       return -99;
4883     }
4884
4885   /* Construct the API message */
4886   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4887
4888   mp->sw_if_index = ntohl (sw_if_index);
4889   mp->is_add = is_add;
4890   mp->del_all = del_all;
4891   if (v6_address_set)
4892     {
4893       mp->is_ipv6 = 1;
4894       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4895     }
4896   else
4897     {
4898       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4899     }
4900   mp->address_length = address_length;
4901
4902   /* send it... */
4903   S;
4904
4905   /* Wait for a reply, return good/bad news  */
4906   W;
4907 }
4908
4909 static int
4910 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4911 {
4912   unformat_input_t *i = vam->input;
4913   vl_api_sw_interface_set_mpls_enable_t *mp;
4914   f64 timeout;
4915   u32 sw_if_index;
4916   u8 sw_if_index_set = 0;
4917   u8 enable = 1;
4918
4919   /* Parse args required to build the message */
4920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4921     {
4922       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4923         sw_if_index_set = 1;
4924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4925         sw_if_index_set = 1;
4926       else if (unformat (i, "disable"))
4927         enable = 0;
4928       else if (unformat (i, "dis"))
4929         enable = 0;
4930       else
4931         break;
4932     }
4933
4934   if (sw_if_index_set == 0)
4935     {
4936       errmsg ("missing interface name or sw_if_index\n");
4937       return -99;
4938     }
4939
4940   /* Construct the API message */
4941   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4942
4943   mp->sw_if_index = ntohl (sw_if_index);
4944   mp->enable = enable;
4945
4946   /* send it... */
4947   S;
4948
4949   /* Wait for a reply... */
4950   W;
4951 }
4952
4953 static int
4954 api_sw_interface_set_table (vat_main_t * vam)
4955 {
4956   unformat_input_t *i = vam->input;
4957   vl_api_sw_interface_set_table_t *mp;
4958   f64 timeout;
4959   u32 sw_if_index, vrf_id = 0;
4960   u8 sw_if_index_set = 0;
4961   u8 is_ipv6 = 0;
4962
4963   /* Parse args required to build the message */
4964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4965     {
4966       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4967         sw_if_index_set = 1;
4968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4969         sw_if_index_set = 1;
4970       else if (unformat (i, "vrf %d", &vrf_id))
4971         ;
4972       else if (unformat (i, "ipv6"))
4973         is_ipv6 = 1;
4974       else
4975         break;
4976     }
4977
4978   if (sw_if_index_set == 0)
4979     {
4980       errmsg ("missing interface name or sw_if_index\n");
4981       return -99;
4982     }
4983
4984   /* Construct the API message */
4985   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4986
4987   mp->sw_if_index = ntohl (sw_if_index);
4988   mp->is_ipv6 = is_ipv6;
4989   mp->vrf_id = ntohl (vrf_id);
4990
4991   /* send it... */
4992   S;
4993
4994   /* Wait for a reply... */
4995   W;
4996 }
4997
4998 static int
4999 api_sw_interface_set_vpath (vat_main_t * vam)
5000 {
5001   unformat_input_t *i = vam->input;
5002   vl_api_sw_interface_set_vpath_t *mp;
5003   f64 timeout;
5004   u32 sw_if_index = 0;
5005   u8 sw_if_index_set = 0;
5006   u8 is_enable = 0;
5007
5008   /* Parse args required to build the message */
5009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5010     {
5011       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5012         sw_if_index_set = 1;
5013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5014         sw_if_index_set = 1;
5015       else if (unformat (i, "enable"))
5016         is_enable = 1;
5017       else if (unformat (i, "disable"))
5018         is_enable = 0;
5019       else
5020         break;
5021     }
5022
5023   if (sw_if_index_set == 0)
5024     {
5025       errmsg ("missing interface name or sw_if_index\n");
5026       return -99;
5027     }
5028
5029   /* Construct the API message */
5030   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5031
5032   mp->sw_if_index = ntohl (sw_if_index);
5033   mp->enable = is_enable;
5034
5035   /* send it... */
5036   S;
5037
5038   /* Wait for a reply... */
5039   W;
5040 }
5041
5042 static int
5043 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5044 {
5045   unformat_input_t *i = vam->input;
5046   vl_api_sw_interface_set_l2_xconnect_t *mp;
5047   f64 timeout;
5048   u32 rx_sw_if_index;
5049   u8 rx_sw_if_index_set = 0;
5050   u32 tx_sw_if_index;
5051   u8 tx_sw_if_index_set = 0;
5052   u8 enable = 1;
5053
5054   /* Parse args required to build the message */
5055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5056     {
5057       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5058         rx_sw_if_index_set = 1;
5059       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5060         tx_sw_if_index_set = 1;
5061       else if (unformat (i, "rx"))
5062         {
5063           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5064             {
5065               if (unformat (i, "%U", unformat_sw_if_index, vam,
5066                             &rx_sw_if_index))
5067                 rx_sw_if_index_set = 1;
5068             }
5069           else
5070             break;
5071         }
5072       else if (unformat (i, "tx"))
5073         {
5074           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5075             {
5076               if (unformat (i, "%U", unformat_sw_if_index, vam,
5077                             &tx_sw_if_index))
5078                 tx_sw_if_index_set = 1;
5079             }
5080           else
5081             break;
5082         }
5083       else if (unformat (i, "enable"))
5084         enable = 1;
5085       else if (unformat (i, "disable"))
5086         enable = 0;
5087       else
5088         break;
5089     }
5090
5091   if (rx_sw_if_index_set == 0)
5092     {
5093       errmsg ("missing rx interface name or rx_sw_if_index\n");
5094       return -99;
5095     }
5096
5097   if (enable && (tx_sw_if_index_set == 0))
5098     {
5099       errmsg ("missing tx interface name or tx_sw_if_index\n");
5100       return -99;
5101     }
5102
5103   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5104
5105   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5106   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5107   mp->enable = enable;
5108
5109   S;
5110   W;
5111   /* NOTREACHED */
5112   return 0;
5113 }
5114
5115 static int
5116 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5117 {
5118   unformat_input_t *i = vam->input;
5119   vl_api_sw_interface_set_l2_bridge_t *mp;
5120   f64 timeout;
5121   u32 rx_sw_if_index;
5122   u8 rx_sw_if_index_set = 0;
5123   u32 bd_id;
5124   u8 bd_id_set = 0;
5125   u8 bvi = 0;
5126   u32 shg = 0;
5127   u8 enable = 1;
5128
5129   /* Parse args required to build the message */
5130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5131     {
5132       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5133         rx_sw_if_index_set = 1;
5134       else if (unformat (i, "bd_id %d", &bd_id))
5135         bd_id_set = 1;
5136       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5137         rx_sw_if_index_set = 1;
5138       else if (unformat (i, "shg %d", &shg))
5139         ;
5140       else if (unformat (i, "bvi"))
5141         bvi = 1;
5142       else if (unformat (i, "enable"))
5143         enable = 1;
5144       else if (unformat (i, "disable"))
5145         enable = 0;
5146       else
5147         break;
5148     }
5149
5150   if (rx_sw_if_index_set == 0)
5151     {
5152       errmsg ("missing rx interface name or sw_if_index\n");
5153       return -99;
5154     }
5155
5156   if (enable && (bd_id_set == 0))
5157     {
5158       errmsg ("missing bridge domain\n");
5159       return -99;
5160     }
5161
5162   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5163
5164   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5165   mp->bd_id = ntohl (bd_id);
5166   mp->shg = (u8) shg;
5167   mp->bvi = bvi;
5168   mp->enable = enable;
5169
5170   S;
5171   W;
5172   /* NOTREACHED */
5173   return 0;
5174 }
5175
5176 static int
5177 api_bridge_domain_dump (vat_main_t * vam)
5178 {
5179   unformat_input_t *i = vam->input;
5180   vl_api_bridge_domain_dump_t *mp;
5181   f64 timeout;
5182   u32 bd_id = ~0;
5183
5184   /* Parse args required to build the message */
5185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5186     {
5187       if (unformat (i, "bd_id %d", &bd_id))
5188         ;
5189       else
5190         break;
5191     }
5192
5193   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5194   mp->bd_id = ntohl (bd_id);
5195   S;
5196
5197   /* Use a control ping for synchronization */
5198   {
5199     vl_api_control_ping_t *mp;
5200     M (CONTROL_PING, control_ping);
5201     S;
5202   }
5203
5204   W;
5205   /* NOTREACHED */
5206   return 0;
5207 }
5208
5209 static int
5210 api_bridge_domain_add_del (vat_main_t * vam)
5211 {
5212   unformat_input_t *i = vam->input;
5213   vl_api_bridge_domain_add_del_t *mp;
5214   f64 timeout;
5215   u32 bd_id = ~0;
5216   u8 is_add = 1;
5217   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5218
5219   /* Parse args required to build the message */
5220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5221     {
5222       if (unformat (i, "bd_id %d", &bd_id))
5223         ;
5224       else if (unformat (i, "flood %d", &flood))
5225         ;
5226       else if (unformat (i, "uu-flood %d", &uu_flood))
5227         ;
5228       else if (unformat (i, "forward %d", &forward))
5229         ;
5230       else if (unformat (i, "learn %d", &learn))
5231         ;
5232       else if (unformat (i, "arp-term %d", &arp_term))
5233         ;
5234       else if (unformat (i, "del"))
5235         {
5236           is_add = 0;
5237           flood = uu_flood = forward = learn = 0;
5238         }
5239       else
5240         break;
5241     }
5242
5243   if (bd_id == ~0)
5244     {
5245       errmsg ("missing bridge domain\n");
5246       return -99;
5247     }
5248
5249   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5250
5251   mp->bd_id = ntohl (bd_id);
5252   mp->flood = flood;
5253   mp->uu_flood = uu_flood;
5254   mp->forward = forward;
5255   mp->learn = learn;
5256   mp->arp_term = arp_term;
5257   mp->is_add = is_add;
5258
5259   S;
5260   W;
5261   /* NOTREACHED */
5262   return 0;
5263 }
5264
5265 static int
5266 api_l2fib_add_del (vat_main_t * vam)
5267 {
5268   unformat_input_t *i = vam->input;
5269   vl_api_l2fib_add_del_t *mp;
5270   f64 timeout;
5271   u64 mac = 0;
5272   u8 mac_set = 0;
5273   u32 bd_id;
5274   u8 bd_id_set = 0;
5275   u32 sw_if_index;
5276   u8 sw_if_index_set = 0;
5277   u8 is_add = 1;
5278   u8 static_mac = 0;
5279   u8 filter_mac = 0;
5280   u8 bvi_mac = 0;
5281   int count = 1;
5282   f64 before = 0;
5283   int j;
5284
5285   /* Parse args required to build the message */
5286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5287     {
5288       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5289         mac_set = 1;
5290       else if (unformat (i, "bd_id %d", &bd_id))
5291         bd_id_set = 1;
5292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5293         sw_if_index_set = 1;
5294       else if (unformat (i, "sw_if"))
5295         {
5296           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5297             {
5298               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5299                 sw_if_index_set = 1;
5300             }
5301           else
5302             break;
5303         }
5304       else if (unformat (i, "static"))
5305         static_mac = 1;
5306       else if (unformat (i, "filter"))
5307         {
5308           filter_mac = 1;
5309           static_mac = 1;
5310         }
5311       else if (unformat (i, "bvi"))
5312         {
5313           bvi_mac = 1;
5314           static_mac = 1;
5315         }
5316       else if (unformat (i, "del"))
5317         is_add = 0;
5318       else if (unformat (i, "count %d", &count))
5319         ;
5320       else
5321         break;
5322     }
5323
5324   if (mac_set == 0)
5325     {
5326       errmsg ("missing mac address\n");
5327       return -99;
5328     }
5329
5330   if (bd_id_set == 0)
5331     {
5332       errmsg ("missing bridge domain\n");
5333       return -99;
5334     }
5335
5336   if (is_add && (sw_if_index_set == 0))
5337     {
5338       errmsg ("missing interface name or sw_if_index\n");
5339       return -99;
5340     }
5341
5342   if (count > 1)
5343     {
5344       /* Turn on async mode */
5345       vam->async_mode = 1;
5346       vam->async_errors = 0;
5347       before = vat_time_now (vam);
5348     }
5349
5350   for (j = 0; j < count; j++)
5351     {
5352       M (L2FIB_ADD_DEL, l2fib_add_del);
5353
5354       mp->mac = mac;
5355       mp->bd_id = ntohl (bd_id);
5356       mp->is_add = is_add;
5357
5358       if (is_add)
5359         {
5360           mp->sw_if_index = ntohl (sw_if_index);
5361           mp->static_mac = static_mac;
5362           mp->filter_mac = filter_mac;
5363           mp->bvi_mac = bvi_mac;
5364         }
5365       increment_mac_address (&mac);
5366       /* send it... */
5367       S;
5368     }
5369
5370   if (count > 1)
5371     {
5372       vl_api_control_ping_t *mp;
5373       f64 after;
5374
5375       /* Shut off async mode */
5376       vam->async_mode = 0;
5377
5378       M (CONTROL_PING, control_ping);
5379       S;
5380
5381       timeout = vat_time_now (vam) + 1.0;
5382       while (vat_time_now (vam) < timeout)
5383         if (vam->result_ready == 1)
5384           goto out;
5385       vam->retval = -99;
5386
5387     out:
5388       if (vam->retval == -99)
5389         errmsg ("timeout\n");
5390
5391       if (vam->async_errors > 0)
5392         {
5393           errmsg ("%d asynchronous errors\n", vam->async_errors);
5394           vam->retval = -98;
5395         }
5396       vam->async_errors = 0;
5397       after = vat_time_now (vam);
5398
5399       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5400                count, after - before, count / (after - before));
5401     }
5402   else
5403     {
5404       /* Wait for a reply... */
5405       W;
5406     }
5407   /* Return the good/bad news */
5408   return (vam->retval);
5409 }
5410
5411 static int
5412 api_l2_flags (vat_main_t * vam)
5413 {
5414   unformat_input_t *i = vam->input;
5415   vl_api_l2_flags_t *mp;
5416   f64 timeout;
5417   u32 sw_if_index;
5418   u32 feature_bitmap = 0;
5419   u8 sw_if_index_set = 0;
5420
5421   /* Parse args required to build the message */
5422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5423     {
5424       if (unformat (i, "sw_if_index %d", &sw_if_index))
5425         sw_if_index_set = 1;
5426       else if (unformat (i, "sw_if"))
5427         {
5428           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5429             {
5430               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5431                 sw_if_index_set = 1;
5432             }
5433           else
5434             break;
5435         }
5436       else if (unformat (i, "learn"))
5437         feature_bitmap |= L2INPUT_FEAT_LEARN;
5438       else if (unformat (i, "forward"))
5439         feature_bitmap |= L2INPUT_FEAT_FWD;
5440       else if (unformat (i, "flood"))
5441         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5442       else if (unformat (i, "uu-flood"))
5443         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5444       else
5445         break;
5446     }
5447
5448   if (sw_if_index_set == 0)
5449     {
5450       errmsg ("missing interface name or sw_if_index\n");
5451       return -99;
5452     }
5453
5454   M (L2_FLAGS, l2_flags);
5455
5456   mp->sw_if_index = ntohl (sw_if_index);
5457   mp->feature_bitmap = ntohl (feature_bitmap);
5458
5459   S;
5460   W;
5461   /* NOTREACHED */
5462   return 0;
5463 }
5464
5465 static int
5466 api_bridge_flags (vat_main_t * vam)
5467 {
5468   unformat_input_t *i = vam->input;
5469   vl_api_bridge_flags_t *mp;
5470   f64 timeout;
5471   u32 bd_id;
5472   u8 bd_id_set = 0;
5473   u8 is_set = 1;
5474   u32 flags = 0;
5475
5476   /* Parse args required to build the message */
5477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5478     {
5479       if (unformat (i, "bd_id %d", &bd_id))
5480         bd_id_set = 1;
5481       else if (unformat (i, "learn"))
5482         flags |= L2_LEARN;
5483       else if (unformat (i, "forward"))
5484         flags |= L2_FWD;
5485       else if (unformat (i, "flood"))
5486         flags |= L2_FLOOD;
5487       else if (unformat (i, "uu-flood"))
5488         flags |= L2_UU_FLOOD;
5489       else if (unformat (i, "arp-term"))
5490         flags |= L2_ARP_TERM;
5491       else if (unformat (i, "off"))
5492         is_set = 0;
5493       else if (unformat (i, "disable"))
5494         is_set = 0;
5495       else
5496         break;
5497     }
5498
5499   if (bd_id_set == 0)
5500     {
5501       errmsg ("missing bridge domain\n");
5502       return -99;
5503     }
5504
5505   M (BRIDGE_FLAGS, bridge_flags);
5506
5507   mp->bd_id = ntohl (bd_id);
5508   mp->feature_bitmap = ntohl (flags);
5509   mp->is_set = is_set;
5510
5511   S;
5512   W;
5513   /* NOTREACHED */
5514   return 0;
5515 }
5516
5517 static int
5518 api_bd_ip_mac_add_del (vat_main_t * vam)
5519 {
5520   unformat_input_t *i = vam->input;
5521   vl_api_bd_ip_mac_add_del_t *mp;
5522   f64 timeout;
5523   u32 bd_id;
5524   u8 is_ipv6 = 0;
5525   u8 is_add = 1;
5526   u8 bd_id_set = 0;
5527   u8 ip_set = 0;
5528   u8 mac_set = 0;
5529   ip4_address_t v4addr;
5530   ip6_address_t v6addr;
5531   u8 macaddr[6];
5532
5533
5534   /* Parse args required to build the message */
5535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5536     {
5537       if (unformat (i, "bd_id %d", &bd_id))
5538         {
5539           bd_id_set++;
5540         }
5541       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5542         {
5543           ip_set++;
5544         }
5545       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5546         {
5547           ip_set++;
5548           is_ipv6++;
5549         }
5550       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5551         {
5552           mac_set++;
5553         }
5554       else if (unformat (i, "del"))
5555         is_add = 0;
5556       else
5557         break;
5558     }
5559
5560   if (bd_id_set == 0)
5561     {
5562       errmsg ("missing bridge domain\n");
5563       return -99;
5564     }
5565   else if (ip_set == 0)
5566     {
5567       errmsg ("missing IP address\n");
5568       return -99;
5569     }
5570   else if (mac_set == 0)
5571     {
5572       errmsg ("missing MAC address\n");
5573       return -99;
5574     }
5575
5576   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5577
5578   mp->bd_id = ntohl (bd_id);
5579   mp->is_ipv6 = is_ipv6;
5580   mp->is_add = is_add;
5581   if (is_ipv6)
5582     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5583   else
5584     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5585   clib_memcpy (mp->mac_address, macaddr, 6);
5586   S;
5587   W;
5588   /* NOTREACHED */
5589   return 0;
5590 }
5591
5592 static int
5593 api_tap_connect (vat_main_t * vam)
5594 {
5595   unformat_input_t *i = vam->input;
5596   vl_api_tap_connect_t *mp;
5597   f64 timeout;
5598   u8 mac_address[6];
5599   u8 random_mac = 1;
5600   u8 name_set = 0;
5601   u8 *tap_name;
5602
5603   memset (mac_address, 0, sizeof (mac_address));
5604
5605   /* Parse args required to build the message */
5606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5607     {
5608       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5609         {
5610           random_mac = 0;
5611         }
5612       else if (unformat (i, "random-mac"))
5613         random_mac = 1;
5614       else if (unformat (i, "tapname %s", &tap_name))
5615         name_set = 1;
5616       else
5617         break;
5618     }
5619
5620   if (name_set == 0)
5621     {
5622       errmsg ("missing tap name\n");
5623       return -99;
5624     }
5625   if (vec_len (tap_name) > 63)
5626     {
5627       errmsg ("tap name too long\n");
5628     }
5629   vec_add1 (tap_name, 0);
5630
5631   /* Construct the API message */
5632   M (TAP_CONNECT, tap_connect);
5633
5634   mp->use_random_mac = random_mac;
5635   clib_memcpy (mp->mac_address, mac_address, 6);
5636   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5637   vec_free (tap_name);
5638
5639   /* send it... */
5640   S;
5641
5642   /* Wait for a reply... */
5643   W;
5644 }
5645
5646 static int
5647 api_tap_modify (vat_main_t * vam)
5648 {
5649   unformat_input_t *i = vam->input;
5650   vl_api_tap_modify_t *mp;
5651   f64 timeout;
5652   u8 mac_address[6];
5653   u8 random_mac = 1;
5654   u8 name_set = 0;
5655   u8 *tap_name;
5656   u32 sw_if_index = ~0;
5657   u8 sw_if_index_set = 0;
5658
5659   memset (mac_address, 0, sizeof (mac_address));
5660
5661   /* Parse args required to build the message */
5662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5663     {
5664       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5665         sw_if_index_set = 1;
5666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5667         sw_if_index_set = 1;
5668       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5669         {
5670           random_mac = 0;
5671         }
5672       else if (unformat (i, "random-mac"))
5673         random_mac = 1;
5674       else if (unformat (i, "tapname %s", &tap_name))
5675         name_set = 1;
5676       else
5677         break;
5678     }
5679
5680   if (sw_if_index_set == 0)
5681     {
5682       errmsg ("missing vpp interface name");
5683       return -99;
5684     }
5685   if (name_set == 0)
5686     {
5687       errmsg ("missing tap name\n");
5688       return -99;
5689     }
5690   if (vec_len (tap_name) > 63)
5691     {
5692       errmsg ("tap name too long\n");
5693     }
5694   vec_add1 (tap_name, 0);
5695
5696   /* Construct the API message */
5697   M (TAP_MODIFY, tap_modify);
5698
5699   mp->use_random_mac = random_mac;
5700   mp->sw_if_index = ntohl (sw_if_index);
5701   clib_memcpy (mp->mac_address, mac_address, 6);
5702   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5703   vec_free (tap_name);
5704
5705   /* send it... */
5706   S;
5707
5708   /* Wait for a reply... */
5709   W;
5710 }
5711
5712 static int
5713 api_tap_delete (vat_main_t * vam)
5714 {
5715   unformat_input_t *i = vam->input;
5716   vl_api_tap_delete_t *mp;
5717   f64 timeout;
5718   u32 sw_if_index = ~0;
5719   u8 sw_if_index_set = 0;
5720
5721   /* Parse args required to build the message */
5722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723     {
5724       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5725         sw_if_index_set = 1;
5726       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5727         sw_if_index_set = 1;
5728       else
5729         break;
5730     }
5731
5732   if (sw_if_index_set == 0)
5733     {
5734       errmsg ("missing vpp interface name");
5735       return -99;
5736     }
5737
5738   /* Construct the API message */
5739   M (TAP_DELETE, tap_delete);
5740
5741   mp->sw_if_index = ntohl (sw_if_index);
5742
5743   /* send it... */
5744   S;
5745
5746   /* Wait for a reply... */
5747   W;
5748 }
5749
5750 static int
5751 api_ip_add_del_route (vat_main_t * vam)
5752 {
5753   unformat_input_t *i = vam->input;
5754   vl_api_ip_add_del_route_t *mp;
5755   f64 timeout;
5756   u32 sw_if_index = ~0, vrf_id = 0;
5757   u8 sw_if_index_set = 0;
5758   u8 is_ipv6 = 0;
5759   u8 is_local = 0, is_drop = 0;
5760   u8 is_unreach = 0, is_prohibit = 0;
5761   u8 create_vrf_if_needed = 0;
5762   u8 is_add = 1;
5763   u8 next_hop_weight = 1;
5764   u8 not_last = 0;
5765   u8 is_multipath = 0;
5766   u8 address_set = 0;
5767   u8 address_length_set = 0;
5768   u32 next_hop_table_id = 0;
5769   u32 resolve_attempts = 0;
5770   u32 dst_address_length = 0;
5771   u8 next_hop_set = 0;
5772   ip4_address_t v4_dst_address, v4_next_hop_address;
5773   ip6_address_t v6_dst_address, v6_next_hop_address;
5774   int count = 1;
5775   int j;
5776   f64 before = 0;
5777   u32 random_add_del = 0;
5778   u32 *random_vector = 0;
5779   uword *random_hash;
5780   u32 random_seed = 0xdeaddabe;
5781   u32 classify_table_index = ~0;
5782   u8 is_classify = 0;
5783   u8 resolve_host = 0, resolve_attached = 0;
5784   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5785
5786   /* Parse args required to build the message */
5787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5788     {
5789       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5790         sw_if_index_set = 1;
5791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5792         sw_if_index_set = 1;
5793       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5794         {
5795           address_set = 1;
5796           is_ipv6 = 0;
5797         }
5798       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5799         {
5800           address_set = 1;
5801           is_ipv6 = 1;
5802         }
5803       else if (unformat (i, "/%d", &dst_address_length))
5804         {
5805           address_length_set = 1;
5806         }
5807
5808       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5809                                          &v4_next_hop_address))
5810         {
5811           next_hop_set = 1;
5812         }
5813       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5814                                          &v6_next_hop_address))
5815         {
5816           next_hop_set = 1;
5817         }
5818       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5819         ;
5820       else if (unformat (i, "weight %d", &next_hop_weight))
5821         ;
5822       else if (unformat (i, "drop"))
5823         {
5824           is_drop = 1;
5825         }
5826       else if (unformat (i, "null-send-unreach"))
5827         {
5828           is_unreach = 1;
5829         }
5830       else if (unformat (i, "null-send-prohibit"))
5831         {
5832           is_prohibit = 1;
5833         }
5834       else if (unformat (i, "local"))
5835         {
5836           is_local = 1;
5837         }
5838       else if (unformat (i, "classify %d", &classify_table_index))
5839         {
5840           is_classify = 1;
5841         }
5842       else if (unformat (i, "del"))
5843         is_add = 0;
5844       else if (unformat (i, "add"))
5845         is_add = 1;
5846       else if (unformat (i, "not-last"))
5847         not_last = 1;
5848       else if (unformat (i, "resolve-via-host"))
5849         resolve_host = 1;
5850       else if (unformat (i, "resolve-via-attached"))
5851         resolve_attached = 1;
5852       else if (unformat (i, "multipath"))
5853         is_multipath = 1;
5854       else if (unformat (i, "vrf %d", &vrf_id))
5855         ;
5856       else if (unformat (i, "create-vrf"))
5857         create_vrf_if_needed = 1;
5858       else if (unformat (i, "count %d", &count))
5859         ;
5860       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5861         ;
5862       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5863         ;
5864       else if (unformat (i, "out-label %d", &next_hop_out_label))
5865         ;
5866       else if (unformat (i, "random"))
5867         random_add_del = 1;
5868       else if (unformat (i, "seed %d", &random_seed))
5869         ;
5870       else
5871         {
5872           clib_warning ("parse error '%U'", format_unformat_error, i);
5873           return -99;
5874         }
5875     }
5876
5877   if (resolve_attempts > 0 && sw_if_index_set == 0)
5878     {
5879       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5880       return -99;
5881     }
5882
5883   if (!next_hop_set && !is_drop && !is_local &&
5884       !is_classify && !is_unreach && !is_prohibit)
5885     {
5886       errmsg
5887         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5888       return -99;
5889     }
5890
5891   if (address_set == 0)
5892     {
5893       errmsg ("missing addresses\n");
5894       return -99;
5895     }
5896
5897   if (address_length_set == 0)
5898     {
5899       errmsg ("missing address length\n");
5900       return -99;
5901     }
5902
5903   /* Generate a pile of unique, random routes */
5904   if (random_add_del)
5905     {
5906       u32 this_random_address;
5907       random_hash = hash_create (count, sizeof (uword));
5908
5909       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5910       for (j = 0; j <= count; j++)
5911         {
5912           do
5913             {
5914               this_random_address = random_u32 (&random_seed);
5915               this_random_address =
5916                 clib_host_to_net_u32 (this_random_address);
5917             }
5918           while (hash_get (random_hash, this_random_address));
5919           vec_add1 (random_vector, this_random_address);
5920           hash_set (random_hash, this_random_address, 1);
5921         }
5922       hash_free (random_hash);
5923       v4_dst_address.as_u32 = random_vector[0];
5924     }
5925
5926   if (count > 1)
5927     {
5928       /* Turn on async mode */
5929       vam->async_mode = 1;
5930       vam->async_errors = 0;
5931       before = vat_time_now (vam);
5932     }
5933
5934   for (j = 0; j < count; j++)
5935     {
5936       /* Construct the API message */
5937       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5938
5939       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5940       mp->table_id = ntohl (vrf_id);
5941       if (resolve_attempts > 0)
5942         {
5943           mp->resolve_attempts = ntohl (resolve_attempts);
5944           mp->resolve_if_needed = 1;
5945         }
5946       mp->create_vrf_if_needed = create_vrf_if_needed;
5947
5948       mp->is_add = is_add;
5949       mp->is_drop = is_drop;
5950       mp->is_unreach = is_unreach;
5951       mp->is_prohibit = is_prohibit;
5952       mp->is_ipv6 = is_ipv6;
5953       mp->is_local = is_local;
5954       mp->is_classify = is_classify;
5955       mp->is_multipath = is_multipath;
5956       mp->is_resolve_host = resolve_host;
5957       mp->is_resolve_attached = resolve_attached;
5958       mp->not_last = not_last;
5959       mp->next_hop_weight = next_hop_weight;
5960       mp->dst_address_length = dst_address_length;
5961       mp->next_hop_table_id = ntohl (next_hop_table_id);
5962       mp->classify_table_index = ntohl (classify_table_index);
5963       mp->next_hop_out_label = ntohl (next_hop_out_label);
5964
5965       if (is_ipv6)
5966         {
5967           clib_memcpy (mp->dst_address, &v6_dst_address,
5968                        sizeof (v6_dst_address));
5969           if (next_hop_set)
5970             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5971                          sizeof (v6_next_hop_address));
5972           increment_v6_address (&v6_dst_address);
5973         }
5974       else
5975         {
5976           clib_memcpy (mp->dst_address, &v4_dst_address,
5977                        sizeof (v4_dst_address));
5978           if (next_hop_set)
5979             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5980                          sizeof (v4_next_hop_address));
5981           if (random_add_del)
5982             v4_dst_address.as_u32 = random_vector[j + 1];
5983           else
5984             increment_v4_address (&v4_dst_address);
5985         }
5986       /* send it... */
5987       S;
5988       /* If we receive SIGTERM, stop now... */
5989       if (vam->do_exit)
5990         break;
5991     }
5992
5993   /* When testing multiple add/del ops, use a control-ping to sync */
5994   if (count > 1)
5995     {
5996       vl_api_control_ping_t *mp;
5997       f64 after;
5998
5999       /* Shut off async mode */
6000       vam->async_mode = 0;
6001
6002       M (CONTROL_PING, control_ping);
6003       S;
6004
6005       timeout = vat_time_now (vam) + 1.0;
6006       while (vat_time_now (vam) < timeout)
6007         if (vam->result_ready == 1)
6008           goto out;
6009       vam->retval = -99;
6010
6011     out:
6012       if (vam->retval == -99)
6013         errmsg ("timeout\n");
6014
6015       if (vam->async_errors > 0)
6016         {
6017           errmsg ("%d asynchronous errors\n", vam->async_errors);
6018           vam->retval = -98;
6019         }
6020       vam->async_errors = 0;
6021       after = vat_time_now (vam);
6022
6023       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6024       if (j > 0)
6025         count = j;
6026
6027       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6028                count, after - before, count / (after - before));
6029     }
6030   else
6031     {
6032       /* Wait for a reply... */
6033       W;
6034     }
6035
6036   /* Return the good/bad news */
6037   return (vam->retval);
6038 }
6039
6040 static int
6041 api_mpls_route_add_del (vat_main_t * vam)
6042 {
6043   unformat_input_t *i = vam->input;
6044   vl_api_mpls_route_add_del_t *mp;
6045   f64 timeout;
6046   u32 sw_if_index = ~0, table_id = 0;
6047   u8 create_table_if_needed = 0;
6048   u8 is_add = 1;
6049   u8 next_hop_weight = 1;
6050   u8 is_multipath = 0;
6051   u32 next_hop_table_id = 0;
6052   u8 next_hop_set = 0;
6053   ip4_address_t v4_next_hop_address = {
6054     .as_u32 = 0,
6055   };
6056   ip6_address_t v6_next_hop_address = { {0} };
6057   int count = 1;
6058   int j;
6059   f64 before = 0;
6060   u32 classify_table_index = ~0;
6061   u8 is_classify = 0;
6062   u8 resolve_host = 0, resolve_attached = 0;
6063   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6064   mpls_label_t local_label = MPLS_LABEL_INVALID;
6065   u8 is_eos = 1;
6066   u8 next_hop_proto_is_ip4 = 1;
6067
6068   /* Parse args required to build the message */
6069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6070     {
6071       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6072         ;
6073       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6074         ;
6075       else if (unformat (i, "%d", &local_label))
6076         ;
6077       else if (unformat (i, "eos"))
6078         is_eos = 1;
6079       else if (unformat (i, "non-eos"))
6080         is_eos = 0;
6081       else if (unformat (i, "via %U", unformat_ip4_address,
6082                          &v4_next_hop_address))
6083         {
6084           next_hop_set = 1;
6085           next_hop_proto_is_ip4 = 1;
6086         }
6087       else if (unformat (i, "via %U", unformat_ip6_address,
6088                          &v6_next_hop_address))
6089         {
6090           next_hop_set = 1;
6091           next_hop_proto_is_ip4 = 0;
6092         }
6093       else if (unformat (i, "weight %d", &next_hop_weight))
6094         ;
6095       else if (unformat (i, "create-table"))
6096         create_table_if_needed = 1;
6097       else if (unformat (i, "classify %d", &classify_table_index))
6098         {
6099           is_classify = 1;
6100         }
6101       else if (unformat (i, "del"))
6102         is_add = 0;
6103       else if (unformat (i, "add"))
6104         is_add = 1;
6105       else if (unformat (i, "resolve-via-host"))
6106         resolve_host = 1;
6107       else if (unformat (i, "resolve-via-attached"))
6108         resolve_attached = 1;
6109       else if (unformat (i, "multipath"))
6110         is_multipath = 1;
6111       else if (unformat (i, "count %d", &count))
6112         ;
6113       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6114         {
6115           next_hop_set = 1;
6116           next_hop_proto_is_ip4 = 1;
6117         }
6118       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6119         {
6120           next_hop_set = 1;
6121           next_hop_proto_is_ip4 = 0;
6122         }
6123       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6124         ;
6125       else if (unformat (i, "out-label %d", &next_hop_out_label))
6126         ;
6127       else
6128         {
6129           clib_warning ("parse error '%U'", format_unformat_error, i);
6130           return -99;
6131         }
6132     }
6133
6134   if (!next_hop_set && !is_classify)
6135     {
6136       errmsg ("next hop / classify not set\n");
6137       return -99;
6138     }
6139
6140   if (MPLS_LABEL_INVALID == local_label)
6141     {
6142       errmsg ("missing label\n");
6143       return -99;
6144     }
6145
6146   if (count > 1)
6147     {
6148       /* Turn on async mode */
6149       vam->async_mode = 1;
6150       vam->async_errors = 0;
6151       before = vat_time_now (vam);
6152     }
6153
6154   for (j = 0; j < count; j++)
6155     {
6156       /* Construct the API message */
6157       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6158
6159       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6160       mp->mr_table_id = ntohl (table_id);
6161       mp->mr_create_table_if_needed = create_table_if_needed;
6162
6163       mp->mr_is_add = is_add;
6164       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6165       mp->mr_is_classify = is_classify;
6166       mp->mr_is_multipath = is_multipath;
6167       mp->mr_is_resolve_host = resolve_host;
6168       mp->mr_is_resolve_attached = resolve_attached;
6169       mp->mr_next_hop_weight = next_hop_weight;
6170       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6171       mp->mr_classify_table_index = ntohl (classify_table_index);
6172       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6173       mp->mr_label = ntohl (local_label);
6174       mp->mr_eos = is_eos;
6175
6176       if (next_hop_set)
6177         {
6178           if (next_hop_proto_is_ip4)
6179             {
6180               clib_memcpy (mp->mr_next_hop,
6181                            &v4_next_hop_address,
6182                            sizeof (v4_next_hop_address));
6183             }
6184           else
6185             {
6186               clib_memcpy (mp->mr_next_hop,
6187                            &v6_next_hop_address,
6188                            sizeof (v6_next_hop_address));
6189             }
6190         }
6191       local_label++;
6192
6193       /* send it... */
6194       S;
6195       /* If we receive SIGTERM, stop now... */
6196       if (vam->do_exit)
6197         break;
6198     }
6199
6200   /* When testing multiple add/del ops, use a control-ping to sync */
6201   if (count > 1)
6202     {
6203       vl_api_control_ping_t *mp;
6204       f64 after;
6205
6206       /* Shut off async mode */
6207       vam->async_mode = 0;
6208
6209       M (CONTROL_PING, control_ping);
6210       S;
6211
6212       timeout = vat_time_now (vam) + 1.0;
6213       while (vat_time_now (vam) < timeout)
6214         if (vam->result_ready == 1)
6215           goto out;
6216       vam->retval = -99;
6217
6218     out:
6219       if (vam->retval == -99)
6220         errmsg ("timeout\n");
6221
6222       if (vam->async_errors > 0)
6223         {
6224           errmsg ("%d asynchronous errors\n", vam->async_errors);
6225           vam->retval = -98;
6226         }
6227       vam->async_errors = 0;
6228       after = vat_time_now (vam);
6229
6230       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6231       if (j > 0)
6232         count = j;
6233
6234       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6235                count, after - before, count / (after - before));
6236     }
6237   else
6238     {
6239       /* Wait for a reply... */
6240       W;
6241     }
6242
6243   /* Return the good/bad news */
6244   return (vam->retval);
6245 }
6246
6247 static int
6248 api_mpls_ip_bind_unbind (vat_main_t * vam)
6249 {
6250   unformat_input_t *i = vam->input;
6251   vl_api_mpls_ip_bind_unbind_t *mp;
6252   f64 timeout;
6253   u32 ip_table_id = 0;
6254   u8 create_table_if_needed = 0;
6255   u8 is_bind = 1;
6256   u8 is_ip4 = 1;
6257   ip4_address_t v4_address;
6258   ip6_address_t v6_address;
6259   u32 address_length;
6260   u8 address_set = 0;
6261   mpls_label_t local_label = MPLS_LABEL_INVALID;
6262
6263   /* Parse args required to build the message */
6264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6265     {
6266       if (unformat (i, "%U/%d", unformat_ip4_address,
6267                     &v4_address, &address_length))
6268         {
6269           is_ip4 = 1;
6270           address_set = 1;
6271         }
6272       else if (unformat (i, "%U/%d", unformat_ip6_address,
6273                          &v6_address, &address_length))
6274         {
6275           is_ip4 = 0;
6276           address_set = 1;
6277         }
6278       else if (unformat (i, "%d", &local_label))
6279         ;
6280       else if (unformat (i, "create-table"))
6281         create_table_if_needed = 1;
6282       else if (unformat (i, "table-id %d", &ip_table_id))
6283         ;
6284       else if (unformat (i, "unbind"))
6285         is_bind = 0;
6286       else if (unformat (i, "bind"))
6287         is_bind = 1;
6288       else
6289         {
6290           clib_warning ("parse error '%U'", format_unformat_error, i);
6291           return -99;
6292         }
6293     }
6294
6295   if (!address_set)
6296     {
6297       errmsg ("IP addres not set\n");
6298       return -99;
6299     }
6300
6301   if (MPLS_LABEL_INVALID == local_label)
6302     {
6303       errmsg ("missing label\n");
6304       return -99;
6305     }
6306
6307   /* Construct the API message */
6308   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6309
6310   mp->mb_create_table_if_needed = create_table_if_needed;
6311   mp->mb_is_bind = is_bind;
6312   mp->mb_is_ip4 = is_ip4;
6313   mp->mb_ip_table_id = ntohl (ip_table_id);
6314   mp->mb_mpls_table_id = 0;
6315   mp->mb_label = ntohl (local_label);
6316   mp->mb_address_length = address_length;
6317
6318   if (is_ip4)
6319     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6320   else
6321     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6322
6323   /* send it... */
6324   S;
6325
6326   /* Wait for a reply... */
6327   W;
6328 }
6329
6330 static int
6331 api_proxy_arp_add_del (vat_main_t * vam)
6332 {
6333   unformat_input_t *i = vam->input;
6334   vl_api_proxy_arp_add_del_t *mp;
6335   f64 timeout;
6336   u32 vrf_id = 0;
6337   u8 is_add = 1;
6338   ip4_address_t lo, hi;
6339   u8 range_set = 0;
6340
6341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6342     {
6343       if (unformat (i, "vrf %d", &vrf_id))
6344         ;
6345       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6346                          unformat_ip4_address, &hi))
6347         range_set = 1;
6348       else if (unformat (i, "del"))
6349         is_add = 0;
6350       else
6351         {
6352           clib_warning ("parse error '%U'", format_unformat_error, i);
6353           return -99;
6354         }
6355     }
6356
6357   if (range_set == 0)
6358     {
6359       errmsg ("address range not set\n");
6360       return -99;
6361     }
6362
6363   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6364
6365   mp->vrf_id = ntohl (vrf_id);
6366   mp->is_add = is_add;
6367   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6368   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6369
6370   S;
6371   W;
6372   /* NOTREACHED */
6373   return 0;
6374 }
6375
6376 static int
6377 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6378 {
6379   unformat_input_t *i = vam->input;
6380   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6381   f64 timeout;
6382   u32 sw_if_index;
6383   u8 enable = 1;
6384   u8 sw_if_index_set = 0;
6385
6386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6387     {
6388       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6389         sw_if_index_set = 1;
6390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6391         sw_if_index_set = 1;
6392       else if (unformat (i, "enable"))
6393         enable = 1;
6394       else if (unformat (i, "disable"))
6395         enable = 0;
6396       else
6397         {
6398           clib_warning ("parse error '%U'", format_unformat_error, i);
6399           return -99;
6400         }
6401     }
6402
6403   if (sw_if_index_set == 0)
6404     {
6405       errmsg ("missing interface name or sw_if_index\n");
6406       return -99;
6407     }
6408
6409   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6410
6411   mp->sw_if_index = ntohl (sw_if_index);
6412   mp->enable_disable = enable;
6413
6414   S;
6415   W;
6416   /* NOTREACHED */
6417   return 0;
6418 }
6419
6420 static int
6421 api_mpls_add_del_encap (vat_main_t * vam)
6422 {
6423   unformat_input_t *i = vam->input;
6424   vl_api_mpls_add_del_encap_t *mp;
6425   f64 timeout;
6426   u32 vrf_id = 0;
6427   u32 *labels = 0;
6428   u32 label;
6429   ip4_address_t dst_address;
6430   u8 is_add = 1;
6431
6432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6433     {
6434       if (unformat (i, "vrf %d", &vrf_id))
6435         ;
6436       else if (unformat (i, "label %d", &label))
6437         vec_add1 (labels, ntohl (label));
6438       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6439         ;
6440       else if (unformat (i, "del"))
6441         is_add = 0;
6442       else
6443         {
6444           clib_warning ("parse error '%U'", format_unformat_error, i);
6445           return -99;
6446         }
6447     }
6448
6449   if (vec_len (labels) == 0)
6450     {
6451       errmsg ("missing encap label stack\n");
6452       return -99;
6453     }
6454
6455   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6456       sizeof (u32) * vec_len (labels));
6457
6458   mp->vrf_id = ntohl (vrf_id);
6459   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6460   mp->is_add = is_add;
6461   mp->nlabels = vec_len (labels);
6462   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6463
6464   vec_free (labels);
6465
6466   S;
6467   W;
6468   /* NOTREACHED */
6469   return 0;
6470 }
6471
6472 static int
6473 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6474 {
6475   unformat_input_t *i = vam->input;
6476   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6477   f64 timeout;
6478   u32 inner_vrf_id = 0;
6479   ip4_address_t intfc_address;
6480   u8 dst_mac_address[6];
6481   int dst_set = 1;
6482   u32 tmp;
6483   u8 intfc_address_length = 0;
6484   u8 is_add = 1;
6485   u8 l2_only = 0;
6486   u32 tx_sw_if_index;
6487   int tx_sw_if_index_set = 0;
6488
6489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6490     {
6491       if (unformat (i, "vrf %d", &inner_vrf_id))
6492         ;
6493       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6494                          &intfc_address, &tmp))
6495         intfc_address_length = tmp;
6496       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6497         tx_sw_if_index_set = 1;
6498       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6499         tx_sw_if_index_set = 1;
6500       else if (unformat (i, "dst %U", unformat_ethernet_address,
6501                          dst_mac_address))
6502         dst_set = 1;
6503       else if (unformat (i, "l2-only"))
6504         l2_only = 1;
6505       else if (unformat (i, "del"))
6506         is_add = 0;
6507       else
6508         {
6509           clib_warning ("parse error '%U'", format_unformat_error, i);
6510           return -99;
6511         }
6512     }
6513
6514   if (!dst_set)
6515     {
6516       errmsg ("dst (mac address) not set\n");
6517       return -99;
6518     }
6519   if (!tx_sw_if_index_set)
6520     {
6521       errmsg ("tx-intfc not set\n");
6522       return -99;
6523     }
6524
6525   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6526
6527   mp->vrf_id = ntohl (inner_vrf_id);
6528   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6529   mp->adj_address_length = intfc_address_length;
6530   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6531                sizeof (dst_mac_address));
6532   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6533   mp->l2_only = l2_only;
6534   mp->is_add = is_add;
6535
6536   S;
6537   W;
6538   /* NOTREACHED */
6539   return 0;
6540 }
6541
6542 static int
6543 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6544 {
6545   unformat_input_t *i = vam->input;
6546   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6547   f64 timeout;
6548   u32 inner_vrf_id = 0;
6549   u32 outer_vrf_id = 0;
6550   ip4_address_t adj_address;
6551   int adj_address_set = 0;
6552   ip4_address_t next_hop_address;
6553   int next_hop_address_set = 0;
6554   u32 tmp;
6555   u8 adj_address_length = 0;
6556   u8 l2_only = 0;
6557   u8 is_add = 1;
6558   u32 resolve_attempts = 5;
6559   u8 resolve_if_needed = 1;
6560
6561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6562     {
6563       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6564         ;
6565       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6566         ;
6567       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6568                          &adj_address, &tmp))
6569         {
6570           adj_address_length = tmp;
6571           adj_address_set = 1;
6572         }
6573       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6574                          &next_hop_address))
6575         next_hop_address_set = 1;
6576       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6577         ;
6578       else if (unformat (i, "resolve-if-needed %d", &tmp))
6579         resolve_if_needed = tmp;
6580       else if (unformat (i, "l2-only"))
6581         l2_only = 1;
6582       else if (unformat (i, "del"))
6583         is_add = 0;
6584       else
6585         {
6586           clib_warning ("parse error '%U'", format_unformat_error, i);
6587           return -99;
6588         }
6589     }
6590
6591   if (!adj_address_set)
6592     {
6593       errmsg ("adjacency address/mask not set\n");
6594       return -99;
6595     }
6596   if (!next_hop_address_set)
6597     {
6598       errmsg ("ip4 next hop address (in outer fib) not set\n");
6599       return -99;
6600     }
6601
6602   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6603
6604   mp->inner_vrf_id = ntohl (inner_vrf_id);
6605   mp->outer_vrf_id = ntohl (outer_vrf_id);
6606   mp->resolve_attempts = ntohl (resolve_attempts);
6607   mp->resolve_if_needed = resolve_if_needed;
6608   mp->is_add = is_add;
6609   mp->l2_only = l2_only;
6610   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6611   mp->adj_address_length = adj_address_length;
6612   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6613                sizeof (next_hop_address));
6614
6615   S;
6616   W;
6617   /* NOTREACHED */
6618   return 0;
6619 }
6620
6621 static int
6622 api_sw_interface_set_unnumbered (vat_main_t * vam)
6623 {
6624   unformat_input_t *i = vam->input;
6625   vl_api_sw_interface_set_unnumbered_t *mp;
6626   f64 timeout;
6627   u32 sw_if_index;
6628   u32 unnum_sw_index = ~0;
6629   u8 is_add = 1;
6630   u8 sw_if_index_set = 0;
6631
6632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6633     {
6634       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6635         sw_if_index_set = 1;
6636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6637         sw_if_index_set = 1;
6638       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6639         ;
6640       else if (unformat (i, "del"))
6641         is_add = 0;
6642       else
6643         {
6644           clib_warning ("parse error '%U'", format_unformat_error, i);
6645           return -99;
6646         }
6647     }
6648
6649   if (sw_if_index_set == 0)
6650     {
6651       errmsg ("missing interface name or sw_if_index\n");
6652       return -99;
6653     }
6654
6655   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6656
6657   mp->sw_if_index = ntohl (sw_if_index);
6658   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6659   mp->is_add = is_add;
6660
6661   S;
6662   W;
6663   /* NOTREACHED */
6664   return 0;
6665 }
6666
6667 static int
6668 api_ip_neighbor_add_del (vat_main_t * vam)
6669 {
6670   unformat_input_t *i = vam->input;
6671   vl_api_ip_neighbor_add_del_t *mp;
6672   f64 timeout;
6673   u32 sw_if_index;
6674   u8 sw_if_index_set = 0;
6675   u32 vrf_id = 0;
6676   u8 is_add = 1;
6677   u8 is_static = 0;
6678   u8 mac_address[6];
6679   u8 mac_set = 0;
6680   u8 v4_address_set = 0;
6681   u8 v6_address_set = 0;
6682   ip4_address_t v4address;
6683   ip6_address_t v6address;
6684
6685   memset (mac_address, 0, sizeof (mac_address));
6686
6687   /* Parse args required to build the message */
6688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6689     {
6690       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6691         {
6692           mac_set = 1;
6693         }
6694       else if (unformat (i, "del"))
6695         is_add = 0;
6696       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6697         sw_if_index_set = 1;
6698       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6699         sw_if_index_set = 1;
6700       else if (unformat (i, "is_static"))
6701         is_static = 1;
6702       else if (unformat (i, "vrf %d", &vrf_id))
6703         ;
6704       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6705         v4_address_set = 1;
6706       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6707         v6_address_set = 1;
6708       else
6709         {
6710           clib_warning ("parse error '%U'", format_unformat_error, i);
6711           return -99;
6712         }
6713     }
6714
6715   if (sw_if_index_set == 0)
6716     {
6717       errmsg ("missing interface name or sw_if_index\n");
6718       return -99;
6719     }
6720   if (v4_address_set && v6_address_set)
6721     {
6722       errmsg ("both v4 and v6 addresses set\n");
6723       return -99;
6724     }
6725   if (!v4_address_set && !v6_address_set)
6726     {
6727       errmsg ("no address set\n");
6728       return -99;
6729     }
6730
6731   /* Construct the API message */
6732   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6733
6734   mp->sw_if_index = ntohl (sw_if_index);
6735   mp->is_add = is_add;
6736   mp->vrf_id = ntohl (vrf_id);
6737   mp->is_static = is_static;
6738   if (mac_set)
6739     clib_memcpy (mp->mac_address, mac_address, 6);
6740   if (v6_address_set)
6741     {
6742       mp->is_ipv6 = 1;
6743       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6744     }
6745   else
6746     {
6747       /* mp->is_ipv6 = 0; via memset in M macro above */
6748       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6749     }
6750
6751   /* send it... */
6752   S;
6753
6754   /* Wait for a reply, return good/bad news  */
6755   W;
6756
6757   /* NOTREACHED */
6758   return 0;
6759 }
6760
6761 static int
6762 api_reset_vrf (vat_main_t * vam)
6763 {
6764   unformat_input_t *i = vam->input;
6765   vl_api_reset_vrf_t *mp;
6766   f64 timeout;
6767   u32 vrf_id = 0;
6768   u8 is_ipv6 = 0;
6769   u8 vrf_id_set = 0;
6770
6771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6772     {
6773       if (unformat (i, "vrf %d", &vrf_id))
6774         vrf_id_set = 1;
6775       else if (unformat (i, "ipv6"))
6776         is_ipv6 = 1;
6777       else
6778         {
6779           clib_warning ("parse error '%U'", format_unformat_error, i);
6780           return -99;
6781         }
6782     }
6783
6784   if (vrf_id_set == 0)
6785     {
6786       errmsg ("missing vrf id\n");
6787       return -99;
6788     }
6789
6790   M (RESET_VRF, reset_vrf);
6791
6792   mp->vrf_id = ntohl (vrf_id);
6793   mp->is_ipv6 = is_ipv6;
6794
6795   S;
6796   W;
6797   /* NOTREACHED */
6798   return 0;
6799 }
6800
6801 static int
6802 api_create_vlan_subif (vat_main_t * vam)
6803 {
6804   unformat_input_t *i = vam->input;
6805   vl_api_create_vlan_subif_t *mp;
6806   f64 timeout;
6807   u32 sw_if_index;
6808   u8 sw_if_index_set = 0;
6809   u32 vlan_id;
6810   u8 vlan_id_set = 0;
6811
6812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6813     {
6814       if (unformat (i, "sw_if_index %d", &sw_if_index))
6815         sw_if_index_set = 1;
6816       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6817         sw_if_index_set = 1;
6818       else if (unformat (i, "vlan %d", &vlan_id))
6819         vlan_id_set = 1;
6820       else
6821         {
6822           clib_warning ("parse error '%U'", format_unformat_error, i);
6823           return -99;
6824         }
6825     }
6826
6827   if (sw_if_index_set == 0)
6828     {
6829       errmsg ("missing interface name or sw_if_index\n");
6830       return -99;
6831     }
6832
6833   if (vlan_id_set == 0)
6834     {
6835       errmsg ("missing vlan_id\n");
6836       return -99;
6837     }
6838   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6839
6840   mp->sw_if_index = ntohl (sw_if_index);
6841   mp->vlan_id = ntohl (vlan_id);
6842
6843   S;
6844   W;
6845   /* NOTREACHED */
6846   return 0;
6847 }
6848
6849 #define foreach_create_subif_bit                \
6850 _(no_tags)                                      \
6851 _(one_tag)                                      \
6852 _(two_tags)                                     \
6853 _(dot1ad)                                       \
6854 _(exact_match)                                  \
6855 _(default_sub)                                  \
6856 _(outer_vlan_id_any)                            \
6857 _(inner_vlan_id_any)
6858
6859 static int
6860 api_create_subif (vat_main_t * vam)
6861 {
6862   unformat_input_t *i = vam->input;
6863   vl_api_create_subif_t *mp;
6864   f64 timeout;
6865   u32 sw_if_index;
6866   u8 sw_if_index_set = 0;
6867   u32 sub_id;
6868   u8 sub_id_set = 0;
6869   u32 no_tags = 0;
6870   u32 one_tag = 0;
6871   u32 two_tags = 0;
6872   u32 dot1ad = 0;
6873   u32 exact_match = 0;
6874   u32 default_sub = 0;
6875   u32 outer_vlan_id_any = 0;
6876   u32 inner_vlan_id_any = 0;
6877   u32 tmp;
6878   u16 outer_vlan_id = 0;
6879   u16 inner_vlan_id = 0;
6880
6881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6882     {
6883       if (unformat (i, "sw_if_index %d", &sw_if_index))
6884         sw_if_index_set = 1;
6885       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6886         sw_if_index_set = 1;
6887       else if (unformat (i, "sub_id %d", &sub_id))
6888         sub_id_set = 1;
6889       else if (unformat (i, "outer_vlan_id %d", &tmp))
6890         outer_vlan_id = tmp;
6891       else if (unformat (i, "inner_vlan_id %d", &tmp))
6892         inner_vlan_id = tmp;
6893
6894 #define _(a) else if (unformat (i, #a)) a = 1 ;
6895       foreach_create_subif_bit
6896 #undef _
6897         else
6898         {
6899           clib_warning ("parse error '%U'", format_unformat_error, i);
6900           return -99;
6901         }
6902     }
6903
6904   if (sw_if_index_set == 0)
6905     {
6906       errmsg ("missing interface name or sw_if_index\n");
6907       return -99;
6908     }
6909
6910   if (sub_id_set == 0)
6911     {
6912       errmsg ("missing sub_id\n");
6913       return -99;
6914     }
6915   M (CREATE_SUBIF, create_subif);
6916
6917   mp->sw_if_index = ntohl (sw_if_index);
6918   mp->sub_id = ntohl (sub_id);
6919
6920 #define _(a) mp->a = a;
6921   foreach_create_subif_bit;
6922 #undef _
6923
6924   mp->outer_vlan_id = ntohs (outer_vlan_id);
6925   mp->inner_vlan_id = ntohs (inner_vlan_id);
6926
6927   S;
6928   W;
6929   /* NOTREACHED */
6930   return 0;
6931 }
6932
6933 static int
6934 api_oam_add_del (vat_main_t * vam)
6935 {
6936   unformat_input_t *i = vam->input;
6937   vl_api_oam_add_del_t *mp;
6938   f64 timeout;
6939   u32 vrf_id = 0;
6940   u8 is_add = 1;
6941   ip4_address_t src, dst;
6942   u8 src_set = 0;
6943   u8 dst_set = 0;
6944
6945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6946     {
6947       if (unformat (i, "vrf %d", &vrf_id))
6948         ;
6949       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6950         src_set = 1;
6951       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6952         dst_set = 1;
6953       else if (unformat (i, "del"))
6954         is_add = 0;
6955       else
6956         {
6957           clib_warning ("parse error '%U'", format_unformat_error, i);
6958           return -99;
6959         }
6960     }
6961
6962   if (src_set == 0)
6963     {
6964       errmsg ("missing src addr\n");
6965       return -99;
6966     }
6967
6968   if (dst_set == 0)
6969     {
6970       errmsg ("missing dst addr\n");
6971       return -99;
6972     }
6973
6974   M (OAM_ADD_DEL, oam_add_del);
6975
6976   mp->vrf_id = ntohl (vrf_id);
6977   mp->is_add = is_add;
6978   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6979   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6980
6981   S;
6982   W;
6983   /* NOTREACHED */
6984   return 0;
6985 }
6986
6987 static int
6988 api_reset_fib (vat_main_t * vam)
6989 {
6990   unformat_input_t *i = vam->input;
6991   vl_api_reset_fib_t *mp;
6992   f64 timeout;
6993   u32 vrf_id = 0;
6994   u8 is_ipv6 = 0;
6995   u8 vrf_id_set = 0;
6996
6997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6998     {
6999       if (unformat (i, "vrf %d", &vrf_id))
7000         vrf_id_set = 1;
7001       else if (unformat (i, "ipv6"))
7002         is_ipv6 = 1;
7003       else
7004         {
7005           clib_warning ("parse error '%U'", format_unformat_error, i);
7006           return -99;
7007         }
7008     }
7009
7010   if (vrf_id_set == 0)
7011     {
7012       errmsg ("missing vrf id\n");
7013       return -99;
7014     }
7015
7016   M (RESET_FIB, reset_fib);
7017
7018   mp->vrf_id = ntohl (vrf_id);
7019   mp->is_ipv6 = is_ipv6;
7020
7021   S;
7022   W;
7023   /* NOTREACHED */
7024   return 0;
7025 }
7026
7027 static int
7028 api_dhcp_proxy_config (vat_main_t * vam)
7029 {
7030   unformat_input_t *i = vam->input;
7031   vl_api_dhcp_proxy_config_t *mp;
7032   f64 timeout;
7033   u32 vrf_id = 0;
7034   u8 is_add = 1;
7035   u8 insert_cid = 1;
7036   u8 v4_address_set = 0;
7037   u8 v6_address_set = 0;
7038   ip4_address_t v4address;
7039   ip6_address_t v6address;
7040   u8 v4_src_address_set = 0;
7041   u8 v6_src_address_set = 0;
7042   ip4_address_t v4srcaddress;
7043   ip6_address_t v6srcaddress;
7044
7045   /* Parse args required to build the message */
7046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7047     {
7048       if (unformat (i, "del"))
7049         is_add = 0;
7050       else if (unformat (i, "vrf %d", &vrf_id))
7051         ;
7052       else if (unformat (i, "insert-cid %d", &insert_cid))
7053         ;
7054       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7055         v4_address_set = 1;
7056       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7057         v6_address_set = 1;
7058       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7059         v4_src_address_set = 1;
7060       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7061         v6_src_address_set = 1;
7062       else
7063         break;
7064     }
7065
7066   if (v4_address_set && v6_address_set)
7067     {
7068       errmsg ("both v4 and v6 server addresses set\n");
7069       return -99;
7070     }
7071   if (!v4_address_set && !v6_address_set)
7072     {
7073       errmsg ("no server addresses set\n");
7074       return -99;
7075     }
7076
7077   if (v4_src_address_set && v6_src_address_set)
7078     {
7079       errmsg ("both v4 and v6  src addresses set\n");
7080       return -99;
7081     }
7082   if (!v4_src_address_set && !v6_src_address_set)
7083     {
7084       errmsg ("no src addresses set\n");
7085       return -99;
7086     }
7087
7088   if (!(v4_src_address_set && v4_address_set) &&
7089       !(v6_src_address_set && v6_address_set))
7090     {
7091       errmsg ("no matching server and src addresses set\n");
7092       return -99;
7093     }
7094
7095   /* Construct the API message */
7096   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7097
7098   mp->insert_circuit_id = insert_cid;
7099   mp->is_add = is_add;
7100   mp->vrf_id = ntohl (vrf_id);
7101   if (v6_address_set)
7102     {
7103       mp->is_ipv6 = 1;
7104       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7105       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7106     }
7107   else
7108     {
7109       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7110       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7111     }
7112
7113   /* send it... */
7114   S;
7115
7116   /* Wait for a reply, return good/bad news  */
7117   W;
7118   /* NOTREACHED */
7119   return 0;
7120 }
7121
7122 static int
7123 api_dhcp_proxy_config_2 (vat_main_t * vam)
7124 {
7125   unformat_input_t *i = vam->input;
7126   vl_api_dhcp_proxy_config_2_t *mp;
7127   f64 timeout;
7128   u32 rx_vrf_id = 0;
7129   u32 server_vrf_id = 0;
7130   u8 is_add = 1;
7131   u8 insert_cid = 1;
7132   u8 v4_address_set = 0;
7133   u8 v6_address_set = 0;
7134   ip4_address_t v4address;
7135   ip6_address_t v6address;
7136   u8 v4_src_address_set = 0;
7137   u8 v6_src_address_set = 0;
7138   ip4_address_t v4srcaddress;
7139   ip6_address_t v6srcaddress;
7140
7141   /* Parse args required to build the message */
7142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7143     {
7144       if (unformat (i, "del"))
7145         is_add = 0;
7146       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7147         ;
7148       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7149         ;
7150       else if (unformat (i, "insert-cid %d", &insert_cid))
7151         ;
7152       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7153         v4_address_set = 1;
7154       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7155         v6_address_set = 1;
7156       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7157         v4_src_address_set = 1;
7158       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7159         v6_src_address_set = 1;
7160       else
7161         break;
7162     }
7163
7164   if (v4_address_set && v6_address_set)
7165     {
7166       errmsg ("both v4 and v6 server addresses set\n");
7167       return -99;
7168     }
7169   if (!v4_address_set && !v6_address_set)
7170     {
7171       errmsg ("no server addresses set\n");
7172       return -99;
7173     }
7174
7175   if (v4_src_address_set && v6_src_address_set)
7176     {
7177       errmsg ("both v4 and v6  src addresses set\n");
7178       return -99;
7179     }
7180   if (!v4_src_address_set && !v6_src_address_set)
7181     {
7182       errmsg ("no src addresses set\n");
7183       return -99;
7184     }
7185
7186   if (!(v4_src_address_set && v4_address_set) &&
7187       !(v6_src_address_set && v6_address_set))
7188     {
7189       errmsg ("no matching server and src addresses set\n");
7190       return -99;
7191     }
7192
7193   /* Construct the API message */
7194   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7195
7196   mp->insert_circuit_id = insert_cid;
7197   mp->is_add = is_add;
7198   mp->rx_vrf_id = ntohl (rx_vrf_id);
7199   mp->server_vrf_id = ntohl (server_vrf_id);
7200   if (v6_address_set)
7201     {
7202       mp->is_ipv6 = 1;
7203       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7204       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7205     }
7206   else
7207     {
7208       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7209       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7210     }
7211
7212   /* send it... */
7213   S;
7214
7215   /* Wait for a reply, return good/bad news  */
7216   W;
7217   /* NOTREACHED */
7218   return 0;
7219 }
7220
7221 static int
7222 api_dhcp_proxy_set_vss (vat_main_t * vam)
7223 {
7224   unformat_input_t *i = vam->input;
7225   vl_api_dhcp_proxy_set_vss_t *mp;
7226   f64 timeout;
7227   u8 is_ipv6 = 0;
7228   u8 is_add = 1;
7229   u32 tbl_id;
7230   u8 tbl_id_set = 0;
7231   u32 oui;
7232   u8 oui_set = 0;
7233   u32 fib_id;
7234   u8 fib_id_set = 0;
7235
7236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7237     {
7238       if (unformat (i, "tbl_id %d", &tbl_id))
7239         tbl_id_set = 1;
7240       if (unformat (i, "fib_id %d", &fib_id))
7241         fib_id_set = 1;
7242       if (unformat (i, "oui %d", &oui))
7243         oui_set = 1;
7244       else if (unformat (i, "ipv6"))
7245         is_ipv6 = 1;
7246       else if (unformat (i, "del"))
7247         is_add = 0;
7248       else
7249         {
7250           clib_warning ("parse error '%U'", format_unformat_error, i);
7251           return -99;
7252         }
7253     }
7254
7255   if (tbl_id_set == 0)
7256     {
7257       errmsg ("missing tbl id\n");
7258       return -99;
7259     }
7260
7261   if (fib_id_set == 0)
7262     {
7263       errmsg ("missing fib id\n");
7264       return -99;
7265     }
7266   if (oui_set == 0)
7267     {
7268       errmsg ("missing oui\n");
7269       return -99;
7270     }
7271
7272   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7273   mp->tbl_id = ntohl (tbl_id);
7274   mp->fib_id = ntohl (fib_id);
7275   mp->oui = ntohl (oui);
7276   mp->is_ipv6 = is_ipv6;
7277   mp->is_add = is_add;
7278
7279   S;
7280   W;
7281   /* NOTREACHED */
7282   return 0;
7283 }
7284
7285 static int
7286 api_dhcp_client_config (vat_main_t * vam)
7287 {
7288   unformat_input_t *i = vam->input;
7289   vl_api_dhcp_client_config_t *mp;
7290   f64 timeout;
7291   u32 sw_if_index;
7292   u8 sw_if_index_set = 0;
7293   u8 is_add = 1;
7294   u8 *hostname = 0;
7295   u8 disable_event = 0;
7296
7297   /* Parse args required to build the message */
7298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7299     {
7300       if (unformat (i, "del"))
7301         is_add = 0;
7302       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7303         sw_if_index_set = 1;
7304       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7305         sw_if_index_set = 1;
7306       else if (unformat (i, "hostname %s", &hostname))
7307         ;
7308       else if (unformat (i, "disable_event"))
7309         disable_event = 1;
7310       else
7311         break;
7312     }
7313
7314   if (sw_if_index_set == 0)
7315     {
7316       errmsg ("missing interface name or sw_if_index\n");
7317       return -99;
7318     }
7319
7320   if (vec_len (hostname) > 63)
7321     {
7322       errmsg ("hostname too long\n");
7323     }
7324   vec_add1 (hostname, 0);
7325
7326   /* Construct the API message */
7327   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7328
7329   mp->sw_if_index = ntohl (sw_if_index);
7330   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7331   vec_free (hostname);
7332   mp->is_add = is_add;
7333   mp->want_dhcp_event = disable_event ? 0 : 1;
7334   mp->pid = getpid ();
7335
7336   /* send it... */
7337   S;
7338
7339   /* Wait for a reply, return good/bad news  */
7340   W;
7341   /* NOTREACHED */
7342   return 0;
7343 }
7344
7345 static int
7346 api_set_ip_flow_hash (vat_main_t * vam)
7347 {
7348   unformat_input_t *i = vam->input;
7349   vl_api_set_ip_flow_hash_t *mp;
7350   f64 timeout;
7351   u32 vrf_id = 0;
7352   u8 is_ipv6 = 0;
7353   u8 vrf_id_set = 0;
7354   u8 src = 0;
7355   u8 dst = 0;
7356   u8 sport = 0;
7357   u8 dport = 0;
7358   u8 proto = 0;
7359   u8 reverse = 0;
7360
7361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7362     {
7363       if (unformat (i, "vrf %d", &vrf_id))
7364         vrf_id_set = 1;
7365       else if (unformat (i, "ipv6"))
7366         is_ipv6 = 1;
7367       else if (unformat (i, "src"))
7368         src = 1;
7369       else if (unformat (i, "dst"))
7370         dst = 1;
7371       else if (unformat (i, "sport"))
7372         sport = 1;
7373       else if (unformat (i, "dport"))
7374         dport = 1;
7375       else if (unformat (i, "proto"))
7376         proto = 1;
7377       else if (unformat (i, "reverse"))
7378         reverse = 1;
7379
7380       else
7381         {
7382           clib_warning ("parse error '%U'", format_unformat_error, i);
7383           return -99;
7384         }
7385     }
7386
7387   if (vrf_id_set == 0)
7388     {
7389       errmsg ("missing vrf id\n");
7390       return -99;
7391     }
7392
7393   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7394   mp->src = src;
7395   mp->dst = dst;
7396   mp->sport = sport;
7397   mp->dport = dport;
7398   mp->proto = proto;
7399   mp->reverse = reverse;
7400   mp->vrf_id = ntohl (vrf_id);
7401   mp->is_ipv6 = is_ipv6;
7402
7403   S;
7404   W;
7405   /* NOTREACHED */
7406   return 0;
7407 }
7408
7409 static int
7410 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7411 {
7412   unformat_input_t *i = vam->input;
7413   vl_api_sw_interface_ip6_enable_disable_t *mp;
7414   f64 timeout;
7415   u32 sw_if_index;
7416   u8 sw_if_index_set = 0;
7417   u8 enable = 0;
7418
7419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7420     {
7421       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7422         sw_if_index_set = 1;
7423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7424         sw_if_index_set = 1;
7425       else if (unformat (i, "enable"))
7426         enable = 1;
7427       else if (unformat (i, "disable"))
7428         enable = 0;
7429       else
7430         {
7431           clib_warning ("parse error '%U'", format_unformat_error, i);
7432           return -99;
7433         }
7434     }
7435
7436   if (sw_if_index_set == 0)
7437     {
7438       errmsg ("missing interface name or sw_if_index\n");
7439       return -99;
7440     }
7441
7442   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7443
7444   mp->sw_if_index = ntohl (sw_if_index);
7445   mp->enable = enable;
7446
7447   S;
7448   W;
7449   /* NOTREACHED */
7450   return 0;
7451 }
7452
7453 static int
7454 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7455 {
7456   unformat_input_t *i = vam->input;
7457   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7458   f64 timeout;
7459   u32 sw_if_index;
7460   u8 sw_if_index_set = 0;
7461   u32 address_length = 0;
7462   u8 v6_address_set = 0;
7463   ip6_address_t v6address;
7464
7465   /* Parse args required to build the message */
7466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7467     {
7468       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7469         sw_if_index_set = 1;
7470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7471         sw_if_index_set = 1;
7472       else if (unformat (i, "%U/%d",
7473                          unformat_ip6_address, &v6address, &address_length))
7474         v6_address_set = 1;
7475       else
7476         break;
7477     }
7478
7479   if (sw_if_index_set == 0)
7480     {
7481       errmsg ("missing interface name or sw_if_index\n");
7482       return -99;
7483     }
7484   if (!v6_address_set)
7485     {
7486       errmsg ("no address set\n");
7487       return -99;
7488     }
7489
7490   /* Construct the API message */
7491   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7492      sw_interface_ip6_set_link_local_address);
7493
7494   mp->sw_if_index = ntohl (sw_if_index);
7495   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7496   mp->address_length = address_length;
7497
7498   /* send it... */
7499   S;
7500
7501   /* Wait for a reply, return good/bad news  */
7502   W;
7503
7504   /* NOTREACHED */
7505   return 0;
7506 }
7507
7508
7509 static int
7510 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7511 {
7512   unformat_input_t *i = vam->input;
7513   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7514   f64 timeout;
7515   u32 sw_if_index;
7516   u8 sw_if_index_set = 0;
7517   u32 address_length = 0;
7518   u8 v6_address_set = 0;
7519   ip6_address_t v6address;
7520   u8 use_default = 0;
7521   u8 no_advertise = 0;
7522   u8 off_link = 0;
7523   u8 no_autoconfig = 0;
7524   u8 no_onlink = 0;
7525   u8 is_no = 0;
7526   u32 val_lifetime = 0;
7527   u32 pref_lifetime = 0;
7528
7529   /* Parse args required to build the message */
7530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7531     {
7532       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7533         sw_if_index_set = 1;
7534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7535         sw_if_index_set = 1;
7536       else if (unformat (i, "%U/%d",
7537                          unformat_ip6_address, &v6address, &address_length))
7538         v6_address_set = 1;
7539       else if (unformat (i, "val_life %d", &val_lifetime))
7540         ;
7541       else if (unformat (i, "pref_life %d", &pref_lifetime))
7542         ;
7543       else if (unformat (i, "def"))
7544         use_default = 1;
7545       else if (unformat (i, "noadv"))
7546         no_advertise = 1;
7547       else if (unformat (i, "offl"))
7548         off_link = 1;
7549       else if (unformat (i, "noauto"))
7550         no_autoconfig = 1;
7551       else if (unformat (i, "nolink"))
7552         no_onlink = 1;
7553       else if (unformat (i, "isno"))
7554         is_no = 1;
7555       else
7556         {
7557           clib_warning ("parse error '%U'", format_unformat_error, i);
7558           return -99;
7559         }
7560     }
7561
7562   if (sw_if_index_set == 0)
7563     {
7564       errmsg ("missing interface name or sw_if_index\n");
7565       return -99;
7566     }
7567   if (!v6_address_set)
7568     {
7569       errmsg ("no address set\n");
7570       return -99;
7571     }
7572
7573   /* Construct the API message */
7574   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7575
7576   mp->sw_if_index = ntohl (sw_if_index);
7577   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7578   mp->address_length = address_length;
7579   mp->use_default = use_default;
7580   mp->no_advertise = no_advertise;
7581   mp->off_link = off_link;
7582   mp->no_autoconfig = no_autoconfig;
7583   mp->no_onlink = no_onlink;
7584   mp->is_no = is_no;
7585   mp->val_lifetime = ntohl (val_lifetime);
7586   mp->pref_lifetime = ntohl (pref_lifetime);
7587
7588   /* send it... */
7589   S;
7590
7591   /* Wait for a reply, return good/bad news  */
7592   W;
7593
7594   /* NOTREACHED */
7595   return 0;
7596 }
7597
7598 static int
7599 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7600 {
7601   unformat_input_t *i = vam->input;
7602   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7603   f64 timeout;
7604   u32 sw_if_index;
7605   u8 sw_if_index_set = 0;
7606   u8 suppress = 0;
7607   u8 managed = 0;
7608   u8 other = 0;
7609   u8 ll_option = 0;
7610   u8 send_unicast = 0;
7611   u8 cease = 0;
7612   u8 is_no = 0;
7613   u8 default_router = 0;
7614   u32 max_interval = 0;
7615   u32 min_interval = 0;
7616   u32 lifetime = 0;
7617   u32 initial_count = 0;
7618   u32 initial_interval = 0;
7619
7620
7621   /* Parse args required to build the message */
7622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7623     {
7624       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7625         sw_if_index_set = 1;
7626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7627         sw_if_index_set = 1;
7628       else if (unformat (i, "maxint %d", &max_interval))
7629         ;
7630       else if (unformat (i, "minint %d", &min_interval))
7631         ;
7632       else if (unformat (i, "life %d", &lifetime))
7633         ;
7634       else if (unformat (i, "count %d", &initial_count))
7635         ;
7636       else if (unformat (i, "interval %d", &initial_interval))
7637         ;
7638       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7639         suppress = 1;
7640       else if (unformat (i, "managed"))
7641         managed = 1;
7642       else if (unformat (i, "other"))
7643         other = 1;
7644       else if (unformat (i, "ll"))
7645         ll_option = 1;
7646       else if (unformat (i, "send"))
7647         send_unicast = 1;
7648       else if (unformat (i, "cease"))
7649         cease = 1;
7650       else if (unformat (i, "isno"))
7651         is_no = 1;
7652       else if (unformat (i, "def"))
7653         default_router = 1;
7654       else
7655         {
7656           clib_warning ("parse error '%U'", format_unformat_error, i);
7657           return -99;
7658         }
7659     }
7660
7661   if (sw_if_index_set == 0)
7662     {
7663       errmsg ("missing interface name or sw_if_index\n");
7664       return -99;
7665     }
7666
7667   /* Construct the API message */
7668   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7669
7670   mp->sw_if_index = ntohl (sw_if_index);
7671   mp->max_interval = ntohl (max_interval);
7672   mp->min_interval = ntohl (min_interval);
7673   mp->lifetime = ntohl (lifetime);
7674   mp->initial_count = ntohl (initial_count);
7675   mp->initial_interval = ntohl (initial_interval);
7676   mp->suppress = suppress;
7677   mp->managed = managed;
7678   mp->other = other;
7679   mp->ll_option = ll_option;
7680   mp->send_unicast = send_unicast;
7681   mp->cease = cease;
7682   mp->is_no = is_no;
7683   mp->default_router = default_router;
7684
7685   /* send it... */
7686   S;
7687
7688   /* Wait for a reply, return good/bad news  */
7689   W;
7690
7691   /* NOTREACHED */
7692   return 0;
7693 }
7694
7695 static int
7696 api_set_arp_neighbor_limit (vat_main_t * vam)
7697 {
7698   unformat_input_t *i = vam->input;
7699   vl_api_set_arp_neighbor_limit_t *mp;
7700   f64 timeout;
7701   u32 arp_nbr_limit;
7702   u8 limit_set = 0;
7703   u8 is_ipv6 = 0;
7704
7705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7706     {
7707       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7708         limit_set = 1;
7709       else if (unformat (i, "ipv6"))
7710         is_ipv6 = 1;
7711       else
7712         {
7713           clib_warning ("parse error '%U'", format_unformat_error, i);
7714           return -99;
7715         }
7716     }
7717
7718   if (limit_set == 0)
7719     {
7720       errmsg ("missing limit value\n");
7721       return -99;
7722     }
7723
7724   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7725
7726   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7727   mp->is_ipv6 = is_ipv6;
7728
7729   S;
7730   W;
7731   /* NOTREACHED */
7732   return 0;
7733 }
7734
7735 static int
7736 api_l2_patch_add_del (vat_main_t * vam)
7737 {
7738   unformat_input_t *i = vam->input;
7739   vl_api_l2_patch_add_del_t *mp;
7740   f64 timeout;
7741   u32 rx_sw_if_index;
7742   u8 rx_sw_if_index_set = 0;
7743   u32 tx_sw_if_index;
7744   u8 tx_sw_if_index_set = 0;
7745   u8 is_add = 1;
7746
7747   /* Parse args required to build the message */
7748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7749     {
7750       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7751         rx_sw_if_index_set = 1;
7752       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7753         tx_sw_if_index_set = 1;
7754       else if (unformat (i, "rx"))
7755         {
7756           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7757             {
7758               if (unformat (i, "%U", unformat_sw_if_index, vam,
7759                             &rx_sw_if_index))
7760                 rx_sw_if_index_set = 1;
7761             }
7762           else
7763             break;
7764         }
7765       else if (unformat (i, "tx"))
7766         {
7767           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7768             {
7769               if (unformat (i, "%U", unformat_sw_if_index, vam,
7770                             &tx_sw_if_index))
7771                 tx_sw_if_index_set = 1;
7772             }
7773           else
7774             break;
7775         }
7776       else if (unformat (i, "del"))
7777         is_add = 0;
7778       else
7779         break;
7780     }
7781
7782   if (rx_sw_if_index_set == 0)
7783     {
7784       errmsg ("missing rx interface name or rx_sw_if_index\n");
7785       return -99;
7786     }
7787
7788   if (tx_sw_if_index_set == 0)
7789     {
7790       errmsg ("missing tx interface name or tx_sw_if_index\n");
7791       return -99;
7792     }
7793
7794   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7795
7796   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7797   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7798   mp->is_add = is_add;
7799
7800   S;
7801   W;
7802   /* NOTREACHED */
7803   return 0;
7804 }
7805
7806 static int
7807 api_ioam_enable (vat_main_t * vam)
7808 {
7809   unformat_input_t *input = vam->input;
7810   vl_api_ioam_enable_t *mp;
7811   f64 timeout;
7812   u32 id = 0;
7813   int has_trace_option = 0;
7814   int has_pot_option = 0;
7815   int has_seqno_option = 0;
7816   int has_analyse_option = 0;
7817
7818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7819     {
7820       if (unformat (input, "trace"))
7821         has_trace_option = 1;
7822       else if (unformat (input, "pot"))
7823         has_pot_option = 1;
7824       else if (unformat (input, "seqno"))
7825         has_seqno_option = 1;
7826       else if (unformat (input, "analyse"))
7827         has_analyse_option = 1;
7828       else
7829         break;
7830     }
7831   M (IOAM_ENABLE, ioam_enable);
7832   mp->id = htons (id);
7833   mp->seqno = has_seqno_option;
7834   mp->analyse = has_analyse_option;
7835   mp->pot_enable = has_pot_option;
7836   mp->trace_enable = has_trace_option;
7837
7838   S;
7839   W;
7840
7841   return (0);
7842
7843 }
7844
7845
7846 static int
7847 api_ioam_disable (vat_main_t * vam)
7848 {
7849   vl_api_ioam_disable_t *mp;
7850   f64 timeout;
7851
7852   M (IOAM_DISABLE, ioam_disable);
7853   S;
7854   W;
7855   return 0;
7856 }
7857
7858 static int
7859 api_sr_tunnel_add_del (vat_main_t * vam)
7860 {
7861   unformat_input_t *i = vam->input;
7862   vl_api_sr_tunnel_add_del_t *mp;
7863   f64 timeout;
7864   int is_del = 0;
7865   int pl_index;
7866   ip6_address_t src_address;
7867   int src_address_set = 0;
7868   ip6_address_t dst_address;
7869   u32 dst_mask_width;
7870   int dst_address_set = 0;
7871   u16 flags = 0;
7872   u32 rx_table_id = 0;
7873   u32 tx_table_id = 0;
7874   ip6_address_t *segments = 0;
7875   ip6_address_t *this_seg;
7876   ip6_address_t *tags = 0;
7877   ip6_address_t *this_tag;
7878   ip6_address_t next_address, tag;
7879   u8 *name = 0;
7880   u8 *policy_name = 0;
7881
7882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7883     {
7884       if (unformat (i, "del"))
7885         is_del = 1;
7886       else if (unformat (i, "name %s", &name))
7887         ;
7888       else if (unformat (i, "policy %s", &policy_name))
7889         ;
7890       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7891         ;
7892       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7893         ;
7894       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7895         src_address_set = 1;
7896       else if (unformat (i, "dst %U/%d",
7897                          unformat_ip6_address, &dst_address, &dst_mask_width))
7898         dst_address_set = 1;
7899       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7900         {
7901           vec_add2 (segments, this_seg, 1);
7902           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7903                        sizeof (*this_seg));
7904         }
7905       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7906         {
7907           vec_add2 (tags, this_tag, 1);
7908           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7909         }
7910       else if (unformat (i, "clean"))
7911         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7912       else if (unformat (i, "protected"))
7913         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7914       else if (unformat (i, "InPE %d", &pl_index))
7915         {
7916           if (pl_index <= 0 || pl_index > 4)
7917             {
7918             pl_index_range_error:
7919               errmsg ("pl index %d out of range\n", pl_index);
7920               return -99;
7921             }
7922           flags |=
7923             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7924         }
7925       else if (unformat (i, "EgPE %d", &pl_index))
7926         {
7927           if (pl_index <= 0 || pl_index > 4)
7928             goto pl_index_range_error;
7929           flags |=
7930             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7931         }
7932       else if (unformat (i, "OrgSrc %d", &pl_index))
7933         {
7934           if (pl_index <= 0 || pl_index > 4)
7935             goto pl_index_range_error;
7936           flags |=
7937             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7938         }
7939       else
7940         break;
7941     }
7942
7943   if (!src_address_set)
7944     {
7945       errmsg ("src address required\n");
7946       return -99;
7947     }
7948
7949   if (!dst_address_set)
7950     {
7951       errmsg ("dst address required\n");
7952       return -99;
7953     }
7954
7955   if (!segments)
7956     {
7957       errmsg ("at least one sr segment required\n");
7958       return -99;
7959     }
7960
7961   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7962       vec_len (segments) * sizeof (ip6_address_t)
7963       + vec_len (tags) * sizeof (ip6_address_t));
7964
7965   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7966   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7967   mp->dst_mask_width = dst_mask_width;
7968   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7969   mp->n_segments = vec_len (segments);
7970   mp->n_tags = vec_len (tags);
7971   mp->is_add = is_del == 0;
7972   clib_memcpy (mp->segs_and_tags, segments,
7973                vec_len (segments) * sizeof (ip6_address_t));
7974   clib_memcpy (mp->segs_and_tags +
7975                vec_len (segments) * sizeof (ip6_address_t), tags,
7976                vec_len (tags) * sizeof (ip6_address_t));
7977
7978   mp->outer_vrf_id = ntohl (rx_table_id);
7979   mp->inner_vrf_id = ntohl (tx_table_id);
7980   memcpy (mp->name, name, vec_len (name));
7981   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7982
7983   vec_free (segments);
7984   vec_free (tags);
7985
7986   S;
7987   W;
7988   /* NOTREACHED */
7989 }
7990
7991 static int
7992 api_sr_policy_add_del (vat_main_t * vam)
7993 {
7994   unformat_input_t *input = vam->input;
7995   vl_api_sr_policy_add_del_t *mp;
7996   f64 timeout;
7997   int is_del = 0;
7998   u8 *name = 0;
7999   u8 *tunnel_name = 0;
8000   u8 **tunnel_names = 0;
8001
8002   int name_set = 0;
8003   int tunnel_set = 0;
8004   int j = 0;
8005   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8006   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8007
8008   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8009     {
8010       if (unformat (input, "del"))
8011         is_del = 1;
8012       else if (unformat (input, "name %s", &name))
8013         name_set = 1;
8014       else if (unformat (input, "tunnel %s", &tunnel_name))
8015         {
8016           if (tunnel_name)
8017             {
8018               vec_add1 (tunnel_names, tunnel_name);
8019               /* For serializer:
8020                  - length = #bytes to store in serial vector
8021                  - +1 = byte to store that length
8022                */
8023               tunnel_names_length += (vec_len (tunnel_name) + 1);
8024               tunnel_set = 1;
8025               tunnel_name = 0;
8026             }
8027         }
8028       else
8029         break;
8030     }
8031
8032   if (!name_set)
8033     {
8034       errmsg ("policy name required\n");
8035       return -99;
8036     }
8037
8038   if ((!tunnel_set) && (!is_del))
8039     {
8040       errmsg ("tunnel name required\n");
8041       return -99;
8042     }
8043
8044   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8045
8046
8047
8048   mp->is_add = !is_del;
8049
8050   memcpy (mp->name, name, vec_len (name));
8051   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8052   u8 *serial_orig = 0;
8053   vec_validate (serial_orig, tunnel_names_length);
8054   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8055   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8056
8057   for (j = 0; j < vec_len (tunnel_names); j++)
8058     {
8059       tun_name_len = vec_len (tunnel_names[j]);
8060       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8061       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8062       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8063       serial_orig += tun_name_len;      // Advance past the copy
8064     }
8065   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8066
8067   vec_free (tunnel_names);
8068   vec_free (tunnel_name);
8069
8070   S;
8071   W;
8072   /* NOTREACHED */
8073 }
8074
8075 static int
8076 api_sr_multicast_map_add_del (vat_main_t * vam)
8077 {
8078   unformat_input_t *input = vam->input;
8079   vl_api_sr_multicast_map_add_del_t *mp;
8080   f64 timeout;
8081   int is_del = 0;
8082   ip6_address_t multicast_address;
8083   u8 *policy_name = 0;
8084   int multicast_address_set = 0;
8085
8086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8087     {
8088       if (unformat (input, "del"))
8089         is_del = 1;
8090       else
8091         if (unformat
8092             (input, "address %U", unformat_ip6_address, &multicast_address))
8093         multicast_address_set = 1;
8094       else if (unformat (input, "sr-policy %s", &policy_name))
8095         ;
8096       else
8097         break;
8098     }
8099
8100   if (!is_del && !policy_name)
8101     {
8102       errmsg ("sr-policy name required\n");
8103       return -99;
8104     }
8105
8106
8107   if (!multicast_address_set)
8108     {
8109       errmsg ("address required\n");
8110       return -99;
8111     }
8112
8113   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8114
8115   mp->is_add = !is_del;
8116   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8117   clib_memcpy (mp->multicast_address, &multicast_address,
8118                sizeof (mp->multicast_address));
8119
8120
8121   vec_free (policy_name);
8122
8123   S;
8124   W;
8125   /* NOTREACHED */
8126 }
8127
8128
8129 #define foreach_tcp_proto_field                 \
8130 _(src_port)                                     \
8131 _(dst_port)
8132
8133 #define foreach_udp_proto_field                 \
8134 _(src_port)                                     \
8135 _(dst_port)
8136
8137 #define foreach_ip4_proto_field                 \
8138 _(src_address)                                  \
8139 _(dst_address)                                  \
8140 _(tos)                                          \
8141 _(length)                                       \
8142 _(fragment_id)                                  \
8143 _(ttl)                                          \
8144 _(protocol)                                     \
8145 _(checksum)
8146
8147 uword
8148 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8149 {
8150   u8 **maskp = va_arg (*args, u8 **);
8151   u8 *mask = 0;
8152   u8 found_something = 0;
8153   tcp_header_t *tcp;
8154
8155 #define _(a) u8 a=0;
8156   foreach_tcp_proto_field;
8157 #undef _
8158
8159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8160     {
8161       if (0);
8162 #define _(a) else if (unformat (input, #a)) a=1;
8163       foreach_tcp_proto_field
8164 #undef _
8165         else
8166         break;
8167     }
8168
8169 #define _(a) found_something += a;
8170   foreach_tcp_proto_field;
8171 #undef _
8172
8173   if (found_something == 0)
8174     return 0;
8175
8176   vec_validate (mask, sizeof (*tcp) - 1);
8177
8178   tcp = (tcp_header_t *) mask;
8179
8180 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8181   foreach_tcp_proto_field;
8182 #undef _
8183
8184   *maskp = mask;
8185   return 1;
8186 }
8187
8188 uword
8189 unformat_udp_mask (unformat_input_t * input, va_list * args)
8190 {
8191   u8 **maskp = va_arg (*args, u8 **);
8192   u8 *mask = 0;
8193   u8 found_something = 0;
8194   udp_header_t *udp;
8195
8196 #define _(a) u8 a=0;
8197   foreach_udp_proto_field;
8198 #undef _
8199
8200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8201     {
8202       if (0);
8203 #define _(a) else if (unformat (input, #a)) a=1;
8204       foreach_udp_proto_field
8205 #undef _
8206         else
8207         break;
8208     }
8209
8210 #define _(a) found_something += a;
8211   foreach_udp_proto_field;
8212 #undef _
8213
8214   if (found_something == 0)
8215     return 0;
8216
8217   vec_validate (mask, sizeof (*udp) - 1);
8218
8219   udp = (udp_header_t *) mask;
8220
8221 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8222   foreach_udp_proto_field;
8223 #undef _
8224
8225   *maskp = mask;
8226   return 1;
8227 }
8228
8229 typedef struct
8230 {
8231   u16 src_port, dst_port;
8232 } tcpudp_header_t;
8233
8234 uword
8235 unformat_l4_mask (unformat_input_t * input, va_list * args)
8236 {
8237   u8 **maskp = va_arg (*args, u8 **);
8238   u16 src_port = 0, dst_port = 0;
8239   tcpudp_header_t *tcpudp;
8240
8241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8242     {
8243       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8244         return 1;
8245       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8246         return 1;
8247       else if (unformat (input, "src_port"))
8248         src_port = 0xFFFF;
8249       else if (unformat (input, "dst_port"))
8250         dst_port = 0xFFFF;
8251       else
8252         return 0;
8253     }
8254
8255   if (!src_port && !dst_port)
8256     return 0;
8257
8258   u8 *mask = 0;
8259   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8260
8261   tcpudp = (tcpudp_header_t *) mask;
8262   tcpudp->src_port = src_port;
8263   tcpudp->dst_port = dst_port;
8264
8265   *maskp = mask;
8266
8267   return 1;
8268 }
8269
8270 uword
8271 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8272 {
8273   u8 **maskp = va_arg (*args, u8 **);
8274   u8 *mask = 0;
8275   u8 found_something = 0;
8276   ip4_header_t *ip;
8277
8278 #define _(a) u8 a=0;
8279   foreach_ip4_proto_field;
8280 #undef _
8281   u8 version = 0;
8282   u8 hdr_length = 0;
8283
8284
8285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8286     {
8287       if (unformat (input, "version"))
8288         version = 1;
8289       else if (unformat (input, "hdr_length"))
8290         hdr_length = 1;
8291       else if (unformat (input, "src"))
8292         src_address = 1;
8293       else if (unformat (input, "dst"))
8294         dst_address = 1;
8295       else if (unformat (input, "proto"))
8296         protocol = 1;
8297
8298 #define _(a) else if (unformat (input, #a)) a=1;
8299       foreach_ip4_proto_field
8300 #undef _
8301         else
8302         break;
8303     }
8304
8305 #define _(a) found_something += a;
8306   foreach_ip4_proto_field;
8307 #undef _
8308
8309   if (found_something == 0)
8310     return 0;
8311
8312   vec_validate (mask, sizeof (*ip) - 1);
8313
8314   ip = (ip4_header_t *) mask;
8315
8316 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8317   foreach_ip4_proto_field;
8318 #undef _
8319
8320   ip->ip_version_and_header_length = 0;
8321
8322   if (version)
8323     ip->ip_version_and_header_length |= 0xF0;
8324
8325   if (hdr_length)
8326     ip->ip_version_and_header_length |= 0x0F;
8327
8328   *maskp = mask;
8329   return 1;
8330 }
8331
8332 #define foreach_ip6_proto_field                 \
8333 _(src_address)                                  \
8334 _(dst_address)                                  \
8335 _(payload_length)                               \
8336 _(hop_limit)                                    \
8337 _(protocol)
8338
8339 uword
8340 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8341 {
8342   u8 **maskp = va_arg (*args, u8 **);
8343   u8 *mask = 0;
8344   u8 found_something = 0;
8345   ip6_header_t *ip;
8346   u32 ip_version_traffic_class_and_flow_label;
8347
8348 #define _(a) u8 a=0;
8349   foreach_ip6_proto_field;
8350 #undef _
8351   u8 version = 0;
8352   u8 traffic_class = 0;
8353   u8 flow_label = 0;
8354
8355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8356     {
8357       if (unformat (input, "version"))
8358         version = 1;
8359       else if (unformat (input, "traffic-class"))
8360         traffic_class = 1;
8361       else if (unformat (input, "flow-label"))
8362         flow_label = 1;
8363       else if (unformat (input, "src"))
8364         src_address = 1;
8365       else if (unformat (input, "dst"))
8366         dst_address = 1;
8367       else if (unformat (input, "proto"))
8368         protocol = 1;
8369
8370 #define _(a) else if (unformat (input, #a)) a=1;
8371       foreach_ip6_proto_field
8372 #undef _
8373         else
8374         break;
8375     }
8376
8377 #define _(a) found_something += a;
8378   foreach_ip6_proto_field;
8379 #undef _
8380
8381   if (found_something == 0)
8382     return 0;
8383
8384   vec_validate (mask, sizeof (*ip) - 1);
8385
8386   ip = (ip6_header_t *) mask;
8387
8388 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8389   foreach_ip6_proto_field;
8390 #undef _
8391
8392   ip_version_traffic_class_and_flow_label = 0;
8393
8394   if (version)
8395     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8396
8397   if (traffic_class)
8398     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8399
8400   if (flow_label)
8401     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8402
8403   ip->ip_version_traffic_class_and_flow_label =
8404     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8405
8406   *maskp = mask;
8407   return 1;
8408 }
8409
8410 uword
8411 unformat_l3_mask (unformat_input_t * input, va_list * args)
8412 {
8413   u8 **maskp = va_arg (*args, u8 **);
8414
8415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8416     {
8417       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8418         return 1;
8419       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8420         return 1;
8421       else
8422         break;
8423     }
8424   return 0;
8425 }
8426
8427 uword
8428 unformat_l2_mask (unformat_input_t * input, va_list * args)
8429 {
8430   u8 **maskp = va_arg (*args, u8 **);
8431   u8 *mask = 0;
8432   u8 src = 0;
8433   u8 dst = 0;
8434   u8 proto = 0;
8435   u8 tag1 = 0;
8436   u8 tag2 = 0;
8437   u8 ignore_tag1 = 0;
8438   u8 ignore_tag2 = 0;
8439   u8 cos1 = 0;
8440   u8 cos2 = 0;
8441   u8 dot1q = 0;
8442   u8 dot1ad = 0;
8443   int len = 14;
8444
8445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8446     {
8447       if (unformat (input, "src"))
8448         src = 1;
8449       else if (unformat (input, "dst"))
8450         dst = 1;
8451       else if (unformat (input, "proto"))
8452         proto = 1;
8453       else if (unformat (input, "tag1"))
8454         tag1 = 1;
8455       else if (unformat (input, "tag2"))
8456         tag2 = 1;
8457       else if (unformat (input, "ignore-tag1"))
8458         ignore_tag1 = 1;
8459       else if (unformat (input, "ignore-tag2"))
8460         ignore_tag2 = 1;
8461       else if (unformat (input, "cos1"))
8462         cos1 = 1;
8463       else if (unformat (input, "cos2"))
8464         cos2 = 1;
8465       else if (unformat (input, "dot1q"))
8466         dot1q = 1;
8467       else if (unformat (input, "dot1ad"))
8468         dot1ad = 1;
8469       else
8470         break;
8471     }
8472   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8473        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8474     return 0;
8475
8476   if (tag1 || ignore_tag1 || cos1 || dot1q)
8477     len = 18;
8478   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8479     len = 22;
8480
8481   vec_validate (mask, len - 1);
8482
8483   if (dst)
8484     memset (mask, 0xff, 6);
8485
8486   if (src)
8487     memset (mask + 6, 0xff, 6);
8488
8489   if (tag2 || dot1ad)
8490     {
8491       /* inner vlan tag */
8492       if (tag2)
8493         {
8494           mask[19] = 0xff;
8495           mask[18] = 0x0f;
8496         }
8497       if (cos2)
8498         mask[18] |= 0xe0;
8499       if (proto)
8500         mask[21] = mask[20] = 0xff;
8501       if (tag1)
8502         {
8503           mask[15] = 0xff;
8504           mask[14] = 0x0f;
8505         }
8506       if (cos1)
8507         mask[14] |= 0xe0;
8508       *maskp = mask;
8509       return 1;
8510     }
8511   if (tag1 | dot1q)
8512     {
8513       if (tag1)
8514         {
8515           mask[15] = 0xff;
8516           mask[14] = 0x0f;
8517         }
8518       if (cos1)
8519         mask[14] |= 0xe0;
8520       if (proto)
8521         mask[16] = mask[17] = 0xff;
8522
8523       *maskp = mask;
8524       return 1;
8525     }
8526   if (cos2)
8527     mask[18] |= 0xe0;
8528   if (cos1)
8529     mask[14] |= 0xe0;
8530   if (proto)
8531     mask[12] = mask[13] = 0xff;
8532
8533   *maskp = mask;
8534   return 1;
8535 }
8536
8537 uword
8538 unformat_classify_mask (unformat_input_t * input, va_list * args)
8539 {
8540   u8 **maskp = va_arg (*args, u8 **);
8541   u32 *skipp = va_arg (*args, u32 *);
8542   u32 *matchp = va_arg (*args, u32 *);
8543   u32 match;
8544   u8 *mask = 0;
8545   u8 *l2 = 0;
8546   u8 *l3 = 0;
8547   u8 *l4 = 0;
8548   int i;
8549
8550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8551     {
8552       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8553         ;
8554       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8555         ;
8556       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8557         ;
8558       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8559         ;
8560       else
8561         break;
8562     }
8563
8564   if (l4 && !l3)
8565     {
8566       vec_free (mask);
8567       vec_free (l2);
8568       vec_free (l4);
8569       return 0;
8570     }
8571
8572   if (mask || l2 || l3 || l4)
8573     {
8574       if (l2 || l3 || l4)
8575         {
8576           /* "With a free Ethernet header in every package" */
8577           if (l2 == 0)
8578             vec_validate (l2, 13);
8579           mask = l2;
8580           if (vec_len (l3))
8581             {
8582               vec_append (mask, l3);
8583               vec_free (l3);
8584             }
8585           if (vec_len (l4))
8586             {
8587               vec_append (mask, l4);
8588               vec_free (l4);
8589             }
8590         }
8591
8592       /* Scan forward looking for the first significant mask octet */
8593       for (i = 0; i < vec_len (mask); i++)
8594         if (mask[i])
8595           break;
8596
8597       /* compute (skip, match) params */
8598       *skipp = i / sizeof (u32x4);
8599       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8600
8601       /* Pad mask to an even multiple of the vector size */
8602       while (vec_len (mask) % sizeof (u32x4))
8603         vec_add1 (mask, 0);
8604
8605       match = vec_len (mask) / sizeof (u32x4);
8606
8607       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8608         {
8609           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8610           if (*tmp || *(tmp + 1))
8611             break;
8612           match--;
8613         }
8614       if (match == 0)
8615         clib_warning ("BUG: match 0");
8616
8617       _vec_len (mask) = match * sizeof (u32x4);
8618
8619       *matchp = match;
8620       *maskp = mask;
8621
8622       return 1;
8623     }
8624
8625   return 0;
8626 }
8627
8628 #define foreach_l2_next                         \
8629 _(drop, DROP)                                   \
8630 _(ethernet, ETHERNET_INPUT)                     \
8631 _(ip4, IP4_INPUT)                               \
8632 _(ip6, IP6_INPUT)
8633
8634 uword
8635 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8636 {
8637   u32 *miss_next_indexp = va_arg (*args, u32 *);
8638   u32 next_index = 0;
8639   u32 tmp;
8640
8641 #define _(n,N) \
8642   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8643   foreach_l2_next;
8644 #undef _
8645
8646   if (unformat (input, "%d", &tmp))
8647     {
8648       next_index = tmp;
8649       goto out;
8650     }
8651
8652   return 0;
8653
8654 out:
8655   *miss_next_indexp = next_index;
8656   return 1;
8657 }
8658
8659 #define foreach_ip_next                         \
8660 _(drop, DROP)                                   \
8661 _(local, LOCAL)                                 \
8662 _(rewrite, REWRITE)
8663
8664 uword
8665 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8666 {
8667   u32 *miss_next_indexp = va_arg (*args, u32 *);
8668   u32 next_index = 0;
8669   u32 tmp;
8670
8671 #define _(n,N) \
8672   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8673   foreach_ip_next;
8674 #undef _
8675
8676   if (unformat (input, "%d", &tmp))
8677     {
8678       next_index = tmp;
8679       goto out;
8680     }
8681
8682   return 0;
8683
8684 out:
8685   *miss_next_indexp = next_index;
8686   return 1;
8687 }
8688
8689 #define foreach_acl_next                        \
8690 _(deny, DENY)
8691
8692 uword
8693 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8694 {
8695   u32 *miss_next_indexp = va_arg (*args, u32 *);
8696   u32 next_index = 0;
8697   u32 tmp;
8698
8699 #define _(n,N) \
8700   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8701   foreach_acl_next;
8702 #undef _
8703
8704   if (unformat (input, "permit"))
8705     {
8706       next_index = ~0;
8707       goto out;
8708     }
8709   else if (unformat (input, "%d", &tmp))
8710     {
8711       next_index = tmp;
8712       goto out;
8713     }
8714
8715   return 0;
8716
8717 out:
8718   *miss_next_indexp = next_index;
8719   return 1;
8720 }
8721
8722 uword
8723 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8724 {
8725   u32 *r = va_arg (*args, u32 *);
8726
8727   if (unformat (input, "conform-color"))
8728     *r = POLICE_CONFORM;
8729   else if (unformat (input, "exceed-color"))
8730     *r = POLICE_EXCEED;
8731   else
8732     return 0;
8733
8734   return 1;
8735 }
8736
8737 static int
8738 api_classify_add_del_table (vat_main_t * vam)
8739 {
8740   unformat_input_t *i = vam->input;
8741   vl_api_classify_add_del_table_t *mp;
8742
8743   u32 nbuckets = 2;
8744   u32 skip = ~0;
8745   u32 match = ~0;
8746   int is_add = 1;
8747   u32 table_index = ~0;
8748   u32 next_table_index = ~0;
8749   u32 miss_next_index = ~0;
8750   u32 memory_size = 32 << 20;
8751   u8 *mask = 0;
8752   f64 timeout;
8753
8754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8755     {
8756       if (unformat (i, "del"))
8757         is_add = 0;
8758       else if (unformat (i, "buckets %d", &nbuckets))
8759         ;
8760       else if (unformat (i, "memory_size %d", &memory_size))
8761         ;
8762       else if (unformat (i, "skip %d", &skip))
8763         ;
8764       else if (unformat (i, "match %d", &match))
8765         ;
8766       else if (unformat (i, "table %d", &table_index))
8767         ;
8768       else if (unformat (i, "mask %U", unformat_classify_mask,
8769                          &mask, &skip, &match))
8770         ;
8771       else if (unformat (i, "next-table %d", &next_table_index))
8772         ;
8773       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8774                          &miss_next_index))
8775         ;
8776       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8777                          &miss_next_index))
8778         ;
8779       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8780                          &miss_next_index))
8781         ;
8782       else
8783         break;
8784     }
8785
8786   if (is_add && mask == 0)
8787     {
8788       errmsg ("Mask required\n");
8789       return -99;
8790     }
8791
8792   if (is_add && skip == ~0)
8793     {
8794       errmsg ("skip count required\n");
8795       return -99;
8796     }
8797
8798   if (is_add && match == ~0)
8799     {
8800       errmsg ("match count required\n");
8801       return -99;
8802     }
8803
8804   if (!is_add && table_index == ~0)
8805     {
8806       errmsg ("table index required for delete\n");
8807       return -99;
8808     }
8809
8810   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8811
8812   mp->is_add = is_add;
8813   mp->table_index = ntohl (table_index);
8814   mp->nbuckets = ntohl (nbuckets);
8815   mp->memory_size = ntohl (memory_size);
8816   mp->skip_n_vectors = ntohl (skip);
8817   mp->match_n_vectors = ntohl (match);
8818   mp->next_table_index = ntohl (next_table_index);
8819   mp->miss_next_index = ntohl (miss_next_index);
8820   clib_memcpy (mp->mask, mask, vec_len (mask));
8821
8822   vec_free (mask);
8823
8824   S;
8825   W;
8826   /* NOTREACHED */
8827 }
8828
8829 uword
8830 unformat_l4_match (unformat_input_t * input, va_list * args)
8831 {
8832   u8 **matchp = va_arg (*args, u8 **);
8833
8834   u8 *proto_header = 0;
8835   int src_port = 0;
8836   int dst_port = 0;
8837
8838   tcpudp_header_t h;
8839
8840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8841     {
8842       if (unformat (input, "src_port %d", &src_port))
8843         ;
8844       else if (unformat (input, "dst_port %d", &dst_port))
8845         ;
8846       else
8847         return 0;
8848     }
8849
8850   h.src_port = clib_host_to_net_u16 (src_port);
8851   h.dst_port = clib_host_to_net_u16 (dst_port);
8852   vec_validate (proto_header, sizeof (h) - 1);
8853   memcpy (proto_header, &h, sizeof (h));
8854
8855   *matchp = proto_header;
8856
8857   return 1;
8858 }
8859
8860 uword
8861 unformat_ip4_match (unformat_input_t * input, va_list * args)
8862 {
8863   u8 **matchp = va_arg (*args, u8 **);
8864   u8 *match = 0;
8865   ip4_header_t *ip;
8866   int version = 0;
8867   u32 version_val;
8868   int hdr_length = 0;
8869   u32 hdr_length_val;
8870   int src = 0, dst = 0;
8871   ip4_address_t src_val, dst_val;
8872   int proto = 0;
8873   u32 proto_val;
8874   int tos = 0;
8875   u32 tos_val;
8876   int length = 0;
8877   u32 length_val;
8878   int fragment_id = 0;
8879   u32 fragment_id_val;
8880   int ttl = 0;
8881   int ttl_val;
8882   int checksum = 0;
8883   u32 checksum_val;
8884
8885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8886     {
8887       if (unformat (input, "version %d", &version_val))
8888         version = 1;
8889       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8890         hdr_length = 1;
8891       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8892         src = 1;
8893       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8894         dst = 1;
8895       else if (unformat (input, "proto %d", &proto_val))
8896         proto = 1;
8897       else if (unformat (input, "tos %d", &tos_val))
8898         tos = 1;
8899       else if (unformat (input, "length %d", &length_val))
8900         length = 1;
8901       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8902         fragment_id = 1;
8903       else if (unformat (input, "ttl %d", &ttl_val))
8904         ttl = 1;
8905       else if (unformat (input, "checksum %d", &checksum_val))
8906         checksum = 1;
8907       else
8908         break;
8909     }
8910
8911   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8912       + ttl + checksum == 0)
8913     return 0;
8914
8915   /*
8916    * Aligned because we use the real comparison functions
8917    */
8918   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8919
8920   ip = (ip4_header_t *) match;
8921
8922   /* These are realistically matched in practice */
8923   if (src)
8924     ip->src_address.as_u32 = src_val.as_u32;
8925
8926   if (dst)
8927     ip->dst_address.as_u32 = dst_val.as_u32;
8928
8929   if (proto)
8930     ip->protocol = proto_val;
8931
8932
8933   /* These are not, but they're included for completeness */
8934   if (version)
8935     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8936
8937   if (hdr_length)
8938     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8939
8940   if (tos)
8941     ip->tos = tos_val;
8942
8943   if (length)
8944     ip->length = clib_host_to_net_u16 (length_val);
8945
8946   if (ttl)
8947     ip->ttl = ttl_val;
8948
8949   if (checksum)
8950     ip->checksum = clib_host_to_net_u16 (checksum_val);
8951
8952   *matchp = match;
8953   return 1;
8954 }
8955
8956 uword
8957 unformat_ip6_match (unformat_input_t * input, va_list * args)
8958 {
8959   u8 **matchp = va_arg (*args, u8 **);
8960   u8 *match = 0;
8961   ip6_header_t *ip;
8962   int version = 0;
8963   u32 version_val;
8964   u8 traffic_class = 0;
8965   u32 traffic_class_val = 0;
8966   u8 flow_label = 0;
8967   u8 flow_label_val;
8968   int src = 0, dst = 0;
8969   ip6_address_t src_val, dst_val;
8970   int proto = 0;
8971   u32 proto_val;
8972   int payload_length = 0;
8973   u32 payload_length_val;
8974   int hop_limit = 0;
8975   int hop_limit_val;
8976   u32 ip_version_traffic_class_and_flow_label;
8977
8978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8979     {
8980       if (unformat (input, "version %d", &version_val))
8981         version = 1;
8982       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8983         traffic_class = 1;
8984       else if (unformat (input, "flow_label %d", &flow_label_val))
8985         flow_label = 1;
8986       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8987         src = 1;
8988       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8989         dst = 1;
8990       else if (unformat (input, "proto %d", &proto_val))
8991         proto = 1;
8992       else if (unformat (input, "payload_length %d", &payload_length_val))
8993         payload_length = 1;
8994       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8995         hop_limit = 1;
8996       else
8997         break;
8998     }
8999
9000   if (version + traffic_class + flow_label + src + dst + proto +
9001       payload_length + hop_limit == 0)
9002     return 0;
9003
9004   /*
9005    * Aligned because we use the real comparison functions
9006    */
9007   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9008
9009   ip = (ip6_header_t *) match;
9010
9011   if (src)
9012     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9013
9014   if (dst)
9015     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9016
9017   if (proto)
9018     ip->protocol = proto_val;
9019
9020   ip_version_traffic_class_and_flow_label = 0;
9021
9022   if (version)
9023     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9024
9025   if (traffic_class)
9026     ip_version_traffic_class_and_flow_label |=
9027       (traffic_class_val & 0xFF) << 20;
9028
9029   if (flow_label)
9030     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9031
9032   ip->ip_version_traffic_class_and_flow_label =
9033     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9034
9035   if (payload_length)
9036     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9037
9038   if (hop_limit)
9039     ip->hop_limit = hop_limit_val;
9040
9041   *matchp = match;
9042   return 1;
9043 }
9044
9045 uword
9046 unformat_l3_match (unformat_input_t * input, va_list * args)
9047 {
9048   u8 **matchp = va_arg (*args, u8 **);
9049
9050   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9051     {
9052       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9053         return 1;
9054       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9055         return 1;
9056       else
9057         break;
9058     }
9059   return 0;
9060 }
9061
9062 uword
9063 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9064 {
9065   u8 *tagp = va_arg (*args, u8 *);
9066   u32 tag;
9067
9068   if (unformat (input, "%d", &tag))
9069     {
9070       tagp[0] = (tag >> 8) & 0x0F;
9071       tagp[1] = tag & 0xFF;
9072       return 1;
9073     }
9074
9075   return 0;
9076 }
9077
9078 uword
9079 unformat_l2_match (unformat_input_t * input, va_list * args)
9080 {
9081   u8 **matchp = va_arg (*args, u8 **);
9082   u8 *match = 0;
9083   u8 src = 0;
9084   u8 src_val[6];
9085   u8 dst = 0;
9086   u8 dst_val[6];
9087   u8 proto = 0;
9088   u16 proto_val;
9089   u8 tag1 = 0;
9090   u8 tag1_val[2];
9091   u8 tag2 = 0;
9092   u8 tag2_val[2];
9093   int len = 14;
9094   u8 ignore_tag1 = 0;
9095   u8 ignore_tag2 = 0;
9096   u8 cos1 = 0;
9097   u8 cos2 = 0;
9098   u32 cos1_val = 0;
9099   u32 cos2_val = 0;
9100
9101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9102     {
9103       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9104         src = 1;
9105       else
9106         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9107         dst = 1;
9108       else if (unformat (input, "proto %U",
9109                          unformat_ethernet_type_host_byte_order, &proto_val))
9110         proto = 1;
9111       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9112         tag1 = 1;
9113       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9114         tag2 = 1;
9115       else if (unformat (input, "ignore-tag1"))
9116         ignore_tag1 = 1;
9117       else if (unformat (input, "ignore-tag2"))
9118         ignore_tag2 = 1;
9119       else if (unformat (input, "cos1 %d", &cos1_val))
9120         cos1 = 1;
9121       else if (unformat (input, "cos2 %d", &cos2_val))
9122         cos2 = 1;
9123       else
9124         break;
9125     }
9126   if ((src + dst + proto + tag1 + tag2 +
9127        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9128     return 0;
9129
9130   if (tag1 || ignore_tag1 || cos1)
9131     len = 18;
9132   if (tag2 || ignore_tag2 || cos2)
9133     len = 22;
9134
9135   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9136
9137   if (dst)
9138     clib_memcpy (match, dst_val, 6);
9139
9140   if (src)
9141     clib_memcpy (match + 6, src_val, 6);
9142
9143   if (tag2)
9144     {
9145       /* inner vlan tag */
9146       match[19] = tag2_val[1];
9147       match[18] = tag2_val[0];
9148       if (cos2)
9149         match[18] |= (cos2_val & 0x7) << 5;
9150       if (proto)
9151         {
9152           match[21] = proto_val & 0xff;
9153           match[20] = proto_val >> 8;
9154         }
9155       if (tag1)
9156         {
9157           match[15] = tag1_val[1];
9158           match[14] = tag1_val[0];
9159         }
9160       if (cos1)
9161         match[14] |= (cos1_val & 0x7) << 5;
9162       *matchp = match;
9163       return 1;
9164     }
9165   if (tag1)
9166     {
9167       match[15] = tag1_val[1];
9168       match[14] = tag1_val[0];
9169       if (proto)
9170         {
9171           match[17] = proto_val & 0xff;
9172           match[16] = proto_val >> 8;
9173         }
9174       if (cos1)
9175         match[14] |= (cos1_val & 0x7) << 5;
9176
9177       *matchp = match;
9178       return 1;
9179     }
9180   if (cos2)
9181     match[18] |= (cos2_val & 0x7) << 5;
9182   if (cos1)
9183     match[14] |= (cos1_val & 0x7) << 5;
9184   if (proto)
9185     {
9186       match[13] = proto_val & 0xff;
9187       match[12] = proto_val >> 8;
9188     }
9189
9190   *matchp = match;
9191   return 1;
9192 }
9193
9194
9195 uword
9196 unformat_classify_match (unformat_input_t * input, va_list * args)
9197 {
9198   u8 **matchp = va_arg (*args, u8 **);
9199   u32 skip_n_vectors = va_arg (*args, u32);
9200   u32 match_n_vectors = va_arg (*args, u32);
9201
9202   u8 *match = 0;
9203   u8 *l2 = 0;
9204   u8 *l3 = 0;
9205   u8 *l4 = 0;
9206
9207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9208     {
9209       if (unformat (input, "hex %U", unformat_hex_string, &match))
9210         ;
9211       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9212         ;
9213       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9214         ;
9215       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9216         ;
9217       else
9218         break;
9219     }
9220
9221   if (l4 && !l3)
9222     {
9223       vec_free (match);
9224       vec_free (l2);
9225       vec_free (l4);
9226       return 0;
9227     }
9228
9229   if (match || l2 || l3 || l4)
9230     {
9231       if (l2 || l3 || l4)
9232         {
9233           /* "Win a free Ethernet header in every packet" */
9234           if (l2 == 0)
9235             vec_validate_aligned (l2, 13, sizeof (u32x4));
9236           match = l2;
9237           if (vec_len (l3))
9238             {
9239               vec_append_aligned (match, l3, sizeof (u32x4));
9240               vec_free (l3);
9241             }
9242           if (vec_len (l4))
9243             {
9244               vec_append_aligned (match, l4, sizeof (u32x4));
9245               vec_free (l4);
9246             }
9247         }
9248
9249       /* Make sure the vector is big enough even if key is all 0's */
9250       vec_validate_aligned
9251         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9252          sizeof (u32x4));
9253
9254       /* Set size, include skipped vectors */
9255       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9256
9257       *matchp = match;
9258
9259       return 1;
9260     }
9261
9262   return 0;
9263 }
9264
9265 static int
9266 api_classify_add_del_session (vat_main_t * vam)
9267 {
9268   unformat_input_t *i = vam->input;
9269   vl_api_classify_add_del_session_t *mp;
9270   int is_add = 1;
9271   u32 table_index = ~0;
9272   u32 hit_next_index = ~0;
9273   u32 opaque_index = ~0;
9274   u8 *match = 0;
9275   i32 advance = 0;
9276   f64 timeout;
9277   u32 skip_n_vectors = 0;
9278   u32 match_n_vectors = 0;
9279
9280   /*
9281    * Warning: you have to supply skip_n and match_n
9282    * because the API client cant simply look at the classify
9283    * table object.
9284    */
9285
9286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9287     {
9288       if (unformat (i, "del"))
9289         is_add = 0;
9290       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9291                          &hit_next_index))
9292         ;
9293       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9294                          &hit_next_index))
9295         ;
9296       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9297                          &hit_next_index))
9298         ;
9299       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9300         ;
9301       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9302         ;
9303       else if (unformat (i, "opaque-index %d", &opaque_index))
9304         ;
9305       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9306         ;
9307       else if (unformat (i, "match_n %d", &match_n_vectors))
9308         ;
9309       else if (unformat (i, "match %U", unformat_classify_match,
9310                          &match, skip_n_vectors, match_n_vectors))
9311         ;
9312       else if (unformat (i, "advance %d", &advance))
9313         ;
9314       else if (unformat (i, "table-index %d", &table_index))
9315         ;
9316       else
9317         break;
9318     }
9319
9320   if (table_index == ~0)
9321     {
9322       errmsg ("Table index required\n");
9323       return -99;
9324     }
9325
9326   if (is_add && match == 0)
9327     {
9328       errmsg ("Match value required\n");
9329       return -99;
9330     }
9331
9332   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9333
9334   mp->is_add = is_add;
9335   mp->table_index = ntohl (table_index);
9336   mp->hit_next_index = ntohl (hit_next_index);
9337   mp->opaque_index = ntohl (opaque_index);
9338   mp->advance = ntohl (advance);
9339   clib_memcpy (mp->match, match, vec_len (match));
9340   vec_free (match);
9341
9342   S;
9343   W;
9344   /* NOTREACHED */
9345 }
9346
9347 static int
9348 api_classify_set_interface_ip_table (vat_main_t * vam)
9349 {
9350   unformat_input_t *i = vam->input;
9351   vl_api_classify_set_interface_ip_table_t *mp;
9352   f64 timeout;
9353   u32 sw_if_index;
9354   int sw_if_index_set;
9355   u32 table_index = ~0;
9356   u8 is_ipv6 = 0;
9357
9358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9359     {
9360       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9361         sw_if_index_set = 1;
9362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9363         sw_if_index_set = 1;
9364       else if (unformat (i, "table %d", &table_index))
9365         ;
9366       else
9367         {
9368           clib_warning ("parse error '%U'", format_unformat_error, i);
9369           return -99;
9370         }
9371     }
9372
9373   if (sw_if_index_set == 0)
9374     {
9375       errmsg ("missing interface name or sw_if_index\n");
9376       return -99;
9377     }
9378
9379
9380   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9381
9382   mp->sw_if_index = ntohl (sw_if_index);
9383   mp->table_index = ntohl (table_index);
9384   mp->is_ipv6 = is_ipv6;
9385
9386   S;
9387   W;
9388   /* NOTREACHED */
9389   return 0;
9390 }
9391
9392 static int
9393 api_classify_set_interface_l2_tables (vat_main_t * vam)
9394 {
9395   unformat_input_t *i = vam->input;
9396   vl_api_classify_set_interface_l2_tables_t *mp;
9397   f64 timeout;
9398   u32 sw_if_index;
9399   int sw_if_index_set;
9400   u32 ip4_table_index = ~0;
9401   u32 ip6_table_index = ~0;
9402   u32 other_table_index = ~0;
9403   u32 is_input = 1;
9404
9405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9406     {
9407       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9408         sw_if_index_set = 1;
9409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9410         sw_if_index_set = 1;
9411       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9412         ;
9413       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9414         ;
9415       else if (unformat (i, "other-table %d", &other_table_index))
9416         ;
9417       else if (unformat (i, "is-input %d", &is_input))
9418         ;
9419       else
9420         {
9421           clib_warning ("parse error '%U'", format_unformat_error, i);
9422           return -99;
9423         }
9424     }
9425
9426   if (sw_if_index_set == 0)
9427     {
9428       errmsg ("missing interface name or sw_if_index\n");
9429       return -99;
9430     }
9431
9432
9433   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9434
9435   mp->sw_if_index = ntohl (sw_if_index);
9436   mp->ip4_table_index = ntohl (ip4_table_index);
9437   mp->ip6_table_index = ntohl (ip6_table_index);
9438   mp->other_table_index = ntohl (other_table_index);
9439   mp->is_input = (u8) is_input;
9440
9441   S;
9442   W;
9443   /* NOTREACHED */
9444   return 0;
9445 }
9446
9447 static int
9448 api_set_ipfix_exporter (vat_main_t * vam)
9449 {
9450   unformat_input_t *i = vam->input;
9451   vl_api_set_ipfix_exporter_t *mp;
9452   ip4_address_t collector_address;
9453   u8 collector_address_set = 0;
9454   u32 collector_port = ~0;
9455   ip4_address_t src_address;
9456   u8 src_address_set = 0;
9457   u32 vrf_id = ~0;
9458   u32 path_mtu = ~0;
9459   u32 template_interval = ~0;
9460   u8 udp_checksum = 0;
9461   f64 timeout;
9462
9463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9464     {
9465       if (unformat (i, "collector_address %U", unformat_ip4_address,
9466                     &collector_address))
9467         collector_address_set = 1;
9468       else if (unformat (i, "collector_port %d", &collector_port))
9469         ;
9470       else if (unformat (i, "src_address %U", unformat_ip4_address,
9471                          &src_address))
9472         src_address_set = 1;
9473       else if (unformat (i, "vrf_id %d", &vrf_id))
9474         ;
9475       else if (unformat (i, "path_mtu %d", &path_mtu))
9476         ;
9477       else if (unformat (i, "template_interval %d", &template_interval))
9478         ;
9479       else if (unformat (i, "udp_checksum"))
9480         udp_checksum = 1;
9481       else
9482         break;
9483     }
9484
9485   if (collector_address_set == 0)
9486     {
9487       errmsg ("collector_address required\n");
9488       return -99;
9489     }
9490
9491   if (src_address_set == 0)
9492     {
9493       errmsg ("src_address required\n");
9494       return -99;
9495     }
9496
9497   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9498
9499   memcpy (mp->collector_address, collector_address.data,
9500           sizeof (collector_address.data));
9501   mp->collector_port = htons ((u16) collector_port);
9502   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9503   mp->vrf_id = htonl (vrf_id);
9504   mp->path_mtu = htonl (path_mtu);
9505   mp->template_interval = htonl (template_interval);
9506   mp->udp_checksum = udp_checksum;
9507
9508   S;
9509   W;
9510   /* NOTREACHED */
9511 }
9512
9513 static int
9514 api_set_ipfix_classify_stream (vat_main_t * vam)
9515 {
9516   unformat_input_t *i = vam->input;
9517   vl_api_set_ipfix_classify_stream_t *mp;
9518   u32 domain_id = 0;
9519   u32 src_port = UDP_DST_PORT_ipfix;
9520   f64 timeout;
9521
9522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9523     {
9524       if (unformat (i, "domain %d", &domain_id))
9525         ;
9526       else if (unformat (i, "src_port %d", &src_port))
9527         ;
9528       else
9529         {
9530           errmsg ("unknown input `%U'", format_unformat_error, i);
9531           return -99;
9532         }
9533     }
9534
9535   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9536
9537   mp->domain_id = htonl (domain_id);
9538   mp->src_port = htons ((u16) src_port);
9539
9540   S;
9541   W;
9542   /* NOTREACHED */
9543 }
9544
9545 static int
9546 api_ipfix_classify_table_add_del (vat_main_t * vam)
9547 {
9548   unformat_input_t *i = vam->input;
9549   vl_api_ipfix_classify_table_add_del_t *mp;
9550   int is_add = -1;
9551   u32 classify_table_index = ~0;
9552   u8 ip_version = 0;
9553   u8 transport_protocol = 255;
9554   f64 timeout;
9555
9556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9557     {
9558       if (unformat (i, "add"))
9559         is_add = 1;
9560       else if (unformat (i, "del"))
9561         is_add = 0;
9562       else if (unformat (i, "table %d", &classify_table_index))
9563         ;
9564       else if (unformat (i, "ip4"))
9565         ip_version = 4;
9566       else if (unformat (i, "ip6"))
9567         ip_version = 6;
9568       else if (unformat (i, "tcp"))
9569         transport_protocol = 6;
9570       else if (unformat (i, "udp"))
9571         transport_protocol = 17;
9572       else
9573         {
9574           errmsg ("unknown input `%U'", format_unformat_error, i);
9575           return -99;
9576         }
9577     }
9578
9579   if (is_add == -1)
9580     {
9581       errmsg ("expecting: add|del");
9582       return -99;
9583     }
9584   if (classify_table_index == ~0)
9585     {
9586       errmsg ("classifier table not specified");
9587       return -99;
9588     }
9589   if (ip_version == 0)
9590     {
9591       errmsg ("IP version not specified");
9592       return -99;
9593     }
9594
9595   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9596
9597   mp->is_add = is_add;
9598   mp->table_id = htonl (classify_table_index);
9599   mp->ip_version = ip_version;
9600   mp->transport_protocol = transport_protocol;
9601
9602   S;
9603   W;
9604   /* NOTREACHED */
9605 }
9606
9607 static int
9608 api_get_node_index (vat_main_t * vam)
9609 {
9610   unformat_input_t *i = vam->input;
9611   vl_api_get_node_index_t *mp;
9612   f64 timeout;
9613   u8 *name = 0;
9614
9615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9616     {
9617       if (unformat (i, "node %s", &name))
9618         ;
9619       else
9620         break;
9621     }
9622   if (name == 0)
9623     {
9624       errmsg ("node name required\n");
9625       return -99;
9626     }
9627   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9628     {
9629       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9630       return -99;
9631     }
9632
9633   M (GET_NODE_INDEX, get_node_index);
9634   clib_memcpy (mp->node_name, name, vec_len (name));
9635   vec_free (name);
9636
9637   S;
9638   W;
9639   /* NOTREACHED */
9640   return 0;
9641 }
9642
9643 static int
9644 api_get_next_index (vat_main_t * vam)
9645 {
9646   unformat_input_t *i = vam->input;
9647   vl_api_get_next_index_t *mp;
9648   f64 timeout;
9649   u8 *node_name = 0, *next_node_name = 0;
9650
9651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9652     {
9653       if (unformat (i, "node-name %s", &node_name))
9654         ;
9655       else if (unformat (i, "next-node-name %s", &next_node_name))
9656         break;
9657     }
9658
9659   if (node_name == 0)
9660     {
9661       errmsg ("node name required\n");
9662       return -99;
9663     }
9664   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9665     {
9666       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9667       return -99;
9668     }
9669
9670   if (next_node_name == 0)
9671     {
9672       errmsg ("next node name required\n");
9673       return -99;
9674     }
9675   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9676     {
9677       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9678       return -99;
9679     }
9680
9681   M (GET_NEXT_INDEX, get_next_index);
9682   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9683   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9684   vec_free (node_name);
9685   vec_free (next_node_name);
9686
9687   S;
9688   W;
9689   /* NOTREACHED */
9690   return 0;
9691 }
9692
9693 static int
9694 api_add_node_next (vat_main_t * vam)
9695 {
9696   unformat_input_t *i = vam->input;
9697   vl_api_add_node_next_t *mp;
9698   f64 timeout;
9699   u8 *name = 0;
9700   u8 *next = 0;
9701
9702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9703     {
9704       if (unformat (i, "node %s", &name))
9705         ;
9706       else if (unformat (i, "next %s", &next))
9707         ;
9708       else
9709         break;
9710     }
9711   if (name == 0)
9712     {
9713       errmsg ("node name required\n");
9714       return -99;
9715     }
9716   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9717     {
9718       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9719       return -99;
9720     }
9721   if (next == 0)
9722     {
9723       errmsg ("next node required\n");
9724       return -99;
9725     }
9726   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9727     {
9728       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9729       return -99;
9730     }
9731
9732   M (ADD_NODE_NEXT, add_node_next);
9733   clib_memcpy (mp->node_name, name, vec_len (name));
9734   clib_memcpy (mp->next_name, next, vec_len (next));
9735   vec_free (name);
9736   vec_free (next);
9737
9738   S;
9739   W;
9740   /* NOTREACHED */
9741   return 0;
9742 }
9743
9744 static int
9745 api_l2tpv3_create_tunnel (vat_main_t * vam)
9746 {
9747   unformat_input_t *i = vam->input;
9748   ip6_address_t client_address, our_address;
9749   int client_address_set = 0;
9750   int our_address_set = 0;
9751   u32 local_session_id = 0;
9752   u32 remote_session_id = 0;
9753   u64 local_cookie = 0;
9754   u64 remote_cookie = 0;
9755   u8 l2_sublayer_present = 0;
9756   vl_api_l2tpv3_create_tunnel_t *mp;
9757   f64 timeout;
9758
9759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9760     {
9761       if (unformat (i, "client_address %U", unformat_ip6_address,
9762                     &client_address))
9763         client_address_set = 1;
9764       else if (unformat (i, "our_address %U", unformat_ip6_address,
9765                          &our_address))
9766         our_address_set = 1;
9767       else if (unformat (i, "local_session_id %d", &local_session_id))
9768         ;
9769       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9770         ;
9771       else if (unformat (i, "local_cookie %lld", &local_cookie))
9772         ;
9773       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9774         ;
9775       else if (unformat (i, "l2-sublayer-present"))
9776         l2_sublayer_present = 1;
9777       else
9778         break;
9779     }
9780
9781   if (client_address_set == 0)
9782     {
9783       errmsg ("client_address required\n");
9784       return -99;
9785     }
9786
9787   if (our_address_set == 0)
9788     {
9789       errmsg ("our_address required\n");
9790       return -99;
9791     }
9792
9793   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9794
9795   clib_memcpy (mp->client_address, client_address.as_u8,
9796                sizeof (mp->client_address));
9797
9798   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9799
9800   mp->local_session_id = ntohl (local_session_id);
9801   mp->remote_session_id = ntohl (remote_session_id);
9802   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9803   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9804   mp->l2_sublayer_present = l2_sublayer_present;
9805   mp->is_ipv6 = 1;
9806
9807   S;
9808   W;
9809   /* NOTREACHED */
9810   return 0;
9811 }
9812
9813 static int
9814 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9815 {
9816   unformat_input_t *i = vam->input;
9817   u32 sw_if_index;
9818   u8 sw_if_index_set = 0;
9819   u64 new_local_cookie = 0;
9820   u64 new_remote_cookie = 0;
9821   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9822   f64 timeout;
9823
9824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9825     {
9826       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9827         sw_if_index_set = 1;
9828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9829         sw_if_index_set = 1;
9830       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9831         ;
9832       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9833         ;
9834       else
9835         break;
9836     }
9837
9838   if (sw_if_index_set == 0)
9839     {
9840       errmsg ("missing interface name or sw_if_index\n");
9841       return -99;
9842     }
9843
9844   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9845
9846   mp->sw_if_index = ntohl (sw_if_index);
9847   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9848   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9849
9850   S;
9851   W;
9852   /* NOTREACHED */
9853   return 0;
9854 }
9855
9856 static int
9857 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9858 {
9859   unformat_input_t *i = vam->input;
9860   vl_api_l2tpv3_interface_enable_disable_t *mp;
9861   f64 timeout;
9862   u32 sw_if_index;
9863   u8 sw_if_index_set = 0;
9864   u8 enable_disable = 1;
9865
9866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9867     {
9868       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9869         sw_if_index_set = 1;
9870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9871         sw_if_index_set = 1;
9872       else if (unformat (i, "enable"))
9873         enable_disable = 1;
9874       else if (unformat (i, "disable"))
9875         enable_disable = 0;
9876       else
9877         break;
9878     }
9879
9880   if (sw_if_index_set == 0)
9881     {
9882       errmsg ("missing interface name or sw_if_index\n");
9883       return -99;
9884     }
9885
9886   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9887
9888   mp->sw_if_index = ntohl (sw_if_index);
9889   mp->enable_disable = enable_disable;
9890
9891   S;
9892   W;
9893   /* NOTREACHED */
9894   return 0;
9895 }
9896
9897 static int
9898 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9899 {
9900   unformat_input_t *i = vam->input;
9901   vl_api_l2tpv3_set_lookup_key_t *mp;
9902   f64 timeout;
9903   u8 key = ~0;
9904
9905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9906     {
9907       if (unformat (i, "lookup_v6_src"))
9908         key = L2T_LOOKUP_SRC_ADDRESS;
9909       else if (unformat (i, "lookup_v6_dst"))
9910         key = L2T_LOOKUP_DST_ADDRESS;
9911       else if (unformat (i, "lookup_session_id"))
9912         key = L2T_LOOKUP_SESSION_ID;
9913       else
9914         break;
9915     }
9916
9917   if (key == (u8) ~ 0)
9918     {
9919       errmsg ("l2tp session lookup key unset\n");
9920       return -99;
9921     }
9922
9923   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9924
9925   mp->key = key;
9926
9927   S;
9928   W;
9929   /* NOTREACHED */
9930   return 0;
9931 }
9932
9933 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9934   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9935 {
9936   vat_main_t *vam = &vat_main;
9937
9938   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9939            format_ip6_address, mp->our_address,
9940            format_ip6_address, mp->client_address,
9941            clib_net_to_host_u32 (mp->sw_if_index));
9942
9943   fformat (vam->ofp,
9944            "   local cookies %016llx %016llx remote cookie %016llx\n",
9945            clib_net_to_host_u64 (mp->local_cookie[0]),
9946            clib_net_to_host_u64 (mp->local_cookie[1]),
9947            clib_net_to_host_u64 (mp->remote_cookie));
9948
9949   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9950            clib_net_to_host_u32 (mp->local_session_id),
9951            clib_net_to_host_u32 (mp->remote_session_id));
9952
9953   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9954            mp->l2_sublayer_present ? "preset" : "absent");
9955
9956 }
9957
9958 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9959   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9960 {
9961   vat_main_t *vam = &vat_main;
9962   vat_json_node_t *node = NULL;
9963   struct in6_addr addr;
9964
9965   if (VAT_JSON_ARRAY != vam->json_tree.type)
9966     {
9967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9968       vat_json_init_array (&vam->json_tree);
9969     }
9970   node = vat_json_array_add (&vam->json_tree);
9971
9972   vat_json_init_object (node);
9973
9974   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9975   vat_json_object_add_ip6 (node, "our_address", addr);
9976   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9977   vat_json_object_add_ip6 (node, "client_address", addr);
9978
9979   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9980   vat_json_init_array (lc);
9981   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9982   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9983   vat_json_object_add_uint (node, "remote_cookie",
9984                             clib_net_to_host_u64 (mp->remote_cookie));
9985
9986   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9987   vat_json_object_add_uint (node, "local_session_id",
9988                             clib_net_to_host_u32 (mp->local_session_id));
9989   vat_json_object_add_uint (node, "remote_session_id",
9990                             clib_net_to_host_u32 (mp->remote_session_id));
9991   vat_json_object_add_string_copy (node, "l2_sublayer",
9992                                    mp->l2_sublayer_present ? (u8 *) "present"
9993                                    : (u8 *) "absent");
9994 }
9995
9996 static int
9997 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9998 {
9999   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10000   f64 timeout;
10001
10002   /* Get list of l2tpv3-tunnel interfaces */
10003   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10004   S;
10005
10006   /* Use a control ping for synchronization */
10007   {
10008     vl_api_control_ping_t *mp;
10009     M (CONTROL_PING, control_ping);
10010     S;
10011   }
10012   W;
10013 }
10014
10015
10016 static void vl_api_sw_interface_tap_details_t_handler
10017   (vl_api_sw_interface_tap_details_t * mp)
10018 {
10019   vat_main_t *vam = &vat_main;
10020
10021   fformat (vam->ofp, "%-16s %d\n",
10022            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10023 }
10024
10025 static void vl_api_sw_interface_tap_details_t_handler_json
10026   (vl_api_sw_interface_tap_details_t * mp)
10027 {
10028   vat_main_t *vam = &vat_main;
10029   vat_json_node_t *node = NULL;
10030
10031   if (VAT_JSON_ARRAY != vam->json_tree.type)
10032     {
10033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10034       vat_json_init_array (&vam->json_tree);
10035     }
10036   node = vat_json_array_add (&vam->json_tree);
10037
10038   vat_json_init_object (node);
10039   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10040   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10041 }
10042
10043 static int
10044 api_sw_interface_tap_dump (vat_main_t * vam)
10045 {
10046   vl_api_sw_interface_tap_dump_t *mp;
10047   f64 timeout;
10048
10049   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10050   /* Get list of tap interfaces */
10051   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10052   S;
10053
10054   /* Use a control ping for synchronization */
10055   {
10056     vl_api_control_ping_t *mp;
10057     M (CONTROL_PING, control_ping);
10058     S;
10059   }
10060   W;
10061 }
10062
10063 static uword unformat_vxlan_decap_next
10064   (unformat_input_t * input, va_list * args)
10065 {
10066   u32 *result = va_arg (*args, u32 *);
10067   u32 tmp;
10068
10069   if (unformat (input, "l2"))
10070     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10071   else if (unformat (input, "%d", &tmp))
10072     *result = tmp;
10073   else
10074     return 0;
10075   return 1;
10076 }
10077
10078 static int
10079 api_vxlan_add_del_tunnel (vat_main_t * vam)
10080 {
10081   unformat_input_t *line_input = vam->input;
10082   vl_api_vxlan_add_del_tunnel_t *mp;
10083   f64 timeout;
10084   ip4_address_t src4, dst4;
10085   ip6_address_t src6, dst6;
10086   u8 is_add = 1;
10087   u8 ipv4_set = 0, ipv6_set = 0;
10088   u8 src_set = 0;
10089   u8 dst_set = 0;
10090   u32 encap_vrf_id = 0;
10091   u32 decap_next_index = ~0;
10092   u32 vni = 0;
10093
10094   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10095     {
10096       if (unformat (line_input, "del"))
10097         is_add = 0;
10098       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10099         {
10100           ipv4_set = 1;
10101           src_set = 1;
10102         }
10103       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10104         {
10105           ipv4_set = 1;
10106           dst_set = 1;
10107         }
10108       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10109         {
10110           ipv6_set = 1;
10111           src_set = 1;
10112         }
10113       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10114         {
10115           ipv6_set = 1;
10116           dst_set = 1;
10117         }
10118       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10119         ;
10120       else if (unformat (line_input, "decap-next %U",
10121                          unformat_vxlan_decap_next, &decap_next_index))
10122         ;
10123       else if (unformat (line_input, "vni %d", &vni))
10124         ;
10125       else
10126         {
10127           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10128           return -99;
10129         }
10130     }
10131
10132   if (src_set == 0)
10133     {
10134       errmsg ("tunnel src address not specified\n");
10135       return -99;
10136     }
10137   if (dst_set == 0)
10138     {
10139       errmsg ("tunnel dst address not specified\n");
10140       return -99;
10141     }
10142
10143   if (ipv4_set && ipv6_set)
10144     {
10145       errmsg ("both IPv4 and IPv6 addresses specified");
10146       return -99;
10147     }
10148
10149   if ((vni == 0) || (vni >> 24))
10150     {
10151       errmsg ("vni not specified or out of range\n");
10152       return -99;
10153     }
10154
10155   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10156
10157   if (ipv6_set)
10158     {
10159       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10160       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10161     }
10162   else
10163     {
10164       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10165       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10166     }
10167   mp->encap_vrf_id = ntohl (encap_vrf_id);
10168   mp->decap_next_index = ntohl (decap_next_index);
10169   mp->vni = ntohl (vni);
10170   mp->is_add = is_add;
10171   mp->is_ipv6 = ipv6_set;
10172
10173   S;
10174   W;
10175   /* NOTREACHED */
10176   return 0;
10177 }
10178
10179 static void vl_api_vxlan_tunnel_details_t_handler
10180   (vl_api_vxlan_tunnel_details_t * mp)
10181 {
10182   vat_main_t *vam = &vat_main;
10183
10184   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10185            ntohl (mp->sw_if_index),
10186            format_ip46_address, &(mp->src_address[0]),
10187            IP46_TYPE_ANY,
10188            format_ip46_address, &(mp->dst_address[0]),
10189            IP46_TYPE_ANY,
10190            ntohl (mp->encap_vrf_id),
10191            ntohl (mp->decap_next_index), ntohl (mp->vni));
10192 }
10193
10194 static void vl_api_vxlan_tunnel_details_t_handler_json
10195   (vl_api_vxlan_tunnel_details_t * mp)
10196 {
10197   vat_main_t *vam = &vat_main;
10198   vat_json_node_t *node = NULL;
10199   struct in_addr ip4;
10200   struct in6_addr ip6;
10201
10202   if (VAT_JSON_ARRAY != vam->json_tree.type)
10203     {
10204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10205       vat_json_init_array (&vam->json_tree);
10206     }
10207   node = vat_json_array_add (&vam->json_tree);
10208
10209   vat_json_init_object (node);
10210   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10211   if (mp->is_ipv6)
10212     {
10213       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10214       vat_json_object_add_ip6 (node, "src_address", ip6);
10215       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10216       vat_json_object_add_ip6 (node, "dst_address", ip6);
10217     }
10218   else
10219     {
10220       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10221       vat_json_object_add_ip4 (node, "src_address", ip4);
10222       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10223       vat_json_object_add_ip4 (node, "dst_address", ip4);
10224     }
10225   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10226   vat_json_object_add_uint (node, "decap_next_index",
10227                             ntohl (mp->decap_next_index));
10228   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10229   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10230 }
10231
10232 static int
10233 api_vxlan_tunnel_dump (vat_main_t * vam)
10234 {
10235   unformat_input_t *i = vam->input;
10236   vl_api_vxlan_tunnel_dump_t *mp;
10237   f64 timeout;
10238   u32 sw_if_index;
10239   u8 sw_if_index_set = 0;
10240
10241   /* Parse args required to build the message */
10242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10243     {
10244       if (unformat (i, "sw_if_index %d", &sw_if_index))
10245         sw_if_index_set = 1;
10246       else
10247         break;
10248     }
10249
10250   if (sw_if_index_set == 0)
10251     {
10252       sw_if_index = ~0;
10253     }
10254
10255   if (!vam->json_output)
10256     {
10257       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10258                "sw_if_index", "src_address", "dst_address",
10259                "encap_vrf_id", "decap_next_index", "vni");
10260     }
10261
10262   /* Get list of vxlan-tunnel interfaces */
10263   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10264
10265   mp->sw_if_index = htonl (sw_if_index);
10266
10267   S;
10268
10269   /* Use a control ping for synchronization */
10270   {
10271     vl_api_control_ping_t *mp;
10272     M (CONTROL_PING, control_ping);
10273     S;
10274   }
10275   W;
10276 }
10277
10278 static int
10279 api_gre_add_del_tunnel (vat_main_t * vam)
10280 {
10281   unformat_input_t *line_input = vam->input;
10282   vl_api_gre_add_del_tunnel_t *mp;
10283   f64 timeout;
10284   ip4_address_t src4, dst4;
10285   u8 is_add = 1;
10286   u8 teb = 0;
10287   u8 src_set = 0;
10288   u8 dst_set = 0;
10289   u32 outer_fib_id = 0;
10290
10291   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10292     {
10293       if (unformat (line_input, "del"))
10294         is_add = 0;
10295       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10296         src_set = 1;
10297       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10298         dst_set = 1;
10299       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10300         ;
10301       else if (unformat (line_input, "teb"))
10302         teb = 1;
10303       else
10304         {
10305           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10306           return -99;
10307         }
10308     }
10309
10310   if (src_set == 0)
10311     {
10312       errmsg ("tunnel src address not specified\n");
10313       return -99;
10314     }
10315   if (dst_set == 0)
10316     {
10317       errmsg ("tunnel dst address not specified\n");
10318       return -99;
10319     }
10320
10321
10322   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10323
10324   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10325   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10326   mp->outer_fib_id = ntohl (outer_fib_id);
10327   mp->is_add = is_add;
10328   mp->teb = teb;
10329
10330   S;
10331   W;
10332   /* NOTREACHED */
10333   return 0;
10334 }
10335
10336 static void vl_api_gre_tunnel_details_t_handler
10337   (vl_api_gre_tunnel_details_t * mp)
10338 {
10339   vat_main_t *vam = &vat_main;
10340
10341   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10342            ntohl (mp->sw_if_index),
10343            format_ip4_address, &mp->src_address,
10344            format_ip4_address, &mp->dst_address,
10345            mp->teb, ntohl (mp->outer_fib_id));
10346 }
10347
10348 static void vl_api_gre_tunnel_details_t_handler_json
10349   (vl_api_gre_tunnel_details_t * mp)
10350 {
10351   vat_main_t *vam = &vat_main;
10352   vat_json_node_t *node = NULL;
10353   struct in_addr ip4;
10354
10355   if (VAT_JSON_ARRAY != vam->json_tree.type)
10356     {
10357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10358       vat_json_init_array (&vam->json_tree);
10359     }
10360   node = vat_json_array_add (&vam->json_tree);
10361
10362   vat_json_init_object (node);
10363   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10364   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10365   vat_json_object_add_ip4 (node, "src_address", ip4);
10366   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10367   vat_json_object_add_ip4 (node, "dst_address", ip4);
10368   vat_json_object_add_uint (node, "teb", mp->teb);
10369   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10370 }
10371
10372 static int
10373 api_gre_tunnel_dump (vat_main_t * vam)
10374 {
10375   unformat_input_t *i = vam->input;
10376   vl_api_gre_tunnel_dump_t *mp;
10377   f64 timeout;
10378   u32 sw_if_index;
10379   u8 sw_if_index_set = 0;
10380
10381   /* Parse args required to build the message */
10382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10383     {
10384       if (unformat (i, "sw_if_index %d", &sw_if_index))
10385         sw_if_index_set = 1;
10386       else
10387         break;
10388     }
10389
10390   if (sw_if_index_set == 0)
10391     {
10392       sw_if_index = ~0;
10393     }
10394
10395   if (!vam->json_output)
10396     {
10397       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10398                "sw_if_index", "src_address", "dst_address", "teb",
10399                "outer_fib_id");
10400     }
10401
10402   /* Get list of gre-tunnel interfaces */
10403   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10404
10405   mp->sw_if_index = htonl (sw_if_index);
10406
10407   S;
10408
10409   /* Use a control ping for synchronization */
10410   {
10411     vl_api_control_ping_t *mp;
10412     M (CONTROL_PING, control_ping);
10413     S;
10414   }
10415   W;
10416 }
10417
10418 static int
10419 api_l2_fib_clear_table (vat_main_t * vam)
10420 {
10421 //  unformat_input_t * i = vam->input;
10422   vl_api_l2_fib_clear_table_t *mp;
10423   f64 timeout;
10424
10425   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10426
10427   S;
10428   W;
10429   /* NOTREACHED */
10430   return 0;
10431 }
10432
10433 static int
10434 api_l2_interface_efp_filter (vat_main_t * vam)
10435 {
10436   unformat_input_t *i = vam->input;
10437   vl_api_l2_interface_efp_filter_t *mp;
10438   f64 timeout;
10439   u32 sw_if_index;
10440   u8 enable = 1;
10441   u8 sw_if_index_set = 0;
10442
10443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10444     {
10445       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10446         sw_if_index_set = 1;
10447       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10448         sw_if_index_set = 1;
10449       else if (unformat (i, "enable"))
10450         enable = 1;
10451       else if (unformat (i, "disable"))
10452         enable = 0;
10453       else
10454         {
10455           clib_warning ("parse error '%U'", format_unformat_error, i);
10456           return -99;
10457         }
10458     }
10459
10460   if (sw_if_index_set == 0)
10461     {
10462       errmsg ("missing sw_if_index\n");
10463       return -99;
10464     }
10465
10466   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10467
10468   mp->sw_if_index = ntohl (sw_if_index);
10469   mp->enable_disable = enable;
10470
10471   S;
10472   W;
10473   /* NOTREACHED */
10474   return 0;
10475 }
10476
10477 #define foreach_vtr_op                          \
10478 _("disable",  L2_VTR_DISABLED)                  \
10479 _("push-1",  L2_VTR_PUSH_1)                     \
10480 _("push-2",  L2_VTR_PUSH_2)                     \
10481 _("pop-1",  L2_VTR_POP_1)                       \
10482 _("pop-2",  L2_VTR_POP_2)                       \
10483 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10484 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10485 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10486 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10487
10488 static int
10489 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10490 {
10491   unformat_input_t *i = vam->input;
10492   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10493   f64 timeout;
10494   u32 sw_if_index;
10495   u8 sw_if_index_set = 0;
10496   u8 vtr_op_set = 0;
10497   u32 vtr_op = 0;
10498   u32 push_dot1q = 1;
10499   u32 tag1 = ~0;
10500   u32 tag2 = ~0;
10501
10502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10503     {
10504       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10505         sw_if_index_set = 1;
10506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10507         sw_if_index_set = 1;
10508       else if (unformat (i, "vtr_op %d", &vtr_op))
10509         vtr_op_set = 1;
10510 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10511       foreach_vtr_op
10512 #undef _
10513         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10514         ;
10515       else if (unformat (i, "tag1 %d", &tag1))
10516         ;
10517       else if (unformat (i, "tag2 %d", &tag2))
10518         ;
10519       else
10520         {
10521           clib_warning ("parse error '%U'", format_unformat_error, i);
10522           return -99;
10523         }
10524     }
10525
10526   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10527     {
10528       errmsg ("missing vtr operation or sw_if_index\n");
10529       return -99;
10530     }
10531
10532   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10533     mp->sw_if_index = ntohl (sw_if_index);
10534   mp->vtr_op = ntohl (vtr_op);
10535   mp->push_dot1q = ntohl (push_dot1q);
10536   mp->tag1 = ntohl (tag1);
10537   mp->tag2 = ntohl (tag2);
10538
10539   S;
10540   W;
10541   /* NOTREACHED */
10542   return 0;
10543 }
10544
10545 static int
10546 api_create_vhost_user_if (vat_main_t * vam)
10547 {
10548   unformat_input_t *i = vam->input;
10549   vl_api_create_vhost_user_if_t *mp;
10550   f64 timeout;
10551   u8 *file_name;
10552   u8 is_server = 0;
10553   u8 file_name_set = 0;
10554   u32 custom_dev_instance = ~0;
10555   u8 hwaddr[6];
10556   u8 use_custom_mac = 0;
10557
10558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10559     {
10560       if (unformat (i, "socket %s", &file_name))
10561         {
10562           file_name_set = 1;
10563         }
10564       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10565         ;
10566       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10567         use_custom_mac = 1;
10568       else if (unformat (i, "server"))
10569         is_server = 1;
10570       else
10571         break;
10572     }
10573
10574   if (file_name_set == 0)
10575     {
10576       errmsg ("missing socket file name\n");
10577       return -99;
10578     }
10579
10580   if (vec_len (file_name) > 255)
10581     {
10582       errmsg ("socket file name too long\n");
10583       return -99;
10584     }
10585   vec_add1 (file_name, 0);
10586
10587   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10588
10589   mp->is_server = is_server;
10590   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10591   vec_free (file_name);
10592   if (custom_dev_instance != ~0)
10593     {
10594       mp->renumber = 1;
10595       mp->custom_dev_instance = ntohl (custom_dev_instance);
10596     }
10597   mp->use_custom_mac = use_custom_mac;
10598   clib_memcpy (mp->mac_address, hwaddr, 6);
10599
10600   S;
10601   W;
10602   /* NOTREACHED */
10603   return 0;
10604 }
10605
10606 static int
10607 api_modify_vhost_user_if (vat_main_t * vam)
10608 {
10609   unformat_input_t *i = vam->input;
10610   vl_api_modify_vhost_user_if_t *mp;
10611   f64 timeout;
10612   u8 *file_name;
10613   u8 is_server = 0;
10614   u8 file_name_set = 0;
10615   u32 custom_dev_instance = ~0;
10616   u8 sw_if_index_set = 0;
10617   u32 sw_if_index = (u32) ~ 0;
10618
10619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10620     {
10621       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10622         sw_if_index_set = 1;
10623       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10624         sw_if_index_set = 1;
10625       else if (unformat (i, "socket %s", &file_name))
10626         {
10627           file_name_set = 1;
10628         }
10629       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10630         ;
10631       else if (unformat (i, "server"))
10632         is_server = 1;
10633       else
10634         break;
10635     }
10636
10637   if (sw_if_index_set == 0)
10638     {
10639       errmsg ("missing sw_if_index or interface name\n");
10640       return -99;
10641     }
10642
10643   if (file_name_set == 0)
10644     {
10645       errmsg ("missing socket file name\n");
10646       return -99;
10647     }
10648
10649   if (vec_len (file_name) > 255)
10650     {
10651       errmsg ("socket file name too long\n");
10652       return -99;
10653     }
10654   vec_add1 (file_name, 0);
10655
10656   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10657
10658   mp->sw_if_index = ntohl (sw_if_index);
10659   mp->is_server = is_server;
10660   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10661   vec_free (file_name);
10662   if (custom_dev_instance != ~0)
10663     {
10664       mp->renumber = 1;
10665       mp->custom_dev_instance = ntohl (custom_dev_instance);
10666     }
10667
10668   S;
10669   W;
10670   /* NOTREACHED */
10671   return 0;
10672 }
10673
10674 static int
10675 api_delete_vhost_user_if (vat_main_t * vam)
10676 {
10677   unformat_input_t *i = vam->input;
10678   vl_api_delete_vhost_user_if_t *mp;
10679   f64 timeout;
10680   u32 sw_if_index = ~0;
10681   u8 sw_if_index_set = 0;
10682
10683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10684     {
10685       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10686         sw_if_index_set = 1;
10687       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10688         sw_if_index_set = 1;
10689       else
10690         break;
10691     }
10692
10693   if (sw_if_index_set == 0)
10694     {
10695       errmsg ("missing sw_if_index or interface name\n");
10696       return -99;
10697     }
10698
10699
10700   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10701
10702   mp->sw_if_index = ntohl (sw_if_index);
10703
10704   S;
10705   W;
10706   /* NOTREACHED */
10707   return 0;
10708 }
10709
10710 static void vl_api_sw_interface_vhost_user_details_t_handler
10711   (vl_api_sw_interface_vhost_user_details_t * mp)
10712 {
10713   vat_main_t *vam = &vat_main;
10714
10715   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10716            (char *) mp->interface_name,
10717            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10718            clib_net_to_host_u64 (mp->features), mp->is_server,
10719            ntohl (mp->num_regions), (char *) mp->sock_filename);
10720   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10721 }
10722
10723 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10724   (vl_api_sw_interface_vhost_user_details_t * mp)
10725 {
10726   vat_main_t *vam = &vat_main;
10727   vat_json_node_t *node = NULL;
10728
10729   if (VAT_JSON_ARRAY != vam->json_tree.type)
10730     {
10731       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10732       vat_json_init_array (&vam->json_tree);
10733     }
10734   node = vat_json_array_add (&vam->json_tree);
10735
10736   vat_json_init_object (node);
10737   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10738   vat_json_object_add_string_copy (node, "interface_name",
10739                                    mp->interface_name);
10740   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10741                             ntohl (mp->virtio_net_hdr_sz));
10742   vat_json_object_add_uint (node, "features",
10743                             clib_net_to_host_u64 (mp->features));
10744   vat_json_object_add_uint (node, "is_server", mp->is_server);
10745   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10746   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10747   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10748 }
10749
10750 static int
10751 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10752 {
10753   vl_api_sw_interface_vhost_user_dump_t *mp;
10754   f64 timeout;
10755   fformat (vam->ofp,
10756            "Interface name           idx hdr_sz features server regions filename\n");
10757
10758   /* Get list of vhost-user interfaces */
10759   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10760   S;
10761
10762   /* Use a control ping for synchronization */
10763   {
10764     vl_api_control_ping_t *mp;
10765     M (CONTROL_PING, control_ping);
10766     S;
10767   }
10768   W;
10769 }
10770
10771 static int
10772 api_show_version (vat_main_t * vam)
10773 {
10774   vl_api_show_version_t *mp;
10775   f64 timeout;
10776
10777   M (SHOW_VERSION, show_version);
10778
10779   S;
10780   W;
10781   /* NOTREACHED */
10782   return 0;
10783 }
10784
10785
10786 static int
10787 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10788 {
10789   unformat_input_t *line_input = vam->input;
10790   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10791   f64 timeout;
10792   ip4_address_t local4, remote4;
10793   ip6_address_t local6, remote6;
10794   u8 is_add = 1;
10795   u8 ipv4_set = 0, ipv6_set = 0;
10796   u8 local_set = 0;
10797   u8 remote_set = 0;
10798   u32 encap_vrf_id = 0;
10799   u32 decap_vrf_id = 0;
10800   u8 protocol = ~0;
10801   u32 vni;
10802   u8 vni_set = 0;
10803
10804   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10805     {
10806       if (unformat (line_input, "del"))
10807         is_add = 0;
10808       else if (unformat (line_input, "local %U",
10809                          unformat_ip4_address, &local4))
10810         {
10811           local_set = 1;
10812           ipv4_set = 1;
10813         }
10814       else if (unformat (line_input, "remote %U",
10815                          unformat_ip4_address, &remote4))
10816         {
10817           remote_set = 1;
10818           ipv4_set = 1;
10819         }
10820       else if (unformat (line_input, "local %U",
10821                          unformat_ip6_address, &local6))
10822         {
10823           local_set = 1;
10824           ipv6_set = 1;
10825         }
10826       else if (unformat (line_input, "remote %U",
10827                          unformat_ip6_address, &remote6))
10828         {
10829           remote_set = 1;
10830           ipv6_set = 1;
10831         }
10832       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10833         ;
10834       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10835         ;
10836       else if (unformat (line_input, "vni %d", &vni))
10837         vni_set = 1;
10838       else if (unformat (line_input, "next-ip4"))
10839         protocol = 1;
10840       else if (unformat (line_input, "next-ip6"))
10841         protocol = 2;
10842       else if (unformat (line_input, "next-ethernet"))
10843         protocol = 3;
10844       else if (unformat (line_input, "next-nsh"))
10845         protocol = 4;
10846       else
10847         {
10848           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10849           return -99;
10850         }
10851     }
10852
10853   if (local_set == 0)
10854     {
10855       errmsg ("tunnel local address not specified\n");
10856       return -99;
10857     }
10858   if (remote_set == 0)
10859     {
10860       errmsg ("tunnel remote address not specified\n");
10861       return -99;
10862     }
10863   if (ipv4_set && ipv6_set)
10864     {
10865       errmsg ("both IPv4 and IPv6 addresses specified");
10866       return -99;
10867     }
10868
10869   if (vni_set == 0)
10870     {
10871       errmsg ("vni not specified\n");
10872       return -99;
10873     }
10874
10875   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10876
10877
10878   if (ipv6_set)
10879     {
10880       clib_memcpy (&mp->local, &local6, sizeof (local6));
10881       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10882     }
10883   else
10884     {
10885       clib_memcpy (&mp->local, &local4, sizeof (local4));
10886       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10887     }
10888
10889   mp->encap_vrf_id = ntohl (encap_vrf_id);
10890   mp->decap_vrf_id = ntohl (decap_vrf_id);
10891   mp->protocol = ntohl (protocol);
10892   mp->vni = ntohl (vni);
10893   mp->is_add = is_add;
10894   mp->is_ipv6 = ipv6_set;
10895
10896   S;
10897   W;
10898   /* NOTREACHED */
10899   return 0;
10900 }
10901
10902 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10903   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10904 {
10905   vat_main_t *vam = &vat_main;
10906
10907   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10908            ntohl (mp->sw_if_index),
10909            format_ip46_address, &(mp->local[0]),
10910            format_ip46_address, &(mp->remote[0]),
10911            ntohl (mp->vni),
10912            ntohl (mp->protocol),
10913            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10914 }
10915
10916 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10917   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10918 {
10919   vat_main_t *vam = &vat_main;
10920   vat_json_node_t *node = NULL;
10921   struct in_addr ip4;
10922   struct in6_addr ip6;
10923
10924   if (VAT_JSON_ARRAY != vam->json_tree.type)
10925     {
10926       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10927       vat_json_init_array (&vam->json_tree);
10928     }
10929   node = vat_json_array_add (&vam->json_tree);
10930
10931   vat_json_init_object (node);
10932   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10933   if (mp->is_ipv6)
10934     {
10935       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10936       vat_json_object_add_ip6 (node, "local", ip6);
10937       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10938       vat_json_object_add_ip6 (node, "remote", ip6);
10939     }
10940   else
10941     {
10942       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10943       vat_json_object_add_ip4 (node, "local", ip4);
10944       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10945       vat_json_object_add_ip4 (node, "remote", ip4);
10946     }
10947   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10948   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10949   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10950   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10951   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10952 }
10953
10954 static int
10955 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10956 {
10957   unformat_input_t *i = vam->input;
10958   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10959   f64 timeout;
10960   u32 sw_if_index;
10961   u8 sw_if_index_set = 0;
10962
10963   /* Parse args required to build the message */
10964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10965     {
10966       if (unformat (i, "sw_if_index %d", &sw_if_index))
10967         sw_if_index_set = 1;
10968       else
10969         break;
10970     }
10971
10972   if (sw_if_index_set == 0)
10973     {
10974       sw_if_index = ~0;
10975     }
10976
10977   if (!vam->json_output)
10978     {
10979       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10980                "sw_if_index", "local", "remote", "vni",
10981                "protocol", "encap_vrf_id", "decap_vrf_id");
10982     }
10983
10984   /* Get list of vxlan-tunnel interfaces */
10985   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10986
10987   mp->sw_if_index = htonl (sw_if_index);
10988
10989   S;
10990
10991   /* Use a control ping for synchronization */
10992   {
10993     vl_api_control_ping_t *mp;
10994     M (CONTROL_PING, control_ping);
10995     S;
10996   }
10997   W;
10998 }
10999
11000 u8 *
11001 format_l2_fib_mac_address (u8 * s, va_list * args)
11002 {
11003   u8 *a = va_arg (*args, u8 *);
11004
11005   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11006                  a[2], a[3], a[4], a[5], a[6], a[7]);
11007 }
11008
11009 static void vl_api_l2_fib_table_entry_t_handler
11010   (vl_api_l2_fib_table_entry_t * mp)
11011 {
11012   vat_main_t *vam = &vat_main;
11013
11014   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11015            "       %d       %d     %d\n",
11016            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11017            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11018            mp->bvi_mac);
11019 }
11020
11021 static void vl_api_l2_fib_table_entry_t_handler_json
11022   (vl_api_l2_fib_table_entry_t * mp)
11023 {
11024   vat_main_t *vam = &vat_main;
11025   vat_json_node_t *node = NULL;
11026
11027   if (VAT_JSON_ARRAY != vam->json_tree.type)
11028     {
11029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11030       vat_json_init_array (&vam->json_tree);
11031     }
11032   node = vat_json_array_add (&vam->json_tree);
11033
11034   vat_json_init_object (node);
11035   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11036   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11037   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11038   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11039   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11040   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11041 }
11042
11043 static int
11044 api_l2_fib_table_dump (vat_main_t * vam)
11045 {
11046   unformat_input_t *i = vam->input;
11047   vl_api_l2_fib_table_dump_t *mp;
11048   f64 timeout;
11049   u32 bd_id;
11050   u8 bd_id_set = 0;
11051
11052   /* Parse args required to build the message */
11053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11054     {
11055       if (unformat (i, "bd_id %d", &bd_id))
11056         bd_id_set = 1;
11057       else
11058         break;
11059     }
11060
11061   if (bd_id_set == 0)
11062     {
11063       errmsg ("missing bridge domain\n");
11064       return -99;
11065     }
11066
11067   fformat (vam->ofp,
11068            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11069
11070   /* Get list of l2 fib entries */
11071   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11072
11073   mp->bd_id = ntohl (bd_id);
11074   S;
11075
11076   /* Use a control ping for synchronization */
11077   {
11078     vl_api_control_ping_t *mp;
11079     M (CONTROL_PING, control_ping);
11080     S;
11081   }
11082   W;
11083 }
11084
11085
11086 static int
11087 api_interface_name_renumber (vat_main_t * vam)
11088 {
11089   unformat_input_t *line_input = vam->input;
11090   vl_api_interface_name_renumber_t *mp;
11091   u32 sw_if_index = ~0;
11092   f64 timeout;
11093   u32 new_show_dev_instance = ~0;
11094
11095   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11096     {
11097       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11098                     &sw_if_index))
11099         ;
11100       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11101         ;
11102       else if (unformat (line_input, "new_show_dev_instance %d",
11103                          &new_show_dev_instance))
11104         ;
11105       else
11106         break;
11107     }
11108
11109   if (sw_if_index == ~0)
11110     {
11111       errmsg ("missing interface name or sw_if_index\n");
11112       return -99;
11113     }
11114
11115   if (new_show_dev_instance == ~0)
11116     {
11117       errmsg ("missing new_show_dev_instance\n");
11118       return -99;
11119     }
11120
11121   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11122
11123   mp->sw_if_index = ntohl (sw_if_index);
11124   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11125
11126   S;
11127   W;
11128 }
11129
11130 static int
11131 api_want_ip4_arp_events (vat_main_t * vam)
11132 {
11133   unformat_input_t *line_input = vam->input;
11134   vl_api_want_ip4_arp_events_t *mp;
11135   f64 timeout;
11136   ip4_address_t address;
11137   int address_set = 0;
11138   u32 enable_disable = 1;
11139
11140   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11141     {
11142       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11143         address_set = 1;
11144       else if (unformat (line_input, "del"))
11145         enable_disable = 0;
11146       else
11147         break;
11148     }
11149
11150   if (address_set == 0)
11151     {
11152       errmsg ("missing addresses\n");
11153       return -99;
11154     }
11155
11156   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11157   mp->enable_disable = enable_disable;
11158   mp->pid = getpid ();
11159   mp->address = address.as_u32;
11160
11161   S;
11162   W;
11163 }
11164
11165 static int
11166 api_want_ip6_nd_events (vat_main_t * vam)
11167 {
11168   unformat_input_t *line_input = vam->input;
11169   vl_api_want_ip6_nd_events_t *mp;
11170   f64 timeout;
11171   ip6_address_t address;
11172   int address_set = 0;
11173   u32 enable_disable = 1;
11174
11175   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11176     {
11177       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11178         address_set = 1;
11179       else if (unformat (line_input, "del"))
11180         enable_disable = 0;
11181       else
11182         break;
11183     }
11184
11185   if (address_set == 0)
11186     {
11187       errmsg ("missing addresses\n");
11188       return -99;
11189     }
11190
11191   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11192   mp->enable_disable = enable_disable;
11193   mp->pid = getpid ();
11194   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11195
11196   S;
11197   W;
11198 }
11199
11200 static int
11201 api_input_acl_set_interface (vat_main_t * vam)
11202 {
11203   unformat_input_t *i = vam->input;
11204   vl_api_input_acl_set_interface_t *mp;
11205   f64 timeout;
11206   u32 sw_if_index;
11207   int sw_if_index_set;
11208   u32 ip4_table_index = ~0;
11209   u32 ip6_table_index = ~0;
11210   u32 l2_table_index = ~0;
11211   u8 is_add = 1;
11212
11213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11214     {
11215       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11216         sw_if_index_set = 1;
11217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11218         sw_if_index_set = 1;
11219       else if (unformat (i, "del"))
11220         is_add = 0;
11221       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11222         ;
11223       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11224         ;
11225       else if (unformat (i, "l2-table %d", &l2_table_index))
11226         ;
11227       else
11228         {
11229           clib_warning ("parse error '%U'", format_unformat_error, i);
11230           return -99;
11231         }
11232     }
11233
11234   if (sw_if_index_set == 0)
11235     {
11236       errmsg ("missing interface name or sw_if_index\n");
11237       return -99;
11238     }
11239
11240   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11241
11242   mp->sw_if_index = ntohl (sw_if_index);
11243   mp->ip4_table_index = ntohl (ip4_table_index);
11244   mp->ip6_table_index = ntohl (ip6_table_index);
11245   mp->l2_table_index = ntohl (l2_table_index);
11246   mp->is_add = is_add;
11247
11248   S;
11249   W;
11250   /* NOTREACHED */
11251   return 0;
11252 }
11253
11254 static int
11255 api_ip_address_dump (vat_main_t * vam)
11256 {
11257   unformat_input_t *i = vam->input;
11258   vl_api_ip_address_dump_t *mp;
11259   u32 sw_if_index = ~0;
11260   u8 sw_if_index_set = 0;
11261   u8 ipv4_set = 0;
11262   u8 ipv6_set = 0;
11263   f64 timeout;
11264
11265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11266     {
11267       if (unformat (i, "sw_if_index %d", &sw_if_index))
11268         sw_if_index_set = 1;
11269       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11270         sw_if_index_set = 1;
11271       else if (unformat (i, "ipv4"))
11272         ipv4_set = 1;
11273       else if (unformat (i, "ipv6"))
11274         ipv6_set = 1;
11275       else
11276         break;
11277     }
11278
11279   if (ipv4_set && ipv6_set)
11280     {
11281       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11282       return -99;
11283     }
11284
11285   if ((!ipv4_set) && (!ipv6_set))
11286     {
11287       errmsg ("no ipv4 nor ipv6 flag set\n");
11288       return -99;
11289     }
11290
11291   if (sw_if_index_set == 0)
11292     {
11293       errmsg ("missing interface name or sw_if_index\n");
11294       return -99;
11295     }
11296
11297   vam->current_sw_if_index = sw_if_index;
11298   vam->is_ipv6 = ipv6_set;
11299
11300   M (IP_ADDRESS_DUMP, ip_address_dump);
11301   mp->sw_if_index = ntohl (sw_if_index);
11302   mp->is_ipv6 = ipv6_set;
11303   S;
11304
11305   /* Use a control ping for synchronization */
11306   {
11307     vl_api_control_ping_t *mp;
11308     M (CONTROL_PING, control_ping);
11309     S;
11310   }
11311   W;
11312 }
11313
11314 static int
11315 api_ip_dump (vat_main_t * vam)
11316 {
11317   vl_api_ip_dump_t *mp;
11318   unformat_input_t *in = vam->input;
11319   int ipv4_set = 0;
11320   int ipv6_set = 0;
11321   int is_ipv6;
11322   f64 timeout;
11323   int i;
11324
11325   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11326     {
11327       if (unformat (in, "ipv4"))
11328         ipv4_set = 1;
11329       else if (unformat (in, "ipv6"))
11330         ipv6_set = 1;
11331       else
11332         break;
11333     }
11334
11335   if (ipv4_set && ipv6_set)
11336     {
11337       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11338       return -99;
11339     }
11340
11341   if ((!ipv4_set) && (!ipv6_set))
11342     {
11343       errmsg ("no ipv4 nor ipv6 flag set\n");
11344       return -99;
11345     }
11346
11347   is_ipv6 = ipv6_set;
11348   vam->is_ipv6 = is_ipv6;
11349
11350   /* free old data */
11351   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11352     {
11353       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11354     }
11355   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11356
11357   M (IP_DUMP, ip_dump);
11358   mp->is_ipv6 = ipv6_set;
11359   S;
11360
11361   /* Use a control ping for synchronization */
11362   {
11363     vl_api_control_ping_t *mp;
11364     M (CONTROL_PING, control_ping);
11365     S;
11366   }
11367   W;
11368 }
11369
11370 static int
11371 api_ipsec_spd_add_del (vat_main_t * vam)
11372 {
11373 #if DPDK > 0
11374   unformat_input_t *i = vam->input;
11375   vl_api_ipsec_spd_add_del_t *mp;
11376   f64 timeout;
11377   u32 spd_id = ~0;
11378   u8 is_add = 1;
11379
11380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11381     {
11382       if (unformat (i, "spd_id %d", &spd_id))
11383         ;
11384       else if (unformat (i, "del"))
11385         is_add = 0;
11386       else
11387         {
11388           clib_warning ("parse error '%U'", format_unformat_error, i);
11389           return -99;
11390         }
11391     }
11392   if (spd_id == ~0)
11393     {
11394       errmsg ("spd_id must be set\n");
11395       return -99;
11396     }
11397
11398   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11399
11400   mp->spd_id = ntohl (spd_id);
11401   mp->is_add = is_add;
11402
11403   S;
11404   W;
11405   /* NOTREACHED */
11406   return 0;
11407 #else
11408   clib_warning ("unsupported (no dpdk)");
11409   return -99;
11410 #endif
11411 }
11412
11413 static int
11414 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11415 {
11416 #if DPDK > 0
11417   unformat_input_t *i = vam->input;
11418   vl_api_ipsec_interface_add_del_spd_t *mp;
11419   f64 timeout;
11420   u32 sw_if_index;
11421   u8 sw_if_index_set = 0;
11422   u32 spd_id = (u32) ~ 0;
11423   u8 is_add = 1;
11424
11425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11426     {
11427       if (unformat (i, "del"))
11428         is_add = 0;
11429       else if (unformat (i, "spd_id %d", &spd_id))
11430         ;
11431       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11432         sw_if_index_set = 1;
11433       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11434         sw_if_index_set = 1;
11435       else
11436         {
11437           clib_warning ("parse error '%U'", format_unformat_error, i);
11438           return -99;
11439         }
11440
11441     }
11442
11443   if (spd_id == (u32) ~ 0)
11444     {
11445       errmsg ("spd_id must be set\n");
11446       return -99;
11447     }
11448
11449   if (sw_if_index_set == 0)
11450     {
11451       errmsg ("missing interface name or sw_if_index\n");
11452       return -99;
11453     }
11454
11455   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11456
11457   mp->spd_id = ntohl (spd_id);
11458   mp->sw_if_index = ntohl (sw_if_index);
11459   mp->is_add = is_add;
11460
11461   S;
11462   W;
11463   /* NOTREACHED */
11464   return 0;
11465 #else
11466   clib_warning ("unsupported (no dpdk)");
11467   return -99;
11468 #endif
11469 }
11470
11471 static int
11472 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11473 {
11474 #if DPDK > 0
11475   unformat_input_t *i = vam->input;
11476   vl_api_ipsec_spd_add_del_entry_t *mp;
11477   f64 timeout;
11478   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11479   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11480   i32 priority = 0;
11481   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11482   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11483   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11484   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11485
11486   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11487   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11488   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11489   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11490   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11491   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11492
11493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11494     {
11495       if (unformat (i, "del"))
11496         is_add = 0;
11497       if (unformat (i, "outbound"))
11498         is_outbound = 1;
11499       if (unformat (i, "inbound"))
11500         is_outbound = 0;
11501       else if (unformat (i, "spd_id %d", &spd_id))
11502         ;
11503       else if (unformat (i, "sa_id %d", &sa_id))
11504         ;
11505       else if (unformat (i, "priority %d", &priority))
11506         ;
11507       else if (unformat (i, "protocol %d", &protocol))
11508         ;
11509       else if (unformat (i, "lport_start %d", &lport_start))
11510         ;
11511       else if (unformat (i, "lport_stop %d", &lport_stop))
11512         ;
11513       else if (unformat (i, "rport_start %d", &rport_start))
11514         ;
11515       else if (unformat (i, "rport_stop %d", &rport_stop))
11516         ;
11517       else
11518         if (unformat
11519             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11520         {
11521           is_ipv6 = 0;
11522           is_ip_any = 0;
11523         }
11524       else
11525         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11526         {
11527           is_ipv6 = 0;
11528           is_ip_any = 0;
11529         }
11530       else
11531         if (unformat
11532             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11533         {
11534           is_ipv6 = 0;
11535           is_ip_any = 0;
11536         }
11537       else
11538         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11539         {
11540           is_ipv6 = 0;
11541           is_ip_any = 0;
11542         }
11543       else
11544         if (unformat
11545             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11546         {
11547           is_ipv6 = 1;
11548           is_ip_any = 0;
11549         }
11550       else
11551         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11552         {
11553           is_ipv6 = 1;
11554           is_ip_any = 0;
11555         }
11556       else
11557         if (unformat
11558             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11559         {
11560           is_ipv6 = 1;
11561           is_ip_any = 0;
11562         }
11563       else
11564         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11565         {
11566           is_ipv6 = 1;
11567           is_ip_any = 0;
11568         }
11569       else
11570         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11571         {
11572           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11573             {
11574               clib_warning ("unsupported action: 'resolve'");
11575               return -99;
11576             }
11577         }
11578       else
11579         {
11580           clib_warning ("parse error '%U'", format_unformat_error, i);
11581           return -99;
11582         }
11583
11584     }
11585
11586   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11587
11588   mp->spd_id = ntohl (spd_id);
11589   mp->priority = ntohl (priority);
11590   mp->is_outbound = is_outbound;
11591
11592   mp->is_ipv6 = is_ipv6;
11593   if (is_ipv6 || is_ip_any)
11594     {
11595       clib_memcpy (mp->remote_address_start, &raddr6_start,
11596                    sizeof (ip6_address_t));
11597       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11598                    sizeof (ip6_address_t));
11599       clib_memcpy (mp->local_address_start, &laddr6_start,
11600                    sizeof (ip6_address_t));
11601       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11602                    sizeof (ip6_address_t));
11603     }
11604   else
11605     {
11606       clib_memcpy (mp->remote_address_start, &raddr4_start,
11607                    sizeof (ip4_address_t));
11608       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11609                    sizeof (ip4_address_t));
11610       clib_memcpy (mp->local_address_start, &laddr4_start,
11611                    sizeof (ip4_address_t));
11612       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11613                    sizeof (ip4_address_t));
11614     }
11615   mp->protocol = (u8) protocol;
11616   mp->local_port_start = ntohs ((u16) lport_start);
11617   mp->local_port_stop = ntohs ((u16) lport_stop);
11618   mp->remote_port_start = ntohs ((u16) rport_start);
11619   mp->remote_port_stop = ntohs ((u16) rport_stop);
11620   mp->policy = (u8) policy;
11621   mp->sa_id = ntohl (sa_id);
11622   mp->is_add = is_add;
11623   mp->is_ip_any = is_ip_any;
11624   S;
11625   W;
11626   /* NOTREACHED */
11627   return 0;
11628 #else
11629   clib_warning ("unsupported (no dpdk)");
11630   return -99;
11631 #endif
11632 }
11633
11634 static int
11635 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11636 {
11637 #if DPDK > 0
11638   unformat_input_t *i = vam->input;
11639   vl_api_ipsec_sad_add_del_entry_t *mp;
11640   f64 timeout;
11641   u32 sad_id = 0, spi = 0;
11642   u8 *ck = 0, *ik = 0;
11643   u8 is_add = 1;
11644
11645   u8 protocol = IPSEC_PROTOCOL_AH;
11646   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11647   u32 crypto_alg = 0, integ_alg = 0;
11648   ip4_address_t tun_src4;
11649   ip4_address_t tun_dst4;
11650   ip6_address_t tun_src6;
11651   ip6_address_t tun_dst6;
11652
11653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11654     {
11655       if (unformat (i, "del"))
11656         is_add = 0;
11657       else if (unformat (i, "sad_id %d", &sad_id))
11658         ;
11659       else if (unformat (i, "spi %d", &spi))
11660         ;
11661       else if (unformat (i, "esp"))
11662         protocol = IPSEC_PROTOCOL_ESP;
11663       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11664         {
11665           is_tunnel = 1;
11666           is_tunnel_ipv6 = 0;
11667         }
11668       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11669         {
11670           is_tunnel = 1;
11671           is_tunnel_ipv6 = 0;
11672         }
11673       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11674         {
11675           is_tunnel = 1;
11676           is_tunnel_ipv6 = 1;
11677         }
11678       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11679         {
11680           is_tunnel = 1;
11681           is_tunnel_ipv6 = 1;
11682         }
11683       else
11684         if (unformat
11685             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11686         {
11687           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11688               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11689             {
11690               clib_warning ("unsupported crypto-alg: '%U'",
11691                             format_ipsec_crypto_alg, crypto_alg);
11692               return -99;
11693             }
11694         }
11695       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11696         ;
11697       else
11698         if (unformat
11699             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11700         {
11701           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11702               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11703             {
11704               clib_warning ("unsupported integ-alg: '%U'",
11705                             format_ipsec_integ_alg, integ_alg);
11706               return -99;
11707             }
11708         }
11709       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11710         ;
11711       else
11712         {
11713           clib_warning ("parse error '%U'", format_unformat_error, i);
11714           return -99;
11715         }
11716
11717     }
11718
11719   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11720
11721   mp->sad_id = ntohl (sad_id);
11722   mp->is_add = is_add;
11723   mp->protocol = protocol;
11724   mp->spi = ntohl (spi);
11725   mp->is_tunnel = is_tunnel;
11726   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11727   mp->crypto_algorithm = crypto_alg;
11728   mp->integrity_algorithm = integ_alg;
11729   mp->crypto_key_length = vec_len (ck);
11730   mp->integrity_key_length = vec_len (ik);
11731
11732   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11733     mp->crypto_key_length = sizeof (mp->crypto_key);
11734
11735   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11736     mp->integrity_key_length = sizeof (mp->integrity_key);
11737
11738   if (ck)
11739     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11740   if (ik)
11741     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11742
11743   if (is_tunnel)
11744     {
11745       if (is_tunnel_ipv6)
11746         {
11747           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11748                        sizeof (ip6_address_t));
11749           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11750                        sizeof (ip6_address_t));
11751         }
11752       else
11753         {
11754           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11755                        sizeof (ip4_address_t));
11756           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11757                        sizeof (ip4_address_t));
11758         }
11759     }
11760
11761   S;
11762   W;
11763   /* NOTREACHED */
11764   return 0;
11765 #else
11766   clib_warning ("unsupported (no dpdk)");
11767   return -99;
11768 #endif
11769 }
11770
11771 static int
11772 api_ipsec_sa_set_key (vat_main_t * vam)
11773 {
11774 #if DPDK > 0
11775   unformat_input_t *i = vam->input;
11776   vl_api_ipsec_sa_set_key_t *mp;
11777   f64 timeout;
11778   u32 sa_id;
11779   u8 *ck = 0, *ik = 0;
11780
11781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11782     {
11783       if (unformat (i, "sa_id %d", &sa_id))
11784         ;
11785       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11786         ;
11787       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11788         ;
11789       else
11790         {
11791           clib_warning ("parse error '%U'", format_unformat_error, i);
11792           return -99;
11793         }
11794     }
11795
11796   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11797
11798   mp->sa_id = ntohl (sa_id);
11799   mp->crypto_key_length = vec_len (ck);
11800   mp->integrity_key_length = vec_len (ik);
11801
11802   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11803     mp->crypto_key_length = sizeof (mp->crypto_key);
11804
11805   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11806     mp->integrity_key_length = sizeof (mp->integrity_key);
11807
11808   if (ck)
11809     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11810   if (ik)
11811     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11812
11813   S;
11814   W;
11815   /* NOTREACHED */
11816   return 0;
11817 #else
11818   clib_warning ("unsupported (no dpdk)");
11819   return -99;
11820 #endif
11821 }
11822
11823 static int
11824 api_ikev2_profile_add_del (vat_main_t * vam)
11825 {
11826 #if DPDK > 0
11827   unformat_input_t *i = vam->input;
11828   vl_api_ikev2_profile_add_del_t *mp;
11829   f64 timeout;
11830   u8 is_add = 1;
11831   u8 *name = 0;
11832
11833   const char *valid_chars = "a-zA-Z0-9_";
11834
11835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11836     {
11837       if (unformat (i, "del"))
11838         is_add = 0;
11839       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11840         vec_add1 (name, 0);
11841       else
11842         {
11843           errmsg ("parse error '%U'", format_unformat_error, i);
11844           return -99;
11845         }
11846     }
11847
11848   if (!vec_len (name))
11849     {
11850       errmsg ("profile name must be specified");
11851       return -99;
11852     }
11853
11854   if (vec_len (name) > 64)
11855     {
11856       errmsg ("profile name too long");
11857       return -99;
11858     }
11859
11860   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11861
11862   clib_memcpy (mp->name, name, vec_len (name));
11863   mp->is_add = is_add;
11864   vec_free (name);
11865
11866   S;
11867   W;
11868   /* NOTREACHED */
11869   return 0;
11870 #else
11871   clib_warning ("unsupported (no dpdk)");
11872   return -99;
11873 #endif
11874 }
11875
11876 static int
11877 api_ikev2_profile_set_auth (vat_main_t * vam)
11878 {
11879 #if DPDK > 0
11880   unformat_input_t *i = vam->input;
11881   vl_api_ikev2_profile_set_auth_t *mp;
11882   f64 timeout;
11883   u8 *name = 0;
11884   u8 *data = 0;
11885   u32 auth_method = 0;
11886   u8 is_hex = 0;
11887
11888   const char *valid_chars = "a-zA-Z0-9_";
11889
11890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11891     {
11892       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11893         vec_add1 (name, 0);
11894       else if (unformat (i, "auth_method %U",
11895                          unformat_ikev2_auth_method, &auth_method))
11896         ;
11897       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11898         is_hex = 1;
11899       else if (unformat (i, "auth_data %v", &data))
11900         ;
11901       else
11902         {
11903           errmsg ("parse error '%U'", format_unformat_error, i);
11904           return -99;
11905         }
11906     }
11907
11908   if (!vec_len (name))
11909     {
11910       errmsg ("profile name must be specified");
11911       return -99;
11912     }
11913
11914   if (vec_len (name) > 64)
11915     {
11916       errmsg ("profile name too long");
11917       return -99;
11918     }
11919
11920   if (!vec_len (data))
11921     {
11922       errmsg ("auth_data must be specified");
11923       return -99;
11924     }
11925
11926   if (!auth_method)
11927     {
11928       errmsg ("auth_method must be specified");
11929       return -99;
11930     }
11931
11932   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11933
11934   mp->is_hex = is_hex;
11935   mp->auth_method = (u8) auth_method;
11936   mp->data_len = vec_len (data);
11937   clib_memcpy (mp->name, name, vec_len (name));
11938   clib_memcpy (mp->data, data, vec_len (data));
11939   vec_free (name);
11940   vec_free (data);
11941
11942   S;
11943   W;
11944   /* NOTREACHED */
11945   return 0;
11946 #else
11947   clib_warning ("unsupported (no dpdk)");
11948   return -99;
11949 #endif
11950 }
11951
11952 static int
11953 api_ikev2_profile_set_id (vat_main_t * vam)
11954 {
11955 #if DPDK > 0
11956   unformat_input_t *i = vam->input;
11957   vl_api_ikev2_profile_set_id_t *mp;
11958   f64 timeout;
11959   u8 *name = 0;
11960   u8 *data = 0;
11961   u8 is_local = 0;
11962   u32 id_type = 0;
11963   ip4_address_t ip4;
11964
11965   const char *valid_chars = "a-zA-Z0-9_";
11966
11967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11968     {
11969       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11970         vec_add1 (name, 0);
11971       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11972         ;
11973       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11974         {
11975           data = vec_new (u8, 4);
11976           clib_memcpy (data, ip4.as_u8, 4);
11977         }
11978       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11979         ;
11980       else if (unformat (i, "id_data %v", &data))
11981         ;
11982       else if (unformat (i, "local"))
11983         is_local = 1;
11984       else if (unformat (i, "remote"))
11985         is_local = 0;
11986       else
11987         {
11988           errmsg ("parse error '%U'", format_unformat_error, i);
11989           return -99;
11990         }
11991     }
11992
11993   if (!vec_len (name))
11994     {
11995       errmsg ("profile name must be specified");
11996       return -99;
11997     }
11998
11999   if (vec_len (name) > 64)
12000     {
12001       errmsg ("profile name too long");
12002       return -99;
12003     }
12004
12005   if (!vec_len (data))
12006     {
12007       errmsg ("id_data must be specified");
12008       return -99;
12009     }
12010
12011   if (!id_type)
12012     {
12013       errmsg ("id_type must be specified");
12014       return -99;
12015     }
12016
12017   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12018
12019   mp->is_local = is_local;
12020   mp->id_type = (u8) id_type;
12021   mp->data_len = vec_len (data);
12022   clib_memcpy (mp->name, name, vec_len (name));
12023   clib_memcpy (mp->data, data, vec_len (data));
12024   vec_free (name);
12025   vec_free (data);
12026
12027   S;
12028   W;
12029   /* NOTREACHED */
12030   return 0;
12031 #else
12032   clib_warning ("unsupported (no dpdk)");
12033   return -99;
12034 #endif
12035 }
12036
12037 static int
12038 api_ikev2_profile_set_ts (vat_main_t * vam)
12039 {
12040 #if DPDK > 0
12041   unformat_input_t *i = vam->input;
12042   vl_api_ikev2_profile_set_ts_t *mp;
12043   f64 timeout;
12044   u8 *name = 0;
12045   u8 is_local = 0;
12046   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12047   ip4_address_t start_addr, end_addr;
12048
12049   const char *valid_chars = "a-zA-Z0-9_";
12050
12051   start_addr.as_u32 = 0;
12052   end_addr.as_u32 = (u32) ~ 0;
12053
12054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12055     {
12056       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12057         vec_add1 (name, 0);
12058       else if (unformat (i, "protocol %d", &proto))
12059         ;
12060       else if (unformat (i, "start_port %d", &start_port))
12061         ;
12062       else if (unformat (i, "end_port %d", &end_port))
12063         ;
12064       else
12065         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12066         ;
12067       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12068         ;
12069       else if (unformat (i, "local"))
12070         is_local = 1;
12071       else if (unformat (i, "remote"))
12072         is_local = 0;
12073       else
12074         {
12075           errmsg ("parse error '%U'", format_unformat_error, i);
12076           return -99;
12077         }
12078     }
12079
12080   if (!vec_len (name))
12081     {
12082       errmsg ("profile name must be specified");
12083       return -99;
12084     }
12085
12086   if (vec_len (name) > 64)
12087     {
12088       errmsg ("profile name too long");
12089       return -99;
12090     }
12091
12092   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12093
12094   mp->is_local = is_local;
12095   mp->proto = (u8) proto;
12096   mp->start_port = (u16) start_port;
12097   mp->end_port = (u16) end_port;
12098   mp->start_addr = start_addr.as_u32;
12099   mp->end_addr = end_addr.as_u32;
12100   clib_memcpy (mp->name, name, vec_len (name));
12101   vec_free (name);
12102
12103   S;
12104   W;
12105   /* NOTREACHED */
12106   return 0;
12107 #else
12108   clib_warning ("unsupported (no dpdk)");
12109   return -99;
12110 #endif
12111 }
12112
12113 static int
12114 api_ikev2_set_local_key (vat_main_t * vam)
12115 {
12116 #if DPDK > 0
12117   unformat_input_t *i = vam->input;
12118   vl_api_ikev2_set_local_key_t *mp;
12119   f64 timeout;
12120   u8 *file = 0;
12121
12122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12123     {
12124       if (unformat (i, "file %v", &file))
12125         vec_add1 (file, 0);
12126       else
12127         {
12128           errmsg ("parse error '%U'", format_unformat_error, i);
12129           return -99;
12130         }
12131     }
12132
12133   if (!vec_len (file))
12134     {
12135       errmsg ("RSA key file must be specified");
12136       return -99;
12137     }
12138
12139   if (vec_len (file) > 256)
12140     {
12141       errmsg ("file name too long");
12142       return -99;
12143     }
12144
12145   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12146
12147   clib_memcpy (mp->key_file, file, vec_len (file));
12148   vec_free (file);
12149
12150   S;
12151   W;
12152   /* NOTREACHED */
12153   return 0;
12154 #else
12155   clib_warning ("unsupported (no dpdk)");
12156   return -99;
12157 #endif
12158 }
12159
12160 /*
12161  * MAP
12162  */
12163 static int
12164 api_map_add_domain (vat_main_t * vam)
12165 {
12166   unformat_input_t *i = vam->input;
12167   vl_api_map_add_domain_t *mp;
12168   f64 timeout;
12169
12170   ip4_address_t ip4_prefix;
12171   ip6_address_t ip6_prefix;
12172   ip6_address_t ip6_src;
12173   u32 num_m_args = 0;
12174   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12175     0, psid_length = 0;
12176   u8 is_translation = 0;
12177   u32 mtu = 0;
12178   u32 ip6_src_len = 128;
12179
12180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12181     {
12182       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12183                     &ip4_prefix, &ip4_prefix_len))
12184         num_m_args++;
12185       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12186                          &ip6_prefix, &ip6_prefix_len))
12187         num_m_args++;
12188       else
12189         if (unformat
12190             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12191              &ip6_src_len))
12192         num_m_args++;
12193       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12194         num_m_args++;
12195       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12196         num_m_args++;
12197       else if (unformat (i, "psid-offset %d", &psid_offset))
12198         num_m_args++;
12199       else if (unformat (i, "psid-len %d", &psid_length))
12200         num_m_args++;
12201       else if (unformat (i, "mtu %d", &mtu))
12202         num_m_args++;
12203       else if (unformat (i, "map-t"))
12204         is_translation = 1;
12205       else
12206         {
12207           clib_warning ("parse error '%U'", format_unformat_error, i);
12208           return -99;
12209         }
12210     }
12211
12212   if (num_m_args < 3)
12213     {
12214       errmsg ("mandatory argument(s) missing\n");
12215       return -99;
12216     }
12217
12218   /* Construct the API message */
12219   M (MAP_ADD_DOMAIN, map_add_domain);
12220
12221   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12222   mp->ip4_prefix_len = ip4_prefix_len;
12223
12224   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12225   mp->ip6_prefix_len = ip6_prefix_len;
12226
12227   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12228   mp->ip6_src_prefix_len = ip6_src_len;
12229
12230   mp->ea_bits_len = ea_bits_len;
12231   mp->psid_offset = psid_offset;
12232   mp->psid_length = psid_length;
12233   mp->is_translation = is_translation;
12234   mp->mtu = htons (mtu);
12235
12236   /* send it... */
12237   S;
12238
12239   /* Wait for a reply, return good/bad news  */
12240   W;
12241 }
12242
12243 static int
12244 api_map_del_domain (vat_main_t * vam)
12245 {
12246   unformat_input_t *i = vam->input;
12247   vl_api_map_del_domain_t *mp;
12248   f64 timeout;
12249
12250   u32 num_m_args = 0;
12251   u32 index;
12252
12253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12254     {
12255       if (unformat (i, "index %d", &index))
12256         num_m_args++;
12257       else
12258         {
12259           clib_warning ("parse error '%U'", format_unformat_error, i);
12260           return -99;
12261         }
12262     }
12263
12264   if (num_m_args != 1)
12265     {
12266       errmsg ("mandatory argument(s) missing\n");
12267       return -99;
12268     }
12269
12270   /* Construct the API message */
12271   M (MAP_DEL_DOMAIN, map_del_domain);
12272
12273   mp->index = ntohl (index);
12274
12275   /* send it... */
12276   S;
12277
12278   /* Wait for a reply, return good/bad news  */
12279   W;
12280 }
12281
12282 static int
12283 api_map_add_del_rule (vat_main_t * vam)
12284 {
12285   unformat_input_t *i = vam->input;
12286   vl_api_map_add_del_rule_t *mp;
12287   f64 timeout;
12288   u8 is_add = 1;
12289   ip6_address_t ip6_dst;
12290   u32 num_m_args = 0, index, psid = 0;
12291
12292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12293     {
12294       if (unformat (i, "index %d", &index))
12295         num_m_args++;
12296       else if (unformat (i, "psid %d", &psid))
12297         num_m_args++;
12298       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12299         num_m_args++;
12300       else if (unformat (i, "del"))
12301         {
12302           is_add = 0;
12303         }
12304       else
12305         {
12306           clib_warning ("parse error '%U'", format_unformat_error, i);
12307           return -99;
12308         }
12309     }
12310
12311   /* Construct the API message */
12312   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12313
12314   mp->index = ntohl (index);
12315   mp->is_add = is_add;
12316   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12317   mp->psid = ntohs (psid);
12318
12319   /* send it... */
12320   S;
12321
12322   /* Wait for a reply, return good/bad news  */
12323   W;
12324 }
12325
12326 static int
12327 api_map_domain_dump (vat_main_t * vam)
12328 {
12329   vl_api_map_domain_dump_t *mp;
12330   f64 timeout;
12331
12332   /* Construct the API message */
12333   M (MAP_DOMAIN_DUMP, map_domain_dump);
12334
12335   /* send it... */
12336   S;
12337
12338   /* Use a control ping for synchronization */
12339   {
12340     vl_api_control_ping_t *mp;
12341     M (CONTROL_PING, control_ping);
12342     S;
12343   }
12344   W;
12345 }
12346
12347 static int
12348 api_map_rule_dump (vat_main_t * vam)
12349 {
12350   unformat_input_t *i = vam->input;
12351   vl_api_map_rule_dump_t *mp;
12352   f64 timeout;
12353   u32 domain_index = ~0;
12354
12355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12356     {
12357       if (unformat (i, "index %u", &domain_index))
12358         ;
12359       else
12360         break;
12361     }
12362
12363   if (domain_index == ~0)
12364     {
12365       clib_warning ("parse error: domain index expected");
12366       return -99;
12367     }
12368
12369   /* Construct the API message */
12370   M (MAP_RULE_DUMP, map_rule_dump);
12371
12372   mp->domain_index = htonl (domain_index);
12373
12374   /* send it... */
12375   S;
12376
12377   /* Use a control ping for synchronization */
12378   {
12379     vl_api_control_ping_t *mp;
12380     M (CONTROL_PING, control_ping);
12381     S;
12382   }
12383   W;
12384 }
12385
12386 static void vl_api_map_add_domain_reply_t_handler
12387   (vl_api_map_add_domain_reply_t * mp)
12388 {
12389   vat_main_t *vam = &vat_main;
12390   i32 retval = ntohl (mp->retval);
12391
12392   if (vam->async_mode)
12393     {
12394       vam->async_errors += (retval < 0);
12395     }
12396   else
12397     {
12398       vam->retval = retval;
12399       vam->result_ready = 1;
12400     }
12401 }
12402
12403 static void vl_api_map_add_domain_reply_t_handler_json
12404   (vl_api_map_add_domain_reply_t * mp)
12405 {
12406   vat_main_t *vam = &vat_main;
12407   vat_json_node_t node;
12408
12409   vat_json_init_object (&node);
12410   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12411   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12412
12413   vat_json_print (vam->ofp, &node);
12414   vat_json_free (&node);
12415
12416   vam->retval = ntohl (mp->retval);
12417   vam->result_ready = 1;
12418 }
12419
12420 static int
12421 api_get_first_msg_id (vat_main_t * vam)
12422 {
12423   vl_api_get_first_msg_id_t *mp;
12424   f64 timeout;
12425   unformat_input_t *i = vam->input;
12426   u8 *name;
12427   u8 name_set = 0;
12428
12429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12430     {
12431       if (unformat (i, "client %s", &name))
12432         name_set = 1;
12433       else
12434         break;
12435     }
12436
12437   if (name_set == 0)
12438     {
12439       errmsg ("missing client name\n");
12440       return -99;
12441     }
12442   vec_add1 (name, 0);
12443
12444   if (vec_len (name) > 63)
12445     {
12446       errmsg ("client name too long\n");
12447       return -99;
12448     }
12449
12450   M (GET_FIRST_MSG_ID, get_first_msg_id);
12451   clib_memcpy (mp->name, name, vec_len (name));
12452   S;
12453   W;
12454   /* NOTREACHED */
12455   return 0;
12456 }
12457
12458 static int
12459 api_cop_interface_enable_disable (vat_main_t * vam)
12460 {
12461   unformat_input_t *line_input = vam->input;
12462   vl_api_cop_interface_enable_disable_t *mp;
12463   f64 timeout;
12464   u32 sw_if_index = ~0;
12465   u8 enable_disable = 1;
12466
12467   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12468     {
12469       if (unformat (line_input, "disable"))
12470         enable_disable = 0;
12471       if (unformat (line_input, "enable"))
12472         enable_disable = 1;
12473       else if (unformat (line_input, "%U", unformat_sw_if_index,
12474                          vam, &sw_if_index))
12475         ;
12476       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12477         ;
12478       else
12479         break;
12480     }
12481
12482   if (sw_if_index == ~0)
12483     {
12484       errmsg ("missing interface name or sw_if_index\n");
12485       return -99;
12486     }
12487
12488   /* Construct the API message */
12489   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12490   mp->sw_if_index = ntohl (sw_if_index);
12491   mp->enable_disable = enable_disable;
12492
12493   /* send it... */
12494   S;
12495   /* Wait for the reply */
12496   W;
12497 }
12498
12499 static int
12500 api_cop_whitelist_enable_disable (vat_main_t * vam)
12501 {
12502   unformat_input_t *line_input = vam->input;
12503   vl_api_cop_whitelist_enable_disable_t *mp;
12504   f64 timeout;
12505   u32 sw_if_index = ~0;
12506   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12507   u32 fib_id = 0;
12508
12509   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12510     {
12511       if (unformat (line_input, "ip4"))
12512         ip4 = 1;
12513       else if (unformat (line_input, "ip6"))
12514         ip6 = 1;
12515       else if (unformat (line_input, "default"))
12516         default_cop = 1;
12517       else if (unformat (line_input, "%U", unformat_sw_if_index,
12518                          vam, &sw_if_index))
12519         ;
12520       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12521         ;
12522       else if (unformat (line_input, "fib-id %d", &fib_id))
12523         ;
12524       else
12525         break;
12526     }
12527
12528   if (sw_if_index == ~0)
12529     {
12530       errmsg ("missing interface name or sw_if_index\n");
12531       return -99;
12532     }
12533
12534   /* Construct the API message */
12535   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12536   mp->sw_if_index = ntohl (sw_if_index);
12537   mp->fib_id = ntohl (fib_id);
12538   mp->ip4 = ip4;
12539   mp->ip6 = ip6;
12540   mp->default_cop = default_cop;
12541
12542   /* send it... */
12543   S;
12544   /* Wait for the reply */
12545   W;
12546 }
12547
12548 static int
12549 api_get_node_graph (vat_main_t * vam)
12550 {
12551   vl_api_get_node_graph_t *mp;
12552   f64 timeout;
12553
12554   M (GET_NODE_GRAPH, get_node_graph);
12555
12556   /* send it... */
12557   S;
12558   /* Wait for the reply */
12559   W;
12560 }
12561
12562 /* *INDENT-OFF* */
12563 /** Used for parsing LISP eids */
12564 typedef CLIB_PACKED(struct{
12565   u8 addr[16];   /**< eid address */
12566   u32 len;       /**< prefix length if IP */
12567   u8 type;      /**< type of eid */
12568 }) lisp_eid_vat_t;
12569 /* *INDENT-ON* */
12570
12571 static uword
12572 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12573 {
12574   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12575
12576   memset (a, 0, sizeof (a[0]));
12577
12578   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12579     {
12580       a->type = 0;              /* ipv4 type */
12581     }
12582   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12583     {
12584       a->type = 1;              /* ipv6 type */
12585     }
12586   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12587     {
12588       a->type = 2;              /* mac type */
12589     }
12590   else
12591     {
12592       return 0;
12593     }
12594
12595   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12596     {
12597       return 0;
12598     }
12599
12600   return 1;
12601 }
12602
12603 static int
12604 lisp_eid_size_vat (u8 type)
12605 {
12606   switch (type)
12607     {
12608     case 0:
12609       return 4;
12610     case 1:
12611       return 16;
12612     case 2:
12613       return 6;
12614     }
12615   return 0;
12616 }
12617
12618 static void
12619 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12620 {
12621   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12622 }
12623
12624 /* *INDENT-OFF* */
12625 /** Used for transferring locators via VPP API */
12626 typedef CLIB_PACKED(struct
12627 {
12628   u32 sw_if_index; /**< locator sw_if_index */
12629   u8 priority; /**< locator priority */
12630   u8 weight;   /**< locator weight */
12631 }) ls_locator_t;
12632 /* *INDENT-ON* */
12633
12634 static int
12635 api_lisp_add_del_locator_set (vat_main_t * vam)
12636 {
12637   unformat_input_t *input = vam->input;
12638   vl_api_lisp_add_del_locator_set_t *mp;
12639   f64 timeout = ~0;
12640   u8 is_add = 1;
12641   u8 *locator_set_name = NULL;
12642   u8 locator_set_name_set = 0;
12643   ls_locator_t locator, *locators = 0;
12644   u32 sw_if_index, priority, weight;
12645   u32 data_len = 0;
12646
12647   /* Parse args required to build the message */
12648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12649     {
12650       if (unformat (input, "del"))
12651         {
12652           is_add = 0;
12653         }
12654       else if (unformat (input, "locator-set %s", &locator_set_name))
12655         {
12656           locator_set_name_set = 1;
12657         }
12658       else if (unformat (input, "sw_if_index %u p %u w %u",
12659                          &sw_if_index, &priority, &weight))
12660         {
12661           locator.sw_if_index = htonl (sw_if_index);
12662           locator.priority = priority;
12663           locator.weight = weight;
12664           vec_add1 (locators, locator);
12665         }
12666       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12667                          vam, &sw_if_index, &priority, &weight))
12668         {
12669           locator.sw_if_index = htonl (sw_if_index);
12670           locator.priority = priority;
12671           locator.weight = weight;
12672           vec_add1 (locators, locator);
12673         }
12674       else
12675         break;
12676     }
12677
12678   if (locator_set_name_set == 0)
12679     {
12680       errmsg ("missing locator-set name");
12681       vec_free (locators);
12682       return -99;
12683     }
12684
12685   if (vec_len (locator_set_name) > 64)
12686     {
12687       errmsg ("locator-set name too long\n");
12688       vec_free (locator_set_name);
12689       vec_free (locators);
12690       return -99;
12691     }
12692   vec_add1 (locator_set_name, 0);
12693
12694   data_len = sizeof (ls_locator_t) * vec_len (locators);
12695
12696   /* Construct the API message */
12697   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12698
12699   mp->is_add = is_add;
12700   clib_memcpy (mp->locator_set_name, locator_set_name,
12701                vec_len (locator_set_name));
12702   vec_free (locator_set_name);
12703
12704   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12705   if (locators)
12706     clib_memcpy (mp->locators, locators, data_len);
12707   vec_free (locators);
12708
12709   /* send it... */
12710   S;
12711
12712   /* Wait for a reply... */
12713   W;
12714
12715   /* NOTREACHED */
12716   return 0;
12717 }
12718
12719 static int
12720 api_lisp_add_del_locator (vat_main_t * vam)
12721 {
12722   unformat_input_t *input = vam->input;
12723   vl_api_lisp_add_del_locator_t *mp;
12724   f64 timeout = ~0;
12725   u32 tmp_if_index = ~0;
12726   u32 sw_if_index = ~0;
12727   u8 sw_if_index_set = 0;
12728   u8 sw_if_index_if_name_set = 0;
12729   u32 priority = ~0;
12730   u8 priority_set = 0;
12731   u32 weight = ~0;
12732   u8 weight_set = 0;
12733   u8 is_add = 1;
12734   u8 *locator_set_name = NULL;
12735   u8 locator_set_name_set = 0;
12736
12737   /* Parse args required to build the message */
12738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12739     {
12740       if (unformat (input, "del"))
12741         {
12742           is_add = 0;
12743         }
12744       else if (unformat (input, "locator-set %s", &locator_set_name))
12745         {
12746           locator_set_name_set = 1;
12747         }
12748       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12749                          &tmp_if_index))
12750         {
12751           sw_if_index_if_name_set = 1;
12752           sw_if_index = tmp_if_index;
12753         }
12754       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12755         {
12756           sw_if_index_set = 1;
12757           sw_if_index = tmp_if_index;
12758         }
12759       else if (unformat (input, "p %d", &priority))
12760         {
12761           priority_set = 1;
12762         }
12763       else if (unformat (input, "w %d", &weight))
12764         {
12765           weight_set = 1;
12766         }
12767       else
12768         break;
12769     }
12770
12771   if (locator_set_name_set == 0)
12772     {
12773       errmsg ("missing locator-set name");
12774       return -99;
12775     }
12776
12777   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12778     {
12779       errmsg ("missing sw_if_index");
12780       vec_free (locator_set_name);
12781       return -99;
12782     }
12783
12784   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12785     {
12786       errmsg ("cannot use both params interface name and sw_if_index");
12787       vec_free (locator_set_name);
12788       return -99;
12789     }
12790
12791   if (priority_set == 0)
12792     {
12793       errmsg ("missing locator-set priority\n");
12794       vec_free (locator_set_name);
12795       return -99;
12796     }
12797
12798   if (weight_set == 0)
12799     {
12800       errmsg ("missing locator-set weight\n");
12801       vec_free (locator_set_name);
12802       return -99;
12803     }
12804
12805   if (vec_len (locator_set_name) > 64)
12806     {
12807       errmsg ("locator-set name too long\n");
12808       vec_free (locator_set_name);
12809       return -99;
12810     }
12811   vec_add1 (locator_set_name, 0);
12812
12813   /* Construct the API message */
12814   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12815
12816   mp->is_add = is_add;
12817   mp->sw_if_index = ntohl (sw_if_index);
12818   mp->priority = priority;
12819   mp->weight = weight;
12820   clib_memcpy (mp->locator_set_name, locator_set_name,
12821                vec_len (locator_set_name));
12822   vec_free (locator_set_name);
12823
12824   /* send it... */
12825   S;
12826
12827   /* Wait for a reply... */
12828   W;
12829
12830   /* NOTREACHED */
12831   return 0;
12832 }
12833
12834 static int
12835 api_lisp_add_del_local_eid (vat_main_t * vam)
12836 {
12837   unformat_input_t *input = vam->input;
12838   vl_api_lisp_add_del_local_eid_t *mp;
12839   f64 timeout = ~0;
12840   u8 is_add = 1;
12841   u8 eid_set = 0;
12842   lisp_eid_vat_t _eid, *eid = &_eid;
12843   u8 *locator_set_name = 0;
12844   u8 locator_set_name_set = 0;
12845   u32 vni = 0;
12846
12847   /* Parse args required to build the message */
12848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12849     {
12850       if (unformat (input, "del"))
12851         {
12852           is_add = 0;
12853         }
12854       else if (unformat (input, "vni %d", &vni))
12855         {
12856           ;
12857         }
12858       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12859         {
12860           eid_set = 1;
12861         }
12862       else if (unformat (input, "locator-set %s", &locator_set_name))
12863         {
12864           locator_set_name_set = 1;
12865         }
12866       else
12867         break;
12868     }
12869
12870   if (locator_set_name_set == 0)
12871     {
12872       errmsg ("missing locator-set name\n");
12873       return -99;
12874     }
12875
12876   if (0 == eid_set)
12877     {
12878       errmsg ("EID address not set!");
12879       vec_free (locator_set_name);
12880       return -99;
12881     }
12882
12883   if (vec_len (locator_set_name) > 64)
12884     {
12885       errmsg ("locator-set name too long\n");
12886       vec_free (locator_set_name);
12887       return -99;
12888     }
12889   vec_add1 (locator_set_name, 0);
12890
12891   /* Construct the API message */
12892   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12893
12894   mp->is_add = is_add;
12895   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12896   mp->eid_type = eid->type;
12897   mp->prefix_len = eid->len;
12898   mp->vni = clib_host_to_net_u32 (vni);
12899   clib_memcpy (mp->locator_set_name, locator_set_name,
12900                vec_len (locator_set_name));
12901
12902   vec_free (locator_set_name);
12903
12904   /* send it... */
12905   S;
12906
12907   /* Wait for a reply... */
12908   W;
12909
12910   /* NOTREACHED */
12911   return 0;
12912 }
12913
12914 /* *INDENT-OFF* */
12915 /** Used for transferring locators via VPP API */
12916 typedef CLIB_PACKED(struct
12917 {
12918   u8 is_ip4; /**< is locator an IPv4 address? */
12919   u8 priority; /**< locator priority */
12920   u8 weight;   /**< locator weight */
12921   u8 addr[16]; /**< IPv4/IPv6 address */
12922 }) rloc_t;
12923 /* *INDENT-ON* */
12924
12925 static int
12926 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12927 {
12928   unformat_input_t *input = vam->input;
12929   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12930   f64 timeout = ~0;
12931   u8 is_add = 1;
12932   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12933   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12934   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12935   u32 action = ~0, p, w;
12936   ip4_address_t rmt_rloc4, lcl_rloc4;
12937   ip6_address_t rmt_rloc6, lcl_rloc6;
12938   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12939
12940   memset (&rloc, 0, sizeof (rloc));
12941
12942   /* Parse args required to build the message */
12943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12944     {
12945       if (unformat (input, "del"))
12946         {
12947           is_add = 0;
12948         }
12949       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12950         {
12951           rmt_eid_set = 1;
12952         }
12953       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12954         {
12955           lcl_eid_set = 1;
12956         }
12957       else if (unformat (input, "p %d w %d", &p, &w))
12958         {
12959           if (!curr_rloc)
12960             {
12961               errmsg ("No RLOC configured for setting priority/weight!");
12962               return -99;
12963             }
12964           curr_rloc->priority = p;
12965           curr_rloc->weight = w;
12966         }
12967       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12968                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12969         {
12970           rloc.is_ip4 = 1;
12971
12972           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12973           rloc.priority = rloc.weight = 0;
12974           vec_add1 (lcl_locs, rloc);
12975
12976           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12977           vec_add1 (rmt_locs, rloc);
12978           /* priority and weight saved in rmt loc */
12979           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12980         }
12981       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12982                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12983         {
12984           rloc.is_ip4 = 0;
12985           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12986           rloc.priority = rloc.weight = 0;
12987           vec_add1 (lcl_locs, rloc);
12988
12989           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12990           vec_add1 (rmt_locs, rloc);
12991           /* priority and weight saved in rmt loc */
12992           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12993         }
12994       else if (unformat (input, "action %d", &action))
12995         {
12996           ;
12997         }
12998       else
12999         {
13000           clib_warning ("parse error '%U'", format_unformat_error, input);
13001           return -99;
13002         }
13003     }
13004
13005   if (!rmt_eid_set)
13006     {
13007       errmsg ("remote eid addresses not set\n");
13008       return -99;
13009     }
13010
13011   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13012     {
13013       errmsg ("eid types don't match\n");
13014       return -99;
13015     }
13016
13017   if (0 == rmt_locs && (u32) ~ 0 == action)
13018     {
13019       errmsg ("action not set for negative mapping\n");
13020       return -99;
13021     }
13022
13023   /* Construct the API message */
13024   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13025
13026   mp->is_add = is_add;
13027   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13028   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13029   mp->eid_type = rmt_eid->type;
13030   mp->rmt_len = rmt_eid->len;
13031   mp->lcl_len = lcl_eid->len;
13032   mp->action = action;
13033
13034   if (0 != rmt_locs && 0 != lcl_locs)
13035     {
13036       mp->loc_num = vec_len (rmt_locs);
13037       clib_memcpy (mp->lcl_locs, lcl_locs,
13038                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13039       clib_memcpy (mp->rmt_locs, rmt_locs,
13040                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13041     }
13042   vec_free (lcl_locs);
13043   vec_free (rmt_locs);
13044
13045   /* send it... */
13046   S;
13047
13048   /* Wait for a reply... */
13049   W;
13050
13051   /* NOTREACHED */
13052   return 0;
13053 }
13054
13055 static int
13056 api_lisp_add_del_map_resolver (vat_main_t * vam)
13057 {
13058   unformat_input_t *input = vam->input;
13059   vl_api_lisp_add_del_map_resolver_t *mp;
13060   f64 timeout = ~0;
13061   u8 is_add = 1;
13062   u8 ipv4_set = 0;
13063   u8 ipv6_set = 0;
13064   ip4_address_t ipv4;
13065   ip6_address_t ipv6;
13066
13067   /* Parse args required to build the message */
13068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13069     {
13070       if (unformat (input, "del"))
13071         {
13072           is_add = 0;
13073         }
13074       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13075         {
13076           ipv4_set = 1;
13077         }
13078       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13079         {
13080           ipv6_set = 1;
13081         }
13082       else
13083         break;
13084     }
13085
13086   if (ipv4_set && ipv6_set)
13087     {
13088       errmsg ("both eid v4 and v6 addresses set\n");
13089       return -99;
13090     }
13091
13092   if (!ipv4_set && !ipv6_set)
13093     {
13094       errmsg ("eid addresses not set\n");
13095       return -99;
13096     }
13097
13098   /* Construct the API message */
13099   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13100
13101   mp->is_add = is_add;
13102   if (ipv6_set)
13103     {
13104       mp->is_ipv6 = 1;
13105       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13106     }
13107   else
13108     {
13109       mp->is_ipv6 = 0;
13110       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13111     }
13112
13113   /* send it... */
13114   S;
13115
13116   /* Wait for a reply... */
13117   W;
13118
13119   /* NOTREACHED */
13120   return 0;
13121 }
13122
13123 static int
13124 api_lisp_gpe_enable_disable (vat_main_t * vam)
13125 {
13126   unformat_input_t *input = vam->input;
13127   vl_api_lisp_gpe_enable_disable_t *mp;
13128   f64 timeout = ~0;
13129   u8 is_set = 0;
13130   u8 is_en = 1;
13131
13132   /* Parse args required to build the message */
13133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13134     {
13135       if (unformat (input, "enable"))
13136         {
13137           is_set = 1;
13138           is_en = 1;
13139         }
13140       else if (unformat (input, "disable"))
13141         {
13142           is_set = 1;
13143           is_en = 0;
13144         }
13145       else
13146         break;
13147     }
13148
13149   if (is_set == 0)
13150     {
13151       errmsg ("Value not set\n");
13152       return -99;
13153     }
13154
13155   /* Construct the API message */
13156   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13157
13158   mp->is_en = is_en;
13159
13160   /* send it... */
13161   S;
13162
13163   /* Wait for a reply... */
13164   W;
13165
13166   /* NOTREACHED */
13167   return 0;
13168 }
13169
13170 static int
13171 api_lisp_enable_disable (vat_main_t * vam)
13172 {
13173   unformat_input_t *input = vam->input;
13174   vl_api_lisp_enable_disable_t *mp;
13175   f64 timeout = ~0;
13176   u8 is_set = 0;
13177   u8 is_en = 0;
13178
13179   /* Parse args required to build the message */
13180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13181     {
13182       if (unformat (input, "enable"))
13183         {
13184           is_set = 1;
13185           is_en = 1;
13186         }
13187       else if (unformat (input, "disable"))
13188         {
13189           is_set = 1;
13190         }
13191       else
13192         break;
13193     }
13194
13195   if (!is_set)
13196     {
13197       errmsg ("Value not set\n");
13198       return -99;
13199     }
13200
13201   /* Construct the API message */
13202   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13203
13204   mp->is_en = is_en;
13205
13206   /* send it... */
13207   S;
13208
13209   /* Wait for a reply... */
13210   W;
13211
13212   /* NOTREACHED */
13213   return 0;
13214 }
13215
13216 static int
13217 api_show_lisp_map_request_mode (vat_main_t * vam)
13218 {
13219   f64 timeout = ~0;
13220   vl_api_show_lisp_map_request_mode_t *mp;
13221
13222   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13223
13224   /* send */
13225   S;
13226
13227   /* wait for reply */
13228   W;
13229
13230   return 0;
13231 }
13232
13233 static int
13234 api_lisp_map_request_mode (vat_main_t * vam)
13235 {
13236   f64 timeout = ~0;
13237   unformat_input_t *input = vam->input;
13238   vl_api_lisp_map_request_mode_t *mp;
13239   u8 mode = 0;
13240
13241   /* Parse args required to build the message */
13242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13243     {
13244       if (unformat (input, "dst-only"))
13245         mode = 0;
13246       else if (unformat (input, "src-dst"))
13247         mode = 1;
13248       else
13249         {
13250           errmsg ("parse error '%U'", format_unformat_error, input);
13251           return -99;
13252         }
13253     }
13254
13255   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13256
13257   mp->mode = mode;
13258
13259   /* send */
13260   S;
13261
13262   /* wait for reply */
13263   W;
13264
13265   /* notreached */
13266   return 0;
13267 }
13268
13269 /**
13270  * Enable/disable LISP proxy ITR.
13271  *
13272  * @param vam vpp API test context
13273  * @return return code
13274  */
13275 static int
13276 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13277 {
13278   f64 timeout = ~0;
13279   u8 ls_name_set = 0;
13280   unformat_input_t *input = vam->input;
13281   vl_api_lisp_pitr_set_locator_set_t *mp;
13282   u8 is_add = 1;
13283   u8 *ls_name = 0;
13284
13285   /* Parse args required to build the message */
13286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13287     {
13288       if (unformat (input, "del"))
13289         is_add = 0;
13290       else if (unformat (input, "locator-set %s", &ls_name))
13291         ls_name_set = 1;
13292       else
13293         {
13294           errmsg ("parse error '%U'", format_unformat_error, input);
13295           return -99;
13296         }
13297     }
13298
13299   if (!ls_name_set)
13300     {
13301       errmsg ("locator-set name not set!");
13302       return -99;
13303     }
13304
13305   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13306
13307   mp->is_add = is_add;
13308   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13309   vec_free (ls_name);
13310
13311   /* send */
13312   S;
13313
13314   /* wait for reply */
13315   W;
13316
13317   /* notreached */
13318   return 0;
13319 }
13320
13321 static int
13322 api_show_lisp_pitr (vat_main_t * vam)
13323 {
13324   vl_api_show_lisp_pitr_t *mp;
13325   f64 timeout = ~0;
13326
13327   if (!vam->json_output)
13328     {
13329       fformat (vam->ofp, "%=20s\n", "lisp status:");
13330     }
13331
13332   M (SHOW_LISP_PITR, show_lisp_pitr);
13333   /* send it... */
13334   S;
13335
13336   /* Wait for a reply... */
13337   W;
13338
13339   /* NOTREACHED */
13340   return 0;
13341 }
13342
13343 /**
13344  * Add/delete mapping between vni and vrf
13345  */
13346 static int
13347 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13348 {
13349   f64 timeout = ~0;
13350   unformat_input_t *input = vam->input;
13351   vl_api_lisp_eid_table_add_del_map_t *mp;
13352   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13353   u32 vni, vrf, bd_index;
13354
13355   /* Parse args required to build the message */
13356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13357     {
13358       if (unformat (input, "del"))
13359         is_add = 0;
13360       else if (unformat (input, "vrf %d", &vrf))
13361         vrf_set = 1;
13362       else if (unformat (input, "bd_index %d", &bd_index))
13363         bd_index_set = 1;
13364       else if (unformat (input, "vni %d", &vni))
13365         vni_set = 1;
13366       else
13367         break;
13368     }
13369
13370   if (!vni_set || (!vrf_set && !bd_index_set))
13371     {
13372       errmsg ("missing arguments!");
13373       return -99;
13374     }
13375
13376   if (vrf_set && bd_index_set)
13377     {
13378       errmsg ("error: both vrf and bd entered!");
13379       return -99;
13380     }
13381
13382   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13383
13384   mp->is_add = is_add;
13385   mp->vni = htonl (vni);
13386   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13387   mp->is_l2 = bd_index_set;
13388
13389   /* send */
13390   S;
13391
13392   /* wait for reply */
13393   W;
13394
13395   /* notreached */
13396   return 0;
13397 }
13398
13399 uword
13400 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13401 {
13402   u32 *action = va_arg (*args, u32 *);
13403   u8 *s = 0;
13404
13405   if (unformat (input, "%s", &s))
13406     {
13407       if (!strcmp ((char *) s, "no-action"))
13408         action[0] = 0;
13409       else if (!strcmp ((char *) s, "natively-forward"))
13410         action[0] = 1;
13411       else if (!strcmp ((char *) s, "send-map-request"))
13412         action[0] = 2;
13413       else if (!strcmp ((char *) s, "drop"))
13414         action[0] = 3;
13415       else
13416         {
13417           clib_warning ("invalid action: '%s'", s);
13418           action[0] = 3;
13419         }
13420     }
13421   else
13422     return 0;
13423
13424   vec_free (s);
13425   return 1;
13426 }
13427
13428 /**
13429  * Add/del remote mapping to/from LISP control plane
13430  *
13431  * @param vam vpp API test context
13432  * @return return code
13433  */
13434 static int
13435 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13436 {
13437   unformat_input_t *input = vam->input;
13438   vl_api_lisp_add_del_remote_mapping_t *mp;
13439   f64 timeout = ~0;
13440   u32 vni = 0;
13441   lisp_eid_vat_t _eid, *eid = &_eid;
13442   lisp_eid_vat_t _seid, *seid = &_seid;
13443   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13444   u32 action = ~0, p, w, data_len;
13445   ip4_address_t rloc4;
13446   ip6_address_t rloc6;
13447   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13448
13449   memset (&rloc, 0, sizeof (rloc));
13450
13451   /* Parse args required to build the message */
13452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13453     {
13454       if (unformat (input, "del-all"))
13455         {
13456           del_all = 1;
13457         }
13458       else if (unformat (input, "del"))
13459         {
13460           is_add = 0;
13461         }
13462       else if (unformat (input, "add"))
13463         {
13464           is_add = 1;
13465         }
13466       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13467         {
13468           eid_set = 1;
13469         }
13470       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13471         {
13472           seid_set = 1;
13473         }
13474       else if (unformat (input, "vni %d", &vni))
13475         {
13476           ;
13477         }
13478       else if (unformat (input, "p %d w %d", &p, &w))
13479         {
13480           if (!curr_rloc)
13481             {
13482               errmsg ("No RLOC configured for setting priority/weight!");
13483               return -99;
13484             }
13485           curr_rloc->priority = p;
13486           curr_rloc->weight = w;
13487         }
13488       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13489         {
13490           rloc.is_ip4 = 1;
13491           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13492           vec_add1 (rlocs, rloc);
13493           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13494         }
13495       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13496         {
13497           rloc.is_ip4 = 0;
13498           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13499           vec_add1 (rlocs, rloc);
13500           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13501         }
13502       else if (unformat (input, "action %U",
13503                          unformat_negative_mapping_action, &action))
13504         {
13505           ;
13506         }
13507       else
13508         {
13509           clib_warning ("parse error '%U'", format_unformat_error, input);
13510           return -99;
13511         }
13512     }
13513
13514   if (0 == eid_set)
13515     {
13516       errmsg ("missing params!");
13517       return -99;
13518     }
13519
13520   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13521     {
13522       errmsg ("no action set for negative map-reply!");
13523       return -99;
13524     }
13525
13526   data_len = vec_len (rlocs) * sizeof (rloc_t);
13527
13528   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13529   mp->is_add = is_add;
13530   mp->vni = htonl (vni);
13531   mp->action = (u8) action;
13532   mp->is_src_dst = seid_set;
13533   mp->eid_len = eid->len;
13534   mp->seid_len = seid->len;
13535   mp->del_all = del_all;
13536   mp->eid_type = eid->type;
13537   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13538   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13539
13540   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13541   clib_memcpy (mp->rlocs, rlocs, data_len);
13542   vec_free (rlocs);
13543
13544   /* send it... */
13545   S;
13546
13547   /* Wait for a reply... */
13548   W;
13549
13550   /* NOTREACHED */
13551   return 0;
13552 }
13553
13554 /**
13555  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13556  * forwarding entries in data-plane accordingly.
13557  *
13558  * @param vam vpp API test context
13559  * @return return code
13560  */
13561 static int
13562 api_lisp_add_del_adjacency (vat_main_t * vam)
13563 {
13564   unformat_input_t *input = vam->input;
13565   vl_api_lisp_add_del_adjacency_t *mp;
13566   f64 timeout = ~0;
13567   u32 vni = 0;
13568   ip4_address_t leid4, reid4;
13569   ip6_address_t leid6, reid6;
13570   u8 reid_mac[6] = { 0 };
13571   u8 leid_mac[6] = { 0 };
13572   u8 reid_type, leid_type;
13573   u32 leid_len = 0, reid_len = 0, len;
13574   u8 is_add = 1;
13575
13576   leid_type = reid_type = (u8) ~ 0;
13577
13578   /* Parse args required to build the message */
13579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13580     {
13581       if (unformat (input, "del"))
13582         {
13583           is_add = 0;
13584         }
13585       else if (unformat (input, "add"))
13586         {
13587           is_add = 1;
13588         }
13589       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13590                          &reid4, &len))
13591         {
13592           reid_type = 0;        /* ipv4 */
13593           reid_len = len;
13594         }
13595       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13596                          &reid6, &len))
13597         {
13598           reid_type = 1;        /* ipv6 */
13599           reid_len = len;
13600         }
13601       else if (unformat (input, "reid %U", unformat_ethernet_address,
13602                          reid_mac))
13603         {
13604           reid_type = 2;        /* mac */
13605         }
13606       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13607                          &leid4, &len))
13608         {
13609           leid_type = 0;        /* ipv4 */
13610           leid_len = len;
13611         }
13612       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13613                          &leid6, &len))
13614         {
13615           leid_type = 1;        /* ipv6 */
13616           leid_len = len;
13617         }
13618       else if (unformat (input, "leid %U", unformat_ethernet_address,
13619                          leid_mac))
13620         {
13621           leid_type = 2;        /* mac */
13622         }
13623       else if (unformat (input, "vni %d", &vni))
13624         {
13625           ;
13626         }
13627       else
13628         {
13629           errmsg ("parse error '%U'", format_unformat_error, input);
13630           return -99;
13631         }
13632     }
13633
13634   if ((u8) ~ 0 == reid_type)
13635     {
13636       errmsg ("missing params!");
13637       return -99;
13638     }
13639
13640   if (leid_type != reid_type)
13641     {
13642       errmsg ("remote and local EIDs are of different types!");
13643       return -99;
13644     }
13645
13646   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13647   mp->is_add = is_add;
13648   mp->vni = htonl (vni);
13649   mp->leid_len = leid_len;
13650   mp->reid_len = reid_len;
13651   mp->eid_type = reid_type;
13652
13653   switch (mp->eid_type)
13654     {
13655     case 0:
13656       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13657       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13658       break;
13659     case 1:
13660       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13661       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13662       break;
13663     case 2:
13664       clib_memcpy (mp->leid, leid_mac, 6);
13665       clib_memcpy (mp->reid, reid_mac, 6);
13666       break;
13667     default:
13668       errmsg ("unknown EID type %d!", mp->eid_type);
13669       return 0;
13670     }
13671
13672   /* send it... */
13673   S;
13674
13675   /* Wait for a reply... */
13676   W;
13677
13678   /* NOTREACHED */
13679   return 0;
13680 }
13681
13682 static int
13683 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13684 {
13685   unformat_input_t *input = vam->input;
13686   vl_api_lisp_gpe_add_del_iface_t *mp;
13687   f64 timeout = ~0;
13688   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13689   u32 dp_table = 0, vni = 0;
13690
13691   /* Parse args required to build the message */
13692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13693     {
13694       if (unformat (input, "up"))
13695         {
13696           action_set = 1;
13697           is_add = 1;
13698         }
13699       else if (unformat (input, "down"))
13700         {
13701           action_set = 1;
13702           is_add = 0;
13703         }
13704       else if (unformat (input, "table_id %d", &dp_table))
13705         {
13706           dp_table_set = 1;
13707         }
13708       else if (unformat (input, "bd_id %d", &dp_table))
13709         {
13710           dp_table_set = 1;
13711           is_l2 = 1;
13712         }
13713       else if (unformat (input, "vni %d", &vni))
13714         {
13715           vni_set = 1;
13716         }
13717       else
13718         break;
13719     }
13720
13721   if (action_set == 0)
13722     {
13723       errmsg ("Action not set\n");
13724       return -99;
13725     }
13726   if (dp_table_set == 0 || vni_set == 0)
13727     {
13728       errmsg ("vni and dp_table must be set\n");
13729       return -99;
13730     }
13731
13732   /* Construct the API message */
13733   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13734
13735   mp->is_add = is_add;
13736   mp->dp_table = dp_table;
13737   mp->is_l2 = is_l2;
13738   mp->vni = vni;
13739
13740   /* send it... */
13741   S;
13742
13743   /* Wait for a reply... */
13744   W;
13745
13746   /* NOTREACHED */
13747   return 0;
13748 }
13749
13750 /**
13751  * Add/del map request itr rlocs from LISP control plane and updates
13752  *
13753  * @param vam vpp API test context
13754  * @return return code
13755  */
13756 static int
13757 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13758 {
13759   unformat_input_t *input = vam->input;
13760   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13761   f64 timeout = ~0;
13762   u8 *locator_set_name = 0;
13763   u8 locator_set_name_set = 0;
13764   u8 is_add = 1;
13765
13766   /* Parse args required to build the message */
13767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13768     {
13769       if (unformat (input, "del"))
13770         {
13771           is_add = 0;
13772         }
13773       else if (unformat (input, "%_%v%_", &locator_set_name))
13774         {
13775           locator_set_name_set = 1;
13776         }
13777       else
13778         {
13779           clib_warning ("parse error '%U'", format_unformat_error, input);
13780           return -99;
13781         }
13782     }
13783
13784   if (is_add && !locator_set_name_set)
13785     {
13786       errmsg ("itr-rloc is not set!");
13787       return -99;
13788     }
13789
13790   if (is_add && vec_len (locator_set_name) > 64)
13791     {
13792       errmsg ("itr-rloc locator-set name too long\n");
13793       vec_free (locator_set_name);
13794       return -99;
13795     }
13796
13797   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13798   mp->is_add = is_add;
13799   if (is_add)
13800     {
13801       clib_memcpy (mp->locator_set_name, locator_set_name,
13802                    vec_len (locator_set_name));
13803     }
13804   else
13805     {
13806       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13807     }
13808   vec_free (locator_set_name);
13809
13810   /* send it... */
13811   S;
13812
13813   /* Wait for a reply... */
13814   W;
13815
13816   /* NOTREACHED */
13817   return 0;
13818 }
13819
13820 static int
13821 api_lisp_locator_dump (vat_main_t * vam)
13822 {
13823   unformat_input_t *input = vam->input;
13824   vl_api_lisp_locator_dump_t *mp;
13825   f64 timeout = ~0;
13826   u8 is_index_set = 0, is_name_set = 0;
13827   u8 *ls_name = 0;
13828   u32 ls_index = ~0;
13829
13830   /* Parse args required to build the message */
13831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13832     {
13833       if (unformat (input, "ls_name %_%v%_", &ls_name))
13834         {
13835           is_name_set = 1;
13836         }
13837       else if (unformat (input, "ls_index %d", &ls_index))
13838         {
13839           is_index_set = 1;
13840         }
13841       else
13842         {
13843           errmsg ("parse error '%U'", format_unformat_error, input);
13844           return -99;
13845         }
13846     }
13847
13848   if (!is_index_set && !is_name_set)
13849     {
13850       errmsg ("error: expected one of index or name!\n");
13851       return -99;
13852     }
13853
13854   if (is_index_set && is_name_set)
13855     {
13856       errmsg ("error: only one param expected!\n");
13857       return -99;
13858     }
13859
13860   if (vec_len (ls_name) > 62)
13861     {
13862       errmsg ("error: locator set name too long!");
13863       return -99;
13864     }
13865
13866   if (!vam->json_output)
13867     {
13868       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13869                "weight");
13870     }
13871
13872   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13873   mp->is_index_set = is_index_set;
13874
13875   if (is_index_set)
13876     mp->ls_index = clib_host_to_net_u32 (ls_index);
13877   else
13878     {
13879       vec_add1 (ls_name, 0);
13880       strncpy ((char *) mp->ls_name, (char *) ls_name,
13881                sizeof (mp->ls_name) - 1);
13882     }
13883
13884   /* send it... */
13885   S;
13886
13887   /* Use a control ping for synchronization */
13888   {
13889     vl_api_control_ping_t *mp;
13890     M (CONTROL_PING, control_ping);
13891     S;
13892   }
13893   /* Wait for a reply... */
13894   W;
13895
13896   /* NOTREACHED */
13897   return 0;
13898 }
13899
13900 static int
13901 api_lisp_locator_set_dump (vat_main_t * vam)
13902 {
13903   vl_api_lisp_locator_set_dump_t *mp;
13904   unformat_input_t *input = vam->input;
13905   f64 timeout = ~0;
13906   u8 filter = 0;
13907
13908   /* Parse args required to build the message */
13909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13910     {
13911       if (unformat (input, "local"))
13912         {
13913           filter = 1;
13914         }
13915       else if (unformat (input, "remote"))
13916         {
13917           filter = 2;
13918         }
13919       else
13920         {
13921           errmsg ("parse error '%U'", format_unformat_error, input);
13922           return -99;
13923         }
13924     }
13925
13926   if (!vam->json_output)
13927     {
13928       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13929     }
13930
13931   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13932
13933   mp->filter = filter;
13934
13935   /* send it... */
13936   S;
13937
13938   /* Use a control ping for synchronization */
13939   {
13940     vl_api_control_ping_t *mp;
13941     M (CONTROL_PING, control_ping);
13942     S;
13943   }
13944   /* Wait for a reply... */
13945   W;
13946
13947   /* NOTREACHED */
13948   return 0;
13949 }
13950
13951 static int
13952 api_lisp_eid_table_map_dump (vat_main_t * vam)
13953 {
13954   u8 is_l2 = 0;
13955   u8 mode_set = 0;
13956   unformat_input_t *input = vam->input;
13957   vl_api_lisp_eid_table_map_dump_t *mp;
13958   f64 timeout = ~0;
13959
13960   /* Parse args required to build the message */
13961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13962     {
13963       if (unformat (input, "l2"))
13964         {
13965           is_l2 = 1;
13966           mode_set = 1;
13967         }
13968       else if (unformat (input, "l3"))
13969         {
13970           is_l2 = 0;
13971           mode_set = 1;
13972         }
13973       else
13974         {
13975           errmsg ("parse error '%U'", format_unformat_error, input);
13976           return -99;
13977         }
13978     }
13979
13980   if (!mode_set)
13981     {
13982       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13983       return -99;
13984     }
13985
13986   if (!vam->json_output)
13987     {
13988       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13989     }
13990
13991   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13992   mp->is_l2 = is_l2;
13993
13994   /* send it... */
13995   S;
13996
13997   /* Use a control ping for synchronization */
13998   {
13999     vl_api_control_ping_t *mp;
14000     M (CONTROL_PING, control_ping);
14001     S;
14002   }
14003   /* Wait for a reply... */
14004   W;
14005
14006   /* NOTREACHED */
14007   return 0;
14008 }
14009
14010 static int
14011 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14012 {
14013   vl_api_lisp_eid_table_vni_dump_t *mp;
14014   f64 timeout = ~0;
14015
14016   if (!vam->json_output)
14017     {
14018       fformat (vam->ofp, "VNI\n");
14019     }
14020
14021   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14022
14023   /* send it... */
14024   S;
14025
14026   /* Use a control ping for synchronization */
14027   {
14028     vl_api_control_ping_t *mp;
14029     M (CONTROL_PING, control_ping);
14030     S;
14031   }
14032   /* Wait for a reply... */
14033   W;
14034
14035   /* NOTREACHED */
14036   return 0;
14037 }
14038
14039 static int
14040 api_lisp_eid_table_dump (vat_main_t * vam)
14041 {
14042   unformat_input_t *i = vam->input;
14043   vl_api_lisp_eid_table_dump_t *mp;
14044   f64 timeout = ~0;
14045   struct in_addr ip4;
14046   struct in6_addr ip6;
14047   u8 mac[6];
14048   u8 eid_type = ~0, eid_set = 0;
14049   u32 prefix_length = ~0, t, vni = 0;
14050   u8 filter = 0;
14051
14052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14053     {
14054       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14055         {
14056           eid_set = 1;
14057           eid_type = 0;
14058           prefix_length = t;
14059         }
14060       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14061         {
14062           eid_set = 1;
14063           eid_type = 1;
14064           prefix_length = t;
14065         }
14066       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14067         {
14068           eid_set = 1;
14069           eid_type = 2;
14070         }
14071       else if (unformat (i, "vni %d", &t))
14072         {
14073           vni = t;
14074         }
14075       else if (unformat (i, "local"))
14076         {
14077           filter = 1;
14078         }
14079       else if (unformat (i, "remote"))
14080         {
14081           filter = 2;
14082         }
14083       else
14084         {
14085           errmsg ("parse error '%U'", format_unformat_error, i);
14086           return -99;
14087         }
14088     }
14089
14090   if (!vam->json_output)
14091     {
14092       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14093                "ls_index", "ttl", "authoritative");
14094     }
14095
14096   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14097
14098   mp->filter = filter;
14099   if (eid_set)
14100     {
14101       mp->eid_set = 1;
14102       mp->vni = htonl (vni);
14103       mp->eid_type = eid_type;
14104       switch (eid_type)
14105         {
14106         case 0:
14107           mp->prefix_length = prefix_length;
14108           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14109           break;
14110         case 1:
14111           mp->prefix_length = prefix_length;
14112           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14113           break;
14114         case 2:
14115           clib_memcpy (mp->eid, mac, sizeof (mac));
14116           break;
14117         default:
14118           errmsg ("unknown EID type %d!", eid_type);
14119           return -99;
14120         }
14121     }
14122
14123   /* send it... */
14124   S;
14125
14126   /* Use a control ping for synchronization */
14127   {
14128     vl_api_control_ping_t *mp;
14129     M (CONTROL_PING, control_ping);
14130     S;
14131   }
14132
14133   /* Wait for a reply... */
14134   W;
14135
14136   /* NOTREACHED */
14137   return 0;
14138 }
14139
14140 static int
14141 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14142 {
14143   vl_api_lisp_gpe_tunnel_dump_t *mp;
14144   f64 timeout = ~0;
14145
14146   if (!vam->json_output)
14147     {
14148       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14149                "%=16s%=16s%=16s%=16s%=16s\n",
14150                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14151                "Decap next", "Lisp version", "Flags", "Next protocol",
14152                "ver_res", "res", "iid");
14153     }
14154
14155   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14156   /* send it... */
14157   S;
14158
14159   /* Use a control ping for synchronization */
14160   {
14161     vl_api_control_ping_t *mp;
14162     M (CONTROL_PING, control_ping);
14163     S;
14164   }
14165   /* Wait for a reply... */
14166   W;
14167
14168   /* NOTREACHED */
14169   return 0;
14170 }
14171
14172 static int
14173 api_lisp_adjacencies_get (vat_main_t * vam)
14174 {
14175   unformat_input_t *i = vam->input;
14176   vl_api_lisp_adjacencies_get_t *mp;
14177   f64 timeout = ~0;
14178   u8 vni_set = 0;
14179   u32 vni = ~0;
14180
14181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14182     {
14183       if (unformat (i, "vni %d", &vni))
14184         {
14185           vni_set = 1;
14186         }
14187       else
14188         {
14189           errmsg ("parse error '%U'\n", format_unformat_error, i);
14190           return -99;
14191         }
14192     }
14193
14194   if (!vni_set)
14195     {
14196       errmsg ("vni not set!\n");
14197       return -99;
14198     }
14199
14200   if (!vam->json_output)
14201     {
14202       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14203     }
14204
14205   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14206   mp->vni = clib_host_to_net_u32 (vni);
14207
14208   /* send it... */
14209   S;
14210
14211   /* Wait for a reply... */
14212   W;
14213
14214   /* NOTREACHED */
14215   return 0;
14216 }
14217
14218 static int
14219 api_lisp_map_resolver_dump (vat_main_t * vam)
14220 {
14221   vl_api_lisp_map_resolver_dump_t *mp;
14222   f64 timeout = ~0;
14223
14224   if (!vam->json_output)
14225     {
14226       fformat (vam->ofp, "%=20s\n", "Map resolver");
14227     }
14228
14229   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14230   /* send it... */
14231   S;
14232
14233   /* Use a control ping for synchronization */
14234   {
14235     vl_api_control_ping_t *mp;
14236     M (CONTROL_PING, control_ping);
14237     S;
14238   }
14239   /* Wait for a reply... */
14240   W;
14241
14242   /* NOTREACHED */
14243   return 0;
14244 }
14245
14246 static int
14247 api_show_lisp_status (vat_main_t * vam)
14248 {
14249   vl_api_show_lisp_status_t *mp;
14250   f64 timeout = ~0;
14251
14252   if (!vam->json_output)
14253     {
14254       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14255     }
14256
14257   M (SHOW_LISP_STATUS, show_lisp_status);
14258   /* send it... */
14259   S;
14260   /* Wait for a reply... */
14261   W;
14262
14263   /* NOTREACHED */
14264   return 0;
14265 }
14266
14267 static int
14268 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14269 {
14270   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14271   f64 timeout = ~0;
14272
14273   if (!vam->json_output)
14274     {
14275       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14276     }
14277
14278   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14279   /* send it... */
14280   S;
14281   /* Wait for a reply... */
14282   W;
14283
14284   /* NOTREACHED */
14285   return 0;
14286 }
14287
14288 static int
14289 api_af_packet_create (vat_main_t * vam)
14290 {
14291   unformat_input_t *i = vam->input;
14292   vl_api_af_packet_create_t *mp;
14293   f64 timeout;
14294   u8 *host_if_name = 0;
14295   u8 hw_addr[6];
14296   u8 random_hw_addr = 1;
14297
14298   memset (hw_addr, 0, sizeof (hw_addr));
14299
14300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14301     {
14302       if (unformat (i, "name %s", &host_if_name))
14303         vec_add1 (host_if_name, 0);
14304       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14305         random_hw_addr = 0;
14306       else
14307         break;
14308     }
14309
14310   if (!vec_len (host_if_name))
14311     {
14312       errmsg ("host-interface name must be specified");
14313       return -99;
14314     }
14315
14316   if (vec_len (host_if_name) > 64)
14317     {
14318       errmsg ("host-interface name too long");
14319       return -99;
14320     }
14321
14322   M (AF_PACKET_CREATE, af_packet_create);
14323
14324   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14325   clib_memcpy (mp->hw_addr, hw_addr, 6);
14326   mp->use_random_hw_addr = random_hw_addr;
14327   vec_free (host_if_name);
14328
14329   S;
14330   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14331   /* NOTREACHED */
14332   return 0;
14333 }
14334
14335 static int
14336 api_af_packet_delete (vat_main_t * vam)
14337 {
14338   unformat_input_t *i = vam->input;
14339   vl_api_af_packet_delete_t *mp;
14340   f64 timeout;
14341   u8 *host_if_name = 0;
14342
14343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14344     {
14345       if (unformat (i, "name %s", &host_if_name))
14346         vec_add1 (host_if_name, 0);
14347       else
14348         break;
14349     }
14350
14351   if (!vec_len (host_if_name))
14352     {
14353       errmsg ("host-interface name must be specified");
14354       return -99;
14355     }
14356
14357   if (vec_len (host_if_name) > 64)
14358     {
14359       errmsg ("host-interface name too long");
14360       return -99;
14361     }
14362
14363   M (AF_PACKET_DELETE, af_packet_delete);
14364
14365   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14366   vec_free (host_if_name);
14367
14368   S;
14369   W;
14370   /* NOTREACHED */
14371   return 0;
14372 }
14373
14374 static int
14375 api_policer_add_del (vat_main_t * vam)
14376 {
14377   unformat_input_t *i = vam->input;
14378   vl_api_policer_add_del_t *mp;
14379   f64 timeout;
14380   u8 is_add = 1;
14381   u8 *name = 0;
14382   u32 cir = 0;
14383   u32 eir = 0;
14384   u64 cb = 0;
14385   u64 eb = 0;
14386   u8 rate_type = 0;
14387   u8 round_type = 0;
14388   u8 type = 0;
14389   u8 color_aware = 0;
14390   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14391
14392   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14393   conform_action.dscp = 0;
14394   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14395   exceed_action.dscp = 0;
14396   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14397   violate_action.dscp = 0;
14398
14399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14400     {
14401       if (unformat (i, "del"))
14402         is_add = 0;
14403       else if (unformat (i, "name %s", &name))
14404         vec_add1 (name, 0);
14405       else if (unformat (i, "cir %u", &cir))
14406         ;
14407       else if (unformat (i, "eir %u", &eir))
14408         ;
14409       else if (unformat (i, "cb %u", &cb))
14410         ;
14411       else if (unformat (i, "eb %u", &eb))
14412         ;
14413       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14414                          &rate_type))
14415         ;
14416       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14417                          &round_type))
14418         ;
14419       else if (unformat (i, "type %U", unformat_policer_type, &type))
14420         ;
14421       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14422                          &conform_action))
14423         ;
14424       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14425                          &exceed_action))
14426         ;
14427       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14428                          &violate_action))
14429         ;
14430       else if (unformat (i, "color-aware"))
14431         color_aware = 1;
14432       else
14433         break;
14434     }
14435
14436   if (!vec_len (name))
14437     {
14438       errmsg ("policer name must be specified");
14439       return -99;
14440     }
14441
14442   if (vec_len (name) > 64)
14443     {
14444       errmsg ("policer name too long");
14445       return -99;
14446     }
14447
14448   M (POLICER_ADD_DEL, policer_add_del);
14449
14450   clib_memcpy (mp->name, name, vec_len (name));
14451   vec_free (name);
14452   mp->is_add = is_add;
14453   mp->cir = cir;
14454   mp->eir = eir;
14455   mp->cb = cb;
14456   mp->eb = eb;
14457   mp->rate_type = rate_type;
14458   mp->round_type = round_type;
14459   mp->type = type;
14460   mp->conform_action_type = conform_action.action_type;
14461   mp->conform_dscp = conform_action.dscp;
14462   mp->exceed_action_type = exceed_action.action_type;
14463   mp->exceed_dscp = exceed_action.dscp;
14464   mp->violate_action_type = violate_action.action_type;
14465   mp->violate_dscp = violate_action.dscp;
14466   mp->color_aware = color_aware;
14467
14468   S;
14469   W;
14470   /* NOTREACHED */
14471   return 0;
14472 }
14473
14474 static int
14475 api_policer_dump (vat_main_t * vam)
14476 {
14477   unformat_input_t *i = vam->input;
14478   vl_api_policer_dump_t *mp;
14479   f64 timeout = ~0;
14480   u8 *match_name = 0;
14481   u8 match_name_valid = 0;
14482
14483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14484     {
14485       if (unformat (i, "name %s", &match_name))
14486         {
14487           vec_add1 (match_name, 0);
14488           match_name_valid = 1;
14489         }
14490       else
14491         break;
14492     }
14493
14494   M (POLICER_DUMP, policer_dump);
14495   mp->match_name_valid = match_name_valid;
14496   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14497   vec_free (match_name);
14498   /* send it... */
14499   S;
14500
14501   /* Use a control ping for synchronization */
14502   {
14503     vl_api_control_ping_t *mp;
14504     M (CONTROL_PING, control_ping);
14505     S;
14506   }
14507   /* Wait for a reply... */
14508   W;
14509
14510   /* NOTREACHED */
14511   return 0;
14512 }
14513
14514 static int
14515 api_policer_classify_set_interface (vat_main_t * vam)
14516 {
14517   unformat_input_t *i = vam->input;
14518   vl_api_policer_classify_set_interface_t *mp;
14519   f64 timeout;
14520   u32 sw_if_index;
14521   int sw_if_index_set;
14522   u32 ip4_table_index = ~0;
14523   u32 ip6_table_index = ~0;
14524   u32 l2_table_index = ~0;
14525   u8 is_add = 1;
14526
14527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14528     {
14529       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14530         sw_if_index_set = 1;
14531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14532         sw_if_index_set = 1;
14533       else if (unformat (i, "del"))
14534         is_add = 0;
14535       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14536         ;
14537       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14538         ;
14539       else if (unformat (i, "l2-table %d", &l2_table_index))
14540         ;
14541       else
14542         {
14543           clib_warning ("parse error '%U'", format_unformat_error, i);
14544           return -99;
14545         }
14546     }
14547
14548   if (sw_if_index_set == 0)
14549     {
14550       errmsg ("missing interface name or sw_if_index\n");
14551       return -99;
14552     }
14553
14554   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14555
14556   mp->sw_if_index = ntohl (sw_if_index);
14557   mp->ip4_table_index = ntohl (ip4_table_index);
14558   mp->ip6_table_index = ntohl (ip6_table_index);
14559   mp->l2_table_index = ntohl (l2_table_index);
14560   mp->is_add = is_add;
14561
14562   S;
14563   W;
14564   /* NOTREACHED */
14565   return 0;
14566 }
14567
14568 static int
14569 api_policer_classify_dump (vat_main_t * vam)
14570 {
14571   unformat_input_t *i = vam->input;
14572   vl_api_policer_classify_dump_t *mp;
14573   f64 timeout = ~0;
14574   u8 type = POLICER_CLASSIFY_N_TABLES;
14575
14576   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14577     ;
14578   else
14579     {
14580       errmsg ("classify table type must be specified\n");
14581       return -99;
14582     }
14583
14584   if (!vam->json_output)
14585     {
14586       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14587     }
14588
14589   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14590   mp->type = type;
14591   /* send it... */
14592   S;
14593
14594   /* Use a control ping for synchronization */
14595   {
14596     vl_api_control_ping_t *mp;
14597     M (CONTROL_PING, control_ping);
14598     S;
14599   }
14600   /* Wait for a reply... */
14601   W;
14602
14603   /* NOTREACHED */
14604   return 0;
14605 }
14606
14607 static int
14608 api_netmap_create (vat_main_t * vam)
14609 {
14610   unformat_input_t *i = vam->input;
14611   vl_api_netmap_create_t *mp;
14612   f64 timeout;
14613   u8 *if_name = 0;
14614   u8 hw_addr[6];
14615   u8 random_hw_addr = 1;
14616   u8 is_pipe = 0;
14617   u8 is_master = 0;
14618
14619   memset (hw_addr, 0, sizeof (hw_addr));
14620
14621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14622     {
14623       if (unformat (i, "name %s", &if_name))
14624         vec_add1 (if_name, 0);
14625       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14626         random_hw_addr = 0;
14627       else if (unformat (i, "pipe"))
14628         is_pipe = 1;
14629       else if (unformat (i, "master"))
14630         is_master = 1;
14631       else if (unformat (i, "slave"))
14632         is_master = 0;
14633       else
14634         break;
14635     }
14636
14637   if (!vec_len (if_name))
14638     {
14639       errmsg ("interface name must be specified");
14640       return -99;
14641     }
14642
14643   if (vec_len (if_name) > 64)
14644     {
14645       errmsg ("interface name too long");
14646       return -99;
14647     }
14648
14649   M (NETMAP_CREATE, netmap_create);
14650
14651   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14652   clib_memcpy (mp->hw_addr, hw_addr, 6);
14653   mp->use_random_hw_addr = random_hw_addr;
14654   mp->is_pipe = is_pipe;
14655   mp->is_master = is_master;
14656   vec_free (if_name);
14657
14658   S;
14659   W;
14660   /* NOTREACHED */
14661   return 0;
14662 }
14663
14664 static int
14665 api_netmap_delete (vat_main_t * vam)
14666 {
14667   unformat_input_t *i = vam->input;
14668   vl_api_netmap_delete_t *mp;
14669   f64 timeout;
14670   u8 *if_name = 0;
14671
14672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14673     {
14674       if (unformat (i, "name %s", &if_name))
14675         vec_add1 (if_name, 0);
14676       else
14677         break;
14678     }
14679
14680   if (!vec_len (if_name))
14681     {
14682       errmsg ("interface name must be specified");
14683       return -99;
14684     }
14685
14686   if (vec_len (if_name) > 64)
14687     {
14688       errmsg ("interface name too long");
14689       return -99;
14690     }
14691
14692   M (NETMAP_DELETE, netmap_delete);
14693
14694   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14695   vec_free (if_name);
14696
14697   S;
14698   W;
14699   /* NOTREACHED */
14700   return 0;
14701 }
14702
14703 static void vl_api_mpls_eth_tunnel_details_t_handler
14704   (vl_api_mpls_eth_tunnel_details_t * mp)
14705 {
14706   vat_main_t *vam = &vat_main;
14707   i32 i;
14708   i32 len = ntohl (mp->nlabels);
14709
14710   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14711            ntohl (mp->tunnel_index),
14712            format_ethernet_address, &mp->tunnel_dst_mac,
14713            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14714   for (i = 0; i < len; i++)
14715     {
14716       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14717     }
14718   fformat (vam->ofp, "\n");
14719   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14720            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14721 }
14722
14723 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14724   (vl_api_mpls_eth_tunnel_details_t * mp)
14725 {
14726   vat_main_t *vam = &vat_main;
14727   vat_json_node_t *node = NULL;
14728   struct in_addr ip4;
14729   i32 i;
14730   i32 len = ntohl (mp->nlabels);
14731
14732   if (VAT_JSON_ARRAY != vam->json_tree.type)
14733     {
14734       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14735       vat_json_init_array (&vam->json_tree);
14736     }
14737   node = vat_json_array_add (&vam->json_tree);
14738
14739   vat_json_init_object (node);
14740   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14741   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14742   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14743   vat_json_object_add_uint (node, "inner_fib_index",
14744                             ntohl (mp->inner_fib_index));
14745   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14746   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14747   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14748   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14749   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14750                                    format (0, "%U", format_ethernet_address,
14751                                            &mp->tunnel_dst_mac));
14752   vat_json_object_add_uint (node, "tx_sw_if_index",
14753                             ntohl (mp->tx_sw_if_index));
14754   vat_json_object_add_uint (node, "label_count", len);
14755   for (i = 0; i < len; i++)
14756     {
14757       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14758     }
14759 }
14760
14761 static int
14762 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14763 {
14764   vl_api_mpls_eth_tunnel_dump_t *mp;
14765   f64 timeout;
14766   i32 index = -1;
14767
14768   /* Parse args required to build the message */
14769   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14770     {
14771       if (!unformat (vam->input, "tunnel_index %d", &index))
14772         {
14773           index = -1;
14774           break;
14775         }
14776     }
14777
14778   fformat (vam->ofp, "  tunnel_index %d\n", index);
14779
14780   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14781   mp->tunnel_index = htonl (index);
14782   S;
14783
14784   /* Use a control ping for synchronization */
14785   {
14786     vl_api_control_ping_t *mp;
14787     M (CONTROL_PING, control_ping);
14788     S;
14789   }
14790   W;
14791 }
14792
14793 static void vl_api_mpls_fib_encap_details_t_handler
14794   (vl_api_mpls_fib_encap_details_t * mp)
14795 {
14796   vat_main_t *vam = &vat_main;
14797   i32 i;
14798   i32 len = ntohl (mp->nlabels);
14799
14800   fformat (vam->ofp, "table %d, dest %U, label ",
14801            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14802   for (i = 0; i < len; i++)
14803     {
14804       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14805     }
14806   fformat (vam->ofp, "\n");
14807 }
14808
14809 static void vl_api_mpls_fib_encap_details_t_handler_json
14810   (vl_api_mpls_fib_encap_details_t * mp)
14811 {
14812   vat_main_t *vam = &vat_main;
14813   vat_json_node_t *node = NULL;
14814   i32 i;
14815   i32 len = ntohl (mp->nlabels);
14816   struct in_addr ip4;
14817
14818   if (VAT_JSON_ARRAY != vam->json_tree.type)
14819     {
14820       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14821       vat_json_init_array (&vam->json_tree);
14822     }
14823   node = vat_json_array_add (&vam->json_tree);
14824
14825   vat_json_init_object (node);
14826   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14827   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14828   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14829   vat_json_object_add_ip4 (node, "dest", ip4);
14830   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14831   vat_json_object_add_uint (node, "label_count", len);
14832   for (i = 0; i < len; i++)
14833     {
14834       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14835     }
14836 }
14837
14838 static int
14839 api_mpls_fib_encap_dump (vat_main_t * vam)
14840 {
14841   vl_api_mpls_fib_encap_dump_t *mp;
14842   f64 timeout;
14843
14844   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14845   S;
14846
14847   /* Use a control ping for synchronization */
14848   {
14849     vl_api_control_ping_t *mp;
14850     M (CONTROL_PING, control_ping);
14851     S;
14852   }
14853   W;
14854 }
14855
14856 static void
14857 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14858 {
14859   vat_main_t *vam = &vat_main;
14860
14861   fformat (vam->ofp,
14862            "table-id %d, label %u, ess_bit %u\n",
14863            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14864 }
14865
14866 static void vl_api_mpls_fib_details_t_handler_json
14867   (vl_api_mpls_fib_details_t * mp)
14868 {
14869   vat_main_t *vam = &vat_main;
14870   vat_json_node_t *node = NULL;
14871
14872   if (VAT_JSON_ARRAY != vam->json_tree.type)
14873     {
14874       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14875       vat_json_init_array (&vam->json_tree);
14876     }
14877   node = vat_json_array_add (&vam->json_tree);
14878
14879   vat_json_init_object (node);
14880   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14881   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14882   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14883 }
14884
14885 static int
14886 api_mpls_fib_dump (vat_main_t * vam)
14887 {
14888   vl_api_mpls_fib_dump_t *mp;
14889   f64 timeout;
14890
14891   M (MPLS_FIB_DUMP, mpls_fib_dump);
14892   S;
14893
14894   /* Use a control ping for synchronization */
14895   {
14896     vl_api_control_ping_t *mp;
14897     M (CONTROL_PING, control_ping);
14898     S;
14899   }
14900   W;
14901 }
14902
14903 int
14904 api_classify_table_ids (vat_main_t * vam)
14905 {
14906   vl_api_classify_table_ids_t *mp;
14907   f64 timeout;
14908
14909   /* Construct the API message */
14910   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14911   mp->context = 0;
14912
14913   S;
14914   W;
14915   /* NOTREACHED */
14916   return 0;
14917 }
14918
14919 int
14920 api_classify_table_by_interface (vat_main_t * vam)
14921 {
14922   unformat_input_t *input = vam->input;
14923   vl_api_classify_table_by_interface_t *mp;
14924   f64 timeout;
14925
14926   u32 sw_if_index = ~0;
14927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14928     {
14929       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14930         ;
14931       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14932         ;
14933       else
14934         break;
14935     }
14936   if (sw_if_index == ~0)
14937     {
14938       errmsg ("missing interface name or sw_if_index\n");
14939       return -99;
14940     }
14941
14942   /* Construct the API message */
14943   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14944   mp->context = 0;
14945   mp->sw_if_index = ntohl (sw_if_index);
14946
14947   S;
14948   W;
14949   /* NOTREACHED */
14950   return 0;
14951 }
14952
14953 int
14954 api_classify_table_info (vat_main_t * vam)
14955 {
14956   unformat_input_t *input = vam->input;
14957   vl_api_classify_table_info_t *mp;
14958   f64 timeout;
14959
14960   u32 table_id = ~0;
14961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14962     {
14963       if (unformat (input, "table_id %d", &table_id))
14964         ;
14965       else
14966         break;
14967     }
14968   if (table_id == ~0)
14969     {
14970       errmsg ("missing table id\n");
14971       return -99;
14972     }
14973
14974   /* Construct the API message */
14975   M (CLASSIFY_TABLE_INFO, classify_table_info);
14976   mp->context = 0;
14977   mp->table_id = ntohl (table_id);
14978
14979   S;
14980   W;
14981   /* NOTREACHED */
14982   return 0;
14983 }
14984
14985 int
14986 api_classify_session_dump (vat_main_t * vam)
14987 {
14988   unformat_input_t *input = vam->input;
14989   vl_api_classify_session_dump_t *mp;
14990   f64 timeout;
14991
14992   u32 table_id = ~0;
14993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14994     {
14995       if (unformat (input, "table_id %d", &table_id))
14996         ;
14997       else
14998         break;
14999     }
15000   if (table_id == ~0)
15001     {
15002       errmsg ("missing table id\n");
15003       return -99;
15004     }
15005
15006   /* Construct the API message */
15007   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15008   mp->context = 0;
15009   mp->table_id = ntohl (table_id);
15010   S;
15011
15012   /* Use a control ping for synchronization */
15013   {
15014     vl_api_control_ping_t *mp;
15015     M (CONTROL_PING, control_ping);
15016     S;
15017   }
15018   W;
15019   /* NOTREACHED */
15020   return 0;
15021 }
15022
15023 static void
15024 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15025 {
15026   vat_main_t *vam = &vat_main;
15027
15028   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15029            "src_address %U, vrf_id %d, path_mtu %u, "
15030            "template_interval %u, udp_checksum %d\n",
15031            format_ip4_address, mp->collector_address,
15032            ntohs (mp->collector_port),
15033            format_ip4_address, mp->src_address,
15034            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15035            ntohl (mp->template_interval), mp->udp_checksum);
15036
15037   vam->retval = 0;
15038   vam->result_ready = 1;
15039 }
15040
15041 static void
15042   vl_api_ipfix_exporter_details_t_handler_json
15043   (vl_api_ipfix_exporter_details_t * mp)
15044 {
15045   vat_main_t *vam = &vat_main;
15046   vat_json_node_t node;
15047   struct in_addr collector_address;
15048   struct in_addr src_address;
15049
15050   vat_json_init_object (&node);
15051   clib_memcpy (&collector_address, &mp->collector_address,
15052                sizeof (collector_address));
15053   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15054   vat_json_object_add_uint (&node, "collector_port",
15055                             ntohs (mp->collector_port));
15056   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15057   vat_json_object_add_ip4 (&node, "src_address", src_address);
15058   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15059   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15060   vat_json_object_add_uint (&node, "template_interval",
15061                             ntohl (mp->template_interval));
15062   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15063
15064   vat_json_print (vam->ofp, &node);
15065   vat_json_free (&node);
15066   vam->retval = 0;
15067   vam->result_ready = 1;
15068 }
15069
15070 int
15071 api_ipfix_exporter_dump (vat_main_t * vam)
15072 {
15073   vl_api_ipfix_exporter_dump_t *mp;
15074   f64 timeout;
15075
15076   /* Construct the API message */
15077   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15078   mp->context = 0;
15079
15080   S;
15081   W;
15082   /* NOTREACHED */
15083   return 0;
15084 }
15085
15086 static int
15087 api_ipfix_classify_stream_dump (vat_main_t * vam)
15088 {
15089   vl_api_ipfix_classify_stream_dump_t *mp;
15090   f64 timeout;
15091
15092   /* Construct the API message */
15093   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15094   mp->context = 0;
15095
15096   S;
15097   W;
15098   /* NOTREACHED */
15099   return 0;
15100 }
15101
15102 static void
15103   vl_api_ipfix_classify_stream_details_t_handler
15104   (vl_api_ipfix_classify_stream_details_t * mp)
15105 {
15106   vat_main_t *vam = &vat_main;
15107   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15108            ntohl (mp->domain_id), ntohs (mp->src_port));
15109   vam->retval = 0;
15110   vam->result_ready = 1;
15111 }
15112
15113 static void
15114   vl_api_ipfix_classify_stream_details_t_handler_json
15115   (vl_api_ipfix_classify_stream_details_t * mp)
15116 {
15117   vat_main_t *vam = &vat_main;
15118   vat_json_node_t node;
15119
15120   vat_json_init_object (&node);
15121   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15122   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15123
15124   vat_json_print (vam->ofp, &node);
15125   vat_json_free (&node);
15126   vam->retval = 0;
15127   vam->result_ready = 1;
15128 }
15129
15130 static int
15131 api_ipfix_classify_table_dump (vat_main_t * vam)
15132 {
15133   vl_api_ipfix_classify_table_dump_t *mp;
15134   f64 timeout;
15135
15136   if (!vam->json_output)
15137     {
15138       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15139                "transport_protocol");
15140     }
15141
15142   /* Construct the API message */
15143   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15144
15145   /* send it... */
15146   S;
15147
15148   /* Use a control ping for synchronization */
15149   {
15150     vl_api_control_ping_t *mp;
15151     M (CONTROL_PING, control_ping);
15152     S;
15153   }
15154   W;
15155 }
15156
15157 static void
15158   vl_api_ipfix_classify_table_details_t_handler
15159   (vl_api_ipfix_classify_table_details_t * mp)
15160 {
15161   vat_main_t *vam = &vat_main;
15162   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15163            mp->transport_protocol);
15164 }
15165
15166 static void
15167   vl_api_ipfix_classify_table_details_t_handler_json
15168   (vl_api_ipfix_classify_table_details_t * mp)
15169 {
15170   vat_json_node_t *node = NULL;
15171   vat_main_t *vam = &vat_main;
15172
15173   if (VAT_JSON_ARRAY != vam->json_tree.type)
15174     {
15175       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15176       vat_json_init_array (&vam->json_tree);
15177     }
15178
15179   node = vat_json_array_add (&vam->json_tree);
15180   vat_json_init_object (node);
15181
15182   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15183   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15184   vat_json_object_add_uint (node, "transport_protocol",
15185                             mp->transport_protocol);
15186 }
15187
15188 int
15189 api_pg_create_interface (vat_main_t * vam)
15190 {
15191   unformat_input_t *input = vam->input;
15192   vl_api_pg_create_interface_t *mp;
15193   f64 timeout;
15194
15195   u32 if_id = ~0;
15196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15197     {
15198       if (unformat (input, "if_id %d", &if_id))
15199         ;
15200       else
15201         break;
15202     }
15203   if (if_id == ~0)
15204     {
15205       errmsg ("missing pg interface index\n");
15206       return -99;
15207     }
15208
15209   /* Construct the API message */
15210   M (PG_CREATE_INTERFACE, pg_create_interface);
15211   mp->context = 0;
15212   mp->interface_id = ntohl (if_id);
15213
15214   S;
15215   W;
15216   /* NOTREACHED */
15217   return 0;
15218 }
15219
15220 int
15221 api_pg_capture (vat_main_t * vam)
15222 {
15223   unformat_input_t *input = vam->input;
15224   vl_api_pg_capture_t *mp;
15225   f64 timeout;
15226
15227   u32 if_id = ~0;
15228   u8 enable = 1;
15229   u32 count = 1;
15230   u8 pcap_file_set = 0;
15231   u8 *pcap_file = 0;
15232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15233     {
15234       if (unformat (input, "if_id %d", &if_id))
15235         ;
15236       else if (unformat (input, "pcap %s", &pcap_file))
15237         pcap_file_set = 1;
15238       else if (unformat (input, "count %d", &count))
15239         ;
15240       else if (unformat (input, "disable"))
15241         enable = 0;
15242       else
15243         break;
15244     }
15245   if (if_id == ~0)
15246     {
15247       errmsg ("missing pg interface index\n");
15248       return -99;
15249     }
15250   if (pcap_file_set > 0)
15251     {
15252       if (vec_len (pcap_file) > 255)
15253         {
15254           errmsg ("pcap file name is too long\n");
15255           return -99;
15256         }
15257     }
15258
15259   u32 name_len = vec_len (pcap_file);
15260   /* Construct the API message */
15261   M (PG_CAPTURE, pg_capture);
15262   mp->context = 0;
15263   mp->interface_id = ntohl (if_id);
15264   mp->is_enabled = enable;
15265   mp->count = ntohl (count);
15266   mp->pcap_name_length = ntohl (name_len);
15267   if (pcap_file_set != 0)
15268     {
15269       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15270     }
15271   vec_free (pcap_file);
15272
15273   S;
15274   W;
15275   /* NOTREACHED */
15276   return 0;
15277 }
15278
15279 int
15280 api_pg_enable_disable (vat_main_t * vam)
15281 {
15282   unformat_input_t *input = vam->input;
15283   vl_api_pg_enable_disable_t *mp;
15284   f64 timeout;
15285
15286   u8 enable = 1;
15287   u8 stream_name_set = 0;
15288   u8 *stream_name = 0;
15289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15290     {
15291       if (unformat (input, "stream %s", &stream_name))
15292         stream_name_set = 1;
15293       else if (unformat (input, "disable"))
15294         enable = 0;
15295       else
15296         break;
15297     }
15298
15299   if (stream_name_set > 0)
15300     {
15301       if (vec_len (stream_name) > 255)
15302         {
15303           errmsg ("stream name too long\n");
15304           return -99;
15305         }
15306     }
15307
15308   u32 name_len = vec_len (stream_name);
15309   /* Construct the API message */
15310   M (PG_ENABLE_DISABLE, pg_enable_disable);
15311   mp->context = 0;
15312   mp->is_enabled = enable;
15313   if (stream_name_set != 0)
15314     {
15315       mp->stream_name_length = ntohl (name_len);
15316       clib_memcpy (mp->stream_name, stream_name, name_len);
15317     }
15318   vec_free (stream_name);
15319
15320   S;
15321   W;
15322   /* NOTREACHED */
15323   return 0;
15324 }
15325
15326 int
15327 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15328 {
15329   unformat_input_t *input = vam->input;
15330   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15331   f64 timeout;
15332
15333   u16 *low_ports = 0;
15334   u16 *high_ports = 0;
15335   u16 this_low;
15336   u16 this_hi;
15337   ip4_address_t ip4_addr;
15338   ip6_address_t ip6_addr;
15339   u32 length;
15340   u32 tmp, tmp2;
15341   u8 prefix_set = 0;
15342   u32 vrf_id = ~0;
15343   u8 is_add = 1;
15344   u8 is_ipv6 = 0;
15345
15346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15347     {
15348       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15349         {
15350           prefix_set = 1;
15351         }
15352       else
15353         if (unformat
15354             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15355         {
15356           prefix_set = 1;
15357           is_ipv6 = 1;
15358         }
15359       else if (unformat (input, "vrf %d", &vrf_id))
15360         ;
15361       else if (unformat (input, "del"))
15362         is_add = 0;
15363       else if (unformat (input, "port %d", &tmp))
15364         {
15365           if (tmp == 0 || tmp > 65535)
15366             {
15367               errmsg ("port %d out of range", tmp);
15368               return -99;
15369             }
15370           this_low = tmp;
15371           this_hi = this_low + 1;
15372           vec_add1 (low_ports, this_low);
15373           vec_add1 (high_ports, this_hi);
15374         }
15375       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15376         {
15377           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15378             {
15379               errmsg ("incorrect range parameters\n");
15380               return -99;
15381             }
15382           this_low = tmp;
15383           /* Note: in debug CLI +1 is added to high before
15384              passing to real fn that does "the work"
15385              (ip_source_and_port_range_check_add_del).
15386              This fn is a wrapper around the binary API fn a
15387              control plane will call, which expects this increment
15388              to have occurred. Hence letting the binary API control
15389              plane fn do the increment for consistency between VAT
15390              and other control planes.
15391            */
15392           this_hi = tmp2;
15393           vec_add1 (low_ports, this_low);
15394           vec_add1 (high_ports, this_hi);
15395         }
15396       else
15397         break;
15398     }
15399
15400   if (prefix_set == 0)
15401     {
15402       errmsg ("<address>/<mask> not specified\n");
15403       return -99;
15404     }
15405
15406   if (vrf_id == ~0)
15407     {
15408       errmsg ("VRF ID required, not specified\n");
15409       return -99;
15410     }
15411
15412   if (vrf_id == 0)
15413     {
15414       errmsg
15415         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15416       return -99;
15417     }
15418
15419   if (vec_len (low_ports) == 0)
15420     {
15421       errmsg ("At least one port or port range required\n");
15422       return -99;
15423     }
15424
15425   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15426      ip_source_and_port_range_check_add_del);
15427
15428   mp->is_add = is_add;
15429
15430   if (is_ipv6)
15431     {
15432       mp->is_ipv6 = 1;
15433       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15434     }
15435   else
15436     {
15437       mp->is_ipv6 = 0;
15438       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15439     }
15440
15441   mp->mask_length = length;
15442   mp->number_of_ranges = vec_len (low_ports);
15443
15444   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15445   vec_free (low_ports);
15446
15447   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15448   vec_free (high_ports);
15449
15450   mp->vrf_id = ntohl (vrf_id);
15451
15452   S;
15453   W;
15454   /* NOTREACHED */
15455   return 0;
15456 }
15457
15458 int
15459 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15460 {
15461   unformat_input_t *input = vam->input;
15462   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15463   f64 timeout;
15464   u32 sw_if_index = ~0;
15465   int vrf_set = 0;
15466   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15467   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15468   u8 is_add = 1;
15469
15470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15471     {
15472       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15473         ;
15474       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15475         ;
15476       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15477         vrf_set = 1;
15478       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15479         vrf_set = 1;
15480       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15481         vrf_set = 1;
15482       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15483         vrf_set = 1;
15484       else if (unformat (input, "del"))
15485         is_add = 0;
15486       else
15487         break;
15488     }
15489
15490   if (sw_if_index == ~0)
15491     {
15492       errmsg ("Interface required but not specified\n");
15493       return -99;
15494     }
15495
15496   if (vrf_set == 0)
15497     {
15498       errmsg ("VRF ID required but not specified\n");
15499       return -99;
15500     }
15501
15502   if (tcp_out_vrf_id == 0
15503       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15504     {
15505       errmsg
15506         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15507       return -99;
15508     }
15509
15510   /* Construct the API message */
15511   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15512      ip_source_and_port_range_check_interface_add_del);
15513
15514   mp->sw_if_index = ntohl (sw_if_index);
15515   mp->is_add = is_add;
15516   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15517   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15518   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15519   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15520
15521   /* send it... */
15522   S;
15523
15524   /* Wait for a reply... */
15525   W;
15526 }
15527
15528 static int
15529 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15530 {
15531   unformat_input_t *i = vam->input;
15532   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15533   f64 timeout;
15534   u32 local_sa_id = 0;
15535   u32 remote_sa_id = 0;
15536   ip4_address_t src_address;
15537   ip4_address_t dst_address;
15538   u8 is_add = 1;
15539
15540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15541     {
15542       if (unformat (i, "local_sa %d", &local_sa_id))
15543         ;
15544       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15545         ;
15546       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15547         ;
15548       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15549         ;
15550       else if (unformat (i, "del"))
15551         is_add = 0;
15552       else
15553         {
15554           clib_warning ("parse error '%U'", format_unformat_error, i);
15555           return -99;
15556         }
15557     }
15558
15559   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15560
15561   mp->local_sa_id = ntohl (local_sa_id);
15562   mp->remote_sa_id = ntohl (remote_sa_id);
15563   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15564   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15565   mp->is_add = is_add;
15566
15567   S;
15568   W;
15569   /* NOTREACHED */
15570   return 0;
15571 }
15572
15573 static int
15574 api_punt (vat_main_t * vam)
15575 {
15576   unformat_input_t *i = vam->input;
15577   vl_api_punt_t *mp;
15578   f64 timeout;
15579   u32 ipv = ~0;
15580   u32 protocol = ~0;
15581   u32 port = ~0;
15582   int is_add = 1;
15583
15584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15585     {
15586       if (unformat (i, "ip %d", &ipv))
15587         ;
15588       else if (unformat (i, "protocol %d", &protocol))
15589         ;
15590       else if (unformat (i, "port %d", &port))
15591         ;
15592       else if (unformat (i, "del"))
15593         is_add = 0;
15594       else
15595         {
15596           clib_warning ("parse error '%U'", format_unformat_error, i);
15597           return -99;
15598         }
15599     }
15600
15601   M (PUNT, punt);
15602
15603   mp->is_add = (u8) is_add;
15604   mp->ipv = (u8) ipv;
15605   mp->l4_protocol = (u8) protocol;
15606   mp->l4_port = htons ((u16) port);
15607
15608   S;
15609   W;
15610   /* NOTREACHED */
15611   return 0;
15612 }
15613
15614 static void vl_api_ipsec_gre_tunnel_details_t_handler
15615   (vl_api_ipsec_gre_tunnel_details_t * mp)
15616 {
15617   vat_main_t *vam = &vat_main;
15618
15619   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15620            ntohl (mp->sw_if_index),
15621            format_ip4_address, &mp->src_address,
15622            format_ip4_address, &mp->dst_address,
15623            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15624 }
15625
15626 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15627   (vl_api_ipsec_gre_tunnel_details_t * mp)
15628 {
15629   vat_main_t *vam = &vat_main;
15630   vat_json_node_t *node = NULL;
15631   struct in_addr ip4;
15632
15633   if (VAT_JSON_ARRAY != vam->json_tree.type)
15634     {
15635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15636       vat_json_init_array (&vam->json_tree);
15637     }
15638   node = vat_json_array_add (&vam->json_tree);
15639
15640   vat_json_init_object (node);
15641   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15642   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15643   vat_json_object_add_ip4 (node, "src_address", ip4);
15644   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15645   vat_json_object_add_ip4 (node, "dst_address", ip4);
15646   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15647   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15648 }
15649
15650 static int
15651 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15652 {
15653   unformat_input_t *i = vam->input;
15654   vl_api_ipsec_gre_tunnel_dump_t *mp;
15655   f64 timeout;
15656   u32 sw_if_index;
15657   u8 sw_if_index_set = 0;
15658
15659   /* Parse args required to build the message */
15660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15661     {
15662       if (unformat (i, "sw_if_index %d", &sw_if_index))
15663         sw_if_index_set = 1;
15664       else
15665         break;
15666     }
15667
15668   if (sw_if_index_set == 0)
15669     {
15670       sw_if_index = ~0;
15671     }
15672
15673   if (!vam->json_output)
15674     {
15675       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15676                "sw_if_index", "src_address", "dst_address",
15677                "local_sa_id", "remote_sa_id");
15678     }
15679
15680   /* Get list of gre-tunnel interfaces */
15681   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15682
15683   mp->sw_if_index = htonl (sw_if_index);
15684
15685   S;
15686
15687   /* Use a control ping for synchronization */
15688   {
15689     vl_api_control_ping_t *mp;
15690     M (CONTROL_PING, control_ping);
15691     S;
15692   }
15693   W;
15694 }
15695
15696 static int
15697 api_delete_subif (vat_main_t * vam)
15698 {
15699   unformat_input_t *i = vam->input;
15700   vl_api_delete_subif_t *mp;
15701   f64 timeout;
15702   u32 sw_if_index = ~0;
15703
15704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15705     {
15706       if (unformat (i, "sw_if_index %d", &sw_if_index))
15707         ;
15708       else
15709         break;
15710     }
15711
15712   if (sw_if_index == ~0)
15713     {
15714       errmsg ("missing sw_if_index\n");
15715       return -99;
15716     }
15717
15718   /* Construct the API message */
15719   M (DELETE_SUBIF, delete_subif);
15720   mp->sw_if_index = ntohl (sw_if_index);
15721
15722   S;
15723   W;
15724 }
15725
15726 #define foreach_pbb_vtr_op      \
15727 _("disable",  L2_VTR_DISABLED)  \
15728 _("pop",  L2_VTR_POP_2)         \
15729 _("push",  L2_VTR_PUSH_2)
15730
15731 static int
15732 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15733 {
15734   unformat_input_t *i = vam->input;
15735   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15736   f64 timeout;
15737   u32 sw_if_index = ~0, vtr_op = ~0;
15738   u16 outer_tag = ~0;
15739   u8 dmac[6], smac[6];
15740   u8 dmac_set = 0, smac_set = 0;
15741   u16 vlanid = 0;
15742   u32 sid = ~0;
15743   u32 tmp;
15744
15745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15746     {
15747       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15748         ;
15749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15750         ;
15751       else if (unformat (i, "vtr_op %d", &vtr_op))
15752         ;
15753 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15754       foreach_pbb_vtr_op
15755 #undef _
15756         else if (unformat (i, "translate_pbb_stag"))
15757         {
15758           if (unformat (i, "%d", &tmp))
15759             {
15760               vtr_op = L2_VTR_TRANSLATE_2_1;
15761               outer_tag = tmp;
15762             }
15763           else
15764             {
15765               errmsg
15766                 ("translate_pbb_stag operation requires outer tag definition\n");
15767               return -99;
15768             }
15769         }
15770       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15771         dmac_set++;
15772       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15773         smac_set++;
15774       else if (unformat (i, "sid %d", &sid))
15775         ;
15776       else if (unformat (i, "vlanid %d", &tmp))
15777         vlanid = tmp;
15778       else
15779         {
15780           clib_warning ("parse error '%U'", format_unformat_error, i);
15781           return -99;
15782         }
15783     }
15784
15785   if ((sw_if_index == ~0) || (vtr_op == ~0))
15786     {
15787       errmsg ("missing sw_if_index or vtr operation\n");
15788       return -99;
15789     }
15790   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15791       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15792     {
15793       errmsg
15794         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15795       return -99;
15796     }
15797
15798   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15799   mp->sw_if_index = ntohl (sw_if_index);
15800   mp->vtr_op = ntohl (vtr_op);
15801   mp->outer_tag = ntohs (outer_tag);
15802   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15803   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15804   mp->b_vlanid = ntohs (vlanid);
15805   mp->i_sid = ntohl (sid);
15806
15807   S;
15808   W;
15809   /* NOTREACHED */
15810   return 0;
15811 }
15812
15813 static int
15814 api_flow_classify_set_interface (vat_main_t * vam)
15815 {
15816   unformat_input_t *i = vam->input;
15817   vl_api_flow_classify_set_interface_t *mp;
15818   f64 timeout;
15819   u32 sw_if_index;
15820   int sw_if_index_set;
15821   u32 ip4_table_index = ~0;
15822   u32 ip6_table_index = ~0;
15823   u8 is_add = 1;
15824
15825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15826     {
15827       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15828         sw_if_index_set = 1;
15829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15830         sw_if_index_set = 1;
15831       else if (unformat (i, "del"))
15832         is_add = 0;
15833       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15834         ;
15835       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15836         ;
15837       else
15838         {
15839           clib_warning ("parse error '%U'", format_unformat_error, i);
15840           return -99;
15841         }
15842     }
15843
15844   if (sw_if_index_set == 0)
15845     {
15846       errmsg ("missing interface name or sw_if_index\n");
15847       return -99;
15848     }
15849
15850   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
15851
15852   mp->sw_if_index = ntohl (sw_if_index);
15853   mp->ip4_table_index = ntohl (ip4_table_index);
15854   mp->ip6_table_index = ntohl (ip6_table_index);
15855   mp->is_add = is_add;
15856
15857   S;
15858   W;
15859   /* NOTREACHED */
15860   return 0;
15861 }
15862
15863 static int
15864 api_flow_classify_dump (vat_main_t * vam)
15865 {
15866   unformat_input_t *i = vam->input;
15867   vl_api_flow_classify_dump_t *mp;
15868   f64 timeout = ~0;
15869   u8 type = FLOW_CLASSIFY_N_TABLES;
15870
15871   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
15872     ;
15873   else
15874     {
15875       errmsg ("classify table type must be specified\n");
15876       return -99;
15877     }
15878
15879   if (!vam->json_output)
15880     {
15881       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15882     }
15883
15884   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
15885   mp->type = type;
15886   /* send it... */
15887   S;
15888
15889   /* Use a control ping for synchronization */
15890   {
15891     vl_api_control_ping_t *mp;
15892     M (CONTROL_PING, control_ping);
15893     S;
15894   }
15895   /* Wait for a reply... */
15896   W;
15897
15898   /* NOTREACHED */
15899   return 0;
15900 }
15901
15902 static int
15903 q_or_quit (vat_main_t * vam)
15904 {
15905   longjmp (vam->jump_buf, 1);
15906   return 0;                     /* not so much */
15907 }
15908
15909 static int
15910 q (vat_main_t * vam)
15911 {
15912   return q_or_quit (vam);
15913 }
15914
15915 static int
15916 quit (vat_main_t * vam)
15917 {
15918   return q_or_quit (vam);
15919 }
15920
15921 static int
15922 comment (vat_main_t * vam)
15923 {
15924   return 0;
15925 }
15926
15927 static int
15928 cmd_cmp (void *a1, void *a2)
15929 {
15930   u8 **c1 = a1;
15931   u8 **c2 = a2;
15932
15933   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15934 }
15935
15936 static int
15937 help (vat_main_t * vam)
15938 {
15939   u8 **cmds = 0;
15940   u8 *name = 0;
15941   hash_pair_t *p;
15942   unformat_input_t *i = vam->input;
15943   int j;
15944
15945   if (unformat (i, "%s", &name))
15946     {
15947       uword *hs;
15948
15949       vec_add1 (name, 0);
15950
15951       hs = hash_get_mem (vam->help_by_name, name);
15952       if (hs)
15953         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15954       else
15955         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15956       vec_free (name);
15957       return 0;
15958     }
15959
15960   fformat (vam->ofp, "Help is available for the following:\n");
15961
15962     /* *INDENT-OFF* */
15963     hash_foreach_pair (p, vam->function_by_name,
15964     ({
15965       vec_add1 (cmds, (u8 *)(p->key));
15966     }));
15967     /* *INDENT-ON* */
15968
15969   vec_sort_with_function (cmds, cmd_cmp);
15970
15971   for (j = 0; j < vec_len (cmds); j++)
15972     fformat (vam->ofp, "%s\n", cmds[j]);
15973
15974   vec_free (cmds);
15975   return 0;
15976 }
15977
15978 static int
15979 set (vat_main_t * vam)
15980 {
15981   u8 *name = 0, *value = 0;
15982   unformat_input_t *i = vam->input;
15983
15984   if (unformat (i, "%s", &name))
15985     {
15986       /* The input buffer is a vector, not a string. */
15987       value = vec_dup (i->buffer);
15988       vec_delete (value, i->index, 0);
15989       /* Almost certainly has a trailing newline */
15990       if (value[vec_len (value) - 1] == '\n')
15991         value[vec_len (value) - 1] = 0;
15992       /* Make sure it's a proper string, one way or the other */
15993       vec_add1 (value, 0);
15994       (void) clib_macro_set_value (&vam->macro_main,
15995                                    (char *) name, (char *) value);
15996     }
15997   else
15998     errmsg ("usage: set <name> <value>\n");
15999
16000   vec_free (name);
16001   vec_free (value);
16002   return 0;
16003 }
16004
16005 static int
16006 unset (vat_main_t * vam)
16007 {
16008   u8 *name = 0;
16009
16010   if (unformat (vam->input, "%s", &name))
16011     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16012       errmsg ("unset: %s wasn't set\n", name);
16013   vec_free (name);
16014   return 0;
16015 }
16016
16017 typedef struct
16018 {
16019   u8 *name;
16020   u8 *value;
16021 } macro_sort_t;
16022
16023
16024 static int
16025 macro_sort_cmp (void *a1, void *a2)
16026 {
16027   macro_sort_t *s1 = a1;
16028   macro_sort_t *s2 = a2;
16029
16030   return strcmp ((char *) (s1->name), (char *) (s2->name));
16031 }
16032
16033 static int
16034 dump_macro_table (vat_main_t * vam)
16035 {
16036   macro_sort_t *sort_me = 0, *sm;
16037   int i;
16038   hash_pair_t *p;
16039
16040     /* *INDENT-OFF* */
16041     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16042     ({
16043       vec_add2 (sort_me, sm, 1);
16044       sm->name = (u8 *)(p->key);
16045       sm->value = (u8 *) (p->value[0]);
16046     }));
16047     /* *INDENT-ON* */
16048
16049   vec_sort_with_function (sort_me, macro_sort_cmp);
16050
16051   if (vec_len (sort_me))
16052     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16053   else
16054     fformat (vam->ofp, "The macro table is empty...\n");
16055
16056   for (i = 0; i < vec_len (sort_me); i++)
16057     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16058   return 0;
16059 }
16060
16061 static int
16062 dump_node_table (vat_main_t * vam)
16063 {
16064   int i, j;
16065   vlib_node_t *node, *next_node;
16066
16067   if (vec_len (vam->graph_nodes) == 0)
16068     {
16069       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16070       return 0;
16071     }
16072
16073   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16074     {
16075       node = vam->graph_nodes[i];
16076       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16077       for (j = 0; j < vec_len (node->next_nodes); j++)
16078         {
16079           if (node->next_nodes[j] != ~0)
16080             {
16081               next_node = vam->graph_nodes[node->next_nodes[j]];
16082               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16083             }
16084         }
16085     }
16086   return 0;
16087 }
16088
16089 static int
16090 search_node_table (vat_main_t * vam)
16091 {
16092   unformat_input_t *line_input = vam->input;
16093   u8 *node_to_find;
16094   int j;
16095   vlib_node_t *node, *next_node;
16096   uword *p;
16097
16098   if (vam->graph_node_index_by_name == 0)
16099     {
16100       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16101       return 0;
16102     }
16103
16104   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16105     {
16106       if (unformat (line_input, "%s", &node_to_find))
16107         {
16108           vec_add1 (node_to_find, 0);
16109           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16110           if (p == 0)
16111             {
16112               fformat (vam->ofp, "%s not found...\n", node_to_find);
16113               goto out;
16114             }
16115           node = vam->graph_nodes[p[0]];
16116           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16117           for (j = 0; j < vec_len (node->next_nodes); j++)
16118             {
16119               if (node->next_nodes[j] != ~0)
16120                 {
16121                   next_node = vam->graph_nodes[node->next_nodes[j]];
16122                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16123                 }
16124             }
16125         }
16126
16127       else
16128         {
16129           clib_warning ("parse error '%U'", format_unformat_error,
16130                         line_input);
16131           return -99;
16132         }
16133
16134     out:
16135       vec_free (node_to_find);
16136
16137     }
16138
16139   return 0;
16140 }
16141
16142
16143 static int
16144 script (vat_main_t * vam)
16145 {
16146   u8 *s = 0;
16147   char *save_current_file;
16148   unformat_input_t save_input;
16149   jmp_buf save_jump_buf;
16150   u32 save_line_number;
16151
16152   FILE *new_fp, *save_ifp;
16153
16154   if (unformat (vam->input, "%s", &s))
16155     {
16156       new_fp = fopen ((char *) s, "r");
16157       if (new_fp == 0)
16158         {
16159           errmsg ("Couldn't open script file %s\n", s);
16160           vec_free (s);
16161           return -99;
16162         }
16163     }
16164   else
16165     {
16166       errmsg ("Missing script name\n");
16167       return -99;
16168     }
16169
16170   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16171   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16172   save_ifp = vam->ifp;
16173   save_line_number = vam->input_line_number;
16174   save_current_file = (char *) vam->current_file;
16175
16176   vam->input_line_number = 0;
16177   vam->ifp = new_fp;
16178   vam->current_file = s;
16179   do_one_file (vam);
16180
16181   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16182   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16183   vam->ifp = save_ifp;
16184   vam->input_line_number = save_line_number;
16185   vam->current_file = (u8 *) save_current_file;
16186   vec_free (s);
16187
16188   return 0;
16189 }
16190
16191 static int
16192 echo (vat_main_t * vam)
16193 {
16194   fformat (vam->ofp, "%v", vam->input->buffer);
16195   return 0;
16196 }
16197
16198 /* List of API message constructors, CLI names map to api_xxx */
16199 #define foreach_vpe_api_msg                                             \
16200 _(create_loopback,"[mac <mac-addr>]")                                   \
16201 _(sw_interface_dump,"")                                                 \
16202 _(sw_interface_set_flags,                                               \
16203   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16204 _(sw_interface_add_del_address,                                         \
16205   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16206 _(sw_interface_set_table,                                               \
16207   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16208 _(sw_interface_set_mpls_enable,                                                \
16209   "<intfc> | sw_if_index [disable | dis]")                                \
16210 _(sw_interface_set_vpath,                                               \
16211   "<intfc> | sw_if_index <id> enable | disable")                        \
16212 _(sw_interface_set_l2_xconnect,                                         \
16213   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16214   "enable | disable")                                                   \
16215 _(sw_interface_set_l2_bridge,                                           \
16216   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16217   "[shg <split-horizon-group>] [bvi]\n"                                 \
16218   "enable | disable")                                                   \
16219 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16220   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16221   "profile <profile-id>\n")                                             \
16222 _(sw_interface_set_dpdk_hqos_subport,                                   \
16223   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16224   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16225 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16226   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16227 _(bridge_domain_add_del,                                                \
16228   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16229 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16230 _(l2fib_add_del,                                                        \
16231   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16232 _(l2_flags,                                                             \
16233   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16234 _(bridge_flags,                                                         \
16235   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16236 _(tap_connect,                                                          \
16237   "tapname <name> mac <mac-addr> | random-mac")                         \
16238 _(tap_modify,                                                           \
16239   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16240 _(tap_delete,                                                           \
16241   "<vpp-if-name> | sw_if_index <id>")                                   \
16242 _(sw_interface_tap_dump, "")                                            \
16243 _(ip_add_del_route,                                                     \
16244   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16245   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16246   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16247   "[multipath] [count <n>]")                                            \
16248 _(mpls_route_add_del,                                                   \
16249   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16250   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16251   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16252   "[multipath] [count <n>]")                                            \
16253 _(mpls_ip_bind_unbind,                                                  \
16254   "<label> <addr/len>")                                                 \
16255 _(proxy_arp_add_del,                                                    \
16256   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16257 _(proxy_arp_intfc_enable_disable,                                       \
16258   "<intfc> | sw_if_index <id> enable | disable")                        \
16259 _(mpls_add_del_encap,                                                   \
16260   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16261 _(sw_interface_set_unnumbered,                                          \
16262   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16263 _(ip_neighbor_add_del,                                                  \
16264   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16265   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16266 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16267 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16268 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16269   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16270   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16271   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16272 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16273 _(reset_fib, "vrf <n> [ipv6]")                                          \
16274 _(dhcp_proxy_config,                                                    \
16275   "svr <v46-address> src <v46-address>\n"                               \
16276    "insert-cid <n> [del]")                                              \
16277 _(dhcp_proxy_config_2,                                                  \
16278   "svr <v46-address> src <v46-address>\n"                               \
16279    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16280 _(dhcp_proxy_set_vss,                                                   \
16281   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16282 _(dhcp_client_config,                                                   \
16283   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16284 _(set_ip_flow_hash,                                                     \
16285   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16286 _(sw_interface_ip6_enable_disable,                                      \
16287   "<intfc> | sw_if_index <id> enable | disable")                        \
16288 _(sw_interface_ip6_set_link_local_address,                              \
16289   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16290 _(sw_interface_ip6nd_ra_prefix,                                         \
16291   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16292   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16293   "[nolink] [isno]")                                                    \
16294 _(sw_interface_ip6nd_ra_config,                                         \
16295   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16296   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16297   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16298 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16299 _(l2_patch_add_del,                                                     \
16300   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16301   "enable | disable")                                                   \
16302 _(mpls_ethernet_add_del_tunnel,                                         \
16303   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16304   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16305 _(mpls_ethernet_add_del_tunnel_2,                                       \
16306   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16307   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16308 _(sr_tunnel_add_del,                                                    \
16309   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16310   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16311   "[policy <policy_name>]")                                             \
16312 _(sr_policy_add_del,                                                    \
16313   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16314 _(sr_multicast_map_add_del,                                             \
16315   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16316 _(classify_add_del_table,                                               \
16317   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16318   "[del] mask <mask-value>\n"                                           \
16319   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
16320 _(classify_add_del_session,                                             \
16321   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16322   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16323   "  [l3 [ip4|ip6]]")                                                   \
16324 _(classify_set_interface_ip_table,                                      \
16325   "<intfc> | sw_if_index <nn> table <nn>")                              \
16326 _(classify_set_interface_l2_tables,                                     \
16327   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16328   "  [other-table <nn>]")                                               \
16329 _(get_node_index, "node <node-name")                                    \
16330 _(add_node_next, "node <node-name> next <next-node-name>")              \
16331 _(l2tpv3_create_tunnel,                                                 \
16332   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16333   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16334   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16335 _(l2tpv3_set_tunnel_cookies,                                            \
16336   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16337   "[new_remote_cookie <nn>]\n")                                         \
16338 _(l2tpv3_interface_enable_disable,                                      \
16339   "<intfc> | sw_if_index <nn> enable | disable")                        \
16340 _(l2tpv3_set_lookup_key,                                                \
16341   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16342 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16343 _(vxlan_add_del_tunnel,                                                 \
16344   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16345   " [decap-next l2|ip4|ip6] [del]")                                     \
16346 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16347 _(gre_add_del_tunnel,                                                   \
16348   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16349 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16350 _(l2_fib_clear_table, "")                                               \
16351 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16352 _(l2_interface_vlan_tag_rewrite,                                        \
16353   "<intfc> | sw_if_index <nn> \n"                                       \
16354   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16355   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16356 _(create_vhost_user_if,                                                 \
16357         "socket <filename> [server] [renumber <dev_instance>] "         \
16358         "[mac <mac_address>]")                                          \
16359 _(modify_vhost_user_if,                                                 \
16360         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16361         "[server] [renumber <dev_instance>]")                           \
16362 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16363 _(sw_interface_vhost_user_dump, "")                                     \
16364 _(show_version, "")                                                     \
16365 _(vxlan_gpe_add_del_tunnel,                                             \
16366   "local <addr> remote <addr> vni <nn>\n"                               \
16367     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16368   "[next-ethernet] [next-nsh]\n")                                       \
16369 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16370 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16371 _(interface_name_renumber,                                              \
16372   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16373 _(input_acl_set_interface,                                              \
16374   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16375   "  [l2-table <nn>] [del]")                                            \
16376 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16377 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16378 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16379 _(ip_dump, "ipv4 | ipv6")                                               \
16380 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16381 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16382   "  spid_id <n> ")                                                     \
16383 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16384   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16385   "  integ_alg <alg> integ_key <hex>")                                  \
16386 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16387   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16388   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16389   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16390 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16391 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16392 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16393   "(auth_data 0x<data> | auth_data <data>)")                            \
16394 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16395   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16396 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16397   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16398   "(local|remote)")                                                     \
16399 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16400 _(delete_loopback,"sw_if_index <nn>")                                   \
16401 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16402 _(map_add_domain,                                                       \
16403   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16404   "ip6-src <ip6addr> "                                                  \
16405   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16406 _(map_del_domain, "index <n>")                                          \
16407 _(map_add_del_rule,                                                     \
16408   "index <n> psid <n> dst <ip6addr> [del]")                             \
16409 _(map_domain_dump, "")                                                  \
16410 _(map_rule_dump, "index <map-domain>")                                  \
16411 _(want_interface_events,  "enable|disable")                             \
16412 _(want_stats,"enable|disable")                                          \
16413 _(get_first_msg_id, "client <name>")                                    \
16414 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16415 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16416   "fib-id <nn> [ip4][ip6][default]")                                    \
16417 _(get_node_graph, " ")                                                  \
16418 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16419 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16420 _(ioam_disable, "")                                                \
16421 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16422                             " sw_if_index <sw_if_index> p <priority> "  \
16423                             "w <weight>] [del]")                        \
16424 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16425                         "iface <intf> | sw_if_index <sw_if_index> "     \
16426                         "p <priority> w <weight> [del]")                \
16427 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16428                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16429                           "locator-set <locator_name> [del]")           \
16430 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16431   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16432 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16433 _(lisp_gpe_enable_disable, "enable|disable")                            \
16434 _(lisp_enable_disable, "enable|disable")                                \
16435 _(lisp_gpe_add_del_iface, "up|down")                                    \
16436 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16437                                "[seid <seid>] "                         \
16438                                "rloc <locator> p <prio> "               \
16439                                "w <weight> [rloc <loc> ... ] "          \
16440                                "action <action> [del-all]")             \
16441 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16442                           "<local-eid>")                                \
16443 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16444 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16445 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16446 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16447 _(lisp_locator_set_dump, "[local | remote]")                            \
16448 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16449 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16450                        "[local] | [remote]")                            \
16451 _(lisp_eid_table_vni_dump, "")                                          \
16452 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16453 _(lisp_gpe_tunnel_dump, "")                                             \
16454 _(lisp_map_resolver_dump, "")                                           \
16455 _(lisp_adjacencies_get, "vni <vni>")                                    \
16456 _(show_lisp_status, "")                                                 \
16457 _(lisp_get_map_request_itr_rlocs, "")                                   \
16458 _(show_lisp_pitr, "")                                                   \
16459 _(show_lisp_map_request_mode, "")                                       \
16460 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16461 _(af_packet_delete, "name <host interface name>")                       \
16462 _(policer_add_del, "name <policer name> <params> [del]")                \
16463 _(policer_dump, "[name <policer name>]")                                \
16464 _(policer_classify_set_interface,                                       \
16465   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16466   "  [l2-table <nn>] [del]")                                            \
16467 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16468 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16469     "[master|slave]")                                                   \
16470 _(netmap_delete, "name <interface name>")                               \
16471 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16472 _(mpls_fib_encap_dump, "")                                              \
16473 _(mpls_fib_dump, "")                                                    \
16474 _(classify_table_ids, "")                                               \
16475 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16476 _(classify_table_info, "table_id <nn>")                                 \
16477 _(classify_session_dump, "table_id <nn>")                               \
16478 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16479     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16480     "[template_interval <nn>] [udp_checksum]")                          \
16481 _(ipfix_exporter_dump, "")                                              \
16482 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16483 _(ipfix_classify_stream_dump, "")                                       \
16484 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16485 _(ipfix_classify_table_dump, "")                                        \
16486 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16487 _(pg_create_interface, "if_id <nn>")                                    \
16488 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16489 _(pg_enable_disable, "[stream <id>] disable")                           \
16490 _(ip_source_and_port_range_check_add_del,                               \
16491   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16492 _(ip_source_and_port_range_check_interface_add_del,                     \
16493   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16494   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16495 _(ipsec_gre_add_del_tunnel,                                             \
16496   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16497 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16498 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
16499 _(l2_interface_pbb_tag_rewrite,                                         \
16500   "<intfc> | sw_if_index <nn> \n"                                       \
16501   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16502   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16503 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16504 _(flow_classify_set_interface,                                          \
16505   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16506 _(flow_classify_dump, "type [ip4|ip6]")
16507
16508 /* List of command functions, CLI names map directly to functions */
16509 #define foreach_cli_function                                    \
16510 _(comment, "usage: comment <ignore-rest-of-line>")              \
16511 _(dump_interface_table, "usage: dump_interface_table")          \
16512 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16513 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16514 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16515 _(dump_stats_table, "usage: dump_stats_table")                  \
16516 _(dump_macro_table, "usage: dump_macro_table ")                 \
16517 _(dump_node_table, "usage: dump_node_table")                    \
16518 _(echo, "usage: echo <message>")                                \
16519 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16520 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16521 _(help, "usage: help")                                          \
16522 _(q, "usage: quit")                                             \
16523 _(quit, "usage: quit")                                          \
16524 _(search_node_table, "usage: search_node_table <name>...")      \
16525 _(set, "usage: set <variable-name> <value>")                    \
16526 _(script, "usage: script <file-name>")                          \
16527 _(unset, "usage: unset <variable-name>")
16528
16529 #define _(N,n)                                  \
16530     static void vl_api_##n##_t_handler_uni      \
16531     (vl_api_##n##_t * mp)                       \
16532     {                                           \
16533         vat_main_t * vam = &vat_main;           \
16534         if (vam->json_output) {                 \
16535             vl_api_##n##_t_handler_json(mp);    \
16536         } else {                                \
16537             vl_api_##n##_t_handler(mp);         \
16538         }                                       \
16539     }
16540 foreach_vpe_api_reply_msg;
16541 #undef _
16542
16543 void
16544 vat_api_hookup (vat_main_t * vam)
16545 {
16546 #define _(N,n)                                                  \
16547     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16548                            vl_api_##n##_t_handler_uni,          \
16549                            vl_noop_handler,                     \
16550                            vl_api_##n##_t_endian,               \
16551                            vl_api_##n##_t_print,                \
16552                            sizeof(vl_api_##n##_t), 1);
16553   foreach_vpe_api_reply_msg;
16554 #undef _
16555
16556   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16557
16558   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16559
16560   vam->function_by_name = hash_create_string (0, sizeof (uword));
16561
16562   vam->help_by_name = hash_create_string (0, sizeof (uword));
16563
16564   /* API messages we can send */
16565 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16566   foreach_vpe_api_msg;
16567 #undef _
16568
16569   /* Help strings */
16570 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16571   foreach_vpe_api_msg;
16572 #undef _
16573
16574   /* CLI functions */
16575 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16576   foreach_cli_function;
16577 #undef _
16578
16579   /* Help strings */
16580 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16581   foreach_cli_function;
16582 #undef _
16583 }
16584
16585 #undef vl_api_version
16586 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16587 #include <vpp-api/vpe.api.h>
16588 #undef vl_api_version
16589
16590 void
16591 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16592 {
16593   /*
16594    * Send the main API signature in slot 0. This bit of code must
16595    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16596    */
16597   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16598 }
16599
16600 /*
16601  * fd.io coding-style-patch-verification: ON
16602  *
16603  * Local Variables:
16604  * eval: (c-set-style "gnu")
16605  * End:
16606  */